msi/tests: Opening package with relative filename sometimes succeeds on Windows.
[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, (LPOLESTR)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, (void *)buf, size, &size);
526     user = (PTOKEN_USER)buf;
527     pConvertSidToStringSidA(user->User.Sid, usersid);
528 }
529
530 static void test_MsiQueryProductState(void)
531 {
532     CHAR prodcode[MAX_PATH];
533     CHAR prod_squashed[MAX_PATH];
534     CHAR keypath[MAX_PATH*2];
535     LPSTR usersid;
536     INSTALLSTATE state;
537     LONG res;
538     HKEY userkey, localkey, props;
539     HKEY prodkey;
540     DWORD data;
541
542     create_test_guid(prodcode, prod_squashed);
543     get_user_sid(&usersid);
544
545     /* NULL prodcode */
546     state = MsiQueryProductStateA(NULL);
547     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
548
549     /* empty prodcode */
550     state = MsiQueryProductStateA("");
551     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
552
553     /* garbage prodcode */
554     state = MsiQueryProductStateA("garbage");
555     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
556
557     /* guid without brackets */
558     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
559     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
560
561     /* guid with brackets */
562     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
563     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
564
565     /* same length as guid, but random */
566     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
567     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
568
569     /* MSIINSTALLCONTEXT_USERUNMANAGED */
570
571     state = MsiQueryProductStateA(prodcode);
572     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
573
574     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
575     lstrcatA(keypath, prod_squashed);
576
577     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
579
580     /* user product key exists */
581     state = MsiQueryProductStateA(prodcode);
582     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
583
584     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
585     lstrcatA(keypath, prodcode);
586
587     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
589
590     /* local uninstall key exists */
591     state = MsiQueryProductStateA(prodcode);
592     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
593
594     data = 1;
595     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
597
598     /* WindowsInstaller value exists */
599     state = MsiQueryProductStateA(prodcode);
600     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
601
602     RegDeleteValueA(localkey, "WindowsInstaller");
603     RegDeleteKeyA(localkey, "");
604
605     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
606     lstrcatA(keypath, usersid);
607     lstrcatA(keypath, "\\Products\\");
608     lstrcatA(keypath, prod_squashed);
609
610     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
612
613     /* local product key exists */
614     state = MsiQueryProductStateA(prodcode);
615     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
616
617     res = RegCreateKeyA(localkey, "InstallProperties", &props);
618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
619
620     /* install properties key exists */
621     state = MsiQueryProductStateA(prodcode);
622     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
623
624     data = 1;
625     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
627
628     /* WindowsInstaller value exists */
629     state = MsiQueryProductStateA(prodcode);
630     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
631
632     data = 2;
633     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
635
636     /* WindowsInstaller value is not 1 */
637     state = MsiQueryProductStateA(prodcode);
638     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
639
640     RegDeleteKeyA(userkey, "");
641
642     /* user product key does not exist */
643     state = MsiQueryProductStateA(prodcode);
644     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
645
646     RegDeleteValueA(props, "WindowsInstaller");
647     RegDeleteKeyA(props, "");
648     RegCloseKey(props);
649     RegDeleteKeyA(localkey, "");
650     RegCloseKey(localkey);
651     RegDeleteKeyA(userkey, "");
652     RegCloseKey(userkey);
653
654     /* MSIINSTALLCONTEXT_USERMANAGED */
655
656     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
657     lstrcatA(keypath, usersid);
658     lstrcatA(keypath, "\\Installer\\Products\\");
659     lstrcatA(keypath, prod_squashed);
660
661     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
663
664     state = MsiQueryProductStateA(prodcode);
665     ok(state == INSTALLSTATE_ADVERTISED,
666        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
667
668     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
669     lstrcatA(keypath, usersid);
670     lstrcatA(keypath, "\\Products\\");
671     lstrcatA(keypath, prod_squashed);
672
673     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
675
676     state = MsiQueryProductStateA(prodcode);
677     ok(state == INSTALLSTATE_ADVERTISED,
678        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
679
680     res = RegCreateKeyA(localkey, "InstallProperties", &props);
681     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
682
683     state = MsiQueryProductStateA(prodcode);
684     ok(state == INSTALLSTATE_ADVERTISED,
685        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
686
687     data = 1;
688     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
690
691     /* WindowsInstaller value exists */
692     state = MsiQueryProductStateA(prodcode);
693     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
694
695     RegDeleteValueA(props, "WindowsInstaller");
696     RegDeleteKeyA(props, "");
697     RegCloseKey(props);
698     RegDeleteKeyA(localkey, "");
699     RegCloseKey(localkey);
700     RegDeleteKeyA(prodkey, "");
701     RegCloseKey(prodkey);
702
703     /* MSIINSTALLCONTEXT_MACHINE */
704
705     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
706     lstrcatA(keypath, prod_squashed);
707
708     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
710
711     state = MsiQueryProductStateA(prodcode);
712     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
713
714     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
715     lstrcatA(keypath, "S-1-5-18\\Products\\");
716     lstrcatA(keypath, prod_squashed);
717
718     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
720
721     state = MsiQueryProductStateA(prodcode);
722     ok(state == INSTALLSTATE_ADVERTISED,
723        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
724
725     res = RegCreateKeyA(localkey, "InstallProperties", &props);
726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
727
728     state = MsiQueryProductStateA(prodcode);
729     ok(state == INSTALLSTATE_ADVERTISED,
730        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
731
732     data = 1;
733     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
735
736     /* WindowsInstaller value exists */
737     state = MsiQueryProductStateA(prodcode);
738     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
739
740     RegDeleteValueA(props, "WindowsInstaller");
741     RegDeleteKeyA(props, "");
742     RegCloseKey(props);
743     RegDeleteKeyA(localkey, "");
744     RegCloseKey(localkey);
745     RegDeleteKeyA(prodkey, "");
746     RegCloseKey(prodkey);
747
748     LocalFree(usersid);
749 }
750
751 static const char table_enc85[] =
752 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
753 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
754 "yz{}~";
755
756 /*
757  *  Encodes a base85 guid given a GUID pointer
758  *  Caller should provide a 21 character buffer for the encoded string.
759  *
760  *  returns TRUE if successful, FALSE if not
761  */
762 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
763 {
764     unsigned int x, *p, i;
765
766     p = (unsigned int*) guid;
767     for( i=0; i<4; i++ )
768     {
769         x = p[i];
770         *str++ = table_enc85[x%85];
771         x = x/85;
772         *str++ = table_enc85[x%85];
773         x = x/85;
774         *str++ = table_enc85[x%85];
775         x = x/85;
776         *str++ = table_enc85[x%85];
777         x = x/85;
778         *str++ = table_enc85[x%85];
779     }
780     *str = 0;
781
782     return TRUE;
783 }
784
785 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
786 {
787     WCHAR guidW[MAX_PATH];
788     WCHAR base85W[MAX_PATH];
789     WCHAR squashedW[MAX_PATH];
790     GUID guid;
791     HRESULT hr;
792     int size;
793
794     hr = CoCreateGuid(&guid);
795     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
796
797     size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
798     ok(size == 39, "Expected 39, got %d\n", hr);
799
800     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
801     encode_base85_guid(&guid, base85W);
802     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
803     squash_guid(guidW, squashedW);
804     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
805 }
806
807 static void test_MsiQueryFeatureState(void)
808 {
809     HKEY userkey, localkey, compkey;
810     CHAR prodcode[MAX_PATH];
811     CHAR prod_squashed[MAX_PATH];
812     CHAR component[MAX_PATH];
813     CHAR comp_base85[MAX_PATH];
814     CHAR comp_squashed[MAX_PATH];
815     CHAR keypath[MAX_PATH*2];
816     INSTALLSTATE state;
817     LPSTR usersid;
818     LONG res;
819
820     create_test_guid(prodcode, prod_squashed);
821     compose_base85_guid(component, comp_base85, comp_squashed);
822     get_user_sid(&usersid);
823
824     /* NULL prodcode */
825     state = MsiQueryFeatureStateA(NULL, "feature");
826     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
827
828     /* empty prodcode */
829     state = MsiQueryFeatureStateA("", "feature");
830     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
831
832     /* garbage prodcode */
833     state = MsiQueryFeatureStateA("garbage", "feature");
834     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
835
836     /* guid without brackets */
837     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
838     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
839
840     /* guid with brackets */
841     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
842     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
843
844     /* same length as guid, but random */
845     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
846     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
847
848     /* NULL szFeature */
849     state = MsiQueryFeatureStateA(prodcode, NULL);
850     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
851
852     /* empty szFeature */
853     state = MsiQueryFeatureStateA(prodcode, "");
854     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
855
856     /* feature key does not exist yet */
857     state = MsiQueryFeatureStateA(prodcode, "feature");
858     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
859
860     /* MSIINSTALLCONTEXT_USERUNMANAGED */
861
862     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
863     lstrcatA(keypath, prod_squashed);
864
865     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
867
868     /* feature key exists */
869     state = MsiQueryFeatureStateA(prodcode, "feature");
870     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
871
872     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
874
875     /* feature value exists */
876     state = MsiQueryFeatureStateA(prodcode, "feature");
877     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
878
879     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
880     lstrcatA(keypath, usersid);
881     lstrcatA(keypath, "\\Products\\");
882     lstrcatA(keypath, prod_squashed);
883     lstrcatA(keypath, "\\Features");
884
885     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
887
888     /* userdata features key exists */
889     state = MsiQueryFeatureStateA(prodcode, "feature");
890     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
891
892     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
894
895     state = MsiQueryFeatureStateA(prodcode, "feature");
896     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
897
898     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
900
901     state = MsiQueryFeatureStateA(prodcode, "feature");
902     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
903
904     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
906
907     state = MsiQueryFeatureStateA(prodcode, "feature");
908     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
909
910     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
911     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
912
913     state = MsiQueryFeatureStateA(prodcode, "feature");
914     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
915
916     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
917     lstrcatA(keypath, usersid);
918     lstrcatA(keypath, "\\Components\\");
919     lstrcatA(keypath, comp_squashed);
920
921     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
922     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
923
924     state = MsiQueryFeatureStateA(prodcode, "feature");
925     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
926
927     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
929
930     state = MsiQueryFeatureStateA(prodcode, "feature");
931     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
932
933     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
934     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
935
936     /* INSTALLSTATE_LOCAL */
937     state = MsiQueryFeatureStateA(prodcode, "feature");
938     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
939
940     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
941     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
942
943     /* INSTALLSTATE_SOURCE */
944     state = MsiQueryFeatureStateA(prodcode, "feature");
945     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
946
947     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
949
950     /* bad INSTALLSTATE_SOURCE */
951     state = MsiQueryFeatureStateA(prodcode, "feature");
952     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
953
954     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
956
957     /* INSTALLSTATE_SOURCE */
958     state = MsiQueryFeatureStateA(prodcode, "feature");
959     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
960
961     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
963
964     /* bad INSTALLSTATE_SOURCE */
965     state = MsiQueryFeatureStateA(prodcode, "feature");
966     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
967
968     RegDeleteValueA(compkey, prod_squashed);
969     RegDeleteKeyA(compkey, "");
970     RegDeleteValueA(localkey, "feature");
971     RegDeleteValueA(userkey, "feature");
972     RegDeleteKeyA(userkey, "");
973     RegCloseKey(compkey);
974     RegCloseKey(localkey);
975     RegCloseKey(userkey);
976
977     /* MSIINSTALLCONTEXT_USERMANAGED */
978
979     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
980     lstrcatA(keypath, usersid);
981     lstrcatA(keypath, "\\Installer\\Features\\");
982     lstrcatA(keypath, prod_squashed);
983
984     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
986
987     /* feature key exists */
988     state = MsiQueryFeatureStateA(prodcode, "feature");
989     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
990
991     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
993
994     /* feature value exists */
995     state = MsiQueryFeatureStateA(prodcode, "feature");
996     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
997
998     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
999     lstrcatA(keypath, usersid);
1000     lstrcatA(keypath, "\\Products\\");
1001     lstrcatA(keypath, prod_squashed);
1002     lstrcatA(keypath, "\\Features");
1003
1004     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1006
1007     /* userdata features key exists */
1008     state = MsiQueryFeatureStateA(prodcode, "feature");
1009     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1010
1011     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1013
1014     state = MsiQueryFeatureStateA(prodcode, "feature");
1015     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1016
1017     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1019
1020     state = MsiQueryFeatureStateA(prodcode, "feature");
1021     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1022
1023     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1025
1026     state = MsiQueryFeatureStateA(prodcode, "feature");
1027     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1028
1029     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1030     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1031
1032     state = MsiQueryFeatureStateA(prodcode, "feature");
1033     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1034
1035     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1036     lstrcatA(keypath, usersid);
1037     lstrcatA(keypath, "\\Components\\");
1038     lstrcatA(keypath, comp_squashed);
1039
1040     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1042
1043     state = MsiQueryFeatureStateA(prodcode, "feature");
1044     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1045
1046     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1048
1049     state = MsiQueryFeatureStateA(prodcode, "feature");
1050     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1051
1052     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1054
1055     state = MsiQueryFeatureStateA(prodcode, "feature");
1056     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1057
1058     RegDeleteValueA(compkey, prod_squashed);
1059     RegDeleteKeyA(compkey, "");
1060     RegDeleteValueA(localkey, "feature");
1061     RegDeleteValueA(userkey, "feature");
1062     RegDeleteKeyA(userkey, "");
1063     RegCloseKey(compkey);
1064     RegCloseKey(localkey);
1065     RegCloseKey(userkey);
1066
1067     /* MSIINSTALLCONTEXT_MACHINE */
1068
1069     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1070     lstrcatA(keypath, prod_squashed);
1071
1072     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1074
1075     /* feature key exists */
1076     state = MsiQueryFeatureStateA(prodcode, "feature");
1077     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1078
1079     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082     /* feature value exists */
1083     state = MsiQueryFeatureStateA(prodcode, "feature");
1084     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1085
1086     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1087     lstrcatA(keypath, "S-1-5-18\\Products\\");
1088     lstrcatA(keypath, prod_squashed);
1089     lstrcatA(keypath, "\\Features");
1090
1091     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1093
1094     /* userdata features key exists */
1095     state = MsiQueryFeatureStateA(prodcode, "feature");
1096     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1097
1098     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1100
1101     state = MsiQueryFeatureStateA(prodcode, "feature");
1102     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1103
1104     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1106
1107     state = MsiQueryFeatureStateA(prodcode, "feature");
1108     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1109
1110     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1112
1113     state = MsiQueryFeatureStateA(prodcode, "feature");
1114     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1115
1116     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1118
1119     state = MsiQueryFeatureStateA(prodcode, "feature");
1120     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1121
1122     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1123     lstrcatA(keypath, "S-1-5-18\\Components\\");
1124     lstrcatA(keypath, comp_squashed);
1125
1126     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1128
1129     state = MsiQueryFeatureStateA(prodcode, "feature");
1130     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1131
1132     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1134
1135     state = MsiQueryFeatureStateA(prodcode, "feature");
1136     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1137
1138     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1140
1141     state = MsiQueryFeatureStateA(prodcode, "feature");
1142     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1143
1144     RegDeleteValueA(compkey, prod_squashed);
1145     RegDeleteKeyA(compkey, "");
1146     RegDeleteValueA(localkey, "feature");
1147     RegDeleteValueA(userkey, "feature");
1148     RegDeleteKeyA(userkey, "");
1149     RegCloseKey(compkey);
1150     RegCloseKey(localkey);
1151     RegCloseKey(userkey);
1152 }
1153
1154 static void test_MsiQueryComponentState(void)
1155 {
1156     HKEY compkey, prodkey;
1157     CHAR prodcode[MAX_PATH];
1158     CHAR prod_squashed[MAX_PATH];
1159     CHAR component[MAX_PATH];
1160     CHAR comp_base85[MAX_PATH];
1161     CHAR comp_squashed[MAX_PATH];
1162     CHAR keypath[MAX_PATH];
1163     INSTALLSTATE state;
1164     LPSTR usersid;
1165     LONG res;
1166     UINT r;
1167
1168     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1169
1170     if (!pMsiQueryComponentStateA)
1171     {
1172         skip("MsiQueryComponentStateA not implemented\n");
1173         return;
1174     }
1175
1176     create_test_guid(prodcode, prod_squashed);
1177     compose_base85_guid(component, comp_base85, comp_squashed);
1178     get_user_sid(&usersid);
1179
1180     /* NULL szProductCode */
1181     state = MAGIC_ERROR;
1182     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1183     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1184     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1185
1186     /* empty szProductCode */
1187     state = MAGIC_ERROR;
1188     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1189     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1190     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1191
1192     /* random szProductCode */
1193     state = MAGIC_ERROR;
1194     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1195     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1196     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1197
1198     /* GUID-length szProductCode */
1199     state = MAGIC_ERROR;
1200     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1201     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1202     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1203
1204     /* GUID-length with brackets */
1205     state = MAGIC_ERROR;
1206     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1207     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1208     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1209
1210     /* actual GUID */
1211     state = MAGIC_ERROR;
1212     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1213     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1214     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1215
1216     state = MAGIC_ERROR;
1217     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1218     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1219     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1220
1221     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1222     lstrcatA(keypath, prod_squashed);
1223
1224     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1226
1227     state = MAGIC_ERROR;
1228     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1229     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1230     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1231
1232     RegDeleteKeyA(prodkey, "");
1233     RegCloseKey(prodkey);
1234
1235     /* create local system product key */
1236     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1237     lstrcatA(keypath, prod_squashed);
1238     lstrcatA(keypath, "\\InstallProperties");
1239
1240     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1242
1243     /* local system product key exists */
1244     state = MAGIC_ERROR;
1245     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1246     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1247     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1248
1249     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1251
1252     /* LocalPackage value exists */
1253     state = MAGIC_ERROR;
1254     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1255     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1256     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1257
1258     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1259     lstrcatA(keypath, comp_squashed);
1260
1261     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1263
1264     /* component key exists */
1265     state = MAGIC_ERROR;
1266     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1267     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1268     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1269
1270     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1272
1273     /* component\product exists */
1274     state = MAGIC_ERROR;
1275     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1277     ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
1278
1279     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1281
1282     /* INSTALLSTATE_LOCAL */
1283     state = MAGIC_ERROR;
1284     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1286     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1287
1288     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1290
1291     /* INSTALLSTATE_SOURCE */
1292     state = MAGIC_ERROR;
1293     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1294     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1295     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1296
1297     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1299
1300     /* bad INSTALLSTATE_SOURCE */
1301     state = MAGIC_ERROR;
1302     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1303     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1304     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1305
1306     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1308
1309     /* INSTALLSTATE_SOURCE */
1310     state = MAGIC_ERROR;
1311     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1312     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1313     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1314
1315     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1317
1318     /* bad INSTALLSTATE_SOURCE */
1319     state = MAGIC_ERROR;
1320     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1321     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1322     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1323
1324     RegDeleteValueA(prodkey, "LocalPackage");
1325     RegDeleteKeyA(prodkey, "");
1326     RegDeleteValueA(compkey, prod_squashed);
1327     RegDeleteKeyA(prodkey, "");
1328     RegCloseKey(prodkey);
1329     RegCloseKey(compkey);
1330
1331     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1332
1333     state = MAGIC_ERROR;
1334     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1335     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1336     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1337
1338     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1339     lstrcatA(keypath, prod_squashed);
1340
1341     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1343
1344     state = MAGIC_ERROR;
1345     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1346     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1347     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1348
1349     RegDeleteKeyA(prodkey, "");
1350     RegCloseKey(prodkey);
1351
1352     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1353     lstrcatA(keypath, usersid);
1354     lstrcatA(keypath, "\\Products\\");
1355     lstrcatA(keypath, prod_squashed);
1356     lstrcatA(keypath, "\\InstallProperties");
1357
1358     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1359     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1360
1361     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1363
1364     RegCloseKey(prodkey);
1365
1366     state = MAGIC_ERROR;
1367     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1368     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1369     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1370
1371     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1372     lstrcatA(keypath, usersid);
1373     lstrcatA(keypath, "\\Components\\");
1374     lstrcatA(keypath, comp_squashed);
1375
1376     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1378
1379     /* component key exists */
1380     state = MAGIC_ERROR;
1381     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1382     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1383     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1384
1385     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1387
1388     /* component\product exists */
1389     state = MAGIC_ERROR;
1390     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1391     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1392     ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
1393
1394     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1395     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1396
1397     state = MAGIC_ERROR;
1398     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1399     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1400     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1401
1402     /* MSIINSTALLCONTEXT_USERMANAGED */
1403
1404     state = MAGIC_ERROR;
1405     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1406     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1407     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1408
1409     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1410     lstrcatA(keypath, prod_squashed);
1411
1412     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1413     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1414
1415     state = MAGIC_ERROR;
1416     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1417     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1418     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1419
1420     RegDeleteKeyA(prodkey, "");
1421     RegCloseKey(prodkey);
1422
1423     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1424     lstrcatA(keypath, usersid);
1425     lstrcatA(keypath, "\\Installer\\Products\\");
1426     lstrcatA(keypath, prod_squashed);
1427
1428     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1430
1431     state = MAGIC_ERROR;
1432     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1433     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1434     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1435
1436     RegDeleteKeyA(prodkey, "");
1437     RegCloseKey(prodkey);
1438
1439     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1440     lstrcatA(keypath, usersid);
1441     lstrcatA(keypath, "\\Products\\");
1442     lstrcatA(keypath, prod_squashed);
1443     lstrcatA(keypath, "\\InstallProperties");
1444
1445     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1447
1448     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1449     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1450
1451     state = MAGIC_ERROR;
1452     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1453     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1454     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1455
1456     RegDeleteValueA(prodkey, "LocalPackage");
1457     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1458     RegDeleteKeyA(prodkey, "");
1459     RegDeleteValueA(compkey, prod_squashed);
1460     RegDeleteKeyA(compkey, "");
1461     RegCloseKey(prodkey);
1462     RegCloseKey(compkey);
1463 }
1464
1465 static void test_MsiGetComponentPath(void)
1466 {
1467     HKEY compkey, prodkey, installprop;
1468     CHAR prodcode[MAX_PATH];
1469     CHAR prod_squashed[MAX_PATH];
1470     CHAR component[MAX_PATH];
1471     CHAR comp_base85[MAX_PATH];
1472     CHAR comp_squashed[MAX_PATH];
1473     CHAR keypath[MAX_PATH];
1474     CHAR path[MAX_PATH];
1475     INSTALLSTATE state;
1476     LPSTR usersid;
1477     DWORD size, val;
1478     LONG res;
1479
1480     create_test_guid(prodcode, prod_squashed);
1481     compose_base85_guid(component, comp_base85, comp_squashed);
1482     get_user_sid(&usersid);
1483
1484     /* NULL szProduct */
1485     size = MAX_PATH;
1486     state = MsiGetComponentPathA(NULL, component, path, &size);
1487     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1488     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1489
1490     /* NULL szComponent */
1491     size = MAX_PATH;
1492     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1493     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1494     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1495
1496     /* NULL lpPathBuf */
1497     size = MAX_PATH;
1498     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1499     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1500     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1501
1502     /* NULL pcchBuf */
1503     size = MAX_PATH;
1504     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1505     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1506     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1507
1508     /* all params valid */
1509     size = MAX_PATH;
1510     state = MsiGetComponentPathA(prodcode, component, path, &size);
1511     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1512     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1513
1514     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1515     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1516     lstrcatA(keypath, comp_squashed);
1517
1518     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1519     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1520
1521     /* local system component key exists */
1522     size = MAX_PATH;
1523     state = MsiGetComponentPathA(prodcode, component, path, &size);
1524     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1525     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1526
1527     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1529
1530     /* product value exists */
1531     size = MAX_PATH;
1532     state = MsiGetComponentPathA(prodcode, component, path, &size);
1533     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1534     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1535     ok(size == 10, "Expected 10, got %d\n", size);
1536
1537     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1538     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1539     lstrcatA(keypath, prod_squashed);
1540     lstrcatA(keypath, "\\InstallProperties");
1541
1542     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1543     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1544
1545     val = 1;
1546     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1548
1549     /* install properties key exists */
1550     size = MAX_PATH;
1551     state = MsiGetComponentPathA(prodcode, component, path, &size);
1552     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1553     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1554     ok(size == 10, "Expected 10, got %d\n", size);
1555
1556     create_file("C:\\imapath", "C:\\imapath", 11);
1557
1558     /* file exists */
1559     size = MAX_PATH;
1560     state = MsiGetComponentPathA(prodcode, component, path, &size);
1561     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1562     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1563     ok(size == 10, "Expected 10, got %d\n", size);
1564
1565     RegDeleteValueA(compkey, prod_squashed);
1566     RegDeleteKeyA(compkey, "");
1567     RegDeleteValueA(installprop, "WindowsInstaller");
1568     RegDeleteKeyA(installprop, "");
1569     RegCloseKey(compkey);
1570     RegCloseKey(installprop);
1571     DeleteFileA("C:\\imapath");
1572
1573     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1574     lstrcatA(keypath, "Installer\\UserData\\");
1575     lstrcatA(keypath, usersid);
1576     lstrcatA(keypath, "\\Components\\");
1577     lstrcatA(keypath, comp_squashed);
1578
1579     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1580     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1581
1582     /* user managed component key exists */
1583     size = MAX_PATH;
1584     state = MsiGetComponentPathA(prodcode, component, path, &size);
1585     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1586     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1587
1588     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1590
1591     /* product value exists */
1592     size = MAX_PATH;
1593     state = MsiGetComponentPathA(prodcode, component, path, &size);
1594     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1595     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1596     ok(size == 10, "Expected 10, got %d\n", size);
1597
1598     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1599     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1600     lstrcatA(keypath, prod_squashed);
1601     lstrcatA(keypath, "\\InstallProperties");
1602
1603     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1605
1606     val = 1;
1607     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1609
1610     /* install properties key exists */
1611     size = MAX_PATH;
1612     state = MsiGetComponentPathA(prodcode, component, path, &size);
1613     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1614     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1615     ok(size == 10, "Expected 10, got %d\n", size);
1616
1617     create_file("C:\\imapath", "C:\\imapath", 11);
1618
1619     /* file exists */
1620     size = MAX_PATH;
1621     state = MsiGetComponentPathA(prodcode, component, path, &size);
1622     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1623     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1624     ok(size == 10, "Expected 10, got %d\n", size);
1625
1626     RegDeleteValueA(compkey, prod_squashed);
1627     RegDeleteKeyA(compkey, "");
1628     RegDeleteValueA(installprop, "WindowsInstaller");
1629     RegDeleteKeyA(installprop, "");
1630     RegCloseKey(compkey);
1631     RegCloseKey(installprop);
1632     DeleteFileA("C:\\imapath");
1633
1634     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1635     lstrcatA(keypath, "Installer\\Managed\\");
1636     lstrcatA(keypath, usersid);
1637     lstrcatA(keypath, "\\Installer\\Products\\");
1638     lstrcatA(keypath, prod_squashed);
1639
1640     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1642
1643     /* user managed product key exists */
1644     size = MAX_PATH;
1645     state = MsiGetComponentPathA(prodcode, component, path, &size);
1646     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1647     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1648
1649     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1650     lstrcatA(keypath, "Installer\\UserData\\");
1651     lstrcatA(keypath, usersid);
1652     lstrcatA(keypath, "\\Components\\");
1653     lstrcatA(keypath, comp_squashed);
1654
1655     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1657
1658     /* user managed component key exists */
1659     size = MAX_PATH;
1660     state = MsiGetComponentPathA(prodcode, component, path, &size);
1661     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1662     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1663
1664     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1666
1667     /* product value exists */
1668     size = MAX_PATH;
1669     state = MsiGetComponentPathA(prodcode, component, path, &size);
1670     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1671     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1672     ok(size == 10, "Expected 10, got %d\n", size);
1673
1674     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1675     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1676     lstrcatA(keypath, prod_squashed);
1677     lstrcatA(keypath, "\\InstallProperties");
1678
1679     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1681
1682     val = 1;
1683     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1685
1686     /* install properties key exists */
1687     size = MAX_PATH;
1688     state = MsiGetComponentPathA(prodcode, component, path, &size);
1689     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1690     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1691     ok(size == 10, "Expected 10, got %d\n", size);
1692
1693     create_file("C:\\imapath", "C:\\imapath", 11);
1694
1695     /* file exists */
1696     size = MAX_PATH;
1697     state = MsiGetComponentPathA(prodcode, component, path, &size);
1698     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1699     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1700     ok(size == 10, "Expected 10, got %d\n", size);
1701
1702     RegDeleteValueA(compkey, prod_squashed);
1703     RegDeleteKeyA(prodkey, "");
1704     RegDeleteKeyA(compkey, "");
1705     RegDeleteValueA(installprop, "WindowsInstaller");
1706     RegDeleteKeyA(installprop, "");
1707     RegCloseKey(prodkey);
1708     RegCloseKey(compkey);
1709     RegCloseKey(installprop);
1710     DeleteFileA("C:\\imapath");
1711
1712     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1713     lstrcatA(keypath, prod_squashed);
1714
1715     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1717
1718     /* user unmanaged product key exists */
1719     size = MAX_PATH;
1720     state = MsiGetComponentPathA(prodcode, component, path, &size);
1721     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1722     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1723
1724     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1725     lstrcatA(keypath, "Installer\\UserData\\");
1726     lstrcatA(keypath, usersid);
1727     lstrcatA(keypath, "\\Components\\");
1728     lstrcatA(keypath, comp_squashed);
1729
1730     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1732
1733     /* user unmanaged component key exists */
1734     size = MAX_PATH;
1735     state = MsiGetComponentPathA(prodcode, component, path, &size);
1736     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1737     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1738
1739     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1741
1742     /* product value exists */
1743     size = MAX_PATH;
1744     state = MsiGetComponentPathA(prodcode, component, path, &size);
1745     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1746     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1747     ok(size == 10, "Expected 10, got %d\n", size);
1748
1749     create_file("C:\\imapath", "C:\\imapath", 11);
1750
1751     /* file exists */
1752     size = MAX_PATH;
1753     state = MsiGetComponentPathA(prodcode, component, path, &size);
1754     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1755     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1756     ok(size == 10, "Expected 10, got %d\n", size);
1757
1758     RegDeleteValueA(compkey, prod_squashed);
1759     RegDeleteKeyA(prodkey, "");
1760     RegDeleteKeyA(compkey, "");
1761     RegCloseKey(prodkey);
1762     RegCloseKey(compkey);
1763     DeleteFileA("C:\\imapath");
1764
1765     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1766     lstrcatA(keypath, prod_squashed);
1767
1768     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1770
1771     /* local classes product key exists */
1772     size = MAX_PATH;
1773     state = MsiGetComponentPathA(prodcode, component, path, &size);
1774     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1775     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1776
1777     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1778     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1779     lstrcatA(keypath, comp_squashed);
1780
1781     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1783
1784     /* local user component key exists */
1785     size = MAX_PATH;
1786     state = MsiGetComponentPathA(prodcode, component, path, &size);
1787     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1788     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1789
1790     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1792
1793     /* product value exists */
1794     size = MAX_PATH;
1795     state = MsiGetComponentPathA(prodcode, component, path, &size);
1796     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1797     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1798     ok(size == 10, "Expected 10, got %d\n", size);
1799
1800     create_file("C:\\imapath", "C:\\imapath", 11);
1801
1802     /* file exists */
1803     size = MAX_PATH;
1804     state = MsiGetComponentPathA(prodcode, component, path, &size);
1805     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1806     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1807     ok(size == 10, "Expected 10, got %d\n", size);
1808
1809     RegDeleteValueA(compkey, prod_squashed);
1810     RegDeleteKeyA(prodkey, "");
1811     RegDeleteKeyA(compkey, "");
1812     RegCloseKey(prodkey);
1813     RegCloseKey(compkey);
1814     DeleteFileA("C:\\imapath");
1815 }
1816
1817 static void test_MsiGetProductCode(void)
1818 {
1819     HKEY compkey, prodkey;
1820     CHAR prodcode[MAX_PATH];
1821     CHAR prod_squashed[MAX_PATH];
1822     CHAR prodcode2[MAX_PATH];
1823     CHAR prod2_squashed[MAX_PATH];
1824     CHAR component[MAX_PATH];
1825     CHAR comp_base85[MAX_PATH];
1826     CHAR comp_squashed[MAX_PATH];
1827     CHAR keypath[MAX_PATH];
1828     CHAR product[MAX_PATH];
1829     LPSTR usersid;
1830     LONG res;
1831     UINT r;
1832
1833     create_test_guid(prodcode, prod_squashed);
1834     create_test_guid(prodcode2, prod2_squashed);
1835     compose_base85_guid(component, comp_base85, comp_squashed);
1836     get_user_sid(&usersid);
1837
1838     /* szComponent is NULL */
1839     lstrcpyA(product, "prod");
1840     r = MsiGetProductCodeA(NULL, product);
1841     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1842     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1843
1844     /* szComponent is empty */
1845     lstrcpyA(product, "prod");
1846     r = MsiGetProductCodeA("", product);
1847     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1848     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1849
1850     /* garbage szComponent */
1851     lstrcpyA(product, "prod");
1852     r = MsiGetProductCodeA("garbage", product);
1853     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1854     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1855
1856     /* guid without brackets */
1857     lstrcpyA(product, "prod");
1858     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1859     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1860     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1861
1862     /* guid with brackets */
1863     lstrcpyA(product, "prod");
1864     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1865     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1866     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1867
1868     /* same length as guid, but random */
1869     lstrcpyA(product, "prod");
1870     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1871     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1872     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1873
1874     /* all params correct, szComponent not published */
1875     lstrcpyA(product, "prod");
1876     r = MsiGetProductCodeA(component, product);
1877     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1878     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1879
1880     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1881     lstrcatA(keypath, "Installer\\UserData\\");
1882     lstrcatA(keypath, usersid);
1883     lstrcatA(keypath, "\\Components\\");
1884     lstrcatA(keypath, comp_squashed);
1885
1886     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1888
1889     /* user unmanaged component key exists */
1890     lstrcpyA(product, "prod");
1891     r = MsiGetProductCodeA(component, product);
1892     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1893     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1894
1895     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1897
1898     /* product value exists */
1899     lstrcpyA(product, "prod");
1900     r = MsiGetProductCodeA(component, product);
1901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1902     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1903
1904     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1906
1907     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1908     lstrcatA(keypath, "Installer\\Managed\\");
1909     lstrcatA(keypath, usersid);
1910     lstrcatA(keypath, "\\Installer\\Products\\");
1911     lstrcatA(keypath, prod_squashed);
1912
1913     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1915
1916     /* user managed product key of first product exists */
1917     lstrcpyA(product, "prod");
1918     r = MsiGetProductCodeA(component, product);
1919     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1920     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1921
1922     RegDeleteKeyA(prodkey, "");
1923     RegCloseKey(prodkey);
1924
1925     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1926     lstrcatA(keypath, prod_squashed);
1927
1928     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1930
1931     /* user unmanaged product key exists */
1932     lstrcpyA(product, "prod");
1933     r = MsiGetProductCodeA(component, product);
1934     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1935     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1936
1937     RegDeleteKeyA(prodkey, "");
1938     RegCloseKey(prodkey);
1939
1940     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1941     lstrcatA(keypath, prod_squashed);
1942
1943     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1945
1946     /* local classes product key exists */
1947     lstrcpyA(product, "prod");
1948     r = MsiGetProductCodeA(component, product);
1949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1950     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1951
1952     RegDeleteKeyA(prodkey, "");
1953     RegCloseKey(prodkey);
1954
1955     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1956     lstrcatA(keypath, "Installer\\Managed\\");
1957     lstrcatA(keypath, usersid);
1958     lstrcatA(keypath, "\\Installer\\Products\\");
1959     lstrcatA(keypath, prod2_squashed);
1960
1961     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1963
1964     /* user managed product key of second product exists */
1965     lstrcpyA(product, "prod");
1966     r = MsiGetProductCodeA(component, product);
1967     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1968     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1969
1970     RegDeleteKeyA(prodkey, "");
1971     RegCloseKey(prodkey);
1972     RegDeleteValueA(compkey, prod_squashed);
1973     RegDeleteValueA(compkey, prod2_squashed);
1974     RegDeleteKeyA(compkey, "");
1975     RegCloseKey(compkey);
1976
1977     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1978     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1979     lstrcatA(keypath, comp_squashed);
1980
1981     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1983
1984     /* local user component key exists */
1985     lstrcpyA(product, "prod");
1986     r = MsiGetProductCodeA(component, product);
1987     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1988     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1989
1990     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1992
1993     /* product value exists */
1994     lstrcpyA(product, "prod");
1995     r = MsiGetProductCodeA(component, product);
1996     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1997     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1998
1999     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2001
2002     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2003     lstrcatA(keypath, "Installer\\Managed\\");
2004     lstrcatA(keypath, usersid);
2005     lstrcatA(keypath, "\\Installer\\Products\\");
2006     lstrcatA(keypath, prod_squashed);
2007
2008     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2010
2011     /* user managed product key of first product exists */
2012     lstrcpyA(product, "prod");
2013     r = MsiGetProductCodeA(component, product);
2014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2015     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2016
2017     RegDeleteKeyA(prodkey, "");
2018     RegCloseKey(prodkey);
2019
2020     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2021     lstrcatA(keypath, prod_squashed);
2022
2023     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2025
2026     /* user unmanaged product key exists */
2027     lstrcpyA(product, "prod");
2028     r = MsiGetProductCodeA(component, product);
2029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2030     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2031
2032     RegDeleteKeyA(prodkey, "");
2033     RegCloseKey(prodkey);
2034
2035     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2036     lstrcatA(keypath, prod_squashed);
2037
2038     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2040
2041     /* local classes product key exists */
2042     lstrcpyA(product, "prod");
2043     r = MsiGetProductCodeA(component, product);
2044     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2045     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2046
2047     RegDeleteKeyA(prodkey, "");
2048     RegCloseKey(prodkey);
2049
2050     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2051     lstrcatA(keypath, "Installer\\Managed\\");
2052     lstrcatA(keypath, usersid);
2053     lstrcatA(keypath, "\\Installer\\Products\\");
2054     lstrcatA(keypath, prod2_squashed);
2055
2056     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2057     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2058
2059     /* user managed product key of second product exists */
2060     lstrcpyA(product, "prod");
2061     r = MsiGetProductCodeA(component, product);
2062     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2063     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2064
2065     RegDeleteKeyA(prodkey, "");
2066     RegCloseKey(prodkey);
2067     RegDeleteValueA(compkey, prod_squashed);
2068     RegDeleteValueA(compkey, prod2_squashed);
2069     RegDeleteKeyA(compkey, "");
2070     RegCloseKey(compkey);
2071 }
2072
2073 static void test_MsiEnumClients(void)
2074 {
2075     HKEY compkey;
2076     CHAR prodcode[MAX_PATH];
2077     CHAR prod_squashed[MAX_PATH];
2078     CHAR prodcode2[MAX_PATH];
2079     CHAR prod2_squashed[MAX_PATH];
2080     CHAR component[MAX_PATH];
2081     CHAR comp_base85[MAX_PATH];
2082     CHAR comp_squashed[MAX_PATH];
2083     CHAR product[MAX_PATH];
2084     CHAR keypath[MAX_PATH];
2085     LPSTR usersid;
2086     LONG res;
2087     UINT r;
2088
2089     create_test_guid(prodcode, prod_squashed);
2090     create_test_guid(prodcode2, prod2_squashed);
2091     compose_base85_guid(component, comp_base85, comp_squashed);
2092     get_user_sid(&usersid);
2093
2094     /* NULL szComponent */
2095     product[0] = '\0';
2096     r = MsiEnumClientsA(NULL, 0, product);
2097     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2098     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2099
2100     /* empty szComponent */
2101     product[0] = '\0';
2102     r = MsiEnumClientsA("", 0, product);
2103     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2104     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2105
2106     /* NULL lpProductBuf */
2107     r = MsiEnumClientsA(component, 0, NULL);
2108     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2109
2110     /* all params correct, component missing */
2111     product[0] = '\0';
2112     r = MsiEnumClientsA(component, 0, product);
2113     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2114     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2115
2116     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2117     lstrcatA(keypath, "Installer\\UserData\\");
2118     lstrcatA(keypath, usersid);
2119     lstrcatA(keypath, "\\Components\\");
2120     lstrcatA(keypath, comp_squashed);
2121
2122     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2124
2125     /* user unmanaged component key exists */
2126     product[0] = '\0';
2127     r = MsiEnumClientsA(component, 0, product);
2128     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2129     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2130
2131     /* index > 0, no products exist */
2132     product[0] = '\0';
2133     r = MsiEnumClientsA(component, 1, product);
2134     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2135     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2136
2137     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2138     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2139
2140     /* product value exists */
2141     r = MsiEnumClientsA(component, 0, product);
2142     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2143     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2144
2145     /* try index 0 again */
2146     product[0] = '\0';
2147     r = MsiEnumClientsA(component, 0, product);
2148     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2149     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2150
2151     /* try index 1, second product value does not exist */
2152     product[0] = '\0';
2153     r = MsiEnumClientsA(component, 1, product);
2154     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2155     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2156
2157     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2159
2160     /* try index 1, second product value does exist */
2161     product[0] = '\0';
2162     r = MsiEnumClientsA(component, 1, product);
2163     todo_wine
2164     {
2165         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2166         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2167     }
2168
2169     /* start the enumeration over */
2170     product[0] = '\0';
2171     r = MsiEnumClientsA(component, 0, product);
2172     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2173     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2174        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2175
2176     /* correctly query second product */
2177     product[0] = '\0';
2178     r = MsiEnumClientsA(component, 1, product);
2179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2180     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2181        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2182
2183     RegDeleteValueA(compkey, prod_squashed);
2184     RegDeleteValueA(compkey, prod2_squashed);
2185     RegDeleteKeyA(compkey, "");
2186     RegCloseKey(compkey);
2187
2188     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2189     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2190     lstrcatA(keypath, comp_squashed);
2191
2192     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2194
2195     /* user local component key exists */
2196     product[0] = '\0';
2197     r = MsiEnumClientsA(component, 0, product);
2198     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2199     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2200
2201     /* index > 0, no products exist */
2202     product[0] = '\0';
2203     r = MsiEnumClientsA(component, 1, product);
2204     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2205     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2206
2207     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2209
2210     /* product value exists */
2211     product[0] = '\0';
2212     r = MsiEnumClientsA(component, 0, product);
2213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2214     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2215
2216     /* try index 0 again */
2217     product[0] = '\0';
2218     r = MsiEnumClientsA(component, 0, product);
2219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2220
2221     /* try index 1, second product value does not exist */
2222     product[0] = '\0';
2223     r = MsiEnumClientsA(component, 1, product);
2224     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2225     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2226
2227     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2229
2230     /* try index 1, second product value does exist */
2231     product[0] = '\0';
2232     r = MsiEnumClientsA(component, 1, product);
2233     todo_wine
2234     {
2235         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2236         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2237     }
2238
2239     /* start the enumeration over */
2240     product[0] = '\0';
2241     r = MsiEnumClientsA(component, 0, product);
2242     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2243     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2244        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2245
2246     /* correctly query second product */
2247     product[0] = '\0';
2248     r = MsiEnumClientsA(component, 1, product);
2249     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2250     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2251        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2252
2253     RegDeleteValueA(compkey, prod_squashed);
2254     RegDeleteValueA(compkey, prod2_squashed);
2255     RegDeleteKeyA(compkey, "");
2256     RegCloseKey(compkey);
2257 }
2258
2259 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2260                              LPSTR *langcheck, LPDWORD langchecksz)
2261 {
2262     LPSTR version;
2263     VS_FIXEDFILEINFO *ffi;
2264     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2265     USHORT *lang;
2266
2267     version = HeapAlloc(GetProcessHeap(), 0, size);
2268     GetFileVersionInfoA(path, 0, size, version);
2269
2270     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2271     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2272     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2273             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2274             LOWORD(ffi->dwFileVersionLS));
2275     *verchecksz = lstrlenA(*vercheck);
2276
2277     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2278     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2279     sprintf(*langcheck, "%d", *lang);
2280     *langchecksz = lstrlenA(*langcheck);
2281
2282     HeapFree(GetProcessHeap(), 0, version);
2283 }
2284
2285 static void test_MsiGetFileVersion(void)
2286 {
2287     UINT r;
2288     DWORD versz, langsz;
2289     char version[MAX_PATH];
2290     char lang[MAX_PATH];
2291     char path[MAX_PATH];
2292     LPSTR vercheck, langcheck;
2293     DWORD verchecksz, langchecksz;
2294
2295     /* NULL szFilePath */
2296     versz = MAX_PATH;
2297     langsz = MAX_PATH;
2298     lstrcpyA(version, "version");
2299     lstrcpyA(lang, "lang");
2300     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2301     ok(r == ERROR_INVALID_PARAMETER,
2302        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2303     ok(!lstrcmpA(version, "version"),
2304        "Expected version to be unchanged, got %s\n", version);
2305     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2306     ok(!lstrcmpA(lang, "lang"),
2307        "Expected lang to be unchanged, got %s\n", lang);
2308     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2309
2310     /* empty szFilePath */
2311     versz = MAX_PATH;
2312     langsz = MAX_PATH;
2313     lstrcpyA(version, "version");
2314     lstrcpyA(lang, "lang");
2315     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2316     ok(r == ERROR_FILE_NOT_FOUND,
2317        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2318     ok(!lstrcmpA(version, "version"),
2319        "Expected version to be unchanged, got %s\n", version);
2320     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2321     ok(!lstrcmpA(lang, "lang"),
2322        "Expected lang to be unchanged, got %s\n", lang);
2323     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2324
2325     /* nonexistent szFilePath */
2326     versz = MAX_PATH;
2327     langsz = MAX_PATH;
2328     lstrcpyA(version, "version");
2329     lstrcpyA(lang, "lang");
2330     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2331     ok(r == ERROR_FILE_NOT_FOUND,
2332        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2333     ok(!lstrcmpA(version, "version"),
2334        "Expected version to be unchanged, got %s\n", version);
2335     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2336     ok(!lstrcmpA(lang, "lang"),
2337        "Expected lang to be unchanged, got %s\n", lang);
2338     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2339
2340     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2341     versz = MAX_PATH;
2342     langsz = MAX_PATH;
2343     lstrcpyA(version, "version");
2344     lstrcpyA(lang, "lang");
2345     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2346     ok(r == ERROR_INVALID_PARAMETER,
2347        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2348     ok(!lstrcmpA(version, "version"),
2349        "Expected version to be unchanged, got %s\n", version);
2350     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2351     ok(!lstrcmpA(lang, "lang"),
2352        "Expected lang to be unchanged, got %s\n", lang);
2353     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2354
2355     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2356     versz = MAX_PATH;
2357     langsz = MAX_PATH;
2358     lstrcpyA(version, "version");
2359     lstrcpyA(lang, "lang");
2360     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2361     ok(r == ERROR_INVALID_PARAMETER,
2362        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2363     ok(!lstrcmpA(version, "version"),
2364        "Expected version to be unchanged, got %s\n", version);
2365     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2366     ok(!lstrcmpA(lang, "lang"),
2367        "Expected lang to be unchanged, got %s\n", lang);
2368     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2369
2370     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2371     versz = 0;
2372     langsz = MAX_PATH;
2373     lstrcpyA(version, "version");
2374     lstrcpyA(lang, "lang");
2375     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2376     ok(r == ERROR_FILE_NOT_FOUND,
2377        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2378     ok(!lstrcmpA(version, "version"),
2379        "Expected version to be unchanged, got %s\n", version);
2380     ok(versz == 0, "Expected 0, got %d\n", versz);
2381     ok(!lstrcmpA(lang, "lang"),
2382        "Expected lang to be unchanged, got %s\n", lang);
2383     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2384
2385     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2386     versz = MAX_PATH;
2387     langsz = 0;
2388     lstrcpyA(version, "version");
2389     lstrcpyA(lang, "lang");
2390     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2391     ok(r == ERROR_FILE_NOT_FOUND,
2392        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2393     ok(!lstrcmpA(version, "version"),
2394        "Expected version to be unchanged, got %s\n", version);
2395     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2396     ok(!lstrcmpA(lang, "lang"),
2397        "Expected lang to be unchanged, got %s\n", lang);
2398     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2399
2400     /* nonexistent szFilePath, rest NULL */
2401     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2402     ok(r == ERROR_FILE_NOT_FOUND,
2403        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2404
2405     create_file("ver.txt", "ver.txt", 20);
2406
2407     /* file exists, no version information */
2408     versz = MAX_PATH;
2409     langsz = MAX_PATH;
2410     lstrcpyA(version, "version");
2411     lstrcpyA(lang, "lang");
2412     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2413     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2414     ok(!lstrcmpA(version, "version"),
2415        "Expected version to be unchanged, got %s\n", version);
2416     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2417     ok(!lstrcmpA(lang, "lang"),
2418        "Expected lang to be unchanged, got %s\n", lang);
2419     ok(r == ERROR_FILE_INVALID,
2420        "Expected ERROR_FILE_INVALID, got %d\n", r);
2421
2422     DeleteFileA("ver.txt");
2423
2424     /* relative path, has version information */
2425     versz = MAX_PATH;
2426     langsz = MAX_PATH;
2427     lstrcpyA(version, "version");
2428     lstrcpyA(lang, "lang");
2429     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2430     todo_wine
2431     {
2432         ok(r == ERROR_FILE_NOT_FOUND,
2433            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2434         ok(!lstrcmpA(version, "version"),
2435            "Expected version to be unchanged, got %s\n", version);
2436         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2437         ok(!lstrcmpA(lang, "lang"),
2438            "Expected lang to be unchanged, got %s\n", lang);
2439         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2440     }
2441
2442     GetSystemDirectoryA(path, MAX_PATH);
2443     lstrcatA(path, "\\kernel32.dll");
2444
2445     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2446
2447     /* absolute path, has version information */
2448     versz = MAX_PATH;
2449     langsz = MAX_PATH;
2450     lstrcpyA(version, "version");
2451     lstrcpyA(lang, "lang");
2452     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2453     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2454     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2455     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2456     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2457     ok(!lstrcmpA(version, vercheck),
2458         "Expected %s, got %s\n", vercheck, version);
2459
2460     /* only check version */
2461     versz = MAX_PATH;
2462     lstrcpyA(version, "version");
2463     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2465     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2466     ok(!lstrcmpA(version, vercheck),
2467        "Expected %s, got %s\n", vercheck, version);
2468
2469     /* only check language */
2470     langsz = MAX_PATH;
2471     lstrcpyA(lang, "lang");
2472     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2474     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2475     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2476
2477     /* check neither version nor language */
2478     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2480
2481     /* get pcchVersionBuf */
2482     versz = MAX_PATH;
2483     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2484     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2485     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2486
2487     /* get pcchLangBuf */
2488     langsz = MAX_PATH;
2489     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2490     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2491     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2492
2493     /* pcchVersionBuf not big enough */
2494     versz = 5;
2495     lstrcpyA(version, "version");
2496     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2497     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2498     ok(!strncmp(version, vercheck, 4),
2499        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2500     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2501
2502     /* pcchLangBuf not big enough */
2503     langsz = 3;
2504     lstrcpyA(lang, "lang");
2505     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2506     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2507     ok(!strncmp(lang, langcheck, 2),
2508        "Expected first character of %s, got %s\n", langcheck, lang);
2509     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2510
2511     HeapFree(GetProcessHeap(), 0, vercheck);
2512     HeapFree(GetProcessHeap(), 0, langcheck);
2513 }
2514
2515 static void test_MsiGetProductInfo(void)
2516 {
2517     UINT r;
2518     LONG res;
2519     HKEY propkey, source;
2520     HKEY prodkey, localkey;
2521     CHAR prodcode[MAX_PATH];
2522     CHAR prod_squashed[MAX_PATH];
2523     CHAR packcode[MAX_PATH];
2524     CHAR pack_squashed[MAX_PATH];
2525     CHAR buf[MAX_PATH];
2526     CHAR keypath[MAX_PATH];
2527     LPSTR usersid;
2528     DWORD sz, val = 42;
2529
2530     create_test_guid(prodcode, prod_squashed);
2531     create_test_guid(packcode, pack_squashed);
2532     get_user_sid(&usersid);
2533
2534     /* NULL szProduct */
2535     sz = MAX_PATH;
2536     lstrcpyA(buf, "apple");
2537     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2538     ok(r == ERROR_INVALID_PARAMETER,
2539        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2540     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2541     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2542
2543     /* empty szProduct */
2544     sz = MAX_PATH;
2545     lstrcpyA(buf, "apple");
2546     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2547     ok(r == ERROR_INVALID_PARAMETER,
2548        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2549     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2550     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2551
2552     /* garbage szProduct */
2553     sz = MAX_PATH;
2554     lstrcpyA(buf, "apple");
2555     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2556     ok(r == ERROR_INVALID_PARAMETER,
2557        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2558     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2559     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2560
2561     /* guid without brackets */
2562     sz = MAX_PATH;
2563     lstrcpyA(buf, "apple");
2564     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2565                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2566     ok(r == ERROR_INVALID_PARAMETER,
2567        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2568     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2569     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2570
2571     /* guid with brackets */
2572     sz = MAX_PATH;
2573     lstrcpyA(buf, "apple");
2574     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2575                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2576     ok(r == ERROR_UNKNOWN_PRODUCT,
2577        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2578     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2579     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2580
2581     /* same length as guid, but random */
2582     sz = MAX_PATH;
2583     lstrcpyA(buf, "apple");
2584     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2585                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2586     ok(r == ERROR_INVALID_PARAMETER,
2587        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2588     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2589     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2590
2591     /* not installed, NULL szAttribute */
2592     sz = MAX_PATH;
2593     lstrcpyA(buf, "apple");
2594     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2595     ok(r == ERROR_INVALID_PARAMETER,
2596        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2597     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2598     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2599
2600     /* not installed, NULL lpValueBuf */
2601     sz = MAX_PATH;
2602     lstrcpyA(buf, "apple");
2603     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2604     ok(r == ERROR_UNKNOWN_PRODUCT,
2605        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2608
2609     /* not installed, NULL pcchValueBuf */
2610     sz = MAX_PATH;
2611     lstrcpyA(buf, "apple");
2612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2613     ok(r == ERROR_INVALID_PARAMETER,
2614        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2615     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2616     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2617
2618     /* created guid cannot possibly be an installed product code */
2619     sz = MAX_PATH;
2620     lstrcpyA(buf, "apple");
2621     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2622     ok(r == ERROR_UNKNOWN_PRODUCT,
2623        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2624     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2625     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2626
2627     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2628     lstrcatA(keypath, usersid);
2629     lstrcatA(keypath, "\\Installer\\Products\\");
2630     lstrcatA(keypath, prod_squashed);
2631
2632     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2633     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2634
2635     /* managed product code exists */
2636     sz = MAX_PATH;
2637     lstrcpyA(buf, "apple");
2638     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2639     ok(r == ERROR_UNKNOWN_PROPERTY,
2640        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2641     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2642     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2643
2644     RegDeleteKeyA(prodkey, "");
2645     RegCloseKey(prodkey);
2646
2647     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2648     lstrcatA(keypath, usersid);
2649     lstrcatA(keypath, "\\Products\\");
2650     lstrcatA(keypath, prod_squashed);
2651
2652     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2654
2655     /* local user product code exists */
2656     sz = MAX_PATH;
2657     lstrcpyA(buf, "apple");
2658     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2659     ok(r == ERROR_UNKNOWN_PRODUCT,
2660        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2661     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2662     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2663
2664     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2665     lstrcatA(keypath, usersid);
2666     lstrcatA(keypath, "\\Installer\\Products\\");
2667     lstrcatA(keypath, prod_squashed);
2668
2669     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2671
2672     /* both local and managed product code exist */
2673     sz = MAX_PATH;
2674     lstrcpyA(buf, "apple");
2675     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2676     ok(r == ERROR_UNKNOWN_PROPERTY,
2677        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2678     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2679     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2680
2681     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2683
2684     /* InstallProperties key exists */
2685     sz = MAX_PATH;
2686     lstrcpyA(buf, "apple");
2687     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2689     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2690     ok(sz == 0, "Expected 0, got %d\n", sz);
2691
2692     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2694
2695     /* HelpLink value exists */
2696     sz = MAX_PATH;
2697     lstrcpyA(buf, "apple");
2698     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2700     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2701     ok(sz == 4, "Expected 4, got %d\n", sz);
2702
2703     /* pcchBuf is NULL */
2704     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2706
2707     /* lpValueBuf is NULL */
2708     sz = MAX_PATH;
2709     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2710     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2711     ok(sz == 4, "Expected 4, got %d\n", sz);
2712
2713     /* lpValueBuf is NULL, pcchValueBuf is too small */
2714     sz = 2;
2715     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2717     ok(sz == 4, "Expected 4, got %d\n", sz);
2718
2719     /* lpValueBuf is NULL, pcchValueBuf is too small */
2720     sz = 2;
2721     lstrcpyA(buf, "apple");
2722     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2723     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2724     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2725     ok(sz == 4, "Expected 4, got %d\n", sz);
2726
2727     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2728     sz = 4;
2729     lstrcpyA(buf, "apple");
2730     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2731     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2732     ok(!lstrcmpA(buf, "apple"),
2733        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2734     ok(sz == 4, "Expected 4, got %d\n", sz);
2735
2736     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2738
2739     /* random property not supported by MSI, value exists */
2740     sz = MAX_PATH;
2741     lstrcpyA(buf, "apple");
2742     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2743     ok(r == ERROR_UNKNOWN_PROPERTY,
2744        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2745     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2746     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2747
2748     RegDeleteValueA(propkey, "IMadeThis");
2749     RegDeleteValueA(propkey, "HelpLink");
2750     RegDeleteKeyA(propkey, "");
2751     RegDeleteKeyA(localkey, "");
2752     RegDeleteKeyA(prodkey, "");
2753     RegCloseKey(propkey);
2754     RegCloseKey(localkey);
2755     RegCloseKey(prodkey);
2756
2757     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2758     lstrcatA(keypath, prod_squashed);
2759
2760     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2761     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2762
2763     /* user product key exists */
2764     sz = MAX_PATH;
2765     lstrcpyA(buf, "apple");
2766     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2767     ok(r == ERROR_UNKNOWN_PROPERTY,
2768        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2769     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2770     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2771
2772     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2773     lstrcatA(keypath, usersid);
2774     lstrcatA(keypath, "\\Products\\");
2775     lstrcatA(keypath, prod_squashed);
2776
2777     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2779
2780     /* local user product key exists */
2781     sz = MAX_PATH;
2782     lstrcpyA(buf, "apple");
2783     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2784     ok(r == ERROR_UNKNOWN_PROPERTY,
2785        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2786     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2787     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2788
2789     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2790     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2791
2792     /* InstallProperties key exists */
2793     sz = MAX_PATH;
2794     lstrcpyA(buf, "apple");
2795     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2796     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2797     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2798     ok(sz == 0, "Expected 0, got %d\n", sz);
2799
2800     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2801     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2802
2803     /* HelpLink value exists */
2804     sz = MAX_PATH;
2805     lstrcpyA(buf, "apple");
2806     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2808     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2809     ok(sz == 4, "Expected 4, got %d\n", sz);
2810
2811     RegDeleteValueA(propkey, "HelpLink");
2812     RegDeleteKeyA(propkey, "");
2813     RegDeleteKeyA(localkey, "");
2814     RegDeleteKeyA(prodkey, "");
2815     RegCloseKey(propkey);
2816     RegCloseKey(localkey);
2817     RegCloseKey(prodkey);
2818
2819     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2820     lstrcatA(keypath, prod_squashed);
2821
2822     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2823     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2824
2825     /* classes product key exists */
2826     sz = MAX_PATH;
2827     lstrcpyA(buf, "apple");
2828     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2829     ok(r == ERROR_UNKNOWN_PROPERTY,
2830        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2831     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2832     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2833
2834     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2835     lstrcatA(keypath, usersid);
2836     lstrcatA(keypath, "\\Products\\");
2837     lstrcatA(keypath, prod_squashed);
2838
2839     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2841
2842     /* local user product key exists */
2843     sz = MAX_PATH;
2844     lstrcpyA(buf, "apple");
2845     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2846     ok(r == ERROR_UNKNOWN_PROPERTY,
2847        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2848     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2849     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2850
2851     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2852     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2853
2854     /* InstallProperties key exists */
2855     sz = MAX_PATH;
2856     lstrcpyA(buf, "apple");
2857     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2858     ok(r == ERROR_UNKNOWN_PROPERTY,
2859        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2860     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2861     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2862
2863     RegDeleteKeyA(propkey, "");
2864     RegDeleteKeyA(localkey, "");
2865     RegCloseKey(propkey);
2866     RegCloseKey(localkey);
2867
2868     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2869     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2870     lstrcatA(keypath, prod_squashed);
2871
2872     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2874
2875     /* Local System product key exists */
2876     sz = MAX_PATH;
2877     lstrcpyA(buf, "apple");
2878     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2879     ok(r == ERROR_UNKNOWN_PROPERTY,
2880         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2881     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2882     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2883
2884     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2886
2887     /* InstallProperties key exists */
2888     sz = MAX_PATH;
2889     lstrcpyA(buf, "apple");
2890     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2892     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2893     ok(sz == 0, "Expected 0, got %d\n", sz);
2894
2895     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2897
2898     /* HelpLink value exists */
2899     sz = MAX_PATH;
2900     lstrcpyA(buf, "apple");
2901     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2903     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2904     ok(sz == 4, "Expected 4, got %d\n", sz);
2905
2906     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2907                          (const BYTE *)&val, sizeof(DWORD));
2908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2909
2910     /* HelpLink type is REG_DWORD */
2911     sz = MAX_PATH;
2912     lstrcpyA(buf, "apple");
2913     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2914     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2915     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2916     ok(sz == 2, "Expected 2, got %d\n", sz);
2917
2918     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2920
2921     /* DisplayName value exists */
2922     sz = MAX_PATH;
2923     lstrcpyA(buf, "apple");
2924     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2926     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2927     ok(sz == 4, "Expected 4, got %d\n", sz);
2928
2929     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2930                          (const BYTE *)&val, sizeof(DWORD));
2931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2932
2933     /* DisplayName type is REG_DWORD */
2934     sz = MAX_PATH;
2935     lstrcpyA(buf, "apple");
2936     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2938     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2939     ok(sz == 2, "Expected 2, got %d\n", sz);
2940
2941     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
2942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2943
2944     /* DisplayVersion value exists */
2945     sz = MAX_PATH;
2946     lstrcpyA(buf, "apple");
2947     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2949     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
2950     ok(sz == 5, "Expected 5, got %d\n", sz);
2951
2952     res = RegSetValueExA(propkey, "DisplayVersion", 0,
2953                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2955
2956     /* DisplayVersion type is REG_DWORD */
2957     sz = MAX_PATH;
2958     lstrcpyA(buf, "apple");
2959     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2960     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2961     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2962     ok(sz == 2, "Expected 2, got %d\n", sz);
2963
2964     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
2965     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2966
2967     /* HelpTelephone value exists */
2968     sz = MAX_PATH;
2969     lstrcpyA(buf, "apple");
2970     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2971     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2972     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
2973     ok(sz == 4, "Expected 4, got %d\n", sz);
2974
2975     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
2976                          (const BYTE *)&val, sizeof(DWORD));
2977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2978
2979     /* HelpTelephone type is REG_DWORD */
2980     sz = MAX_PATH;
2981     lstrcpyA(buf, "apple");
2982     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2984     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2985     ok(sz == 2, "Expected 2, got %d\n", sz);
2986
2987     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
2988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2989
2990     /* InstallLocation value exists */
2991     sz = MAX_PATH;
2992     lstrcpyA(buf, "apple");
2993     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
2994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2995     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
2996     ok(sz == 3, "Expected 3, got %d\n", sz);
2997
2998     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
2999                          (const BYTE *)&val, sizeof(DWORD));
3000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3001
3002     /* InstallLocation type is REG_DWORD */
3003     sz = MAX_PATH;
3004     lstrcpyA(buf, "apple");
3005     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3006     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3007     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3008     ok(sz == 2, "Expected 2, got %d\n", sz);
3009
3010     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3012
3013     /* InstallSource value exists */
3014     sz = MAX_PATH;
3015     lstrcpyA(buf, "apple");
3016     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3018     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3019     ok(sz == 6, "Expected 6, got %d\n", sz);
3020
3021     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3022                          (const BYTE *)&val, sizeof(DWORD));
3023     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3024
3025     /* InstallSource type is REG_DWORD */
3026     sz = MAX_PATH;
3027     lstrcpyA(buf, "apple");
3028     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3030     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3031     ok(sz == 2, "Expected 2, got %d\n", sz);
3032
3033     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3035
3036     /* InstallDate value exists */
3037     sz = MAX_PATH;
3038     lstrcpyA(buf, "apple");
3039     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3040     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3041     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3042     ok(sz == 4, "Expected 4, got %d\n", sz);
3043
3044     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3045                          (const BYTE *)&val, sizeof(DWORD));
3046     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3047
3048     /* InstallDate type is REG_DWORD */
3049     sz = MAX_PATH;
3050     lstrcpyA(buf, "apple");
3051     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3052     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3053     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3054     ok(sz == 2, "Expected 2, got %d\n", sz);
3055
3056     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3057     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3058
3059     /* Publisher value exists */
3060     sz = MAX_PATH;
3061     lstrcpyA(buf, "apple");
3062     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3063     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3064     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3065     ok(sz == 3, "Expected 3, got %d\n", sz);
3066
3067     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3068                          (const BYTE *)&val, sizeof(DWORD));
3069     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3070
3071     /* Publisher type is REG_DWORD */
3072     sz = MAX_PATH;
3073     lstrcpyA(buf, "apple");
3074     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3076     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3077     ok(sz == 2, "Expected 2, got %d\n", sz);
3078
3079     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3081
3082     /* LocalPackage value exists */
3083     sz = MAX_PATH;
3084     lstrcpyA(buf, "apple");
3085     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3086     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3087     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3088     ok(sz == 4, "Expected 4, got %d\n", sz);
3089
3090     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3091                          (const BYTE *)&val, sizeof(DWORD));
3092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3093
3094     /* LocalPackage type is REG_DWORD */
3095     sz = MAX_PATH;
3096     lstrcpyA(buf, "apple");
3097     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3098     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3099     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3100     ok(sz == 2, "Expected 2, got %d\n", sz);
3101
3102     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3103     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3104
3105     /* UrlInfoAbout value exists */
3106     sz = MAX_PATH;
3107     lstrcpyA(buf, "apple");
3108     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3109     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3110     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3111     ok(sz == 5, "Expected 5, got %d\n", sz);
3112
3113     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3114                          (const BYTE *)&val, sizeof(DWORD));
3115     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3116
3117     /* UrlInfoAbout type is REG_DWORD */
3118     sz = MAX_PATH;
3119     lstrcpyA(buf, "apple");
3120     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3121     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3122     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3123     ok(sz == 2, "Expected 2, got %d\n", sz);
3124
3125     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3127
3128     /* UrlUpdateInfo value exists */
3129     sz = MAX_PATH;
3130     lstrcpyA(buf, "apple");
3131     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3132     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3133     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3134     ok(sz == 4, "Expected 4, got %d\n", sz);
3135
3136     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3137                          (const BYTE *)&val, sizeof(DWORD));
3138     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3139
3140     /* UrlUpdateInfo type is REG_DWORD */
3141     sz = MAX_PATH;
3142     lstrcpyA(buf, "apple");
3143     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3144     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3145     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3146     ok(sz == 2, "Expected 2, got %d\n", sz);
3147
3148     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3149     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3150
3151     /* VersionMinor value exists */
3152     sz = MAX_PATH;
3153     lstrcpyA(buf, "apple");
3154     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3155     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3156     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3157     ok(sz == 1, "Expected 1, got %d\n", sz);
3158
3159     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3160                          (const BYTE *)&val, sizeof(DWORD));
3161     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3162
3163     /* VersionMinor type is REG_DWORD */
3164     sz = MAX_PATH;
3165     lstrcpyA(buf, "apple");
3166     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3168     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3169     ok(sz == 2, "Expected 2, got %d\n", sz);
3170
3171     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3173
3174     /* VersionMajor value exists */
3175     sz = MAX_PATH;
3176     lstrcpyA(buf, "apple");
3177     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3178     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3179     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3180     ok(sz == 1, "Expected 1, got %d\n", sz);
3181
3182     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3183                          (const BYTE *)&val, sizeof(DWORD));
3184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3185
3186     /* VersionMajor type is REG_DWORD */
3187     sz = MAX_PATH;
3188     lstrcpyA(buf, "apple");
3189     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3190     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3191     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3192     ok(sz == 2, "Expected 2, got %d\n", sz);
3193
3194     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3196
3197     /* ProductID value exists */
3198     sz = MAX_PATH;
3199     lstrcpyA(buf, "apple");
3200     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3201     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3202     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3203     ok(sz == 2, "Expected 2, got %d\n", sz);
3204
3205     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3206                          (const BYTE *)&val, sizeof(DWORD));
3207     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3208
3209     /* ProductID type is REG_DWORD */
3210     sz = MAX_PATH;
3211     lstrcpyA(buf, "apple");
3212     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3214     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3215     ok(sz == 2, "Expected 2, got %d\n", sz);
3216
3217     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3218     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3219
3220     /* RegCompany value exists */
3221     sz = MAX_PATH;
3222     lstrcpyA(buf, "apple");
3223     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3225     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3226     ok(sz == 4, "Expected 4, got %d\n", sz);
3227
3228     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3229                          (const BYTE *)&val, sizeof(DWORD));
3230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3231
3232     /* RegCompany type is REG_DWORD */
3233     sz = MAX_PATH;
3234     lstrcpyA(buf, "apple");
3235     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3237     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3238     ok(sz == 2, "Expected 2, got %d\n", sz);
3239
3240     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3242
3243     /* RegOwner value exists */
3244     sz = MAX_PATH;
3245     lstrcpyA(buf, "apple");
3246     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3248     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3249     ok(sz == 3, "Expected 3, got %d\n", sz);
3250
3251     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3252                          (const BYTE *)&val, sizeof(DWORD));
3253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3254
3255     /* RegOwner type is REG_DWORD */
3256     sz = MAX_PATH;
3257     lstrcpyA(buf, "apple");
3258     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3259     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3260     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3261     ok(sz == 2, "Expected 2, got %d\n", sz);
3262
3263     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3264     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3265
3266     /* InstanceType value exists */
3267     sz = MAX_PATH;
3268     lstrcpyA(buf, "apple");
3269     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3271     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3272     ok(sz == 0, "Expected 0, got %d\n", sz);
3273
3274     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3275                          (const BYTE *)&val, sizeof(DWORD));
3276     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3277
3278     /* InstanceType type is REG_DWORD */
3279     sz = MAX_PATH;
3280     lstrcpyA(buf, "apple");
3281     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3282     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3283     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3284     ok(sz == 0, "Expected 0, got %d\n", sz);
3285
3286     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3288
3289     /* InstanceType value exists */
3290     sz = MAX_PATH;
3291     lstrcpyA(buf, "apple");
3292     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3294     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3295     ok(sz == 4, "Expected 4, got %d\n", sz);
3296
3297     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3298                          (const BYTE *)&val, sizeof(DWORD));
3299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3300
3301     /* InstanceType type is REG_DWORD */
3302     sz = MAX_PATH;
3303     lstrcpyA(buf, "apple");
3304     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3306     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3307     ok(sz == 2, "Expected 2, got %d\n", sz);
3308
3309     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3311
3312     /* Transforms value exists */
3313     sz = MAX_PATH;
3314     lstrcpyA(buf, "apple");
3315     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3317     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3318     ok(sz == 0, "Expected 0, got %d\n", sz);
3319
3320     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3321                          (const BYTE *)&val, sizeof(DWORD));
3322     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3323
3324     /* Transforms type is REG_DWORD */
3325     sz = MAX_PATH;
3326     lstrcpyA(buf, "apple");
3327     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3329     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3330     ok(sz == 0, "Expected 0, got %d\n", sz);
3331
3332     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3333     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3334
3335     /* Transforms value exists */
3336     sz = MAX_PATH;
3337     lstrcpyA(buf, "apple");
3338     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3339     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3340     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3341     ok(sz == 6, "Expected 6, got %d\n", sz);
3342
3343     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3344                          (const BYTE *)&val, sizeof(DWORD));
3345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3346
3347     /* Transforms type is REG_DWORD */
3348     sz = MAX_PATH;
3349     lstrcpyA(buf, "apple");
3350     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3351     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3352     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3353     ok(sz == 2, "Expected 2, got %d\n", sz);
3354
3355     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3357
3358     /* Language value exists */
3359     sz = MAX_PATH;
3360     lstrcpyA(buf, "apple");
3361     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3363     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3364     ok(sz == 0, "Expected 0, got %d\n", sz);
3365
3366     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3367                          (const BYTE *)&val, sizeof(DWORD));
3368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3369
3370     /* Language type is REG_DWORD */
3371     sz = MAX_PATH;
3372     lstrcpyA(buf, "apple");
3373     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3374     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3375     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3376     ok(sz == 0, "Expected 0, got %d\n", sz);
3377
3378     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3380
3381     /* Language value exists */
3382     sz = MAX_PATH;
3383     lstrcpyA(buf, "apple");
3384     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3385     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3386     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3387     ok(sz == 4, "Expected 4, got %d\n", sz);
3388
3389     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3390                          (const BYTE *)&val, sizeof(DWORD));
3391     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3392
3393     /* Language type is REG_DWORD */
3394     sz = MAX_PATH;
3395     lstrcpyA(buf, "apple");
3396     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3397     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3398     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3399     ok(sz == 2, "Expected 2, got %d\n", sz);
3400
3401     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3403
3404     /* ProductName value exists */
3405     sz = MAX_PATH;
3406     lstrcpyA(buf, "apple");
3407     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3408     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3409     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3410     ok(sz == 0, "Expected 0, got %d\n", sz);
3411
3412     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3413                          (const BYTE *)&val, sizeof(DWORD));
3414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3415
3416     /* ProductName type is REG_DWORD */
3417     sz = MAX_PATH;
3418     lstrcpyA(buf, "apple");
3419     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3420     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3421     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3422     ok(sz == 0, "Expected 0, got %d\n", sz);
3423
3424     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3426
3427     /* ProductName value exists */
3428     sz = MAX_PATH;
3429     lstrcpyA(buf, "apple");
3430     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3431     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3432     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3433     ok(sz == 4, "Expected 4, got %d\n", sz);
3434
3435     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3436                          (const BYTE *)&val, sizeof(DWORD));
3437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3438
3439     /* ProductName type is REG_DWORD */
3440     sz = MAX_PATH;
3441     lstrcpyA(buf, "apple");
3442     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3444     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3445     ok(sz == 2, "Expected 2, got %d\n", sz);
3446
3447     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3449
3450     /* Assignment value exists */
3451     sz = MAX_PATH;
3452     lstrcpyA(buf, "apple");
3453     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3455     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3456     ok(sz == 0, "Expected 0, got %d\n", sz);
3457
3458     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3459                          (const BYTE *)&val, sizeof(DWORD));
3460     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3461
3462     /* Assignment type is REG_DWORD */
3463     sz = MAX_PATH;
3464     lstrcpyA(buf, "apple");
3465     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3466     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3467     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3468     ok(sz == 0, "Expected 0, got %d\n", sz);
3469
3470     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3472
3473     /* Assignment value exists */
3474     sz = MAX_PATH;
3475     lstrcpyA(buf, "apple");
3476     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3477     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3478     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3479     ok(sz == 2, "Expected 2, got %d\n", sz);
3480
3481     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3482                          (const BYTE *)&val, sizeof(DWORD));
3483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3484
3485     /* Assignment type is REG_DWORD */
3486     sz = MAX_PATH;
3487     lstrcpyA(buf, "apple");
3488     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3489     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3490     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3491     ok(sz == 2, "Expected 2, got %d\n", sz);
3492
3493     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3495
3496     /* PackageCode value exists */
3497     sz = MAX_PATH;
3498     lstrcpyA(buf, "apple");
3499     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3501     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3502     ok(sz == 0, "Expected 0, got %d\n", sz);
3503
3504     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3505                          (const BYTE *)&val, sizeof(DWORD));
3506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3507
3508     /* PackageCode type is REG_DWORD */
3509     sz = MAX_PATH;
3510     lstrcpyA(buf, "apple");
3511     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3512     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3513     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3514     ok(sz == 0, "Expected 0, got %d\n", sz);
3515
3516     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3518
3519     /* PackageCode value exists */
3520     sz = MAX_PATH;
3521     lstrcpyA(buf, "apple");
3522     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3523     ok(r == ERROR_BAD_CONFIGURATION,
3524        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3525     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3526     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3527
3528     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3529                          (const BYTE *)&val, sizeof(DWORD));
3530     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3531
3532     /* PackageCode type is REG_DWORD */
3533     sz = MAX_PATH;
3534     lstrcpyA(buf, "apple");
3535     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3536     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3537     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3538     ok(sz == 2, "Expected 2, got %d\n", sz);
3539
3540     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3541     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3542
3543     /* PackageCode value exists */
3544     sz = MAX_PATH;
3545     lstrcpyA(buf, "apple");
3546     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3547     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3548     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3549     ok(sz == 38, "Expected 38, got %d\n", sz);
3550
3551     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3553
3554     /* Version value exists */
3555     sz = MAX_PATH;
3556     lstrcpyA(buf, "apple");
3557     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3558     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3559     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3560     ok(sz == 0, "Expected 0, got %d\n", sz);
3561
3562     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3563                          (const BYTE *)&val, sizeof(DWORD));
3564     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3565
3566     /* Version type is REG_DWORD */
3567     sz = MAX_PATH;
3568     lstrcpyA(buf, "apple");
3569     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3570     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3571     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3572     ok(sz == 0, "Expected 0, got %d\n", sz);
3573
3574     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3576
3577     /* Version value exists */
3578     sz = MAX_PATH;
3579     lstrcpyA(buf, "apple");
3580     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3582     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3583     ok(sz == 3, "Expected 3, got %d\n", sz);
3584
3585     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3586                          (const BYTE *)&val, sizeof(DWORD));
3587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3588
3589     /* Version type is REG_DWORD */
3590     sz = MAX_PATH;
3591     lstrcpyA(buf, "apple");
3592     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3593     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3594     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3595     ok(sz == 2, "Expected 2, got %d\n", sz);
3596
3597     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3599
3600     /* ProductIcon value exists */
3601     sz = MAX_PATH;
3602     lstrcpyA(buf, "apple");
3603     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3604     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3605     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3606     ok(sz == 0, "Expected 0, got %d\n", sz);
3607
3608     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3609                          (const BYTE *)&val, sizeof(DWORD));
3610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3611
3612     /* ProductIcon type is REG_DWORD */
3613     sz = MAX_PATH;
3614     lstrcpyA(buf, "apple");
3615     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3616     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3617     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3618     ok(sz == 0, "Expected 0, got %d\n", sz);
3619
3620     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3621     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3622
3623     /* ProductIcon value exists */
3624     sz = MAX_PATH;
3625     lstrcpyA(buf, "apple");
3626     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3627     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3628     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3629     ok(sz == 3, "Expected 3, got %d\n", sz);
3630
3631     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3632                          (const BYTE *)&val, sizeof(DWORD));
3633     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3634
3635     /* ProductIcon type is REG_DWORD */
3636     sz = MAX_PATH;
3637     lstrcpyA(buf, "apple");
3638     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3639     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3640     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3641     ok(sz == 2, "Expected 2, got %d\n", sz);
3642
3643     res = RegCreateKeyA(prodkey, "SourceList", &source);
3644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3645
3646     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3648
3649     sz = MAX_PATH;
3650     lstrcpyA(buf, "apple");
3651     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3652     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3653     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3654     ok(sz == 8, "Expected 8, got %d\n", sz);
3655
3656     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3657                          (const BYTE *)&val, sizeof(DWORD));
3658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3659
3660     /* PackageName type is REG_DWORD */
3661     sz = MAX_PATH;
3662     lstrcpyA(buf, "apple");
3663     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3665     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3666     ok(sz == 2, "Expected 2, got %d\n", sz);
3667
3668     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3670
3671     /* Authorized value exists */
3672     sz = MAX_PATH;
3673     lstrcpyA(buf, "apple");
3674     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3675     if (r != ERROR_UNKNOWN_PROPERTY)
3676     {
3677         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3678         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3679         ok(sz == 0, "Expected 0, got %d\n", sz);
3680     }
3681
3682     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3683                          (const BYTE *)&val, sizeof(DWORD));
3684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3685
3686     /* AuthorizedLUAApp type is REG_DWORD */
3687     sz = MAX_PATH;
3688     lstrcpyA(buf, "apple");
3689     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3690     if (r != ERROR_UNKNOWN_PROPERTY)
3691     {
3692         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3693         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3694         ok(sz == 0, "Expected 0, got %d\n", sz);
3695     }
3696
3697     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3699
3700     /* Authorized value exists */
3701     sz = MAX_PATH;
3702     lstrcpyA(buf, "apple");
3703     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3704     if (r != ERROR_UNKNOWN_PROPERTY)
3705     {
3706         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3707         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3708         ok(sz == 4, "Expected 4, got %d\n", sz);
3709     }
3710
3711     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3712                          (const BYTE *)&val, sizeof(DWORD));
3713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3714
3715     /* AuthorizedLUAApp type is REG_DWORD */
3716     sz = MAX_PATH;
3717     lstrcpyA(buf, "apple");
3718     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3719     if (r != ERROR_UNKNOWN_PROPERTY)
3720     {
3721         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3722         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3723         ok(sz == 2, "Expected 2, got %d\n", sz);
3724     }
3725
3726     RegDeleteValueA(propkey, "HelpLink");
3727     RegDeleteValueA(propkey, "DisplayName");
3728     RegDeleteValueA(propkey, "DisplayVersion");
3729     RegDeleteValueA(propkey, "HelpTelephone");
3730     RegDeleteValueA(propkey, "InstallLocation");
3731     RegDeleteValueA(propkey, "InstallSource");
3732     RegDeleteValueA(propkey, "InstallDate");
3733     RegDeleteValueA(propkey, "Publisher");
3734     RegDeleteValueA(propkey, "LocalPackage");
3735     RegDeleteValueA(propkey, "UrlInfoAbout");
3736     RegDeleteValueA(propkey, "UrlUpdateInfo");
3737     RegDeleteValueA(propkey, "VersionMinor");
3738     RegDeleteValueA(propkey, "VersionMajor");
3739     RegDeleteValueA(propkey, "ProductID");
3740     RegDeleteValueA(propkey, "RegCompany");
3741     RegDeleteValueA(propkey, "RegOwner");
3742     RegDeleteValueA(propkey, "InstanceType");
3743     RegDeleteValueA(propkey, "Transforms");
3744     RegDeleteValueA(propkey, "Language");
3745     RegDeleteValueA(propkey, "ProductName");
3746     RegDeleteValueA(propkey, "Assignment");
3747     RegDeleteValueA(propkey, "PackageCode");
3748     RegDeleteValueA(propkey, "Version");
3749     RegDeleteValueA(propkey, "ProductIcon");
3750     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3751     RegDeleteKeyA(propkey, "");
3752     RegDeleteKeyA(localkey, "");
3753     RegDeleteValueA(prodkey, "InstanceType");
3754     RegDeleteValueA(prodkey, "Transforms");
3755     RegDeleteValueA(prodkey, "Language");
3756     RegDeleteValueA(prodkey, "ProductName");
3757     RegDeleteValueA(prodkey, "Assignment");
3758     RegDeleteValueA(prodkey, "PackageCode");
3759     RegDeleteValueA(prodkey, "Version");
3760     RegDeleteValueA(prodkey, "ProductIcon");
3761     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3762     RegDeleteValueA(source, "PackageName");
3763     RegDeleteKeyA(source, "");
3764     RegDeleteKeyA(prodkey, "");
3765     RegCloseKey(propkey);
3766     RegCloseKey(localkey);
3767     RegCloseKey(source);
3768     RegCloseKey(prodkey);
3769 }
3770
3771 static void test_MsiGetProductInfoEx(void)
3772 {
3773     UINT r;
3774     LONG res;
3775     HKEY propkey, userkey;
3776     HKEY prodkey, localkey;
3777     CHAR prodcode[MAX_PATH];
3778     CHAR prod_squashed[MAX_PATH];
3779     CHAR packcode[MAX_PATH];
3780     CHAR pack_squashed[MAX_PATH];
3781     CHAR buf[MAX_PATH];
3782     CHAR keypath[MAX_PATH];
3783     LPSTR usersid;
3784     DWORD sz;
3785
3786     if (!pMsiGetProductInfoExA)
3787     {
3788         skip("MsiGetProductInfoExA is not available\n");
3789         return;
3790     }
3791
3792     create_test_guid(prodcode, prod_squashed);
3793     create_test_guid(packcode, pack_squashed);
3794     get_user_sid(&usersid);
3795
3796     /* NULL szProductCode */
3797     sz = MAX_PATH;
3798     lstrcpyA(buf, "apple");
3799     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3800                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3801     ok(r == ERROR_INVALID_PARAMETER,
3802        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3803     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3804     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3805
3806     /* empty szProductCode */
3807     sz = MAX_PATH;
3808     lstrcpyA(buf, "apple");
3809     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3810                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3811     ok(r == ERROR_INVALID_PARAMETER,
3812        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3813     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3814     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3815
3816     /* garbage szProductCode */
3817     sz = MAX_PATH;
3818     lstrcpyA(buf, "apple");
3819     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3820                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3821     ok(r == ERROR_INVALID_PARAMETER,
3822        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3823     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3824     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3825
3826     /* guid without brackets */
3827     sz = MAX_PATH;
3828     lstrcpyA(buf, "apple");
3829     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3830                               MSIINSTALLCONTEXT_USERUNMANAGED,
3831                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3832     ok(r == ERROR_INVALID_PARAMETER,
3833        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3834     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3835     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3836
3837     /* guid with brackets */
3838     sz = MAX_PATH;
3839     lstrcpyA(buf, "apple");
3840     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3841                               MSIINSTALLCONTEXT_USERUNMANAGED,
3842                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3843     ok(r == ERROR_UNKNOWN_PRODUCT,
3844        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3845     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3846     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3847
3848     /* szValue is non-NULL while pcchValue is NULL */
3849     lstrcpyA(buf, "apple");
3850     r = pMsiGetProductInfoExA(prodcode, usersid,
3851                               MSIINSTALLCONTEXT_USERUNMANAGED,
3852                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3853     ok(r == ERROR_INVALID_PARAMETER,
3854        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3855     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3856
3857     /* dwContext is out of range */
3858     sz = MAX_PATH;
3859     lstrcpyA(buf, "apple");
3860     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3861                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3862     ok(r == ERROR_INVALID_PARAMETER,
3863        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3864     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3865     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3866
3867     /* szProperty is NULL */
3868     sz = MAX_PATH;
3869     lstrcpyA(buf, "apple");
3870     r = pMsiGetProductInfoExA(prodcode, usersid,
3871                               MSIINSTALLCONTEXT_USERUNMANAGED,
3872                               NULL, buf, &sz);
3873     ok(r == ERROR_INVALID_PARAMETER,
3874        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3875     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3876     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3877
3878     /* szProperty is empty */
3879     sz = MAX_PATH;
3880     lstrcpyA(buf, "apple");
3881     r = pMsiGetProductInfoExA(prodcode, usersid,
3882                               MSIINSTALLCONTEXT_USERUNMANAGED,
3883                               "", buf, &sz);
3884     ok(r == ERROR_INVALID_PARAMETER,
3885        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3886     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3887     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3888
3889     /* szProperty is not a valid property */
3890     sz = MAX_PATH;
3891     lstrcpyA(buf, "apple");
3892     r = pMsiGetProductInfoExA(prodcode, usersid,
3893                               MSIINSTALLCONTEXT_USERUNMANAGED,
3894                               "notvalid", buf, &sz);
3895     ok(r == ERROR_UNKNOWN_PRODUCT,
3896        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3897     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3898     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3899
3900     /* same length as guid, but random */
3901     sz = MAX_PATH;
3902     lstrcpyA(buf, "apple");
3903     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3904                               MSIINSTALLCONTEXT_USERUNMANAGED,
3905                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3906     ok(r == ERROR_INVALID_PARAMETER,
3907        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3908     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3909     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3910
3911     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3912
3913     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3914     lstrcatA(keypath, usersid);
3915     lstrcatA(keypath, "\\Products\\");
3916     lstrcatA(keypath, prod_squashed);
3917
3918     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3920
3921     /* local user product key exists */
3922     sz = MAX_PATH;
3923     lstrcpyA(buf, "apple");
3924     r = pMsiGetProductInfoExA(prodcode, usersid,
3925                               MSIINSTALLCONTEXT_USERUNMANAGED,
3926                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3927     ok(r == ERROR_UNKNOWN_PRODUCT,
3928        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3929     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3930     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3931
3932     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3934
3935     /* InstallProperties key exists */
3936     sz = MAX_PATH;
3937     lstrcpyA(buf, "apple");
3938     r = pMsiGetProductInfoExA(prodcode, usersid,
3939                               MSIINSTALLCONTEXT_USERUNMANAGED,
3940                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3941     ok(r == ERROR_UNKNOWN_PRODUCT,
3942        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3943     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3944     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3945
3946     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3948
3949     /* LocalPackage value exists */
3950     sz = MAX_PATH;
3951     lstrcpyA(buf, "apple");
3952     r = pMsiGetProductInfoExA(prodcode, usersid,
3953                               MSIINSTALLCONTEXT_USERUNMANAGED,
3954                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3955     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3956     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
3957     ok(sz == 1, "Expected 1, got %d\n", sz);
3958
3959     RegDeleteValueA(propkey, "LocalPackage");
3960
3961     /* LocalPackage value must exist */
3962     sz = MAX_PATH;
3963     lstrcpyA(buf, "apple");
3964     r = pMsiGetProductInfoExA(prodcode, usersid,
3965                               MSIINSTALLCONTEXT_USERUNMANAGED,
3966                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3967     ok(r == ERROR_UNKNOWN_PRODUCT,
3968        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3969     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3970     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3971
3972     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3974
3975     /* LocalPackage exists, but HelpLink does not exist */
3976     sz = MAX_PATH;
3977     lstrcpyA(buf, "apple");
3978     r = pMsiGetProductInfoExA(prodcode, usersid,
3979                               MSIINSTALLCONTEXT_USERUNMANAGED,
3980                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3982     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3983     ok(sz == 0, "Expected 0, got %d\n", sz);
3984
3985     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3987
3988     /* HelpLink value exists */
3989     sz = MAX_PATH;
3990     lstrcpyA(buf, "apple");
3991     r = pMsiGetProductInfoExA(prodcode, usersid,
3992                               MSIINSTALLCONTEXT_USERUNMANAGED,
3993                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3995     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3996     ok(sz == 4, "Expected 4, got %d\n", sz);
3997
3998     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
3999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4000
4001     /* HelpTelephone value exists */
4002     sz = MAX_PATH;
4003     lstrcpyA(buf, "apple");
4004     r = pMsiGetProductInfoExA(prodcode, usersid,
4005                               MSIINSTALLCONTEXT_USERUNMANAGED,
4006                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4007     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4008     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4009     ok(sz == 5, "Expected 5, got %d\n", sz);
4010
4011     /* szValue and pcchValue are NULL */
4012     r = pMsiGetProductInfoExA(prodcode, usersid,
4013                               MSIINSTALLCONTEXT_USERUNMANAGED,
4014                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4016
4017     /* pcchValue is exactly 5 */
4018     sz = 5;
4019     lstrcpyA(buf, "apple");
4020     r = pMsiGetProductInfoExA(prodcode, usersid,
4021                               MSIINSTALLCONTEXT_USERUNMANAGED,
4022                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4023     ok(r == ERROR_MORE_DATA,
4024        "Expected ERROR_MORE_DATA, got %d\n", r);
4025     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4026     ok(sz == 10, "Expected 10, got %d\n", sz);
4027
4028     /* szValue is NULL, pcchValue is exactly 5 */
4029     sz = 5;
4030     r = pMsiGetProductInfoExA(prodcode, usersid,
4031                               MSIINSTALLCONTEXT_USERUNMANAGED,
4032                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4034     ok(sz == 10, "Expected 10, got %d\n", sz);
4035
4036     /* szValue is NULL, pcchValue is MAX_PATH */
4037     sz = MAX_PATH;
4038     r = pMsiGetProductInfoExA(prodcode, usersid,
4039                               MSIINSTALLCONTEXT_USERUNMANAGED,
4040                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4042     ok(sz == 10, "Expected 10, got %d\n", sz);
4043
4044     /* pcchValue is exactly 0 */
4045     sz = 0;
4046     lstrcpyA(buf, "apple");
4047     r = pMsiGetProductInfoExA(prodcode, usersid,
4048                               MSIINSTALLCONTEXT_USERUNMANAGED,
4049                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4050     ok(r == ERROR_MORE_DATA,
4051        "Expected ERROR_MORE_DATA, got %d\n", r);
4052     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4053     ok(sz == 10, "Expected 10, got %d\n", sz);
4054
4055     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4057
4058     /* szProperty is not a valid property */
4059     sz = MAX_PATH;
4060     lstrcpyA(buf, "apple");
4061     r = pMsiGetProductInfoExA(prodcode, usersid,
4062                               MSIINSTALLCONTEXT_USERUNMANAGED,
4063                               "notvalid", buf, &sz);
4064     ok(r == ERROR_UNKNOWN_PROPERTY,
4065        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4066     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4067     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4068
4069     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4071
4072     /* InstallDate value exists */
4073     sz = MAX_PATH;
4074     lstrcpyA(buf, "apple");
4075     r = pMsiGetProductInfoExA(prodcode, usersid,
4076                               MSIINSTALLCONTEXT_USERUNMANAGED,
4077                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4078     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4079     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4080     ok(sz == 4, "Expected 4, got %d\n", sz);
4081
4082     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4084
4085     /* DisplayName value exists */
4086     sz = MAX_PATH;
4087     lstrcpyA(buf, "apple");
4088     r = pMsiGetProductInfoExA(prodcode, usersid,
4089                               MSIINSTALLCONTEXT_USERUNMANAGED,
4090                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4091     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4092     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4093     ok(sz == 4, "Expected 4, got %d\n", sz);
4094
4095     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4096     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4097
4098     /* InstallLocation value exists */
4099     sz = MAX_PATH;
4100     lstrcpyA(buf, "apple");
4101     r = pMsiGetProductInfoExA(prodcode, usersid,
4102                               MSIINSTALLCONTEXT_USERUNMANAGED,
4103                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4104     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4105     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4106     ok(sz == 3, "Expected 3, got %d\n", sz);
4107
4108     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4110
4111     /* InstallSource value exists */
4112     sz = MAX_PATH;
4113     lstrcpyA(buf, "apple");
4114     r = pMsiGetProductInfoExA(prodcode, usersid,
4115                               MSIINSTALLCONTEXT_USERUNMANAGED,
4116                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4118     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4119     ok(sz == 6, "Expected 6, got %d\n", sz);
4120
4121     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4123
4124     /* LocalPackage value exists */
4125     sz = MAX_PATH;
4126     lstrcpyA(buf, "apple");
4127     r = pMsiGetProductInfoExA(prodcode, usersid,
4128                               MSIINSTALLCONTEXT_USERUNMANAGED,
4129                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4131     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4132     ok(sz == 5, "Expected 5, got %d\n", sz);
4133
4134     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4136
4137     /* Publisher value exists */
4138     sz = MAX_PATH;
4139     lstrcpyA(buf, "apple");
4140     r = pMsiGetProductInfoExA(prodcode, usersid,
4141                               MSIINSTALLCONTEXT_USERUNMANAGED,
4142                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4143     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4144     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4145     ok(sz == 3, "Expected 3, got %d\n", sz);
4146
4147     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4149
4150     /* URLInfoAbout value exists */
4151     sz = MAX_PATH;
4152     lstrcpyA(buf, "apple");
4153     r = pMsiGetProductInfoExA(prodcode, usersid,
4154                               MSIINSTALLCONTEXT_USERUNMANAGED,
4155                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4156     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4157     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4158     ok(sz == 5, "Expected 5, got %d\n", sz);
4159
4160     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4161     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4162
4163     /* URLUpdateInfo value exists */
4164     sz = MAX_PATH;
4165     lstrcpyA(buf, "apple");
4166     r = pMsiGetProductInfoExA(prodcode, usersid,
4167                               MSIINSTALLCONTEXT_USERUNMANAGED,
4168                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4169     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4170     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4171     ok(sz == 6, "Expected 6, got %d\n", sz);
4172
4173     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4175
4176     /* VersionMinor value exists */
4177     sz = MAX_PATH;
4178     lstrcpyA(buf, "apple");
4179     r = pMsiGetProductInfoExA(prodcode, usersid,
4180                               MSIINSTALLCONTEXT_USERUNMANAGED,
4181                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4183     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4184     ok(sz == 1, "Expected 1, got %d\n", sz);
4185
4186     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4188
4189     /* VersionMajor value exists */
4190     sz = MAX_PATH;
4191     lstrcpyA(buf, "apple");
4192     r = pMsiGetProductInfoExA(prodcode, usersid,
4193                               MSIINSTALLCONTEXT_USERUNMANAGED,
4194                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4196     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4197     ok(sz == 1, "Expected 1, got %d\n", sz);
4198
4199     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4200     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4201
4202     /* DisplayVersion value exists */
4203     sz = MAX_PATH;
4204     lstrcpyA(buf, "apple");
4205     r = pMsiGetProductInfoExA(prodcode, usersid,
4206                               MSIINSTALLCONTEXT_USERUNMANAGED,
4207                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4208     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4209     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4210     ok(sz == 5, "Expected 5, got %d\n", sz);
4211
4212     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4213     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4214
4215     /* ProductID value exists */
4216     sz = MAX_PATH;
4217     lstrcpyA(buf, "apple");
4218     r = pMsiGetProductInfoExA(prodcode, usersid,
4219                               MSIINSTALLCONTEXT_USERUNMANAGED,
4220                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4222     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4223     ok(sz == 2, "Expected 2, got %d\n", sz);
4224
4225     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4227
4228     /* RegCompany value exists */
4229     sz = MAX_PATH;
4230     lstrcpyA(buf, "apple");
4231     r = pMsiGetProductInfoExA(prodcode, usersid,
4232                               MSIINSTALLCONTEXT_USERUNMANAGED,
4233                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4235     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4236     ok(sz == 4, "Expected 4, got %d\n", sz);
4237
4238     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4240
4241     /* RegOwner value exists */
4242     sz = MAX_PATH;
4243     lstrcpyA(buf, "apple");
4244     r = pMsiGetProductInfoExA(prodcode, usersid,
4245                               MSIINSTALLCONTEXT_USERUNMANAGED,
4246                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4248     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4249     ok(sz == 5, "Expected 5, got %d\n", sz);
4250
4251     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4253
4254     /* Transforms value exists */
4255     sz = MAX_PATH;
4256     lstrcpyA(buf, "apple");
4257     r = pMsiGetProductInfoExA(prodcode, usersid,
4258                               MSIINSTALLCONTEXT_USERUNMANAGED,
4259                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4260     ok(r == ERROR_UNKNOWN_PRODUCT,
4261        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4262     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4263     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4264
4265     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4267
4268     /* Language value exists */
4269     sz = MAX_PATH;
4270     lstrcpyA(buf, "apple");
4271     r = pMsiGetProductInfoExA(prodcode, usersid,
4272                               MSIINSTALLCONTEXT_USERUNMANAGED,
4273                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4274     ok(r == ERROR_UNKNOWN_PRODUCT,
4275        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4276     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4277     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4278
4279     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4281
4282     /* ProductName value exists */
4283     sz = MAX_PATH;
4284     lstrcpyA(buf, "apple");
4285     r = pMsiGetProductInfoExA(prodcode, usersid,
4286                               MSIINSTALLCONTEXT_USERUNMANAGED,
4287                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4288     ok(r == ERROR_UNKNOWN_PRODUCT,
4289        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4290     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4291     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4292
4293     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4295
4296     /* FIXME */
4297
4298     /* AssignmentType value exists */
4299     sz = MAX_PATH;
4300     lstrcpyA(buf, "apple");
4301     r = pMsiGetProductInfoExA(prodcode, usersid,
4302                               MSIINSTALLCONTEXT_USERUNMANAGED,
4303                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4304     ok(r == ERROR_UNKNOWN_PRODUCT,
4305        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4306     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4307     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4308
4309     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4311
4312     /* PackageCode value exists */
4313     sz = MAX_PATH;
4314     lstrcpyA(buf, "apple");
4315     r = pMsiGetProductInfoExA(prodcode, usersid,
4316                               MSIINSTALLCONTEXT_USERUNMANAGED,
4317                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4318     ok(r == ERROR_UNKNOWN_PRODUCT,
4319        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4320     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4321     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4322
4323     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4325
4326     /* Version value exists */
4327     sz = MAX_PATH;
4328     lstrcpyA(buf, "apple");
4329     r = pMsiGetProductInfoExA(prodcode, usersid,
4330                               MSIINSTALLCONTEXT_USERUNMANAGED,
4331                               INSTALLPROPERTY_VERSION, buf, &sz);
4332     ok(r == ERROR_UNKNOWN_PRODUCT,
4333        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4334     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4335     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4336
4337     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4339
4340     /* ProductIcon value exists */
4341     sz = MAX_PATH;
4342     lstrcpyA(buf, "apple");
4343     r = pMsiGetProductInfoExA(prodcode, usersid,
4344                               MSIINSTALLCONTEXT_USERUNMANAGED,
4345                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4346     ok(r == ERROR_UNKNOWN_PRODUCT,
4347        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4348     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4349     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4350
4351     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4353
4354     /* PackageName value exists */
4355     sz = MAX_PATH;
4356     lstrcpyA(buf, "apple");
4357     r = pMsiGetProductInfoExA(prodcode, usersid,
4358                               MSIINSTALLCONTEXT_USERUNMANAGED,
4359                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4360     ok(r == ERROR_UNKNOWN_PRODUCT,
4361        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4362     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4363     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4364
4365     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4367
4368     /* AuthorizedLUAApp value exists */
4369     sz = MAX_PATH;
4370     lstrcpyA(buf, "apple");
4371     r = pMsiGetProductInfoExA(prodcode, usersid,
4372                               MSIINSTALLCONTEXT_USERUNMANAGED,
4373                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4374     ok(r == ERROR_UNKNOWN_PRODUCT,
4375        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4376     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4377     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4378
4379     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4380     RegDeleteValueA(propkey, "PackageName");
4381     RegDeleteValueA(propkey, "ProductIcon");
4382     RegDeleteValueA(propkey, "Version");
4383     RegDeleteValueA(propkey, "PackageCode");
4384     RegDeleteValueA(propkey, "AssignmentType");
4385     RegDeleteValueA(propkey, "ProductName");
4386     RegDeleteValueA(propkey, "Language");
4387     RegDeleteValueA(propkey, "Transforms");
4388     RegDeleteValueA(propkey, "RegOwner");
4389     RegDeleteValueA(propkey, "RegCompany");
4390     RegDeleteValueA(propkey, "ProductID");
4391     RegDeleteValueA(propkey, "DisplayVersion");
4392     RegDeleteValueA(propkey, "VersionMajor");
4393     RegDeleteValueA(propkey, "VersionMinor");
4394     RegDeleteValueA(propkey, "URLUpdateInfo");
4395     RegDeleteValueA(propkey, "URLInfoAbout");
4396     RegDeleteValueA(propkey, "Publisher");
4397     RegDeleteValueA(propkey, "LocalPackage");
4398     RegDeleteValueA(propkey, "InstallSource");
4399     RegDeleteValueA(propkey, "InstallLocation");
4400     RegDeleteValueA(propkey, "DisplayName");
4401     RegDeleteValueA(propkey, "InstallDate");
4402     RegDeleteValueA(propkey, "HelpTelephone");
4403     RegDeleteValueA(propkey, "HelpLink");
4404     RegDeleteValueA(propkey, "LocalPackage");
4405     RegDeleteKeyA(propkey, "");
4406     RegCloseKey(propkey);
4407     RegDeleteKeyA(localkey, "");
4408     RegCloseKey(localkey);
4409
4410     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4411     lstrcatA(keypath, usersid);
4412     lstrcatA(keypath, "\\Installer\\Products\\");
4413     lstrcatA(keypath, prod_squashed);
4414
4415     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4417
4418     /* user product key exists */
4419     sz = MAX_PATH;
4420     lstrcpyA(buf, "apple");
4421     r = pMsiGetProductInfoExA(prodcode, usersid,
4422                               MSIINSTALLCONTEXT_USERUNMANAGED,
4423                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4424     ok(r == ERROR_UNKNOWN_PRODUCT,
4425        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4426     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4427     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4428
4429     RegDeleteKeyA(userkey, "");
4430     RegCloseKey(userkey);
4431
4432     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4433     lstrcatA(keypath, prod_squashed);
4434
4435     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4437
4438     sz = MAX_PATH;
4439     lstrcpyA(buf, "apple");
4440     r = pMsiGetProductInfoExA(prodcode, usersid,
4441                               MSIINSTALLCONTEXT_USERUNMANAGED,
4442                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4444     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4445     ok(sz == 1, "Expected 1, got %d\n", sz);
4446
4447     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4449
4450     /* HelpLink value exists */
4451     sz = MAX_PATH;
4452     lstrcpyA(buf, "apple");
4453     r = pMsiGetProductInfoExA(prodcode, usersid,
4454                               MSIINSTALLCONTEXT_USERUNMANAGED,
4455                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4456     ok(r == ERROR_UNKNOWN_PROPERTY,
4457        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4458     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4459     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4460
4461     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4463
4464     /* HelpTelephone value exists */
4465     sz = MAX_PATH;
4466     lstrcpyA(buf, "apple");
4467     r = pMsiGetProductInfoExA(prodcode, usersid,
4468                               MSIINSTALLCONTEXT_USERUNMANAGED,
4469                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4470     ok(r == ERROR_UNKNOWN_PROPERTY,
4471        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4472     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4473     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4474
4475     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4476     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4477
4478     /* InstallDate value exists */
4479     sz = MAX_PATH;
4480     lstrcpyA(buf, "apple");
4481     r = pMsiGetProductInfoExA(prodcode, usersid,
4482                               MSIINSTALLCONTEXT_USERUNMANAGED,
4483                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4484     ok(r == ERROR_UNKNOWN_PROPERTY,
4485        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4486     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4487     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4488
4489     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4491
4492     /* DisplayName value exists */
4493     sz = MAX_PATH;
4494     lstrcpyA(buf, "apple");
4495     r = pMsiGetProductInfoExA(prodcode, usersid,
4496                               MSIINSTALLCONTEXT_USERUNMANAGED,
4497                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4498     ok(r == ERROR_UNKNOWN_PROPERTY,
4499        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4500     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4501     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4502
4503     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4504     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4505
4506     /* InstallLocation value exists */
4507     sz = MAX_PATH;
4508     lstrcpyA(buf, "apple");
4509     r = pMsiGetProductInfoExA(prodcode, usersid,
4510                               MSIINSTALLCONTEXT_USERUNMANAGED,
4511                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4512     ok(r == ERROR_UNKNOWN_PROPERTY,
4513        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4514     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4515     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4516
4517     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4518     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4519
4520     /* InstallSource value exists */
4521     sz = MAX_PATH;
4522     lstrcpyA(buf, "apple");
4523     r = pMsiGetProductInfoExA(prodcode, usersid,
4524                               MSIINSTALLCONTEXT_USERUNMANAGED,
4525                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4526     ok(r == ERROR_UNKNOWN_PROPERTY,
4527        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4528     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4529     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4530
4531     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4533
4534     /* LocalPackage value exists */
4535     sz = MAX_PATH;
4536     lstrcpyA(buf, "apple");
4537     r = pMsiGetProductInfoExA(prodcode, usersid,
4538                               MSIINSTALLCONTEXT_USERUNMANAGED,
4539                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4540     ok(r == ERROR_UNKNOWN_PROPERTY,
4541        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4542     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4543     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4544
4545     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4547
4548     /* Publisher value exists */
4549     sz = MAX_PATH;
4550     lstrcpyA(buf, "apple");
4551     r = pMsiGetProductInfoExA(prodcode, usersid,
4552                               MSIINSTALLCONTEXT_USERUNMANAGED,
4553                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4554     ok(r == ERROR_UNKNOWN_PROPERTY,
4555        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4556     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4557     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4558
4559     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4561
4562     /* URLInfoAbout value exists */
4563     sz = MAX_PATH;
4564     lstrcpyA(buf, "apple");
4565     r = pMsiGetProductInfoExA(prodcode, usersid,
4566                               MSIINSTALLCONTEXT_USERUNMANAGED,
4567                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4568     ok(r == ERROR_UNKNOWN_PROPERTY,
4569        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4570     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4571     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4572
4573     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4575
4576     /* URLUpdateInfo value exists */
4577     sz = MAX_PATH;
4578     lstrcpyA(buf, "apple");
4579     r = pMsiGetProductInfoExA(prodcode, usersid,
4580                               MSIINSTALLCONTEXT_USERUNMANAGED,
4581                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4582     ok(r == ERROR_UNKNOWN_PROPERTY,
4583        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4584     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4585     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4586
4587     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4589
4590     /* VersionMinor value exists */
4591     sz = MAX_PATH;
4592     lstrcpyA(buf, "apple");
4593     r = pMsiGetProductInfoExA(prodcode, usersid,
4594                               MSIINSTALLCONTEXT_USERUNMANAGED,
4595                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4596     ok(r == ERROR_UNKNOWN_PROPERTY,
4597        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4598     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4599     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4600
4601     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4603
4604     /* VersionMajor value exists */
4605     sz = MAX_PATH;
4606     lstrcpyA(buf, "apple");
4607     r = pMsiGetProductInfoExA(prodcode, usersid,
4608                               MSIINSTALLCONTEXT_USERUNMANAGED,
4609                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4610     ok(r == ERROR_UNKNOWN_PROPERTY,
4611        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4612     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4613     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4614
4615     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4616     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4617
4618     /* DisplayVersion value exists */
4619     sz = MAX_PATH;
4620     lstrcpyA(buf, "apple");
4621     r = pMsiGetProductInfoExA(prodcode, usersid,
4622                               MSIINSTALLCONTEXT_USERUNMANAGED,
4623                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4624     ok(r == ERROR_UNKNOWN_PROPERTY,
4625        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4626     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4627     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4628
4629     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4631
4632     /* ProductID value exists */
4633     sz = MAX_PATH;
4634     lstrcpyA(buf, "apple");
4635     r = pMsiGetProductInfoExA(prodcode, usersid,
4636                               MSIINSTALLCONTEXT_USERUNMANAGED,
4637                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4638     ok(r == ERROR_UNKNOWN_PROPERTY,
4639        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4640     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4641     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4642
4643     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4645
4646     /* RegCompany value exists */
4647     sz = MAX_PATH;
4648     lstrcpyA(buf, "apple");
4649     r = pMsiGetProductInfoExA(prodcode, usersid,
4650                               MSIINSTALLCONTEXT_USERUNMANAGED,
4651                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4652     ok(r == ERROR_UNKNOWN_PROPERTY,
4653        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4654     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4655     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4656
4657     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4659
4660     /* RegOwner value exists */
4661     sz = MAX_PATH;
4662     lstrcpyA(buf, "apple");
4663     r = pMsiGetProductInfoExA(prodcode, usersid,
4664                               MSIINSTALLCONTEXT_USERUNMANAGED,
4665                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4666     ok(r == ERROR_UNKNOWN_PROPERTY,
4667        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4668     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4669     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4670
4671     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4673
4674     /* Transforms value exists */
4675     sz = MAX_PATH;
4676     lstrcpyA(buf, "apple");
4677     r = pMsiGetProductInfoExA(prodcode, usersid,
4678                               MSIINSTALLCONTEXT_USERUNMANAGED,
4679                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4680     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4681     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4682     ok(sz == 5, "Expected 5, got %d\n", sz);
4683
4684     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4686
4687     /* Language value exists */
4688     sz = MAX_PATH;
4689     lstrcpyA(buf, "apple");
4690     r = pMsiGetProductInfoExA(prodcode, usersid,
4691                               MSIINSTALLCONTEXT_USERUNMANAGED,
4692                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4693     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4694     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4695     ok(sz == 4, "Expected 4, got %d\n", sz);
4696
4697     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4699
4700     /* ProductName value exists */
4701     sz = MAX_PATH;
4702     lstrcpyA(buf, "apple");
4703     r = pMsiGetProductInfoExA(prodcode, usersid,
4704                               MSIINSTALLCONTEXT_USERUNMANAGED,
4705                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4706     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4707     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4708     ok(sz == 4, "Expected 4, got %d\n", sz);
4709
4710     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4711     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4712
4713     /* FIXME */
4714
4715     /* AssignmentType value exists */
4716     sz = MAX_PATH;
4717     lstrcpyA(buf, "apple");
4718     r = pMsiGetProductInfoExA(prodcode, usersid,
4719                               MSIINSTALLCONTEXT_USERUNMANAGED,
4720                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4721     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4722     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4723     ok(sz == 0, "Expected 0, got %d\n", sz);
4724
4725     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4727
4728     /* FIXME */
4729
4730     /* PackageCode value exists */
4731     sz = MAX_PATH;
4732     lstrcpyA(buf, "apple");
4733     r = pMsiGetProductInfoExA(prodcode, usersid,
4734                               MSIINSTALLCONTEXT_USERUNMANAGED,
4735                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4736     todo_wine
4737     {
4738         ok(r == ERROR_BAD_CONFIGURATION,
4739            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4740         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4741         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4742     }
4743
4744     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4746
4747     /* Version value exists */
4748     sz = MAX_PATH;
4749     lstrcpyA(buf, "apple");
4750     r = pMsiGetProductInfoExA(prodcode, usersid,
4751                               MSIINSTALLCONTEXT_USERUNMANAGED,
4752                               INSTALLPROPERTY_VERSION, buf, &sz);
4753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4754     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4755     ok(sz == 3, "Expected 3, got %d\n", sz);
4756
4757     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4759
4760     /* ProductIcon value exists */
4761     sz = MAX_PATH;
4762     lstrcpyA(buf, "apple");
4763     r = pMsiGetProductInfoExA(prodcode, usersid,
4764                               MSIINSTALLCONTEXT_USERUNMANAGED,
4765                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4766     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4767     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4768     ok(sz == 4, "Expected 4, got %d\n", sz);
4769
4770     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4772
4773     /* PackageName value exists */
4774     sz = MAX_PATH;
4775     lstrcpyA(buf, "apple");
4776     r = pMsiGetProductInfoExA(prodcode, usersid,
4777                               MSIINSTALLCONTEXT_USERUNMANAGED,
4778                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4779     todo_wine
4780     {
4781         ok(r == ERROR_UNKNOWN_PRODUCT,
4782            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4783         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4784         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4785     }
4786
4787     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4789
4790     /* AuthorizedLUAApp value exists */
4791     sz = MAX_PATH;
4792     lstrcpyA(buf, "apple");
4793     r = pMsiGetProductInfoExA(prodcode, usersid,
4794                               MSIINSTALLCONTEXT_USERUNMANAGED,
4795                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4796     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4797     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4798     ok(sz == 4, "Expected 4, got %d\n", sz);
4799
4800     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4801     RegDeleteValueA(prodkey, "PackageName");
4802     RegDeleteValueA(prodkey, "ProductIcon");
4803     RegDeleteValueA(prodkey, "Version");
4804     RegDeleteValueA(prodkey, "PackageCode");
4805     RegDeleteValueA(prodkey, "AssignmentType");
4806     RegDeleteValueA(prodkey, "ProductName");
4807     RegDeleteValueA(prodkey, "Language");
4808     RegDeleteValueA(prodkey, "Transforms");
4809     RegDeleteValueA(prodkey, "RegOwner");
4810     RegDeleteValueA(prodkey, "RegCompany");
4811     RegDeleteValueA(prodkey, "ProductID");
4812     RegDeleteValueA(prodkey, "DisplayVersion");
4813     RegDeleteValueA(prodkey, "VersionMajor");
4814     RegDeleteValueA(prodkey, "VersionMinor");
4815     RegDeleteValueA(prodkey, "URLUpdateInfo");
4816     RegDeleteValueA(prodkey, "URLInfoAbout");
4817     RegDeleteValueA(prodkey, "Publisher");
4818     RegDeleteValueA(prodkey, "LocalPackage");
4819     RegDeleteValueA(prodkey, "InstallSource");
4820     RegDeleteValueA(prodkey, "InstallLocation");
4821     RegDeleteValueA(prodkey, "DisplayName");
4822     RegDeleteValueA(prodkey, "InstallDate");
4823     RegDeleteValueA(prodkey, "HelpTelephone");
4824     RegDeleteValueA(prodkey, "HelpLink");
4825     RegDeleteValueA(prodkey, "LocalPackage");
4826     RegDeleteKeyA(prodkey, "");
4827     RegCloseKey(prodkey);
4828
4829     /* MSIINSTALLCONTEXT_USERMANAGED */
4830
4831     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4832     lstrcatA(keypath, usersid);
4833     lstrcatA(keypath, "\\Products\\");
4834     lstrcatA(keypath, prod_squashed);
4835
4836     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4837     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4838
4839     /* local user product key exists */
4840     sz = MAX_PATH;
4841     lstrcpyA(buf, "apple");
4842     r = pMsiGetProductInfoExA(prodcode, usersid,
4843                               MSIINSTALLCONTEXT_USERMANAGED,
4844                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4845     ok(r == ERROR_UNKNOWN_PRODUCT,
4846        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4847     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4848     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4849
4850     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4852
4853     /* InstallProperties key exists */
4854     sz = MAX_PATH;
4855     lstrcpyA(buf, "apple");
4856     r = pMsiGetProductInfoExA(prodcode, usersid,
4857                               MSIINSTALLCONTEXT_USERMANAGED,
4858                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4859     ok(r == ERROR_UNKNOWN_PRODUCT,
4860        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4861     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4862     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4863
4864     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4865     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4866
4867     /* ManagedLocalPackage value exists */
4868     sz = MAX_PATH;
4869     lstrcpyA(buf, "apple");
4870     r = pMsiGetProductInfoExA(prodcode, usersid,
4871                               MSIINSTALLCONTEXT_USERMANAGED,
4872                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4873     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4874     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4875     ok(sz == 1, "Expected 1, got %d\n", sz);
4876
4877     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4878     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4879
4880     /* HelpLink value exists */
4881     sz = MAX_PATH;
4882     lstrcpyA(buf, "apple");
4883     r = pMsiGetProductInfoExA(prodcode, usersid,
4884                               MSIINSTALLCONTEXT_USERMANAGED,
4885                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4886     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4887     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4888     ok(sz == 4, "Expected 4, got %d\n", sz);
4889
4890     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4892
4893     /* HelpTelephone value exists */
4894     sz = MAX_PATH;
4895     lstrcpyA(buf, "apple");
4896     r = pMsiGetProductInfoExA(prodcode, usersid,
4897                               MSIINSTALLCONTEXT_USERMANAGED,
4898                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4899     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4900     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4901     ok(sz == 5, "Expected 5, got %d\n", sz);
4902
4903     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4905
4906     /* InstallDate value exists */
4907     sz = MAX_PATH;
4908     lstrcpyA(buf, "apple");
4909     r = pMsiGetProductInfoExA(prodcode, usersid,
4910                               MSIINSTALLCONTEXT_USERMANAGED,
4911                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4912     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4913     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4914     ok(sz == 4, "Expected 4, got %d\n", sz);
4915
4916     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4918
4919     /* DisplayName value exists */
4920     sz = MAX_PATH;
4921     lstrcpyA(buf, "apple");
4922     r = pMsiGetProductInfoExA(prodcode, usersid,
4923                               MSIINSTALLCONTEXT_USERMANAGED,
4924                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4926     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4927     ok(sz == 4, "Expected 4, got %d\n", sz);
4928
4929     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4931
4932     /* InstallLocation value exists */
4933     sz = MAX_PATH;
4934     lstrcpyA(buf, "apple");
4935     r = pMsiGetProductInfoExA(prodcode, usersid,
4936                               MSIINSTALLCONTEXT_USERMANAGED,
4937                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4939     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4940     ok(sz == 3, "Expected 3, got %d\n", sz);
4941
4942     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4944
4945     /* InstallSource value exists */
4946     sz = MAX_PATH;
4947     lstrcpyA(buf, "apple");
4948     r = pMsiGetProductInfoExA(prodcode, usersid,
4949                               MSIINSTALLCONTEXT_USERMANAGED,
4950                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4952     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4953     ok(sz == 6, "Expected 6, got %d\n", sz);
4954
4955     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4957
4958     /* LocalPackage value exists */
4959     sz = MAX_PATH;
4960     lstrcpyA(buf, "apple");
4961     r = pMsiGetProductInfoExA(prodcode, usersid,
4962                               MSIINSTALLCONTEXT_USERMANAGED,
4963                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4965     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4966     ok(sz == 5, "Expected 5, got %d\n", sz);
4967
4968     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4970
4971     /* Publisher value exists */
4972     sz = MAX_PATH;
4973     lstrcpyA(buf, "apple");
4974     r = pMsiGetProductInfoExA(prodcode, usersid,
4975                               MSIINSTALLCONTEXT_USERMANAGED,
4976                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4978     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4979     ok(sz == 3, "Expected 3, got %d\n", sz);
4980
4981     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4983
4984     /* URLInfoAbout value exists */
4985     sz = MAX_PATH;
4986     lstrcpyA(buf, "apple");
4987     r = pMsiGetProductInfoExA(prodcode, usersid,
4988                               MSIINSTALLCONTEXT_USERMANAGED,
4989                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4991     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4992     ok(sz == 5, "Expected 5, got %d\n", sz);
4993
4994     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4996
4997     /* URLUpdateInfo value exists */
4998     sz = MAX_PATH;
4999     lstrcpyA(buf, "apple");
5000     r = pMsiGetProductInfoExA(prodcode, usersid,
5001                               MSIINSTALLCONTEXT_USERMANAGED,
5002                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5004     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5005     ok(sz == 6, "Expected 6, got %d\n", sz);
5006
5007     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5009
5010     /* VersionMinor value exists */
5011     sz = MAX_PATH;
5012     lstrcpyA(buf, "apple");
5013     r = pMsiGetProductInfoExA(prodcode, usersid,
5014                               MSIINSTALLCONTEXT_USERMANAGED,
5015                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5017     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5018     ok(sz == 1, "Expected 1, got %d\n", sz);
5019
5020     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5021     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5022
5023     /* VersionMajor value exists */
5024     sz = MAX_PATH;
5025     lstrcpyA(buf, "apple");
5026     r = pMsiGetProductInfoExA(prodcode, usersid,
5027                               MSIINSTALLCONTEXT_USERMANAGED,
5028                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5030     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5031     ok(sz == 1, "Expected 1, got %d\n", sz);
5032
5033     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5035
5036     /* DisplayVersion value exists */
5037     sz = MAX_PATH;
5038     lstrcpyA(buf, "apple");
5039     r = pMsiGetProductInfoExA(prodcode, usersid,
5040                               MSIINSTALLCONTEXT_USERMANAGED,
5041                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5043     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5044     ok(sz == 5, "Expected 5, got %d\n", sz);
5045
5046     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5048
5049     /* ProductID value exists */
5050     sz = MAX_PATH;
5051     lstrcpyA(buf, "apple");
5052     r = pMsiGetProductInfoExA(prodcode, usersid,
5053                               MSIINSTALLCONTEXT_USERMANAGED,
5054                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5055     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5056     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5057     ok(sz == 2, "Expected 2, got %d\n", sz);
5058
5059     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5061
5062     /* RegCompany value exists */
5063     sz = MAX_PATH;
5064     lstrcpyA(buf, "apple");
5065     r = pMsiGetProductInfoExA(prodcode, usersid,
5066                               MSIINSTALLCONTEXT_USERMANAGED,
5067                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5068     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5069     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5070     ok(sz == 4, "Expected 4, got %d\n", sz);
5071
5072     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5074
5075     /* RegOwner value exists */
5076     sz = MAX_PATH;
5077     lstrcpyA(buf, "apple");
5078     r = pMsiGetProductInfoExA(prodcode, usersid,
5079                               MSIINSTALLCONTEXT_USERMANAGED,
5080                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5081     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5082     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5083     ok(sz == 5, "Expected 5, got %d\n", sz);
5084
5085     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5087
5088     /* Transforms value exists */
5089     sz = MAX_PATH;
5090     lstrcpyA(buf, "apple");
5091     r = pMsiGetProductInfoExA(prodcode, usersid,
5092                               MSIINSTALLCONTEXT_USERMANAGED,
5093                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5094     ok(r == ERROR_UNKNOWN_PRODUCT,
5095        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5096     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5097     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5098
5099     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5101
5102     /* Language value exists */
5103     sz = MAX_PATH;
5104     lstrcpyA(buf, "apple");
5105     r = pMsiGetProductInfoExA(prodcode, usersid,
5106                               MSIINSTALLCONTEXT_USERMANAGED,
5107                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5108     ok(r == ERROR_UNKNOWN_PRODUCT,
5109        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5110     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5111     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5112
5113     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5114     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5115
5116     /* ProductName value exists */
5117     sz = MAX_PATH;
5118     lstrcpyA(buf, "apple");
5119     r = pMsiGetProductInfoExA(prodcode, usersid,
5120                               MSIINSTALLCONTEXT_USERMANAGED,
5121                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5122     ok(r == ERROR_UNKNOWN_PRODUCT,
5123        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5124     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5125     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5126
5127     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5129
5130     /* FIXME */
5131
5132     /* AssignmentType value exists */
5133     sz = MAX_PATH;
5134     lstrcpyA(buf, "apple");
5135     r = pMsiGetProductInfoExA(prodcode, usersid,
5136                               MSIINSTALLCONTEXT_USERMANAGED,
5137                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5138     ok(r == ERROR_UNKNOWN_PRODUCT,
5139        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5140     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5141     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5142
5143     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5145
5146     /* PackageCode value exists */
5147     sz = MAX_PATH;
5148     lstrcpyA(buf, "apple");
5149     r = pMsiGetProductInfoExA(prodcode, usersid,
5150                               MSIINSTALLCONTEXT_USERMANAGED,
5151                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5152     ok(r == ERROR_UNKNOWN_PRODUCT,
5153        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5154     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5155     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5156
5157     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5159
5160     /* Version value exists */
5161     sz = MAX_PATH;
5162     lstrcpyA(buf, "apple");
5163     r = pMsiGetProductInfoExA(prodcode, usersid,
5164                               MSIINSTALLCONTEXT_USERMANAGED,
5165                               INSTALLPROPERTY_VERSION, buf, &sz);
5166     ok(r == ERROR_UNKNOWN_PRODUCT,
5167        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5168     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5169     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5170
5171     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5173
5174     /* ProductIcon value exists */
5175     sz = MAX_PATH;
5176     lstrcpyA(buf, "apple");
5177     r = pMsiGetProductInfoExA(prodcode, usersid,
5178                               MSIINSTALLCONTEXT_USERMANAGED,
5179                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5180     ok(r == ERROR_UNKNOWN_PRODUCT,
5181        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5182     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5183     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5184
5185     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5187
5188     /* PackageName value exists */
5189     sz = MAX_PATH;
5190     lstrcpyA(buf, "apple");
5191     r = pMsiGetProductInfoExA(prodcode, usersid,
5192                               MSIINSTALLCONTEXT_USERMANAGED,
5193                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5194     ok(r == ERROR_UNKNOWN_PRODUCT,
5195        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5196     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5197     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5198
5199     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5200     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5201
5202     /* AuthorizedLUAApp value exists */
5203     sz = MAX_PATH;
5204     lstrcpyA(buf, "apple");
5205     r = pMsiGetProductInfoExA(prodcode, usersid,
5206                               MSIINSTALLCONTEXT_USERMANAGED,
5207                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5208     ok(r == ERROR_UNKNOWN_PRODUCT,
5209        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5210     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5211     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5212
5213     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5214     RegDeleteValueA(propkey, "PackageName");
5215     RegDeleteValueA(propkey, "ProductIcon");
5216     RegDeleteValueA(propkey, "Version");
5217     RegDeleteValueA(propkey, "PackageCode");
5218     RegDeleteValueA(propkey, "AssignmentType");
5219     RegDeleteValueA(propkey, "ProductName");
5220     RegDeleteValueA(propkey, "Language");
5221     RegDeleteValueA(propkey, "Transforms");
5222     RegDeleteValueA(propkey, "RegOwner");
5223     RegDeleteValueA(propkey, "RegCompany");
5224     RegDeleteValueA(propkey, "ProductID");
5225     RegDeleteValueA(propkey, "DisplayVersion");
5226     RegDeleteValueA(propkey, "VersionMajor");
5227     RegDeleteValueA(propkey, "VersionMinor");
5228     RegDeleteValueA(propkey, "URLUpdateInfo");
5229     RegDeleteValueA(propkey, "URLInfoAbout");
5230     RegDeleteValueA(propkey, "Publisher");
5231     RegDeleteValueA(propkey, "LocalPackage");
5232     RegDeleteValueA(propkey, "InstallSource");
5233     RegDeleteValueA(propkey, "InstallLocation");
5234     RegDeleteValueA(propkey, "DisplayName");
5235     RegDeleteValueA(propkey, "InstallDate");
5236     RegDeleteValueA(propkey, "HelpTelephone");
5237     RegDeleteValueA(propkey, "HelpLink");
5238     RegDeleteValueA(propkey, "ManagedLocalPackage");
5239     RegDeleteKeyA(propkey, "");
5240     RegCloseKey(propkey);
5241     RegDeleteKeyA(localkey, "");
5242     RegCloseKey(localkey);
5243
5244     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5245     lstrcatA(keypath, usersid);
5246     lstrcatA(keypath, "\\Installer\\Products\\");
5247     lstrcatA(keypath, prod_squashed);
5248
5249     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5251
5252     /* user product key exists */
5253     sz = MAX_PATH;
5254     lstrcpyA(buf, "apple");
5255     r = pMsiGetProductInfoExA(prodcode, usersid,
5256                               MSIINSTALLCONTEXT_USERMANAGED,
5257                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5259     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5260     ok(sz == 1, "Expected 1, got %d\n", sz);
5261
5262     RegDeleteKeyA(userkey, "");
5263     RegCloseKey(userkey);
5264
5265     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5266     lstrcatA(keypath, prod_squashed);
5267
5268     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5270
5271     /* current user product key exists */
5272     sz = MAX_PATH;
5273     lstrcpyA(buf, "apple");
5274     r = pMsiGetProductInfoExA(prodcode, usersid,
5275                               MSIINSTALLCONTEXT_USERMANAGED,
5276                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5277     ok(r == ERROR_UNKNOWN_PRODUCT,
5278        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5279     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5280     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5281
5282     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5283     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5284
5285     /* HelpLink value exists, user product key does not exist */
5286     sz = MAX_PATH;
5287     lstrcpyA(buf, "apple");
5288     r = pMsiGetProductInfoExA(prodcode, usersid,
5289                               MSIINSTALLCONTEXT_USERMANAGED,
5290                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5291     ok(r == ERROR_UNKNOWN_PRODUCT,
5292        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5293     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5294     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5295
5296     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5297     lstrcatA(keypath, usersid);
5298     lstrcatA(keypath, "\\Installer\\Products\\");
5299     lstrcatA(keypath, prod_squashed);
5300
5301     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5303
5304     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5306
5307     /* HelpLink value exists, user product key does exist */
5308     sz = MAX_PATH;
5309     lstrcpyA(buf, "apple");
5310     r = pMsiGetProductInfoExA(prodcode, usersid,
5311                               MSIINSTALLCONTEXT_USERMANAGED,
5312                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5313     ok(r == ERROR_UNKNOWN_PROPERTY,
5314        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5315     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5316     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5317
5318     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5320
5321     /* HelpTelephone value exists */
5322     sz = MAX_PATH;
5323     lstrcpyA(buf, "apple");
5324     r = pMsiGetProductInfoExA(prodcode, usersid,
5325                               MSIINSTALLCONTEXT_USERMANAGED,
5326                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5327     ok(r == ERROR_UNKNOWN_PROPERTY,
5328        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5329     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5330     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5331
5332     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5333     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5334
5335     /* InstallDate value exists */
5336     sz = MAX_PATH;
5337     lstrcpyA(buf, "apple");
5338     r = pMsiGetProductInfoExA(prodcode, usersid,
5339                               MSIINSTALLCONTEXT_USERMANAGED,
5340                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5341     ok(r == ERROR_UNKNOWN_PROPERTY,
5342        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5343     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5344     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5345
5346     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5348
5349     /* DisplayName value exists */
5350     sz = MAX_PATH;
5351     lstrcpyA(buf, "apple");
5352     r = pMsiGetProductInfoExA(prodcode, usersid,
5353                               MSIINSTALLCONTEXT_USERMANAGED,
5354                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5355     ok(r == ERROR_UNKNOWN_PROPERTY,
5356        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5357     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5358     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5359
5360     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5362
5363     /* InstallLocation value exists */
5364     sz = MAX_PATH;
5365     lstrcpyA(buf, "apple");
5366     r = pMsiGetProductInfoExA(prodcode, usersid,
5367                               MSIINSTALLCONTEXT_USERMANAGED,
5368                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5369     ok(r == ERROR_UNKNOWN_PROPERTY,
5370        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5371     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5372     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5373
5374     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5376
5377     /* InstallSource value exists */
5378     sz = MAX_PATH;
5379     lstrcpyA(buf, "apple");
5380     r = pMsiGetProductInfoExA(prodcode, usersid,
5381                               MSIINSTALLCONTEXT_USERMANAGED,
5382                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5383     ok(r == ERROR_UNKNOWN_PROPERTY,
5384        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5385     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5386     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5387
5388     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5390
5391     /* LocalPackage value exists */
5392     sz = MAX_PATH;
5393     lstrcpyA(buf, "apple");
5394     r = pMsiGetProductInfoExA(prodcode, usersid,
5395                               MSIINSTALLCONTEXT_USERMANAGED,
5396                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5397     ok(r == ERROR_UNKNOWN_PROPERTY,
5398        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5399     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5400     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5401
5402     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5404
5405     /* Publisher value exists */
5406     sz = MAX_PATH;
5407     lstrcpyA(buf, "apple");
5408     r = pMsiGetProductInfoExA(prodcode, usersid,
5409                               MSIINSTALLCONTEXT_USERMANAGED,
5410                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5411     ok(r == ERROR_UNKNOWN_PROPERTY,
5412        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5413     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5414     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5415
5416     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5418
5419     /* URLInfoAbout value exists */
5420     sz = MAX_PATH;
5421     lstrcpyA(buf, "apple");
5422     r = pMsiGetProductInfoExA(prodcode, usersid,
5423                               MSIINSTALLCONTEXT_USERMANAGED,
5424                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5425     ok(r == ERROR_UNKNOWN_PROPERTY,
5426        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5427     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5428     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5429
5430     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5432
5433     /* URLUpdateInfo value exists */
5434     sz = MAX_PATH;
5435     lstrcpyA(buf, "apple");
5436     r = pMsiGetProductInfoExA(prodcode, usersid,
5437                               MSIINSTALLCONTEXT_USERMANAGED,
5438                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5439     ok(r == ERROR_UNKNOWN_PROPERTY,
5440        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5441     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5442     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5443
5444     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5446
5447     /* VersionMinor value exists */
5448     sz = MAX_PATH;
5449     lstrcpyA(buf, "apple");
5450     r = pMsiGetProductInfoExA(prodcode, usersid,
5451                               MSIINSTALLCONTEXT_USERMANAGED,
5452                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5453     ok(r == ERROR_UNKNOWN_PROPERTY,
5454        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5455     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5456     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5457
5458     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5460
5461     /* VersionMajor value exists */
5462     sz = MAX_PATH;
5463     lstrcpyA(buf, "apple");
5464     r = pMsiGetProductInfoExA(prodcode, usersid,
5465                               MSIINSTALLCONTEXT_USERMANAGED,
5466                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5467     ok(r == ERROR_UNKNOWN_PROPERTY,
5468        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5469     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5470     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5471
5472     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5474
5475     /* DisplayVersion value exists */
5476     sz = MAX_PATH;
5477     lstrcpyA(buf, "apple");
5478     r = pMsiGetProductInfoExA(prodcode, usersid,
5479                               MSIINSTALLCONTEXT_USERMANAGED,
5480                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5481     ok(r == ERROR_UNKNOWN_PROPERTY,
5482        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5483     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5484     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5485
5486     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5488
5489     /* ProductID value exists */
5490     sz = MAX_PATH;
5491     lstrcpyA(buf, "apple");
5492     r = pMsiGetProductInfoExA(prodcode, usersid,
5493                               MSIINSTALLCONTEXT_USERMANAGED,
5494                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5495     ok(r == ERROR_UNKNOWN_PROPERTY,
5496        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5497     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5498     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5499
5500     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5501     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5502
5503     /* RegCompany value exists */
5504     sz = MAX_PATH;
5505     lstrcpyA(buf, "apple");
5506     r = pMsiGetProductInfoExA(prodcode, usersid,
5507                               MSIINSTALLCONTEXT_USERMANAGED,
5508                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5509     ok(r == ERROR_UNKNOWN_PROPERTY,
5510        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5511     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5512     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5513
5514     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5516
5517     /* RegOwner value exists */
5518     sz = MAX_PATH;
5519     lstrcpyA(buf, "apple");
5520     r = pMsiGetProductInfoExA(prodcode, usersid,
5521                               MSIINSTALLCONTEXT_USERMANAGED,
5522                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5523     ok(r == ERROR_UNKNOWN_PROPERTY,
5524        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5525     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5526     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5527
5528     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5530
5531     /* Transforms value exists */
5532     sz = MAX_PATH;
5533     lstrcpyA(buf, "apple");
5534     r = pMsiGetProductInfoExA(prodcode, usersid,
5535                               MSIINSTALLCONTEXT_USERMANAGED,
5536                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5537     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5538     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5539     ok(sz == 5, "Expected 5, got %d\n", sz);
5540
5541     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5543
5544     /* Language value exists */
5545     sz = MAX_PATH;
5546     lstrcpyA(buf, "apple");
5547     r = pMsiGetProductInfoExA(prodcode, usersid,
5548                               MSIINSTALLCONTEXT_USERMANAGED,
5549                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5551     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5552     ok(sz == 4, "Expected 4, got %d\n", sz);
5553
5554     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5556
5557     /* ProductName value exists */
5558     sz = MAX_PATH;
5559     lstrcpyA(buf, "apple");
5560     r = pMsiGetProductInfoExA(prodcode, usersid,
5561                               MSIINSTALLCONTEXT_USERMANAGED,
5562                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5564     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5565     ok(sz == 4, "Expected 4, got %d\n", sz);
5566
5567     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5569
5570     /* FIXME */
5571
5572     /* AssignmentType value exists */
5573     sz = MAX_PATH;
5574     lstrcpyA(buf, "apple");
5575     r = pMsiGetProductInfoExA(prodcode, usersid,
5576                               MSIINSTALLCONTEXT_USERMANAGED,
5577                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5579     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5580     ok(sz == 0, "Expected 0, got %d\n", sz);
5581
5582     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5583     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5584
5585     /* FIXME */
5586
5587     /* PackageCode value exists */
5588     sz = MAX_PATH;
5589     lstrcpyA(buf, "apple");
5590     r = pMsiGetProductInfoExA(prodcode, usersid,
5591                               MSIINSTALLCONTEXT_USERMANAGED,
5592                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5593     todo_wine
5594     {
5595         ok(r == ERROR_BAD_CONFIGURATION,
5596            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5597         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5598         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5599     }
5600
5601     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5603
5604     /* Version value exists */
5605     sz = MAX_PATH;
5606     lstrcpyA(buf, "apple");
5607     r = pMsiGetProductInfoExA(prodcode, usersid,
5608                               MSIINSTALLCONTEXT_USERMANAGED,
5609                               INSTALLPROPERTY_VERSION, buf, &sz);
5610     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5611     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5612     ok(sz == 3, "Expected 3, got %d\n", sz);
5613
5614     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5616
5617     /* ProductIcon value exists */
5618     sz = MAX_PATH;
5619     lstrcpyA(buf, "apple");
5620     r = pMsiGetProductInfoExA(prodcode, usersid,
5621                               MSIINSTALLCONTEXT_USERMANAGED,
5622                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5623     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5624     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5625     ok(sz == 4, "Expected 4, got %d\n", sz);
5626
5627     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5629
5630     /* PackageName value exists */
5631     sz = MAX_PATH;
5632     lstrcpyA(buf, "apple");
5633     r = pMsiGetProductInfoExA(prodcode, usersid,
5634                               MSIINSTALLCONTEXT_USERMANAGED,
5635                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5636     todo_wine
5637     {
5638         ok(r == ERROR_UNKNOWN_PRODUCT,
5639            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5640         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5641         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5642     }
5643
5644     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5646
5647     /* AuthorizedLUAApp value exists */
5648     sz = MAX_PATH;
5649     lstrcpyA(buf, "apple");
5650     r = pMsiGetProductInfoExA(prodcode, usersid,
5651                               MSIINSTALLCONTEXT_USERMANAGED,
5652                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5653     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5654     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5655     ok(sz == 4, "Expected 4, got %d\n", sz);
5656
5657     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5658     RegDeleteValueA(userkey, "PackageName");
5659     RegDeleteValueA(userkey, "ProductIcon");
5660     RegDeleteValueA(userkey, "Version");
5661     RegDeleteValueA(userkey, "PackageCode");
5662     RegDeleteValueA(userkey, "AssignmentType");
5663     RegDeleteValueA(userkey, "ProductName");
5664     RegDeleteValueA(userkey, "Language");
5665     RegDeleteValueA(userkey, "Transforms");
5666     RegDeleteValueA(userkey, "RegOwner");
5667     RegDeleteValueA(userkey, "RegCompany");
5668     RegDeleteValueA(userkey, "ProductID");
5669     RegDeleteValueA(userkey, "DisplayVersion");
5670     RegDeleteValueA(userkey, "VersionMajor");
5671     RegDeleteValueA(userkey, "VersionMinor");
5672     RegDeleteValueA(userkey, "URLUpdateInfo");
5673     RegDeleteValueA(userkey, "URLInfoAbout");
5674     RegDeleteValueA(userkey, "Publisher");
5675     RegDeleteValueA(userkey, "LocalPackage");
5676     RegDeleteValueA(userkey, "InstallSource");
5677     RegDeleteValueA(userkey, "InstallLocation");
5678     RegDeleteValueA(userkey, "DisplayName");
5679     RegDeleteValueA(userkey, "InstallDate");
5680     RegDeleteValueA(userkey, "HelpTelephone");
5681     RegDeleteValueA(userkey, "HelpLink");
5682     RegDeleteKeyA(userkey, "");
5683     RegCloseKey(userkey);
5684     RegDeleteKeyA(prodkey, "");
5685     RegCloseKey(prodkey);
5686
5687     /* MSIINSTALLCONTEXT_MACHINE */
5688
5689     /* szUserSid is non-NULL */
5690     sz = MAX_PATH;
5691     lstrcpyA(buf, "apple");
5692     r = pMsiGetProductInfoExA(prodcode, usersid,
5693                               MSIINSTALLCONTEXT_MACHINE,
5694                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5695     ok(r == ERROR_INVALID_PARAMETER,
5696        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5697     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5698     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5699
5700     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5701     lstrcatA(keypath, prod_squashed);
5702
5703     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5704     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5705
5706     /* local system product key exists */
5707     sz = MAX_PATH;
5708     lstrcpyA(buf, "apple");
5709     r = pMsiGetProductInfoExA(prodcode, NULL,
5710                               MSIINSTALLCONTEXT_MACHINE,
5711                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5712     ok(r == ERROR_UNKNOWN_PRODUCT,
5713        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5714     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5715     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5716
5717     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5719
5720     /* InstallProperties key exists */
5721     sz = MAX_PATH;
5722     lstrcpyA(buf, "apple");
5723     r = pMsiGetProductInfoExA(prodcode, NULL,
5724                               MSIINSTALLCONTEXT_MACHINE,
5725                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5726     ok(r == ERROR_UNKNOWN_PRODUCT,
5727        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5728     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5729     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5730
5731     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5732     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5733
5734     /* LocalPackage value exists */
5735     sz = MAX_PATH;
5736     lstrcpyA(buf, "apple");
5737     r = pMsiGetProductInfoExA(prodcode, NULL,
5738                               MSIINSTALLCONTEXT_MACHINE,
5739                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5741     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5742     ok(sz == 1, "Expected 1, got %d\n", sz);
5743
5744     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5746
5747     /* HelpLink value exists */
5748     sz = MAX_PATH;
5749     lstrcpyA(buf, "apple");
5750     r = pMsiGetProductInfoExA(prodcode, NULL,
5751                               MSIINSTALLCONTEXT_MACHINE,
5752                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5754     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5755     ok(sz == 4, "Expected 4, got %d\n", sz);
5756
5757     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5759
5760     /* HelpTelephone value exists */
5761     sz = MAX_PATH;
5762     lstrcpyA(buf, "apple");
5763     r = pMsiGetProductInfoExA(prodcode, NULL,
5764                               MSIINSTALLCONTEXT_MACHINE,
5765                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5766     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5767     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5768     ok(sz == 5, "Expected 5, got %d\n", sz);
5769
5770     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5772
5773     /* InstallDate value exists */
5774     sz = MAX_PATH;
5775     lstrcpyA(buf, "apple");
5776     r = pMsiGetProductInfoExA(prodcode, NULL,
5777                               MSIINSTALLCONTEXT_MACHINE,
5778                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5779     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5780     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5781     ok(sz == 4, "Expected 4, got %d\n", sz);
5782
5783     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5785
5786     /* DisplayName value exists */
5787     sz = MAX_PATH;
5788     lstrcpyA(buf, "apple");
5789     r = pMsiGetProductInfoExA(prodcode, NULL,
5790                               MSIINSTALLCONTEXT_MACHINE,
5791                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5793     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5794     ok(sz == 4, "Expected 4, got %d\n", sz);
5795
5796     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5798
5799     /* InstallLocation value exists */
5800     sz = MAX_PATH;
5801     lstrcpyA(buf, "apple");
5802     r = pMsiGetProductInfoExA(prodcode, NULL,
5803                               MSIINSTALLCONTEXT_MACHINE,
5804                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5806     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5807     ok(sz == 3, "Expected 3, got %d\n", sz);
5808
5809     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5811
5812     /* InstallSource value exists */
5813     sz = MAX_PATH;
5814     lstrcpyA(buf, "apple");
5815     r = pMsiGetProductInfoExA(prodcode, NULL,
5816                               MSIINSTALLCONTEXT_MACHINE,
5817                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5818     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5819     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5820     ok(sz == 6, "Expected 6, got %d\n", sz);
5821
5822     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5823     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5824
5825     /* LocalPackage value exists */
5826     sz = MAX_PATH;
5827     lstrcpyA(buf, "apple");
5828     r = pMsiGetProductInfoExA(prodcode, NULL,
5829                               MSIINSTALLCONTEXT_MACHINE,
5830                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5832     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5833     ok(sz == 5, "Expected 5, got %d\n", sz);
5834
5835     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5837
5838     /* Publisher value exists */
5839     sz = MAX_PATH;
5840     lstrcpyA(buf, "apple");
5841     r = pMsiGetProductInfoExA(prodcode, NULL,
5842                               MSIINSTALLCONTEXT_MACHINE,
5843                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5845     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5846     ok(sz == 3, "Expected 3, got %d\n", sz);
5847
5848     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5850
5851     /* URLInfoAbout value exists */
5852     sz = MAX_PATH;
5853     lstrcpyA(buf, "apple");
5854     r = pMsiGetProductInfoExA(prodcode, NULL,
5855                               MSIINSTALLCONTEXT_MACHINE,
5856                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5858     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5859     ok(sz == 5, "Expected 5, got %d\n", sz);
5860
5861     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5863
5864     /* URLUpdateInfo value exists */
5865     sz = MAX_PATH;
5866     lstrcpyA(buf, "apple");
5867     r = pMsiGetProductInfoExA(prodcode, NULL,
5868                               MSIINSTALLCONTEXT_MACHINE,
5869                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5871     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5872     ok(sz == 6, "Expected 6, got %d\n", sz);
5873
5874     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5876
5877     /* VersionMinor value exists */
5878     sz = MAX_PATH;
5879     lstrcpyA(buf, "apple");
5880     r = pMsiGetProductInfoExA(prodcode, NULL,
5881                               MSIINSTALLCONTEXT_MACHINE,
5882                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5883     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5884     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5885     ok(sz == 1, "Expected 1, got %d\n", sz);
5886
5887     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5889
5890     /* VersionMajor value exists */
5891     sz = MAX_PATH;
5892     lstrcpyA(buf, "apple");
5893     r = pMsiGetProductInfoExA(prodcode, NULL,
5894                               MSIINSTALLCONTEXT_MACHINE,
5895                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5897     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5898     ok(sz == 1, "Expected 1, got %d\n", sz);
5899
5900     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5902
5903     /* DisplayVersion value exists */
5904     sz = MAX_PATH;
5905     lstrcpyA(buf, "apple");
5906     r = pMsiGetProductInfoExA(prodcode, NULL,
5907                               MSIINSTALLCONTEXT_MACHINE,
5908                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5910     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5911     ok(sz == 5, "Expected 5, got %d\n", sz);
5912
5913     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5915
5916     /* ProductID value exists */
5917     sz = MAX_PATH;
5918     lstrcpyA(buf, "apple");
5919     r = pMsiGetProductInfoExA(prodcode, NULL,
5920                               MSIINSTALLCONTEXT_MACHINE,
5921                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5922     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5923     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5924     ok(sz == 2, "Expected 2, got %d\n", sz);
5925
5926     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5928
5929     /* RegCompany value exists */
5930     sz = MAX_PATH;
5931     lstrcpyA(buf, "apple");
5932     r = pMsiGetProductInfoExA(prodcode, NULL,
5933                               MSIINSTALLCONTEXT_MACHINE,
5934                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5936     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5937     ok(sz == 4, "Expected 4, got %d\n", sz);
5938
5939     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5941
5942     /* RegOwner value exists */
5943     sz = MAX_PATH;
5944     lstrcpyA(buf, "apple");
5945     r = pMsiGetProductInfoExA(prodcode, NULL,
5946                               MSIINSTALLCONTEXT_MACHINE,
5947                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5949     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5950     ok(sz == 5, "Expected 5, got %d\n", sz);
5951
5952     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5954
5955     /* Transforms value exists */
5956     sz = MAX_PATH;
5957     lstrcpyA(buf, "apple");
5958     r = pMsiGetProductInfoExA(prodcode, NULL,
5959                               MSIINSTALLCONTEXT_MACHINE,
5960                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5961     ok(r == ERROR_UNKNOWN_PRODUCT,
5962        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5963     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5964     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5965
5966     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5967     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5968
5969     /* Language value exists */
5970     sz = MAX_PATH;
5971     lstrcpyA(buf, "apple");
5972     r = pMsiGetProductInfoExA(prodcode, NULL,
5973                               MSIINSTALLCONTEXT_MACHINE,
5974                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5975     ok(r == ERROR_UNKNOWN_PRODUCT,
5976        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5977     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5978     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5979
5980     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5982
5983     /* ProductName value exists */
5984     sz = MAX_PATH;
5985     lstrcpyA(buf, "apple");
5986     r = pMsiGetProductInfoExA(prodcode, NULL,
5987                               MSIINSTALLCONTEXT_MACHINE,
5988                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5989     ok(r == ERROR_UNKNOWN_PRODUCT,
5990        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5991     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5992     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5993
5994     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5996
5997     /* FIXME */
5998
5999     /* AssignmentType value exists */
6000     sz = MAX_PATH;
6001     lstrcpyA(buf, "apple");
6002     r = pMsiGetProductInfoExA(prodcode, NULL,
6003                               MSIINSTALLCONTEXT_MACHINE,
6004                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6005     ok(r == ERROR_UNKNOWN_PRODUCT,
6006        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6007     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6008     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6009
6010     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6012
6013     /* PackageCode value exists */
6014     sz = MAX_PATH;
6015     lstrcpyA(buf, "apple");
6016     r = pMsiGetProductInfoExA(prodcode, NULL,
6017                               MSIINSTALLCONTEXT_MACHINE,
6018                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6019     ok(r == ERROR_UNKNOWN_PRODUCT,
6020        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6021     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6022     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6023
6024     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6026
6027     /* Version value exists */
6028     sz = MAX_PATH;
6029     lstrcpyA(buf, "apple");
6030     r = pMsiGetProductInfoExA(prodcode, NULL,
6031                               MSIINSTALLCONTEXT_MACHINE,
6032                               INSTALLPROPERTY_VERSION, buf, &sz);
6033     ok(r == ERROR_UNKNOWN_PRODUCT,
6034        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6035     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6036     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6037
6038     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6040
6041     /* ProductIcon value exists */
6042     sz = MAX_PATH;
6043     lstrcpyA(buf, "apple");
6044     r = pMsiGetProductInfoExA(prodcode, NULL,
6045                               MSIINSTALLCONTEXT_MACHINE,
6046                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6047     ok(r == ERROR_UNKNOWN_PRODUCT,
6048        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6049     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6050     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6051
6052     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6054
6055     /* PackageName value exists */
6056     sz = MAX_PATH;
6057     lstrcpyA(buf, "apple");
6058     r = pMsiGetProductInfoExA(prodcode, NULL,
6059                               MSIINSTALLCONTEXT_MACHINE,
6060                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6061     ok(r == ERROR_UNKNOWN_PRODUCT,
6062        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6063     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6064     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6065
6066     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6068
6069     /* AuthorizedLUAApp value exists */
6070     sz = MAX_PATH;
6071     lstrcpyA(buf, "apple");
6072     r = pMsiGetProductInfoExA(prodcode, NULL,
6073                               MSIINSTALLCONTEXT_MACHINE,
6074                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6075     ok(r == ERROR_UNKNOWN_PRODUCT,
6076        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6077     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6078     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6079
6080     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6081     RegDeleteValueA(propkey, "PackageName");
6082     RegDeleteValueA(propkey, "ProductIcon");
6083     RegDeleteValueA(propkey, "Version");
6084     RegDeleteValueA(propkey, "PackageCode");
6085     RegDeleteValueA(propkey, "AssignmentType");
6086     RegDeleteValueA(propkey, "ProductName");
6087     RegDeleteValueA(propkey, "Language");
6088     RegDeleteValueA(propkey, "Transforms");
6089     RegDeleteValueA(propkey, "RegOwner");
6090     RegDeleteValueA(propkey, "RegCompany");
6091     RegDeleteValueA(propkey, "ProductID");
6092     RegDeleteValueA(propkey, "DisplayVersion");
6093     RegDeleteValueA(propkey, "VersionMajor");
6094     RegDeleteValueA(propkey, "VersionMinor");
6095     RegDeleteValueA(propkey, "URLUpdateInfo");
6096     RegDeleteValueA(propkey, "URLInfoAbout");
6097     RegDeleteValueA(propkey, "Publisher");
6098     RegDeleteValueA(propkey, "LocalPackage");
6099     RegDeleteValueA(propkey, "InstallSource");
6100     RegDeleteValueA(propkey, "InstallLocation");
6101     RegDeleteValueA(propkey, "DisplayName");
6102     RegDeleteValueA(propkey, "InstallDate");
6103     RegDeleteValueA(propkey, "HelpTelephone");
6104     RegDeleteValueA(propkey, "HelpLink");
6105     RegDeleteValueA(propkey, "LocalPackage");
6106     RegDeleteKeyA(propkey, "");
6107     RegCloseKey(propkey);
6108     RegDeleteKeyA(localkey, "");
6109     RegCloseKey(localkey);
6110
6111     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6112     lstrcatA(keypath, prod_squashed);
6113
6114     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6115     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6116
6117     /* local classes product key exists */
6118     sz = MAX_PATH;
6119     lstrcpyA(buf, "apple");
6120     r = pMsiGetProductInfoExA(prodcode, NULL,
6121                               MSIINSTALLCONTEXT_MACHINE,
6122                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6124     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6125     ok(sz == 1, "Expected 1, got %d\n", sz);
6126
6127     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6129
6130     /* HelpLink value exists */
6131     sz = MAX_PATH;
6132     lstrcpyA(buf, "apple");
6133     r = pMsiGetProductInfoExA(prodcode, NULL,
6134                               MSIINSTALLCONTEXT_MACHINE,
6135                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6136     ok(r == ERROR_UNKNOWN_PROPERTY,
6137        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6138     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6139     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6140
6141     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6143
6144     /* HelpTelephone value exists */
6145     sz = MAX_PATH;
6146     lstrcpyA(buf, "apple");
6147     r = pMsiGetProductInfoExA(prodcode, NULL,
6148                               MSIINSTALLCONTEXT_MACHINE,
6149                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6150     ok(r == ERROR_UNKNOWN_PROPERTY,
6151        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6152     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6153     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6154
6155     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6157
6158     /* InstallDate value exists */
6159     sz = MAX_PATH;
6160     lstrcpyA(buf, "apple");
6161     r = pMsiGetProductInfoExA(prodcode, NULL,
6162                               MSIINSTALLCONTEXT_MACHINE,
6163                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6164     ok(r == ERROR_UNKNOWN_PROPERTY,
6165        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6166     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6167     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6168
6169     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6171
6172     /* DisplayName value exists */
6173     sz = MAX_PATH;
6174     lstrcpyA(buf, "apple");
6175     r = pMsiGetProductInfoExA(prodcode, NULL,
6176                               MSIINSTALLCONTEXT_MACHINE,
6177                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6178     ok(r == ERROR_UNKNOWN_PROPERTY,
6179        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6180     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6181     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6182
6183     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6185
6186     /* InstallLocation value exists */
6187     sz = MAX_PATH;
6188     lstrcpyA(buf, "apple");
6189     r = pMsiGetProductInfoExA(prodcode, NULL,
6190                               MSIINSTALLCONTEXT_MACHINE,
6191                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6192     ok(r == ERROR_UNKNOWN_PROPERTY,
6193        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6194     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6195     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6196
6197     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6199
6200     /* InstallSource value exists */
6201     sz = MAX_PATH;
6202     lstrcpyA(buf, "apple");
6203     r = pMsiGetProductInfoExA(prodcode, NULL,
6204                               MSIINSTALLCONTEXT_MACHINE,
6205                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6206     ok(r == ERROR_UNKNOWN_PROPERTY,
6207        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6208     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6209     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6210
6211     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6213
6214     /* LocalPackage value exists */
6215     sz = MAX_PATH;
6216     lstrcpyA(buf, "apple");
6217     r = pMsiGetProductInfoExA(prodcode, NULL,
6218                               MSIINSTALLCONTEXT_MACHINE,
6219                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6220     ok(r == ERROR_UNKNOWN_PROPERTY,
6221        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6222     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6223     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6224
6225     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6227
6228     /* Publisher value exists */
6229     sz = MAX_PATH;
6230     lstrcpyA(buf, "apple");
6231     r = pMsiGetProductInfoExA(prodcode, NULL,
6232                               MSIINSTALLCONTEXT_MACHINE,
6233                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6234     ok(r == ERROR_UNKNOWN_PROPERTY,
6235        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6236     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6237     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6238
6239     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6241
6242     /* URLInfoAbout value exists */
6243     sz = MAX_PATH;
6244     lstrcpyA(buf, "apple");
6245     r = pMsiGetProductInfoExA(prodcode, NULL,
6246                               MSIINSTALLCONTEXT_MACHINE,
6247                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6248     ok(r == ERROR_UNKNOWN_PROPERTY,
6249        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6250     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6251     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6252
6253     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6255
6256     /* URLUpdateInfo value exists */
6257     sz = MAX_PATH;
6258     lstrcpyA(buf, "apple");
6259     r = pMsiGetProductInfoExA(prodcode, NULL,
6260                               MSIINSTALLCONTEXT_MACHINE,
6261                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6262     ok(r == ERROR_UNKNOWN_PROPERTY,
6263        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6264     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6265     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6266
6267     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6269
6270     /* VersionMinor value exists */
6271     sz = MAX_PATH;
6272     lstrcpyA(buf, "apple");
6273     r = pMsiGetProductInfoExA(prodcode, NULL,
6274                               MSIINSTALLCONTEXT_MACHINE,
6275                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6276     ok(r == ERROR_UNKNOWN_PROPERTY,
6277        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6278     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6279     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6280
6281     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6283
6284     /* VersionMajor value exists */
6285     sz = MAX_PATH;
6286     lstrcpyA(buf, "apple");
6287     r = pMsiGetProductInfoExA(prodcode, NULL,
6288                               MSIINSTALLCONTEXT_MACHINE,
6289                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6290     ok(r == ERROR_UNKNOWN_PROPERTY,
6291        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6292     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6293     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6294
6295     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6297
6298     /* DisplayVersion value exists */
6299     sz = MAX_PATH;
6300     lstrcpyA(buf, "apple");
6301     r = pMsiGetProductInfoExA(prodcode, NULL,
6302                               MSIINSTALLCONTEXT_MACHINE,
6303                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6304     ok(r == ERROR_UNKNOWN_PROPERTY,
6305        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6306     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6307     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6308
6309     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6311
6312     /* ProductID value exists */
6313     sz = MAX_PATH;
6314     lstrcpyA(buf, "apple");
6315     r = pMsiGetProductInfoExA(prodcode, NULL,
6316                               MSIINSTALLCONTEXT_MACHINE,
6317                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6318     ok(r == ERROR_UNKNOWN_PROPERTY,
6319        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6320     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6321     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6322
6323     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6325
6326     /* RegCompany value exists */
6327     sz = MAX_PATH;
6328     lstrcpyA(buf, "apple");
6329     r = pMsiGetProductInfoExA(prodcode, NULL,
6330                               MSIINSTALLCONTEXT_MACHINE,
6331                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6332     ok(r == ERROR_UNKNOWN_PROPERTY,
6333        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6334     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6335     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6336
6337     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6339
6340     /* RegOwner value exists */
6341     sz = MAX_PATH;
6342     lstrcpyA(buf, "apple");
6343     r = pMsiGetProductInfoExA(prodcode, NULL,
6344                               MSIINSTALLCONTEXT_MACHINE,
6345                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6346     ok(r == ERROR_UNKNOWN_PROPERTY,
6347        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6348     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6349     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6350
6351     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6353
6354     /* Transforms value exists */
6355     sz = MAX_PATH;
6356     lstrcpyA(buf, "apple");
6357     r = pMsiGetProductInfoExA(prodcode, NULL,
6358                               MSIINSTALLCONTEXT_MACHINE,
6359                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6361     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6362     ok(sz == 5, "Expected 5, got %d\n", sz);
6363
6364     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6366
6367     /* Language value exists */
6368     sz = MAX_PATH;
6369     lstrcpyA(buf, "apple");
6370     r = pMsiGetProductInfoExA(prodcode, NULL,
6371                               MSIINSTALLCONTEXT_MACHINE,
6372                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6374     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6375     ok(sz == 4, "Expected 4, got %d\n", sz);
6376
6377     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6378     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6379
6380     /* ProductName value exists */
6381     sz = MAX_PATH;
6382     lstrcpyA(buf, "apple");
6383     r = pMsiGetProductInfoExA(prodcode, NULL,
6384                               MSIINSTALLCONTEXT_MACHINE,
6385                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6387     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6388     ok(sz == 4, "Expected 4, got %d\n", sz);
6389
6390     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6391     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6392
6393     /* FIXME */
6394
6395     /* AssignmentType value exists */
6396     sz = MAX_PATH;
6397     lstrcpyA(buf, "apple");
6398     r = pMsiGetProductInfoExA(prodcode, NULL,
6399                               MSIINSTALLCONTEXT_MACHINE,
6400                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6402     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6403     ok(sz == 0, "Expected 0, got %d\n", sz);
6404
6405     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6406     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6407
6408     /* FIXME */
6409
6410     /* PackageCode value exists */
6411     sz = MAX_PATH;
6412     lstrcpyA(buf, "apple");
6413     r = pMsiGetProductInfoExA(prodcode, NULL,
6414                               MSIINSTALLCONTEXT_MACHINE,
6415                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6416     todo_wine
6417     {
6418         ok(r == ERROR_BAD_CONFIGURATION,
6419            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6420         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6421         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6422     }
6423
6424     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6426
6427     /* Version value exists */
6428     sz = MAX_PATH;
6429     lstrcpyA(buf, "apple");
6430     r = pMsiGetProductInfoExA(prodcode, NULL,
6431                               MSIINSTALLCONTEXT_MACHINE,
6432                               INSTALLPROPERTY_VERSION, buf, &sz);
6433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6434     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6435     ok(sz == 3, "Expected 3, got %d\n", sz);
6436
6437     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6439
6440     /* ProductIcon value exists */
6441     sz = MAX_PATH;
6442     lstrcpyA(buf, "apple");
6443     r = pMsiGetProductInfoExA(prodcode, NULL,
6444                               MSIINSTALLCONTEXT_MACHINE,
6445                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6447     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6448     ok(sz == 4, "Expected 4, got %d\n", sz);
6449
6450     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6452
6453     /* PackageName value exists */
6454     sz = MAX_PATH;
6455     lstrcpyA(buf, "apple");
6456     r = pMsiGetProductInfoExA(prodcode, NULL,
6457                               MSIINSTALLCONTEXT_MACHINE,
6458                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6459     todo_wine
6460     {
6461         ok(r == ERROR_UNKNOWN_PRODUCT,
6462            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6463         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6464         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6465     }
6466
6467     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6469
6470     /* AuthorizedLUAApp value exists */
6471     sz = MAX_PATH;
6472     lstrcpyA(buf, "apple");
6473     r = pMsiGetProductInfoExA(prodcode, NULL,
6474                               MSIINSTALLCONTEXT_MACHINE,
6475                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6477     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6478     ok(sz == 4, "Expected 4, got %d\n", sz);
6479
6480     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6481     RegDeleteValueA(prodkey, "PackageName");
6482     RegDeleteValueA(prodkey, "ProductIcon");
6483     RegDeleteValueA(prodkey, "Version");
6484     RegDeleteValueA(prodkey, "PackageCode");
6485     RegDeleteValueA(prodkey, "AssignmentType");
6486     RegDeleteValueA(prodkey, "ProductName");
6487     RegDeleteValueA(prodkey, "Language");
6488     RegDeleteValueA(prodkey, "Transforms");
6489     RegDeleteValueA(prodkey, "RegOwner");
6490     RegDeleteValueA(prodkey, "RegCompany");
6491     RegDeleteValueA(prodkey, "ProductID");
6492     RegDeleteValueA(prodkey, "DisplayVersion");
6493     RegDeleteValueA(prodkey, "VersionMajor");
6494     RegDeleteValueA(prodkey, "VersionMinor");
6495     RegDeleteValueA(prodkey, "URLUpdateInfo");
6496     RegDeleteValueA(prodkey, "URLInfoAbout");
6497     RegDeleteValueA(prodkey, "Publisher");
6498     RegDeleteValueA(prodkey, "LocalPackage");
6499     RegDeleteValueA(prodkey, "InstallSource");
6500     RegDeleteValueA(prodkey, "InstallLocation");
6501     RegDeleteValueA(prodkey, "DisplayName");
6502     RegDeleteValueA(prodkey, "InstallDate");
6503     RegDeleteValueA(prodkey, "HelpTelephone");
6504     RegDeleteValueA(prodkey, "HelpLink");
6505     RegDeleteKeyA(prodkey, "");
6506     RegCloseKey(prodkey);
6507 }
6508
6509 #define INIT_USERINFO() \
6510     lstrcpyA(user, "apple"); \
6511     lstrcpyA(org, "orange"); \
6512     lstrcpyA(serial, "banana"); \
6513     usersz = orgsz = serialsz = MAX_PATH;
6514
6515 static void test_MsiGetUserInfo(void)
6516 {
6517     USERINFOSTATE state;
6518     CHAR user[MAX_PATH];
6519     CHAR org[MAX_PATH];
6520     CHAR serial[MAX_PATH];
6521     DWORD usersz, orgsz, serialsz;
6522     CHAR keypath[MAX_PATH * 2];
6523     CHAR prodcode[MAX_PATH];
6524     CHAR prod_squashed[MAX_PATH];
6525     HKEY prodkey, userprod, props;
6526     LPSTR usersid;
6527     LONG res;
6528
6529     create_test_guid(prodcode, prod_squashed);
6530     get_user_sid(&usersid);
6531
6532     /* NULL szProduct */
6533     INIT_USERINFO();
6534     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6535     ok(state == USERINFOSTATE_INVALIDARG,
6536        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6537     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6538     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6539     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6540     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6541     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6542     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6543
6544     /* empty szProductCode */
6545     INIT_USERINFO();
6546     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6547     ok(state == USERINFOSTATE_INVALIDARG,
6548        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6549     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6550     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6551     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6552     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6553     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6554     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6555
6556     /* garbage szProductCode */
6557     INIT_USERINFO();
6558     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6559     ok(state == USERINFOSTATE_INVALIDARG,
6560        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6561     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6562     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6563     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6564     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6565     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6566     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6567
6568     /* guid without brackets */
6569     INIT_USERINFO();
6570     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6571                             user, &usersz, org, &orgsz, serial, &serialsz);
6572     ok(state == USERINFOSTATE_INVALIDARG,
6573        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6574     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6575     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6576     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6577     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6578     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6579     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6580
6581     /* guid with brackets */
6582     INIT_USERINFO();
6583     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6584                             user, &usersz, org, &orgsz, serial, &serialsz);
6585     ok(state == USERINFOSTATE_UNKNOWN,
6586        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6587     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6588     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6589     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6590     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6591     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6592     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6593
6594     /* NULL lpUserNameBuf */
6595     INIT_USERINFO();
6596     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6597     ok(state == USERINFOSTATE_UNKNOWN,
6598        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6599     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6600     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6601     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6602     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6603     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6604
6605     /* NULL pcchUserNameBuf */
6606     INIT_USERINFO();
6607     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6608     ok(state == USERINFOSTATE_INVALIDARG,
6609        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6610     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6611     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6612     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6613     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6614     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6615
6616     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6617     INIT_USERINFO();
6618     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6619     ok(state == USERINFOSTATE_UNKNOWN,
6620        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6621     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6622     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6623     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6624     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6625
6626     /* NULL lpOrgNameBuf */
6627     INIT_USERINFO();
6628     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6629     ok(state == USERINFOSTATE_UNKNOWN,
6630        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6631     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6632     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6633     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6634     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6635     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6636
6637     /* NULL pcchOrgNameBuf */
6638     INIT_USERINFO();
6639     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6640     ok(state == USERINFOSTATE_INVALIDARG,
6641        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6642     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6643     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6644     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6645     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6646     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6647
6648     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6649     INIT_USERINFO();
6650     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6651     ok(state == USERINFOSTATE_UNKNOWN,
6652        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6653     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6654     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6655     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6656     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6657
6658     /* NULL lpSerialBuf */
6659     INIT_USERINFO();
6660     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6661     ok(state == USERINFOSTATE_UNKNOWN,
6662        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6663     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6664     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6665     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6666     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6667     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6668
6669     /* NULL pcchSerialBuf */
6670     INIT_USERINFO();
6671     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6672     ok(state == USERINFOSTATE_INVALIDARG,
6673        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6674     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6675     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6676     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6677     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6678     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6679
6680     /* both lpSerialBuf and pcchSerialBuf NULL */
6681     INIT_USERINFO();
6682     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6683     ok(state == USERINFOSTATE_UNKNOWN,
6684        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6685     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6686     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6687     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6688     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6689
6690     /* MSIINSTALLCONTEXT_USERMANAGED */
6691
6692     /* create local system product key */
6693     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6694     lstrcatA(keypath, usersid);
6695     lstrcatA(keypath, "\\Installer\\Products\\");
6696     lstrcatA(keypath, prod_squashed);
6697
6698     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6700
6701     /* managed product key exists */
6702     INIT_USERINFO();
6703     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6704     ok(state == USERINFOSTATE_ABSENT,
6705        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6706     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6707     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6708     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6709     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6710     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6711     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6712
6713     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6714     lstrcatA(keypath, "Installer\\UserData\\");
6715     lstrcatA(keypath, usersid);
6716     lstrcatA(keypath, "\\Products\\");
6717     lstrcatA(keypath, prod_squashed);
6718
6719     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6721
6722     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6723     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6724
6725     /* InstallProperties key exists */
6726     INIT_USERINFO();
6727     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6728     ok(state == USERINFOSTATE_ABSENT,
6729        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6730     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6731     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6732     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6733     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6734     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6735     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6736
6737     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6738     INIT_USERINFO();
6739     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6740     ok(state == USERINFOSTATE_ABSENT,
6741        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6742     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6743     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6744     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6745     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6746
6747     /* RegOwner, RegCompany don't exist, out params are NULL */
6748     INIT_USERINFO();
6749     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6750     ok(state == USERINFOSTATE_ABSENT,
6751        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6752     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6753     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6754
6755     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6757
6758     /* RegOwner value exists */
6759     INIT_USERINFO();
6760     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6761     ok(state == USERINFOSTATE_ABSENT,
6762        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6763     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6764     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6765     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6766     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6767     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6768     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6769
6770     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6772
6773     /* RegCompany value exists */
6774     INIT_USERINFO();
6775     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6776     ok(state == USERINFOSTATE_ABSENT,
6777        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6778     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6779     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6780     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6781     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6782     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6783     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6784
6785     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6787
6788     /* ProductID value exists */
6789     INIT_USERINFO();
6790     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6791     ok(state == USERINFOSTATE_PRESENT,
6792        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6793     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6794     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6795     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6796     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6797     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6798     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6799
6800     /* pcchUserNameBuf is too small */
6801     INIT_USERINFO();
6802     usersz = 0;
6803     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6804     ok(state == USERINFOSTATE_MOREDATA,
6805        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6806     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6807     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6808     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6809     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6810     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6811     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6812
6813     /* pcchUserNameBuf has no room for NULL terminator */
6814     INIT_USERINFO();
6815     usersz = 5;
6816     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6817     ok(state == USERINFOSTATE_MOREDATA,
6818        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6819     todo_wine
6820     {
6821         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6822     }
6823     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6824     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6825     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6826     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6827     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6828
6829     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6830     INIT_USERINFO();
6831     usersz = 0;
6832     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6833     ok(state == USERINFOSTATE_PRESENT,
6834        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6835     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6836     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6837     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6838     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6839     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6840     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6841
6842     RegDeleteValueA(props, "ProductID");
6843     RegDeleteValueA(props, "RegCompany");
6844     RegDeleteValueA(props, "RegOwner");
6845     RegDeleteKeyA(props, "");
6846     RegCloseKey(props);
6847     RegDeleteKeyA(userprod, "");
6848     RegCloseKey(userprod);
6849     RegDeleteKeyA(prodkey, "");
6850     RegCloseKey(prodkey);
6851
6852     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6853
6854     /* create local system product key */
6855     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6856     lstrcatA(keypath, prod_squashed);
6857
6858     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6860
6861     /* product key exists */
6862     INIT_USERINFO();
6863     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6864     ok(state == USERINFOSTATE_ABSENT,
6865        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6866     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6867     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6868     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6869     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6870     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6871     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6872
6873     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6874     lstrcatA(keypath, "Installer\\UserData\\");
6875     lstrcatA(keypath, usersid);
6876     lstrcatA(keypath, "\\Products\\");
6877     lstrcatA(keypath, prod_squashed);
6878
6879     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6880     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6881
6882     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6884
6885     /* InstallProperties key exists */
6886     INIT_USERINFO();
6887     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6888     ok(state == USERINFOSTATE_ABSENT,
6889        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6890     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6891     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6892     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6893     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6894     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6895     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6896
6897     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6898     INIT_USERINFO();
6899     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6900     ok(state == USERINFOSTATE_ABSENT,
6901        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6902     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6903     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6904     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6905     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6906
6907     /* RegOwner, RegCompany don't exist, out params are NULL */
6908     INIT_USERINFO();
6909     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6910     ok(state == USERINFOSTATE_ABSENT,
6911        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6912     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6913     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6914
6915     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6917
6918     /* RegOwner value exists */
6919     INIT_USERINFO();
6920     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6921     ok(state == USERINFOSTATE_ABSENT,
6922        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6923     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6924     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6925     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6926     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6927     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6928     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6929
6930     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6932
6933     /* RegCompany value exists */
6934     INIT_USERINFO();
6935     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6936     ok(state == USERINFOSTATE_ABSENT,
6937        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6938     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6939     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6940     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6941     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6942     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6943     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6944
6945     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6947
6948     /* ProductID value exists */
6949     INIT_USERINFO();
6950     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6951     ok(state == USERINFOSTATE_PRESENT,
6952        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6953     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6954     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6955     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6956     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6957     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6958     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6959
6960     RegDeleteValueA(props, "ProductID");
6961     RegDeleteValueA(props, "RegCompany");
6962     RegDeleteValueA(props, "RegOwner");
6963     RegDeleteKeyA(props, "");
6964     RegCloseKey(props);
6965     RegDeleteKeyA(userprod, "");
6966     RegCloseKey(userprod);
6967     RegDeleteKeyA(prodkey, "");
6968     RegCloseKey(prodkey);
6969
6970     /* MSIINSTALLCONTEXT_MACHINE */
6971
6972     /* create local system product key */
6973     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6974     lstrcatA(keypath, prod_squashed);
6975
6976     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6978
6979     /* product key exists */
6980     INIT_USERINFO();
6981     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6982     ok(state == USERINFOSTATE_ABSENT,
6983        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6984     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6985     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6986     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6987     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6988     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6989     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6990
6991     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6992     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
6993     lstrcatA(keypath, "\\Products\\");
6994     lstrcatA(keypath, prod_squashed);
6995
6996     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6998
6999     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7001
7002     /* InstallProperties key exists */
7003     INIT_USERINFO();
7004     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7005     ok(state == USERINFOSTATE_ABSENT,
7006        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7007     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7008     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7009     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7010     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7011     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7012     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7013
7014     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7015     INIT_USERINFO();
7016     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7017     ok(state == USERINFOSTATE_ABSENT,
7018        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7019     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7020     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7021     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7022     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7023
7024     /* RegOwner, RegCompany don't exist, out params are NULL */
7025     INIT_USERINFO();
7026     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7027     ok(state == USERINFOSTATE_ABSENT,
7028        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7029     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7030     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7031
7032     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7034
7035     /* RegOwner value exists */
7036     INIT_USERINFO();
7037     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7038     ok(state == USERINFOSTATE_ABSENT,
7039        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7040     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7041     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7042     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7043     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7044     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7045     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7046
7047     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7049
7050     /* RegCompany value exists */
7051     INIT_USERINFO();
7052     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7053     ok(state == USERINFOSTATE_ABSENT,
7054        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7055     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7056     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7057     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7058     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7059     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7060     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7061
7062     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7064
7065     /* ProductID value exists */
7066     INIT_USERINFO();
7067     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7068     ok(state == USERINFOSTATE_PRESENT,
7069        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7070     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7071     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7072     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7073     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7074     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7075     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7076
7077     RegDeleteValueA(props, "ProductID");
7078     RegDeleteValueA(props, "RegCompany");
7079     RegDeleteValueA(props, "RegOwner");
7080     RegDeleteKeyA(props, "");
7081     RegCloseKey(props);
7082     RegDeleteKeyA(userprod, "");
7083     RegCloseKey(userprod);
7084     RegDeleteKeyA(prodkey, "");
7085     RegCloseKey(prodkey);
7086 }
7087
7088 static void test_MsiOpenProduct(void)
7089 {
7090     MSIHANDLE hprod, hdb;
7091     CHAR val[MAX_PATH];
7092     CHAR path[MAX_PATH];
7093     CHAR keypath[MAX_PATH*2];
7094     CHAR prodcode[MAX_PATH];
7095     CHAR prod_squashed[MAX_PATH];
7096     HKEY prodkey, userkey, props;
7097     LPSTR usersid;
7098     DWORD size;
7099     LONG res;
7100     UINT r;
7101
7102     GetCurrentDirectoryA(MAX_PATH, path);
7103     lstrcatA(path, "\\");
7104
7105     create_test_guid(prodcode, prod_squashed);
7106     get_user_sid(&usersid);
7107
7108     hdb = create_package_db(prodcode);
7109     MsiCloseHandle(hdb);
7110
7111     /* NULL szProduct */
7112     hprod = 0xdeadbeef;
7113     r = MsiOpenProductA(NULL, &hprod);
7114     ok(r == ERROR_INVALID_PARAMETER,
7115        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7116     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7117
7118     /* empty szProduct */
7119     hprod = 0xdeadbeef;
7120     r = MsiOpenProductA("", &hprod);
7121     ok(r == ERROR_INVALID_PARAMETER,
7122        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7123     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7124
7125     /* garbage szProduct */
7126     hprod = 0xdeadbeef;
7127     r = MsiOpenProductA("garbage", &hprod);
7128     ok(r == ERROR_INVALID_PARAMETER,
7129        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7130     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7131
7132     /* guid without brackets */
7133     hprod = 0xdeadbeef;
7134     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7135     ok(r == ERROR_INVALID_PARAMETER,
7136        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7137     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7138
7139     /* guid with brackets */
7140     hprod = 0xdeadbeef;
7141     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7142     ok(r == ERROR_UNKNOWN_PRODUCT,
7143        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7144     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7145
7146     /* same length as guid, but random */
7147     hprod = 0xdeadbeef;
7148     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7149     ok(r == ERROR_INVALID_PARAMETER,
7150        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7151     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7152
7153     /* hProduct is NULL */
7154     hprod = 0xdeadbeef;
7155     r = MsiOpenProductA(prodcode, NULL);
7156     ok(r == ERROR_INVALID_PARAMETER,
7157        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7158     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7159
7160     /* MSIINSTALLCONTEXT_USERMANAGED */
7161
7162     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7163     lstrcatA(keypath, "Installer\\Managed\\");
7164     lstrcatA(keypath, usersid);
7165     lstrcatA(keypath, "\\Installer\\Products\\");
7166     lstrcatA(keypath, prod_squashed);
7167
7168     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7170
7171     /* managed product key exists */
7172     hprod = 0xdeadbeef;
7173     r = MsiOpenProductA(prodcode, &hprod);
7174     ok(r == ERROR_UNKNOWN_PRODUCT,
7175        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7176     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7177
7178     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7179     lstrcatA(keypath, "Installer\\UserData\\");
7180     lstrcatA(keypath, usersid);
7181     lstrcatA(keypath, "\\Products\\");
7182     lstrcatA(keypath, prod_squashed);
7183
7184     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7185     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7186
7187     /* user product key exists */
7188     hprod = 0xdeadbeef;
7189     r = MsiOpenProductA(prodcode, &hprod);
7190     ok(r == ERROR_UNKNOWN_PRODUCT,
7191        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7192     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7193
7194     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7196
7197     /* InstallProperties key exists */
7198     hprod = 0xdeadbeef;
7199     r = MsiOpenProductA(prodcode, &hprod);
7200     ok(r == ERROR_UNKNOWN_PRODUCT,
7201        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7202     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7203
7204     lstrcpyA(val, path);
7205     lstrcatA(val, "\\winetest.msi");
7206     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7207                          (const BYTE *)val, lstrlenA(val) + 1);
7208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7209
7210     /* ManagedLocalPackage value exists */
7211     hprod = 0xdeadbeef;
7212     r = MsiOpenProductA(prodcode, &hprod);
7213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7214     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7215
7216     size = MAX_PATH;
7217     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7219     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7220     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7221
7222     MsiCloseHandle(hprod);
7223
7224     RegDeleteValueA(props, "ManagedLocalPackage");
7225     RegDeleteKeyA(props, "");
7226     RegCloseKey(props);
7227     RegDeleteKeyA(userkey, "");
7228     RegCloseKey(userkey);
7229     RegDeleteKeyA(prodkey, "");
7230     RegCloseKey(prodkey);
7231
7232     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7233
7234     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7235     lstrcatA(keypath, prod_squashed);
7236
7237     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7239
7240     /* unmanaged product key exists */
7241     hprod = 0xdeadbeef;
7242     r = MsiOpenProductA(prodcode, &hprod);
7243     ok(r == ERROR_UNKNOWN_PRODUCT,
7244        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7245     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7246
7247     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7248     lstrcatA(keypath, "Installer\\UserData\\");
7249     lstrcatA(keypath, usersid);
7250     lstrcatA(keypath, "\\Products\\");
7251     lstrcatA(keypath, prod_squashed);
7252
7253     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7255
7256     /* user product key exists */
7257     hprod = 0xdeadbeef;
7258     r = MsiOpenProductA(prodcode, &hprod);
7259     ok(r == ERROR_UNKNOWN_PRODUCT,
7260        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7261     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7262
7263     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7264     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7265
7266     /* InstallProperties key exists */
7267     hprod = 0xdeadbeef;
7268     r = MsiOpenProductA(prodcode, &hprod);
7269     ok(r == ERROR_UNKNOWN_PRODUCT,
7270        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7271     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7272
7273     lstrcpyA(val, path);
7274     lstrcatA(val, "\\winetest.msi");
7275     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7276                          (const BYTE *)val, lstrlenA(val) + 1);
7277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7278
7279     /* LocalPackage value exists */
7280     hprod = 0xdeadbeef;
7281     r = MsiOpenProductA(prodcode, &hprod);
7282     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7283     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7284
7285     size = MAX_PATH;
7286     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7287     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7288     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7289     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7290
7291     MsiCloseHandle(hprod);
7292
7293     RegDeleteValueA(props, "LocalPackage");
7294     RegDeleteKeyA(props, "");
7295     RegCloseKey(props);
7296     RegDeleteKeyA(userkey, "");
7297     RegCloseKey(userkey);
7298     RegDeleteKeyA(prodkey, "");
7299     RegCloseKey(prodkey);
7300
7301     /* MSIINSTALLCONTEXT_MACHINE */
7302
7303     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7304     lstrcatA(keypath, prod_squashed);
7305
7306     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7308
7309     /* managed product key exists */
7310     hprod = 0xdeadbeef;
7311     r = MsiOpenProductA(prodcode, &hprod);
7312     ok(r == ERROR_UNKNOWN_PRODUCT,
7313        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7314     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7315
7316     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7317     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7318     lstrcatA(keypath, prod_squashed);
7319
7320     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7322
7323     /* user product key exists */
7324     hprod = 0xdeadbeef;
7325     r = MsiOpenProductA(prodcode, &hprod);
7326     ok(r == ERROR_UNKNOWN_PRODUCT,
7327        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7328     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7329
7330     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7332
7333     /* InstallProperties key exists */
7334     hprod = 0xdeadbeef;
7335     r = MsiOpenProductA(prodcode, &hprod);
7336     ok(r == ERROR_UNKNOWN_PRODUCT,
7337        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7338     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7339
7340     lstrcpyA(val, path);
7341     lstrcatA(val, "\\winetest.msi");
7342     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7343                          (const BYTE *)val, lstrlenA(val) + 1);
7344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7345
7346     /* LocalPackage value exists */
7347     hprod = 0xdeadbeef;
7348     r = MsiOpenProductA(prodcode, &hprod);
7349     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7350     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7351
7352     size = MAX_PATH;
7353     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7355     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7356     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7357
7358     MsiCloseHandle(hprod);
7359
7360     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7361                          (const BYTE *)"winetest.msi", 13);
7362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7363
7364     /* LocalPackage has just the package name */
7365     hprod = 0xdeadbeef;
7366     r = MsiOpenProductA(prodcode, &hprod);
7367     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7368        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7369     if (r == ERROR_SUCCESS)
7370         MsiCloseHandle(hprod);
7371     else
7372         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7373
7374     lstrcpyA(val, path);
7375     lstrcatA(val, "\\winetest.msi");
7376     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7377                          (const BYTE *)val, lstrlenA(val) + 1);
7378     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7379
7380     DeleteFileA(msifile);
7381
7382     /* local package does not exist */
7383     hprod = 0xdeadbeef;
7384     r = MsiOpenProductA(prodcode, &hprod);
7385     ok(r == ERROR_UNKNOWN_PRODUCT,
7386        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7387     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7388
7389     RegDeleteValueA(props, "LocalPackage");
7390     RegDeleteKeyA(props, "");
7391     RegCloseKey(props);
7392     RegDeleteKeyA(userkey, "");
7393     RegCloseKey(userkey);
7394     RegDeleteKeyA(prodkey, "");
7395     RegCloseKey(prodkey);
7396
7397     DeleteFileA(msifile);
7398 }
7399
7400 static void test_MsiEnumPatchesEx(void)
7401 {
7402     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7403     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7404     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7405     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7406     HKEY prodkey, patches, udprod, udpatch;
7407     HKEY userkey, hpatch;
7408     MSIINSTALLCONTEXT context;
7409     DWORD size, data;
7410     LPSTR usersid;
7411     LONG res;
7412     UINT r;
7413
7414     if (!pMsiEnumPatchesExA)
7415     {
7416         win_skip("MsiEnumPatchesExA not implemented\n");
7417         return;
7418     }
7419
7420     create_test_guid(prodcode, prod_squashed);
7421     create_test_guid(patch, patch_squashed);
7422     get_user_sid(&usersid);
7423
7424     /* empty szProductCode */
7425     lstrcpyA(patchcode, "apple");
7426     lstrcpyA(targetprod, "banana");
7427     context = 0xdeadbeef;
7428     lstrcpyA(targetsid, "kiwi");
7429     size = MAX_PATH;
7430     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7431                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7432                            targetsid, &size);
7433     ok(r == ERROR_INVALID_PARAMETER,
7434        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7435     ok(!lstrcmpA(patchcode, "apple"),
7436        "Expected patchcode to be unchanged, got %s\n", patchcode);
7437     ok(!lstrcmpA(targetprod, "banana"),
7438        "Expected targetprod to be unchanged, got %s\n", targetprod);
7439     ok(context == 0xdeadbeef,
7440        "Expected context to be unchanged, got %d\n", context);
7441     ok(!lstrcmpA(targetsid, "kiwi"),
7442        "Expected targetsid to be unchanged, got %s\n", targetsid);
7443     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7444
7445     /* garbage szProductCode */
7446     lstrcpyA(patchcode, "apple");
7447     lstrcpyA(targetprod, "banana");
7448     context = 0xdeadbeef;
7449     lstrcpyA(targetsid, "kiwi");
7450     size = MAX_PATH;
7451     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7452                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7453                            targetsid, &size);
7454     ok(r == ERROR_INVALID_PARAMETER,
7455        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7456     ok(!lstrcmpA(patchcode, "apple"),
7457        "Expected patchcode to be unchanged, got %s\n", patchcode);
7458     ok(!lstrcmpA(targetprod, "banana"),
7459        "Expected targetprod to be unchanged, got %s\n", targetprod);
7460     ok(context == 0xdeadbeef,
7461        "Expected context to be unchanged, got %d\n", context);
7462     ok(!lstrcmpA(targetsid, "kiwi"),
7463        "Expected targetsid to be unchanged, got %s\n", targetsid);
7464     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7465
7466     /* guid without brackets */
7467     lstrcpyA(patchcode, "apple");
7468     lstrcpyA(targetprod, "banana");
7469     context = 0xdeadbeef;
7470     lstrcpyA(targetsid, "kiwi");
7471     size = MAX_PATH;
7472     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
7473                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7474                            0, patchcode, targetprod, &context,
7475                            targetsid, &size);
7476     ok(r == ERROR_INVALID_PARAMETER,
7477        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7478     ok(!lstrcmpA(patchcode, "apple"),
7479        "Expected patchcode to be unchanged, got %s\n", patchcode);
7480     ok(!lstrcmpA(targetprod, "banana"),
7481        "Expected targetprod to be unchanged, got %s\n", targetprod);
7482     ok(context == 0xdeadbeef,
7483        "Expected context to be unchanged, got %d\n", context);
7484     ok(!lstrcmpA(targetsid, "kiwi"),
7485        "Expected targetsid to be unchanged, got %s\n", targetsid);
7486     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7487
7488     /* guid with brackets */
7489     lstrcpyA(patchcode, "apple");
7490     lstrcpyA(targetprod, "banana");
7491     context = 0xdeadbeef;
7492     lstrcpyA(targetsid, "kiwi");
7493     size = MAX_PATH;
7494     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
7495                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7496                            0, patchcode, targetprod, &context,
7497                            targetsid, &size);
7498     ok(r == ERROR_NO_MORE_ITEMS,
7499        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7500     ok(!lstrcmpA(patchcode, "apple"),
7501        "Expected patchcode to be unchanged, got %s\n", patchcode);
7502     ok(!lstrcmpA(targetprod, "banana"),
7503        "Expected targetprod to be unchanged, got %s\n", targetprod);
7504     ok(context == 0xdeadbeef,
7505        "Expected context to be unchanged, got %d\n", context);
7506     ok(!lstrcmpA(targetsid, "kiwi"),
7507        "Expected targetsid to be unchanged, got %s\n", targetsid);
7508     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7509
7510     /* szUserSid is S-1-5-18 */
7511     lstrcpyA(patchcode, "apple");
7512     lstrcpyA(targetprod, "banana");
7513     context = 0xdeadbeef;
7514     lstrcpyA(targetsid, "kiwi");
7515     size = MAX_PATH;
7516     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
7517                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7518                            0, patchcode, targetprod, &context,
7519                            targetsid, &size);
7520     ok(r == ERROR_INVALID_PARAMETER,
7521        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7522     ok(!lstrcmpA(patchcode, "apple"),
7523        "Expected patchcode to be unchanged, got %s\n", patchcode);
7524     ok(!lstrcmpA(targetprod, "banana"),
7525        "Expected targetprod to be unchanged, got %s\n", targetprod);
7526     ok(context == 0xdeadbeef,
7527        "Expected context to be unchanged, got %d\n", context);
7528     ok(!lstrcmpA(targetsid, "kiwi"),
7529        "Expected targetsid to be unchanged, got %s\n", targetsid);
7530     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7531
7532     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
7533     lstrcpyA(patchcode, "apple");
7534     lstrcpyA(targetprod, "banana");
7535     context = 0xdeadbeef;
7536     lstrcpyA(targetsid, "kiwi");
7537     size = MAX_PATH;
7538     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
7539                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7540                            &context, targetsid, &size);
7541     ok(r == ERROR_INVALID_PARAMETER,
7542        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7543     ok(!lstrcmpA(patchcode, "apple"),
7544        "Expected patchcode to be unchanged, got %s\n", patchcode);
7545     ok(!lstrcmpA(targetprod, "banana"),
7546        "Expected targetprod to be unchanged, got %s\n", targetprod);
7547     ok(context == 0xdeadbeef,
7548        "Expected context to be unchanged, got %d\n", context);
7549     ok(!lstrcmpA(targetsid, "kiwi"),
7550        "Expected targetsid to be unchanged, got %s\n", targetsid);
7551     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7552
7553     /* dwContext is out of bounds */
7554     lstrcpyA(patchcode, "apple");
7555     lstrcpyA(targetprod, "banana");
7556     context = 0xdeadbeef;
7557     lstrcpyA(targetsid, "kiwi");
7558     size = MAX_PATH;
7559     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
7560                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7561                            &context, targetsid, &size);
7562     ok(r == ERROR_INVALID_PARAMETER,
7563        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7564     ok(!lstrcmpA(patchcode, "apple"),
7565        "Expected patchcode to be unchanged, got %s\n", patchcode);
7566     ok(!lstrcmpA(targetprod, "banana"),
7567        "Expected targetprod to be unchanged, got %s\n", targetprod);
7568     ok(context == 0xdeadbeef,
7569        "Expected context to be unchanged, got %d\n", context);
7570     ok(!lstrcmpA(targetsid, "kiwi"),
7571        "Expected targetsid to be unchanged, got %s\n", targetsid);
7572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7573
7574     /* dwContext is out of bounds */
7575     lstrcpyA(patchcode, "apple");
7576     lstrcpyA(targetprod, "banana");
7577     context = 0xdeadbeef;
7578     lstrcpyA(targetsid, "kiwi");
7579     size = MAX_PATH;
7580     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
7581                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7582                            &context, targetsid, &size);
7583     ok(r == ERROR_INVALID_PARAMETER,
7584        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7585     ok(!lstrcmpA(patchcode, "apple"),
7586        "Expected patchcode to be unchanged, got %s\n", patchcode);
7587     ok(!lstrcmpA(targetprod, "banana"),
7588        "Expected targetprod to be unchanged, got %s\n", targetprod);
7589     ok(context == 0xdeadbeef,
7590        "Expected context to be unchanged, got %d\n", context);
7591     ok(!lstrcmpA(targetsid, "kiwi"),
7592        "Expected targetsid to be unchanged, got %s\n", targetsid);
7593     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7594
7595     /* dwFilter is out of bounds */
7596     lstrcpyA(patchcode, "apple");
7597     lstrcpyA(targetprod, "banana");
7598     context = 0xdeadbeef;
7599     lstrcpyA(targetsid, "kiwi");
7600     size = MAX_PATH;
7601     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7602                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
7603                            &context, targetsid, &size);
7604     ok(r == ERROR_INVALID_PARAMETER,
7605        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7606     ok(!lstrcmpA(patchcode, "apple"),
7607        "Expected patchcode to be unchanged, got %s\n", patchcode);
7608     ok(!lstrcmpA(targetprod, "banana"),
7609        "Expected targetprod to be unchanged, got %s\n", targetprod);
7610     ok(context == 0xdeadbeef,
7611        "Expected context to be unchanged, got %d\n", context);
7612     ok(!lstrcmpA(targetsid, "kiwi"),
7613        "Expected targetsid to be unchanged, got %s\n", targetsid);
7614     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7615
7616     /* dwFilter is out of bounds */
7617     lstrcpyA(patchcode, "apple");
7618     lstrcpyA(targetprod, "banana");
7619     context = 0xdeadbeef;
7620     lstrcpyA(targetsid, "kiwi");
7621     size = MAX_PATH;
7622     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7623                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
7624                            &context, targetsid, &size);
7625     ok(r == ERROR_INVALID_PARAMETER,
7626        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7627     ok(!lstrcmpA(patchcode, "apple"),
7628        "Expected patchcode to be unchanged, got %s\n", patchcode);
7629     ok(!lstrcmpA(targetprod, "banana"),
7630        "Expected targetprod to be unchanged, got %s\n", targetprod);
7631     ok(context == 0xdeadbeef,
7632        "Expected context to be unchanged, got %d\n", context);
7633     ok(!lstrcmpA(targetsid, "kiwi"),
7634        "Expected targetsid to be unchanged, got %s\n", targetsid);
7635     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7636
7637     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
7638     lstrcpyA(patchcode, "apple");
7639     lstrcpyA(targetprod, "banana");
7640     context = 0xdeadbeef;
7641     lstrcpyA(targetsid, "kiwi");
7642     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7643                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7644                            &context, targetsid, NULL);
7645     ok(r == ERROR_INVALID_PARAMETER,
7646        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7647     ok(!lstrcmpA(patchcode, "apple"),
7648        "Expected patchcode to be unchanged, got %s\n", patchcode);
7649     ok(!lstrcmpA(targetprod, "banana"),
7650        "Expected targetprod to be unchanged, got %s\n", targetprod);
7651     ok(context == 0xdeadbeef,
7652        "Expected context to be unchanged, got %d\n", context);
7653     ok(!lstrcmpA(targetsid, "kiwi"),
7654        "Expected targetsid to be unchanged, got %s\n", targetsid);
7655
7656     /* MSIINSTALLCONTEXT_USERMANAGED */
7657
7658     /* MSIPATCHSTATE_APPLIED */
7659
7660     lstrcpyA(patchcode, "apple");
7661     lstrcpyA(targetprod, "banana");
7662     context = 0xdeadbeef;
7663     lstrcpyA(targetsid, "kiwi");
7664     size = MAX_PATH;
7665     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7666                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7667                            &context, targetsid, &size);
7668     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7669     ok(!lstrcmpA(patchcode, "apple"),
7670        "Expected patchcode to be unchanged, got %s\n", patchcode);
7671     ok(!lstrcmpA(targetprod, "banana"),
7672        "Expected targetprod to be unchanged, got %s\n", targetprod);
7673     ok(context == 0xdeadbeef,
7674        "Expected context to be unchanged, got %d\n", context);
7675     ok(!lstrcmpA(targetsid, "kiwi"),
7676        "Expected targetsid to be unchanged, got %s\n", targetsid);
7677     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7678
7679     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7680     lstrcatA(keypath, usersid);
7681     lstrcatA(keypath, "\\Installer\\Products\\");
7682     lstrcatA(keypath, prod_squashed);
7683
7684     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7686
7687     /* managed product key exists */
7688     lstrcpyA(patchcode, "apple");
7689     lstrcpyA(targetprod, "banana");
7690     context = 0xdeadbeef;
7691     lstrcpyA(targetsid, "kiwi");
7692     size = MAX_PATH;
7693     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7694                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7695                            &context, targetsid, &size);
7696     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7697     ok(!lstrcmpA(patchcode, "apple"),
7698        "Expected patchcode to be unchanged, got %s\n", patchcode);
7699     ok(!lstrcmpA(targetprod, "banana"),
7700        "Expected targetprod to be unchanged, got %s\n", targetprod);
7701     ok(context == 0xdeadbeef,
7702        "Expected context to be unchanged, got %d\n", context);
7703     ok(!lstrcmpA(targetsid, "kiwi"),
7704        "Expected targetsid to be unchanged, got %s\n", targetsid);
7705     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7706
7707     res = RegCreateKeyA(prodkey, "Patches", &patches);
7708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7709
7710     /* patches key exists */
7711     lstrcpyA(patchcode, "apple");
7712     lstrcpyA(targetprod, "banana");
7713     context = 0xdeadbeef;
7714     lstrcpyA(targetsid, "kiwi");
7715     size = MAX_PATH;
7716     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7717                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7718                            &context, targetsid, &size);
7719     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7720     ok(!lstrcmpA(patchcode, "apple"),
7721        "Expected patchcode to be unchanged, got %s\n", patchcode);
7722     ok(!lstrcmpA(targetprod, "banana"),
7723        "Expected targetprod to be unchanged, got %s\n", targetprod);
7724     ok(context == 0xdeadbeef,
7725        "Expected context to be unchanged, got %d\n", context);
7726     ok(!lstrcmpA(targetsid, "kiwi"),
7727        "Expected targetsid to be unchanged, got %s\n", targetsid);
7728     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7729
7730     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7731                          (const BYTE *)patch_squashed,
7732                          lstrlenA(patch_squashed) + 1);
7733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7734
7735     /* Patches value exists, is not REG_MULTI_SZ */
7736     lstrcpyA(patchcode, "apple");
7737     lstrcpyA(targetprod, "banana");
7738     context = 0xdeadbeef;
7739     lstrcpyA(targetsid, "kiwi");
7740     size = MAX_PATH;
7741     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7742                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7743                            &context, targetsid, &size);
7744     ok(r == ERROR_BAD_CONFIGURATION,
7745        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7746     ok(!lstrcmpA(patchcode, "apple"),
7747        "Expected patchcode to be unchanged, got %s\n", patchcode);
7748     ok(!lstrcmpA(targetprod, "banana"),
7749        "Expected targetprod to be unchanged, got %s\n", targetprod);
7750     ok(context == 0xdeadbeef,
7751        "Expected context to be unchanged, got %d\n", context);
7752     ok(!lstrcmpA(targetsid, "kiwi"),
7753        "Expected targetsid to be unchanged, got %s\n", targetsid);
7754     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7755
7756     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7757                          (const BYTE *)"a\0b\0c\0\0", 7);
7758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7759
7760     /* Patches value exists, is not a squashed guid */
7761     lstrcpyA(patchcode, "apple");
7762     lstrcpyA(targetprod, "banana");
7763     context = 0xdeadbeef;
7764     lstrcpyA(targetsid, "kiwi");
7765     size = MAX_PATH;
7766     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
7767                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7768                            &context, targetsid, &size);
7769     ok(r == ERROR_BAD_CONFIGURATION,
7770        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7771     ok(!lstrcmpA(patchcode, "apple"),
7772        "Expected patchcode to be unchanged, got %s\n", patchcode);
7773     ok(!lstrcmpA(targetprod, "banana"),
7774        "Expected targetprod to be unchanged, got %s\n", targetprod);
7775     ok(context == 0xdeadbeef,
7776        "Expected context to be unchanged, got %d\n", context);
7777     ok(!lstrcmpA(targetsid, "kiwi"),
7778        "Expected targetsid to be unchanged, got %s\n", targetsid);
7779     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7780
7781     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7782                          (const BYTE *)patch_squashed,
7783                          lstrlenA(patch_squashed) + 1);
7784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7785
7786     /* Patches value exists */
7787     lstrcpyA(patchcode, "apple");
7788     lstrcpyA(targetprod, "banana");
7789     context = 0xdeadbeef;
7790     lstrcpyA(targetsid, "kiwi");
7791     size = MAX_PATH;
7792     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7793                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7794                            &context, targetsid, &size);
7795     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7796     ok(!lstrcmpA(patchcode, "apple"),
7797        "Expected patchcode to be unchanged, got %s\n", patchcode);
7798     ok(!lstrcmpA(targetprod, "banana"),
7799        "Expected targetprod to be unchanged, got %s\n", targetprod);
7800     ok(context == 0xdeadbeef,
7801        "Expected context to be unchanged, got %d\n", context);
7802     ok(!lstrcmpA(targetsid, "kiwi"),
7803        "Expected targetsid to be unchanged, got %s\n", targetsid);
7804     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7805
7806     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7807                          (const BYTE *)"whatever", 9);
7808     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7809
7810     /* patch squashed value exists */
7811     lstrcpyA(patchcode, "apple");
7812     lstrcpyA(targetprod, "banana");
7813     context = 0xdeadbeef;
7814     lstrcpyA(targetsid, "kiwi");
7815     size = MAX_PATH;
7816     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7817                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7818                            &context, targetsid, &size);
7819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7820     ok(!lstrcmpA(patchcode, patch),
7821        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7822     ok(!lstrcmpA(targetprod, prodcode),
7823        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7824     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7825        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7826     ok(!lstrcmpA(targetsid, usersid),
7827        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7828     ok(size == lstrlenA(usersid),
7829        "Expected %d, got %d\n", lstrlenA(usersid), size);
7830
7831     /* increase the index */
7832     lstrcpyA(patchcode, "apple");
7833     lstrcpyA(targetprod, "banana");
7834     context = 0xdeadbeef;
7835     lstrcpyA(targetsid, "kiwi");
7836     size = MAX_PATH;
7837     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7838                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7839                            &context, targetsid, &size);
7840     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7841     ok(!lstrcmpA(patchcode, "apple"),
7842        "Expected patchcode to be unchanged, got %s\n", patchcode);
7843     ok(!lstrcmpA(targetprod, "banana"),
7844        "Expected targetprod to be unchanged, got %s\n", targetprod);
7845     ok(context == 0xdeadbeef,
7846        "Expected context to be unchanged, got %d\n", context);
7847     ok(!lstrcmpA(targetsid, "kiwi"),
7848        "Expected targetsid to be unchanged, got %s\n", targetsid);
7849     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7850
7851     /* increase again */
7852     lstrcpyA(patchcode, "apple");
7853     lstrcpyA(targetprod, "banana");
7854     context = 0xdeadbeef;
7855     lstrcpyA(targetsid, "kiwi");
7856     size = MAX_PATH;
7857     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7858                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7859                            &context, targetsid, &size);
7860     ok(r == ERROR_INVALID_PARAMETER,
7861        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7862     ok(!lstrcmpA(patchcode, "apple"),
7863        "Expected patchcode to be unchanged, got %s\n", patchcode);
7864     ok(!lstrcmpA(targetprod, "banana"),
7865        "Expected targetprod to be unchanged, got %s\n", targetprod);
7866     ok(context == 0xdeadbeef,
7867        "Expected context to be unchanged, got %d\n", context);
7868     ok(!lstrcmpA(targetsid, "kiwi"),
7869        "Expected targetsid to be unchanged, got %s\n", targetsid);
7870     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7871
7872     /* szPatchCode is NULL */
7873     lstrcpyA(targetprod, "banana");
7874     context = 0xdeadbeef;
7875     lstrcpyA(targetsid, "kiwi");
7876     size = MAX_PATH;
7877     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7878                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7879                            &context, targetsid, &size);
7880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7881     ok(!lstrcmpA(targetprod, prodcode),
7882        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7883     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7884        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7885     ok(!lstrcmpA(targetsid, usersid),
7886        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7887     ok(size == lstrlenA(usersid),
7888        "Expected %d, got %d\n", lstrlenA(usersid), size);
7889
7890     /* szTargetProductCode is NULL */
7891     lstrcpyA(patchcode, "apple");
7892     context = 0xdeadbeef;
7893     lstrcpyA(targetsid, "kiwi");
7894     size = MAX_PATH;
7895     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7896                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7897                            &context, targetsid, &size);
7898     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7899     ok(!lstrcmpA(patchcode, patch),
7900        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7901     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7902        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7903     ok(!lstrcmpA(targetsid, usersid),
7904        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7905     ok(size == lstrlenA(usersid),
7906        "Expected %d, got %d\n", lstrlenA(usersid), size);
7907
7908     /* pdwTargetProductContext is NULL */
7909     lstrcpyA(patchcode, "apple");
7910     lstrcpyA(targetprod, "banana");
7911     lstrcpyA(targetsid, "kiwi");
7912     size = MAX_PATH;
7913     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7914                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7915                            NULL, targetsid, &size);
7916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7917     ok(!lstrcmpA(patchcode, patch),
7918        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7919     ok(!lstrcmpA(targetprod, prodcode),
7920        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7921     ok(!lstrcmpA(targetsid, usersid),
7922        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7923     ok(size == lstrlenA(usersid),
7924        "Expected %d, got %d\n", lstrlenA(usersid), size);
7925
7926     /* szTargetUserSid is NULL */
7927     lstrcpyA(patchcode, "apple");
7928     lstrcpyA(targetprod, "banana");
7929     context = 0xdeadbeef;
7930     size = MAX_PATH;
7931     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7932                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7933                            &context, NULL, &size);
7934     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7935     ok(!lstrcmpA(patchcode, patch),
7936        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7937     ok(!lstrcmpA(targetprod, prodcode),
7938        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7939     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7940        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7941     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7942        "Got %d\n", size);
7943
7944     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7945     lstrcpyA(patchcode, "apple");
7946     lstrcpyA(targetprod, "banana");
7947     context = 0xdeadbeef;
7948     lstrcpyA(targetsid, "kiwi");
7949     size = lstrlenA(usersid);
7950     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7951                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7952                            &context, targetsid, &size);
7953     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7954     ok(!lstrcmpA(patchcode, patch),
7955        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7956     ok(!lstrcmpA(targetprod, prodcode),
7957        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7958     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7959        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7960     ok(!strncmp(targetsid, usersid, lstrlenA(usersid) - 1),
7961        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7962     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7963        "Got %d\n", size);
7964
7965     /* pcchTargetUserSid has enough room for NULL terminator */
7966     lstrcpyA(patchcode, "apple");
7967     lstrcpyA(targetprod, "banana");
7968     context = 0xdeadbeef;
7969     lstrcpyA(targetsid, "kiwi");
7970     size = lstrlenA(usersid) + 1;
7971     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7972                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7973                            &context, targetsid, &size);
7974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7975     ok(!lstrcmpA(patchcode, patch),
7976        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7977     ok(!lstrcmpA(targetprod, prodcode),
7978        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7979     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7980        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7981     ok(!lstrcmpA(targetsid, usersid),
7982        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7983     ok(size == lstrlenA(usersid),
7984        "Expected %d, got %d\n", lstrlenA(usersid), size);
7985
7986     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7987     lstrcpyA(patchcode, "apple");
7988     lstrcpyA(targetprod, "banana");
7989     context = 0xdeadbeef;
7990     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7991                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7992                            &context, NULL, NULL);
7993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7994     ok(!lstrcmpA(patchcode, patch),
7995        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7996     ok(!lstrcmpA(targetprod, prodcode),
7997        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7998     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7999        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8000
8001     /* MSIPATCHSTATE_SUPERSEDED */
8002
8003     lstrcpyA(patchcode, "apple");
8004     lstrcpyA(targetprod, "banana");
8005     context = 0xdeadbeef;
8006     lstrcpyA(targetsid, "kiwi");
8007     size = MAX_PATH;
8008     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8009                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8010                            &context, targetsid, &size);
8011     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8012     ok(!lstrcmpA(patchcode, "apple"),
8013        "Expected patchcode to be unchanged, got %s\n", patchcode);
8014     ok(!lstrcmpA(targetprod, "banana"),
8015        "Expected targetprod to be unchanged, got %s\n", targetprod);
8016     ok(context == 0xdeadbeef,
8017        "Expected context to be unchanged, got %d\n", context);
8018     ok(!lstrcmpA(targetsid, "kiwi"),
8019        "Expected targetsid to be unchanged, got %s\n", targetsid);
8020     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8021
8022     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8023     lstrcatA(keypath, usersid);
8024     lstrcatA(keypath, "\\Products\\");
8025     lstrcatA(keypath, prod_squashed);
8026
8027     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8029
8030     /* UserData product key exists */
8031     lstrcpyA(patchcode, "apple");
8032     lstrcpyA(targetprod, "banana");
8033     context = 0xdeadbeef;
8034     lstrcpyA(targetsid, "kiwi");
8035     size = MAX_PATH;
8036     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8037                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8038                            &context, targetsid, &size);
8039     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8040     ok(!lstrcmpA(patchcode, "apple"),
8041        "Expected patchcode to be unchanged, got %s\n", patchcode);
8042     ok(!lstrcmpA(targetprod, "banana"),
8043        "Expected targetprod to be unchanged, got %s\n", targetprod);
8044     ok(context == 0xdeadbeef,
8045        "Expected context to be unchanged, got %d\n", context);
8046     ok(!lstrcmpA(targetsid, "kiwi"),
8047        "Expected targetsid to be unchanged, got %s\n", targetsid);
8048     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8049
8050     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8051     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8052
8053     /* UserData patches key exists */
8054     lstrcpyA(patchcode, "apple");
8055     lstrcpyA(targetprod, "banana");
8056     context = 0xdeadbeef;
8057     lstrcpyA(targetsid, "kiwi");
8058     size = MAX_PATH;
8059     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8060                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8061                            &context, targetsid, &size);
8062     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8063     ok(!lstrcmpA(patchcode, "apple"),
8064        "Expected patchcode to be unchanged, got %s\n", patchcode);
8065     ok(!lstrcmpA(targetprod, "banana"),
8066        "Expected targetprod to be unchanged, got %s\n", targetprod);
8067     ok(context == 0xdeadbeef,
8068        "Expected context to be unchanged, got %d\n", context);
8069     ok(!lstrcmpA(targetsid, "kiwi"),
8070        "Expected targetsid to be unchanged, got %s\n", targetsid);
8071     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8072
8073     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8075
8076     /* specific UserData patch key exists */
8077     lstrcpyA(patchcode, "apple");
8078     lstrcpyA(targetprod, "banana");
8079     context = 0xdeadbeef;
8080     lstrcpyA(targetsid, "kiwi");
8081     size = MAX_PATH;
8082     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8083                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8084                            &context, targetsid, &size);
8085     ok(r == ERROR_BAD_CONFIGURATION,
8086        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8087     ok(!lstrcmpA(patchcode, "apple"),
8088        "Expected patchcode to be unchanged, got %s\n", patchcode);
8089     ok(!lstrcmpA(targetprod, "banana"),
8090        "Expected targetprod to be unchanged, got %s\n", targetprod);
8091     ok(context == 0xdeadbeef,
8092        "Expected context to be unchanged, got %d\n", context);
8093     ok(!lstrcmpA(targetsid, "kiwi"),
8094        "Expected targetsid to be unchanged, got %s\n", targetsid);
8095     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8096
8097     data = MSIPATCHSTATE_SUPERSEDED;
8098     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8099                          (const BYTE *)&data, sizeof(DWORD));
8100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8101
8102     /* State value exists */
8103     lstrcpyA(patchcode, "apple");
8104     lstrcpyA(targetprod, "banana");
8105     context = 0xdeadbeef;
8106     lstrcpyA(targetsid, "kiwi");
8107     size = MAX_PATH;
8108     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8109                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8110                            &context, targetsid, &size);
8111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8112     ok(!lstrcmpA(patchcode, patch),
8113        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8114     ok(!lstrcmpA(targetprod, prodcode),
8115        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8116     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8117        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8118     ok(!lstrcmpA(targetsid, usersid),
8119        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8120     ok(size == lstrlenA(usersid),
8121        "Expected %d, got %d\n", lstrlenA(usersid), size);
8122
8123     /* MSIPATCHSTATE_OBSOLETED */
8124
8125     lstrcpyA(patchcode, "apple");
8126     lstrcpyA(targetprod, "banana");
8127     context = 0xdeadbeef;
8128     lstrcpyA(targetsid, "kiwi");
8129     size = MAX_PATH;
8130     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8131                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8132                            &context, targetsid, &size);
8133     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8134     ok(!lstrcmpA(patchcode, "apple"),
8135        "Expected patchcode to be unchanged, got %s\n", patchcode);
8136     ok(!lstrcmpA(targetprod, "banana"),
8137        "Expected targetprod to be unchanged, got %s\n", targetprod);
8138     ok(context == 0xdeadbeef,
8139        "Expected context to be unchanged, got %d\n", context);
8140     ok(!lstrcmpA(targetsid, "kiwi"),
8141        "Expected targetsid to be unchanged, got %s\n", targetsid);
8142     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8143
8144     data = MSIPATCHSTATE_OBSOLETED;
8145     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8146                          (const BYTE *)&data, sizeof(DWORD));
8147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8148
8149     /* State value is obsoleted */
8150     lstrcpyA(patchcode, "apple");
8151     lstrcpyA(targetprod, "banana");
8152     context = 0xdeadbeef;
8153     lstrcpyA(targetsid, "kiwi");
8154     size = MAX_PATH;
8155     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8156                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8157                            &context, targetsid, &size);
8158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8159     ok(!lstrcmpA(patchcode, patch),
8160        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8161     ok(!lstrcmpA(targetprod, prodcode),
8162        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8163     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8164        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8165     ok(!lstrcmpA(targetsid, usersid),
8166        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8167     ok(size == lstrlenA(usersid),
8168        "Expected %d, got %d\n", lstrlenA(usersid), size);
8169
8170     /* MSIPATCHSTATE_REGISTERED */
8171     /* FIXME */
8172
8173     /* MSIPATCHSTATE_ALL */
8174
8175     /* 1st */
8176     lstrcpyA(patchcode, "apple");
8177     lstrcpyA(targetprod, "banana");
8178     context = 0xdeadbeef;
8179     lstrcpyA(targetsid, "kiwi");
8180     size = MAX_PATH;
8181     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8182                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8183                            &context, targetsid, &size);
8184     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8185     ok(!lstrcmpA(patchcode, patch),
8186        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8187     ok(!lstrcmpA(targetprod, prodcode),
8188        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8189     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8190        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8191     ok(!lstrcmpA(targetsid, usersid),
8192        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8193     ok(size == lstrlenA(usersid),
8194        "Expected %d, got %d\n", lstrlenA(usersid), size);
8195
8196     /* same patch in multiple places, only one is enumerated */
8197     lstrcpyA(patchcode, "apple");
8198     lstrcpyA(targetprod, "banana");
8199     context = 0xdeadbeef;
8200     lstrcpyA(targetsid, "kiwi");
8201     size = MAX_PATH;
8202     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8203                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8204                            &context, targetsid, &size);
8205     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8206     ok(!lstrcmpA(patchcode, "apple"),
8207        "Expected patchcode to be unchanged, got %s\n", patchcode);
8208     ok(!lstrcmpA(targetprod, "banana"),
8209        "Expected targetprod to be unchanged, got %s\n", targetprod);
8210     ok(context == 0xdeadbeef,
8211        "Expected context to be unchanged, got %d\n", context);
8212     ok(!lstrcmpA(targetsid, "kiwi"),
8213        "Expected targetsid to be unchanged, got %s\n", targetsid);
8214     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8215
8216     RegDeleteValueA(hpatch, "State");
8217     RegDeleteKeyA(hpatch, "");
8218     RegCloseKey(hpatch);
8219     RegDeleteKeyA(udpatch, "");
8220     RegCloseKey(udpatch);
8221     RegDeleteKeyA(udprod, "");
8222     RegCloseKey(udprod);
8223     RegDeleteValueA(patches, "Patches");
8224     RegDeleteKeyA(patches, "");
8225     RegCloseKey(patches);
8226     RegDeleteKeyA(prodkey, "");
8227     RegCloseKey(prodkey);
8228
8229     /* MSIINSTALLCONTEXT_USERUNMANAGED */
8230
8231     /* MSIPATCHSTATE_APPLIED */
8232
8233     lstrcpyA(patchcode, "apple");
8234     lstrcpyA(targetprod, "banana");
8235     context = 0xdeadbeef;
8236     lstrcpyA(targetsid, "kiwi");
8237     size = MAX_PATH;
8238     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8239                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8240                            &context, targetsid, &size);
8241     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8242     ok(!lstrcmpA(patchcode, "apple"),
8243        "Expected patchcode to be unchanged, got %s\n", patchcode);
8244     ok(!lstrcmpA(targetprod, "banana"),
8245        "Expected targetprod to be unchanged, got %s\n", targetprod);
8246     ok(context == 0xdeadbeef,
8247        "Expected context to be unchanged, got %d\n", context);
8248     ok(!lstrcmpA(targetsid, "kiwi"),
8249        "Expected targetsid to be unchanged, got %s\n", targetsid);
8250     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8251
8252     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8253     lstrcatA(keypath, prod_squashed);
8254
8255     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8257
8258     /* current user product key exists */
8259     lstrcpyA(patchcode, "apple");
8260     lstrcpyA(targetprod, "banana");
8261     context = 0xdeadbeef;
8262     lstrcpyA(targetsid, "kiwi");
8263     size = MAX_PATH;
8264     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8265                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8266                            &context, targetsid, &size);
8267     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8268     ok(!lstrcmpA(patchcode, "apple"),
8269        "Expected patchcode to be unchanged, got %s\n", patchcode);
8270     ok(!lstrcmpA(targetprod, "banana"),
8271        "Expected targetprod to be unchanged, got %s\n", targetprod);
8272     ok(context == 0xdeadbeef,
8273        "Expected context to be unchanged, got %d\n", context);
8274     ok(!lstrcmpA(targetsid, "kiwi"),
8275        "Expected targetsid to be unchanged, got %s\n", targetsid);
8276     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8277
8278     res = RegCreateKeyA(prodkey, "Patches", &patches);
8279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8280
8281     /* Patches key exists */
8282     lstrcpyA(patchcode, "apple");
8283     lstrcpyA(targetprod, "banana");
8284     context = 0xdeadbeef;
8285     lstrcpyA(targetsid, "kiwi");
8286     size = MAX_PATH;
8287     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8288                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8289                            &context, targetsid, &size);
8290     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8291     ok(!lstrcmpA(patchcode, "apple"),
8292        "Expected patchcode to be unchanged, got %s\n", patchcode);
8293     ok(!lstrcmpA(targetprod, "banana"),
8294        "Expected targetprod to be unchanged, got %s\n", targetprod);
8295     ok(context == 0xdeadbeef,
8296        "Expected context to be unchanged, got %d\n", context);
8297     ok(!lstrcmpA(targetsid, "kiwi"),
8298        "Expected targetsid to be unchanged, got %s\n", targetsid);
8299     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8300
8301     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8302                          (const BYTE *)patch_squashed,
8303                          lstrlenA(patch_squashed) + 1);
8304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8305
8306     /* Patches value exists, is not REG_MULTI_SZ */
8307     lstrcpyA(patchcode, "apple");
8308     lstrcpyA(targetprod, "banana");
8309     context = 0xdeadbeef;
8310     lstrcpyA(targetsid, "kiwi");
8311     size = MAX_PATH;
8312     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8313                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8314                            &context, targetsid, &size);
8315     ok(r == ERROR_BAD_CONFIGURATION,
8316        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8317     ok(!lstrcmpA(patchcode, "apple"),
8318        "Expected patchcode to be unchanged, got %s\n", patchcode);
8319     ok(!lstrcmpA(targetprod, "banana"),
8320        "Expected targetprod to be unchanged, got %s\n", targetprod);
8321     ok(context == 0xdeadbeef,
8322        "Expected context to be unchanged, got %d\n", context);
8323     ok(!lstrcmpA(targetsid, "kiwi"),
8324        "Expected targetsid to be unchanged, got %s\n", targetsid);
8325     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8326
8327     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8328                          (const BYTE *)"a\0b\0c\0\0", 7);
8329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8330
8331     /* Patches value exists, is not a squashed guid */
8332     lstrcpyA(patchcode, "apple");
8333     lstrcpyA(targetprod, "banana");
8334     context = 0xdeadbeef;
8335     lstrcpyA(targetsid, "kiwi");
8336     size = MAX_PATH;
8337     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8338                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8339                            &context, targetsid, &size);
8340     ok(r == ERROR_BAD_CONFIGURATION,
8341        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8342     ok(!lstrcmpA(patchcode, "apple"),
8343        "Expected patchcode to be unchanged, got %s\n", patchcode);
8344     ok(!lstrcmpA(targetprod, "banana"),
8345        "Expected targetprod to be unchanged, got %s\n", targetprod);
8346     ok(context == 0xdeadbeef,
8347        "Expected context to be unchanged, got %d\n", context);
8348     ok(!lstrcmpA(targetsid, "kiwi"),
8349        "Expected targetsid to be unchanged, got %s\n", targetsid);
8350     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8351
8352     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8353                          (const BYTE *)patch_squashed,
8354                          lstrlenA(patch_squashed) + 1);
8355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8356
8357     /* Patches value exists */
8358     lstrcpyA(patchcode, "apple");
8359     lstrcpyA(targetprod, "banana");
8360     context = 0xdeadbeef;
8361     lstrcpyA(targetsid, "kiwi");
8362     size = MAX_PATH;
8363     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8364                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8365                            &context, targetsid, &size);
8366     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8367     ok(!lstrcmpA(patchcode, "apple"),
8368        "Expected patchcode to be unchanged, got %s\n", patchcode);
8369     ok(!lstrcmpA(targetprod, "banana"),
8370        "Expected targetprod to be unchanged, got %s\n", targetprod);
8371     ok(context == 0xdeadbeef,
8372        "Expected context to be unchanged, got %d\n", context);
8373     ok(!lstrcmpA(targetsid, "kiwi"),
8374        "Expected targetsid to be unchanged, got %s\n", targetsid);
8375     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8376
8377     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8378                          (const BYTE *)"whatever", 9);
8379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8380
8381     /* patch code value exists */
8382     lstrcpyA(patchcode, "apple");
8383     lstrcpyA(targetprod, "banana");
8384     context = 0xdeadbeef;
8385     lstrcpyA(targetsid, "kiwi");
8386     size = MAX_PATH;
8387     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8388                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8389                            &context, targetsid, &size);
8390     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8391     ok(!lstrcmpA(patchcode, "apple"),
8392        "Expected patchcode to be unchanged, got %s\n", patchcode);
8393     ok(!lstrcmpA(targetprod, "banana"),
8394        "Expected targetprod to be unchanged, got %s\n", targetprod);
8395     ok(context == 0xdeadbeef,
8396        "Expected context to be unchanged, got %d\n", context);
8397     ok(!lstrcmpA(targetsid, "kiwi"),
8398        "Expected targetsid to be unchanged, got %s\n", targetsid);
8399     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8400
8401     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8402     lstrcatA(keypath, usersid);
8403     lstrcatA(keypath, "\\Patches\\");
8404     lstrcatA(keypath, patch_squashed);
8405
8406     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8408
8409     /* userdata patch key exists */
8410     lstrcpyA(patchcode, "apple");
8411     lstrcpyA(targetprod, "banana");
8412     context = 0xdeadbeef;
8413     lstrcpyA(targetsid, "kiwi");
8414     size = MAX_PATH;
8415     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8416                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8417                            &context, targetsid, &size);
8418     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8419     ok(!lstrcmpA(patchcode, patch),
8420        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8421     ok(!lstrcmpA(targetprod, prodcode),
8422        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8423     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8424        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8425     ok(!lstrcmpA(targetsid, usersid),
8426        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8427     ok(size == lstrlenA(usersid),
8428        "Expected %d, got %d\n", lstrlenA(usersid), size);
8429
8430     /* MSIPATCHSTATE_SUPERSEDED */
8431
8432     lstrcpyA(patchcode, "apple");
8433     lstrcpyA(targetprod, "banana");
8434     context = 0xdeadbeef;
8435     lstrcpyA(targetsid, "kiwi");
8436     size = MAX_PATH;
8437     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8438                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8439                            &context, targetsid, &size);
8440     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8441     ok(!lstrcmpA(patchcode, "apple"),
8442        "Expected patchcode to be unchanged, got %s\n", patchcode);
8443     ok(!lstrcmpA(targetprod, "banana"),
8444        "Expected targetprod to be unchanged, got %s\n", targetprod);
8445     ok(context == 0xdeadbeef,
8446        "Expected context to be unchanged, got %d\n", context);
8447     ok(!lstrcmpA(targetsid, "kiwi"),
8448        "Expected targetsid to be unchanged, got %s\n", targetsid);
8449     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8450
8451     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8452     lstrcatA(keypath, usersid);
8453     lstrcatA(keypath, "\\Products\\");
8454     lstrcatA(keypath, prod_squashed);
8455
8456     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8458
8459     /* UserData product key exists */
8460     lstrcpyA(patchcode, "apple");
8461     lstrcpyA(targetprod, "banana");
8462     context = 0xdeadbeef;
8463     lstrcpyA(targetsid, "kiwi");
8464     size = MAX_PATH;
8465     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8466                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8467                            &context, targetsid, &size);
8468     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8469     ok(!lstrcmpA(patchcode, "apple"),
8470        "Expected patchcode to be unchanged, got %s\n", patchcode);
8471     ok(!lstrcmpA(targetprod, "banana"),
8472        "Expected targetprod to be unchanged, got %s\n", targetprod);
8473     ok(context == 0xdeadbeef,
8474        "Expected context to be unchanged, got %d\n", context);
8475     ok(!lstrcmpA(targetsid, "kiwi"),
8476        "Expected targetsid to be unchanged, got %s\n", targetsid);
8477     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8478
8479     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8481
8482     /* UserData patches key exists */
8483     lstrcpyA(patchcode, "apple");
8484     lstrcpyA(targetprod, "banana");
8485     context = 0xdeadbeef;
8486     lstrcpyA(targetsid, "kiwi");
8487     size = MAX_PATH;
8488     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8489                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8490                            &context, targetsid, &size);
8491     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8492     ok(!lstrcmpA(patchcode, "apple"),
8493        "Expected patchcode to be unchanged, got %s\n", patchcode);
8494     ok(!lstrcmpA(targetprod, "banana"),
8495        "Expected targetprod to be unchanged, got %s\n", targetprod);
8496     ok(context == 0xdeadbeef,
8497        "Expected context to be unchanged, got %d\n", context);
8498     ok(!lstrcmpA(targetsid, "kiwi"),
8499        "Expected targetsid to be unchanged, got %s\n", targetsid);
8500     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8501
8502     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8504
8505     /* specific UserData patch key exists */
8506     lstrcpyA(patchcode, "apple");
8507     lstrcpyA(targetprod, "banana");
8508     context = 0xdeadbeef;
8509     lstrcpyA(targetsid, "kiwi");
8510     size = MAX_PATH;
8511     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8512                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8513                            &context, targetsid, &size);
8514     ok(r == ERROR_BAD_CONFIGURATION,
8515        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8516     ok(!lstrcmpA(patchcode, "apple"),
8517        "Expected patchcode to be unchanged, got %s\n", patchcode);
8518     ok(!lstrcmpA(targetprod, "banana"),
8519        "Expected targetprod to be unchanged, got %s\n", targetprod);
8520     ok(context == 0xdeadbeef,
8521        "Expected context to be unchanged, got %d\n", context);
8522     ok(!lstrcmpA(targetsid, "kiwi"),
8523        "Expected targetsid to be unchanged, got %s\n", targetsid);
8524     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8525
8526     data = MSIPATCHSTATE_SUPERSEDED;
8527     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8528                          (const BYTE *)&data, sizeof(DWORD));
8529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8530
8531     /* State value exists */
8532     lstrcpyA(patchcode, "apple");
8533     lstrcpyA(targetprod, "banana");
8534     context = 0xdeadbeef;
8535     lstrcpyA(targetsid, "kiwi");
8536     size = MAX_PATH;
8537     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8538                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8539                            &context, targetsid, &size);
8540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8541     ok(!lstrcmpA(patchcode, patch),
8542        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8543     ok(!lstrcmpA(targetprod, prodcode),
8544        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8545     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8546        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8547     ok(!lstrcmpA(targetsid, usersid),
8548        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8549     ok(size == lstrlenA(usersid),
8550        "Expected %d, got %d\n", lstrlenA(usersid), size);
8551
8552     /* MSIPATCHSTATE_OBSOLETED */
8553
8554     lstrcpyA(patchcode, "apple");
8555     lstrcpyA(targetprod, "banana");
8556     context = 0xdeadbeef;
8557     lstrcpyA(targetsid, "kiwi");
8558     size = MAX_PATH;
8559     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8560                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8561                            &context, targetsid, &size);
8562     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8563     ok(!lstrcmpA(patchcode, "apple"),
8564        "Expected patchcode to be unchanged, got %s\n", patchcode);
8565     ok(!lstrcmpA(targetprod, "banana"),
8566        "Expected targetprod to be unchanged, got %s\n", targetprod);
8567     ok(context == 0xdeadbeef,
8568        "Expected context to be unchanged, got %d\n", context);
8569     ok(!lstrcmpA(targetsid, "kiwi"),
8570        "Expected targetsid to be unchanged, got %s\n", targetsid);
8571     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8572
8573     data = MSIPATCHSTATE_OBSOLETED;
8574     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8575                          (const BYTE *)&data, sizeof(DWORD));
8576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8577
8578     /* State value is obsoleted */
8579     lstrcpyA(patchcode, "apple");
8580     lstrcpyA(targetprod, "banana");
8581     context = 0xdeadbeef;
8582     lstrcpyA(targetsid, "kiwi");
8583     size = MAX_PATH;
8584     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8585                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8586                            &context, targetsid, &size);
8587     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8588     ok(!lstrcmpA(patchcode, patch),
8589        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8590     ok(!lstrcmpA(targetprod, prodcode),
8591        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8592     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8593        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8594     ok(!lstrcmpA(targetsid, usersid),
8595        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8596     ok(size == lstrlenA(usersid),
8597        "Expected %d, got %d\n", lstrlenA(usersid), size);
8598
8599     /* MSIPATCHSTATE_REGISTERED */
8600     /* FIXME */
8601
8602     /* MSIPATCHSTATE_ALL */
8603
8604     /* 1st */
8605     lstrcpyA(patchcode, "apple");
8606     lstrcpyA(targetprod, "banana");
8607     context = 0xdeadbeef;
8608     lstrcpyA(targetsid, "kiwi");
8609     size = MAX_PATH;
8610     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8611                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8612                            &context, targetsid, &size);
8613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8614     ok(!lstrcmpA(patchcode, patch),
8615        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8616     ok(!lstrcmpA(targetprod, prodcode),
8617        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8618     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8619        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8620     ok(!lstrcmpA(targetsid, usersid),
8621        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8622     ok(size == lstrlenA(usersid),
8623        "Expected %d, got %d\n", lstrlenA(usersid), size);
8624
8625     /* same patch in multiple places, only one is enumerated */
8626     lstrcpyA(patchcode, "apple");
8627     lstrcpyA(targetprod, "banana");
8628     context = 0xdeadbeef;
8629     lstrcpyA(targetsid, "kiwi");
8630     size = MAX_PATH;
8631     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8632                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8633                            &context, targetsid, &size);
8634     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8635     ok(!lstrcmpA(patchcode, "apple"),
8636        "Expected patchcode to be unchanged, got %s\n", patchcode);
8637     ok(!lstrcmpA(targetprod, "banana"),
8638        "Expected targetprod to be unchanged, got %s\n", targetprod);
8639     ok(context == 0xdeadbeef,
8640        "Expected context to be unchanged, got %d\n", context);
8641     ok(!lstrcmpA(targetsid, "kiwi"),
8642        "Expected targetsid to be unchanged, got %s\n", targetsid);
8643     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8644
8645     RegDeleteValueA(hpatch, "State");
8646     RegDeleteKeyA(hpatch, "");
8647     RegCloseKey(hpatch);
8648     RegDeleteKeyA(udpatch, "");
8649     RegCloseKey(udpatch);
8650     RegDeleteKeyA(userkey, "");
8651     RegCloseKey(userkey);
8652     RegDeleteValueA(patches, patch_squashed);
8653     RegDeleteValueA(patches, "Patches");
8654     RegDeleteKeyA(patches, "");
8655     RegCloseKey(patches);
8656     RegDeleteKeyA(prodkey, "");
8657     RegCloseKey(prodkey);
8658
8659     /* MSIINSTALLCONTEXT_MACHINE */
8660
8661     /* MSIPATCHSTATE_APPLIED */
8662
8663     lstrcpyA(patchcode, "apple");
8664     lstrcpyA(targetprod, "banana");
8665     context = 0xdeadbeef;
8666     lstrcpyA(targetsid, "kiwi");
8667     size = MAX_PATH;
8668     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8669                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8670                            &context, targetsid, &size);
8671     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8672     ok(!lstrcmpA(patchcode, "apple"),
8673        "Expected patchcode to be unchanged, got %s\n", patchcode);
8674     ok(!lstrcmpA(targetprod, "banana"),
8675        "Expected targetprod to be unchanged, got %s\n", targetprod);
8676     ok(context == 0xdeadbeef,
8677        "Expected context to be unchanged, got %d\n", context);
8678     ok(!lstrcmpA(targetsid, "kiwi"),
8679        "Expected targetsid to be unchanged, got %s\n", targetsid);
8680     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8681
8682     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8683     lstrcatA(keypath, prod_squashed);
8684
8685     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8687
8688     /* local product key exists */
8689     lstrcpyA(patchcode, "apple");
8690     lstrcpyA(targetprod, "banana");
8691     context = 0xdeadbeef;
8692     lstrcpyA(targetsid, "kiwi");
8693     size = MAX_PATH;
8694     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8695                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8696                            &context, targetsid, &size);
8697     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8698     ok(!lstrcmpA(patchcode, "apple"),
8699        "Expected patchcode to be unchanged, got %s\n", patchcode);
8700     ok(!lstrcmpA(targetprod, "banana"),
8701        "Expected targetprod to be unchanged, got %s\n", targetprod);
8702     ok(context == 0xdeadbeef,
8703        "Expected context to be unchanged, got %d\n", context);
8704     ok(!lstrcmpA(targetsid, "kiwi"),
8705        "Expected targetsid to be unchanged, got %s\n", targetsid);
8706     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8707
8708     res = RegCreateKeyA(prodkey, "Patches", &patches);
8709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8710
8711     /* Patches key exists */
8712     lstrcpyA(patchcode, "apple");
8713     lstrcpyA(targetprod, "banana");
8714     context = 0xdeadbeef;
8715     lstrcpyA(targetsid, "kiwi");
8716     size = MAX_PATH;
8717     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8718                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8719                            &context, targetsid, &size);
8720     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8721     ok(!lstrcmpA(patchcode, "apple"),
8722        "Expected patchcode to be unchanged, got %s\n", patchcode);
8723     ok(!lstrcmpA(targetprod, "banana"),
8724        "Expected targetprod to be unchanged, got %s\n", targetprod);
8725     ok(context == 0xdeadbeef,
8726        "Expected context to be unchanged, got %d\n", context);
8727     ok(!lstrcmpA(targetsid, "kiwi"),
8728        "Expected targetsid to be unchanged, got %s\n", targetsid);
8729     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8730
8731     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8732                          (const BYTE *)patch_squashed,
8733                          lstrlenA(patch_squashed) + 1);
8734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8735
8736     /* Patches value exists, is not REG_MULTI_SZ */
8737     lstrcpyA(patchcode, "apple");
8738     lstrcpyA(targetprod, "banana");
8739     context = 0xdeadbeef;
8740     lstrcpyA(targetsid, "kiwi");
8741     size = MAX_PATH;
8742     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8743                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8744                            &context, targetsid, &size);
8745     ok(r == ERROR_BAD_CONFIGURATION,
8746        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8747     ok(!lstrcmpA(patchcode, "apple"),
8748        "Expected patchcode to be unchanged, got %s\n", patchcode);
8749     ok(!lstrcmpA(targetprod, "banana"),
8750        "Expected targetprod to be unchanged, got %s\n", targetprod);
8751     ok(context == 0xdeadbeef,
8752        "Expected context to be unchanged, got %d\n", context);
8753     ok(!lstrcmpA(targetsid, "kiwi"),
8754        "Expected targetsid to be unchanged, got %s\n", targetsid);
8755     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8756
8757     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8758                          (const BYTE *)"a\0b\0c\0\0", 7);
8759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8760
8761     /* Patches value exists, is not a squashed guid */
8762     lstrcpyA(patchcode, "apple");
8763     lstrcpyA(targetprod, "banana");
8764     context = 0xdeadbeef;
8765     lstrcpyA(targetsid, "kiwi");
8766     size = MAX_PATH;
8767     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8768                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8769                            &context, targetsid, &size);
8770     ok(r == ERROR_BAD_CONFIGURATION,
8771        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8772     ok(!lstrcmpA(patchcode, "apple"),
8773        "Expected patchcode to be unchanged, got %s\n", patchcode);
8774     ok(!lstrcmpA(targetprod, "banana"),
8775        "Expected targetprod to be unchanged, got %s\n", targetprod);
8776     ok(context == 0xdeadbeef,
8777        "Expected context to be unchanged, got %d\n", context);
8778     ok(!lstrcmpA(targetsid, "kiwi"),
8779        "Expected targetsid to be unchanged, got %s\n", targetsid);
8780     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8781
8782     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8783                          (const BYTE *)patch_squashed,
8784                          lstrlenA(patch_squashed) + 1);
8785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8786
8787     /* Patches value exists */
8788     lstrcpyA(patchcode, "apple");
8789     lstrcpyA(targetprod, "banana");
8790     context = 0xdeadbeef;
8791     lstrcpyA(targetsid, "kiwi");
8792     size = MAX_PATH;
8793     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8794                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8795                            &context, targetsid, &size);
8796     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8797     ok(!lstrcmpA(patchcode, "apple"),
8798        "Expected patchcode to be unchanged, got %s\n", patchcode);
8799     ok(!lstrcmpA(targetprod, "banana"),
8800        "Expected targetprod to be unchanged, got %s\n", targetprod);
8801     ok(context == 0xdeadbeef,
8802        "Expected context to be unchanged, got %d\n", context);
8803     ok(!lstrcmpA(targetsid, "kiwi"),
8804        "Expected targetsid to be unchanged, got %s\n", targetsid);
8805     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8806
8807     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8808                          (const BYTE *)"whatever", 9);
8809     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8810
8811     /* patch code value exists */
8812     lstrcpyA(patchcode, "apple");
8813     lstrcpyA(targetprod, "banana");
8814     context = 0xdeadbeef;
8815     lstrcpyA(targetsid, "kiwi");
8816     size = MAX_PATH;
8817     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8818                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8819                            &context, targetsid, &size);
8820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8821     ok(!lstrcmpA(patchcode, patch),
8822        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8823     ok(!lstrcmpA(targetprod, prodcode),
8824        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8825     ok(context == MSIINSTALLCONTEXT_MACHINE,
8826        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8827     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8828     ok(size == 0, "Expected 0, got %d\n", size);
8829
8830     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8831     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8832     lstrcatA(keypath, prod_squashed);
8833
8834     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8835     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8836
8837     /* local UserData product key exists */
8838     lstrcpyA(patchcode, "apple");
8839     lstrcpyA(targetprod, "banana");
8840     context = 0xdeadbeef;
8841     lstrcpyA(targetsid, "kiwi");
8842     size = MAX_PATH;
8843     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8844                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8845                            &context, targetsid, &size);
8846     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8847     ok(!lstrcmpA(patchcode, patch),
8848        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8849     ok(!lstrcmpA(targetprod, prodcode),
8850        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8851     ok(context == MSIINSTALLCONTEXT_MACHINE,
8852        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8853     ok(!lstrcmpA(targetsid, ""),
8854        "Expected \"\", got \"%s\"\n", targetsid);
8855     ok(size == 0, "Expected 0, got %d\n", size);
8856
8857     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8858     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8859
8860     /* local UserData Patches key exists */
8861     lstrcpyA(patchcode, "apple");
8862     lstrcpyA(targetprod, "banana");
8863     context = 0xdeadbeef;
8864     lstrcpyA(targetsid, "kiwi");
8865     size = MAX_PATH;
8866     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8867                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8868                            &context, targetsid, &size);
8869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8870     ok(!lstrcmpA(patchcode, patch),
8871        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8872     ok(!lstrcmpA(targetprod, prodcode),
8873        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8874     ok(context == MSIINSTALLCONTEXT_MACHINE,
8875        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8876     ok(!lstrcmpA(targetsid, ""),
8877        "Expected \"\", got \"%s\"\n", targetsid);
8878     ok(size == 0, "Expected 0, got %d\n", size);
8879
8880     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8881     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8882
8883     /* local UserData Product patch key exists */
8884     lstrcpyA(patchcode, "apple");
8885     lstrcpyA(targetprod, "banana");
8886     context = 0xdeadbeef;
8887     lstrcpyA(targetsid, "kiwi");
8888     size = MAX_PATH;
8889     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8890                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8891                            &context, targetsid, &size);
8892     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8893     ok(!lstrcmpA(patchcode, "apple"),
8894        "Expected patchcode to be unchanged, got %s\n", patchcode);
8895     ok(!lstrcmpA(targetprod, "banana"),
8896        "Expected targetprod to be unchanged, got %s\n", targetprod);
8897     ok(context == 0xdeadbeef,
8898        "Expected context to be unchanged, got %d\n", context);
8899     ok(!lstrcmpA(targetsid, "kiwi"),
8900        "Expected targetsid to be unchanged, got %s\n", targetsid);
8901     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8902
8903     data = MSIPATCHSTATE_APPLIED;
8904     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8905                          (const BYTE *)&data, sizeof(DWORD));
8906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8907
8908     /* State value exists */
8909     lstrcpyA(patchcode, "apple");
8910     lstrcpyA(targetprod, "banana");
8911     context = 0xdeadbeef;
8912     lstrcpyA(targetsid, "kiwi");
8913     size = MAX_PATH;
8914     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8915                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8916                            &context, targetsid, &size);
8917     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8918     ok(!lstrcmpA(patchcode, patch),
8919        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8920     ok(!lstrcmpA(targetprod, prodcode),
8921        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8922     ok(context == MSIINSTALLCONTEXT_MACHINE,
8923        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8924     ok(!lstrcmpA(targetsid, ""),
8925        "Expected \"\", got \"%s\"\n", targetsid);
8926     ok(size == 0, "Expected 0, got %d\n", size);
8927
8928     /* MSIPATCHSTATE_SUPERSEDED */
8929
8930     lstrcpyA(patchcode, "apple");
8931     lstrcpyA(targetprod, "banana");
8932     context = 0xdeadbeef;
8933     lstrcpyA(targetsid, "kiwi");
8934     size = MAX_PATH;
8935     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8936                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8937                            &context, targetsid, &size);
8938     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8939     ok(!lstrcmpA(patchcode, "apple"),
8940        "Expected patchcode to be unchanged, got %s\n", patchcode);
8941     ok(!lstrcmpA(targetprod, "banana"),
8942        "Expected targetprod to be unchanged, got %s\n", targetprod);
8943     ok(context == 0xdeadbeef,
8944        "Expected context to be unchanged, got %d\n", context);
8945     ok(!lstrcmpA(targetsid, "kiwi"),
8946        "Expected targetsid to be unchanged, got %s\n", targetsid);
8947     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8948
8949     data = MSIPATCHSTATE_SUPERSEDED;
8950     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8951                          (const BYTE *)&data, sizeof(DWORD));
8952     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8953
8954     /* State value is MSIPATCHSTATE_SUPERSEDED */
8955     lstrcpyA(patchcode, "apple");
8956     lstrcpyA(targetprod, "banana");
8957     context = 0xdeadbeef;
8958     lstrcpyA(targetsid, "kiwi");
8959     size = MAX_PATH;
8960     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8961                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8962                            &context, targetsid, &size);
8963     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8964     ok(!lstrcmpA(patchcode, patch),
8965        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8966     ok(!lstrcmpA(targetprod, prodcode),
8967        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8968     ok(context == MSIINSTALLCONTEXT_MACHINE,
8969        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8970     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8971     ok(size == 0, "Expected 0, got %d\n", size);
8972
8973     /* MSIPATCHSTATE_OBSOLETED */
8974
8975     lstrcpyA(patchcode, "apple");
8976     lstrcpyA(targetprod, "banana");
8977     context = 0xdeadbeef;
8978     lstrcpyA(targetsid, "kiwi");
8979     size = MAX_PATH;
8980     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8981                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8982                            &context, targetsid, &size);
8983     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8984     ok(!lstrcmpA(patchcode, "apple"),
8985        "Expected patchcode to be unchanged, got %s\n", patchcode);
8986     ok(!lstrcmpA(targetprod, "banana"),
8987        "Expected targetprod to be unchanged, got %s\n", targetprod);
8988     ok(context == 0xdeadbeef,
8989        "Expected context to be unchanged, got %d\n", context);
8990     ok(!lstrcmpA(targetsid, "kiwi"),
8991        "Expected targetsid to be unchanged, got %s\n", targetsid);
8992     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8993
8994     data = MSIPATCHSTATE_OBSOLETED;
8995     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8996                          (const BYTE *)&data, sizeof(DWORD));
8997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8998
8999     /* State value is obsoleted */
9000     lstrcpyA(patchcode, "apple");
9001     lstrcpyA(targetprod, "banana");
9002     context = 0xdeadbeef;
9003     lstrcpyA(targetsid, "kiwi");
9004     size = MAX_PATH;
9005     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9006                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9007                            &context, targetsid, &size);
9008     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9009     ok(!lstrcmpA(patchcode, patch),
9010        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9011     ok(!lstrcmpA(targetprod, prodcode),
9012        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9013     ok(context == MSIINSTALLCONTEXT_MACHINE,
9014        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9015     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9016     ok(size == 0, "Expected 0, got %d\n", size);
9017
9018     /* MSIPATCHSTATE_REGISTERED */
9019     /* FIXME */
9020
9021     /* MSIPATCHSTATE_ALL */
9022
9023     /* 1st */
9024     lstrcpyA(patchcode, "apple");
9025     lstrcpyA(targetprod, "banana");
9026     context = 0xdeadbeef;
9027     lstrcpyA(targetsid, "kiwi");
9028     size = MAX_PATH;
9029     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9030                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9031                            &context, targetsid, &size);
9032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9033     ok(!lstrcmpA(patchcode, patch),
9034        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9035     ok(!lstrcmpA(targetprod, prodcode),
9036        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9037     ok(context == MSIINSTALLCONTEXT_MACHINE,
9038        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9039     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9040     ok(size == 0, "Expected 0, got %d\n", size);
9041
9042     /* same patch in multiple places, only one is enumerated */
9043     lstrcpyA(patchcode, "apple");
9044     lstrcpyA(targetprod, "banana");
9045     context = 0xdeadbeef;
9046     lstrcpyA(targetsid, "kiwi");
9047     size = MAX_PATH;
9048     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9049                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9050                            &context, targetsid, &size);
9051     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9052     ok(!lstrcmpA(patchcode, "apple"),
9053        "Expected patchcode to be unchanged, got %s\n", patchcode);
9054     ok(!lstrcmpA(targetprod, "banana"),
9055        "Expected targetprod to be unchanged, got %s\n", targetprod);
9056     ok(context == 0xdeadbeef,
9057        "Expected context to be unchanged, got %d\n", context);
9058     ok(!lstrcmpA(targetsid, "kiwi"),
9059        "Expected targetsid to be unchanged, got %s\n", targetsid);
9060     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9061
9062     RegDeleteValueA(patches, patch_squashed);
9063     RegDeleteValueA(patches, "Patches");
9064     RegDeleteKeyA(patches, "");
9065     RegCloseKey(patches);
9066     RegDeleteValueA(hpatch, "State");
9067     RegDeleteKeyA(hpatch, "");
9068     RegCloseKey(hpatch);
9069     RegDeleteKeyA(udpatch, "");
9070     RegCloseKey(udpatch);
9071     RegDeleteKeyA(udprod, "");
9072     RegCloseKey(udprod);
9073     RegDeleteKeyA(prodkey, "");
9074     RegCloseKey(prodkey);
9075 }
9076
9077 static void test_MsiEnumPatches(void)
9078 {
9079     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9080     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9081     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9082     CHAR transforms[MAX_PATH];
9083     HKEY prodkey, patches, udprod;
9084     HKEY userkey, hpatch, udpatch;
9085     DWORD size, data;
9086     LPSTR usersid;
9087     LONG res;
9088     UINT r;
9089
9090     create_test_guid(prodcode, prod_squashed);
9091     create_test_guid(patchcode, patch_squashed);
9092     get_user_sid(&usersid);
9093
9094     /* NULL szProduct */
9095     size = MAX_PATH;
9096     lstrcpyA(patch, "apple");
9097     lstrcpyA(transforms, "banana");
9098     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9099     ok(r == ERROR_INVALID_PARAMETER,
9100        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9101     ok(!lstrcmpA(patch, "apple"),
9102        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9103     ok(!lstrcmpA(transforms, "banana"),
9104        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9105     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9106
9107     /* empty szProduct */
9108     size = MAX_PATH;
9109     lstrcpyA(patch, "apple");
9110     lstrcpyA(transforms, "banana");
9111     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9112     ok(r == ERROR_INVALID_PARAMETER,
9113        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9114     ok(!lstrcmpA(patch, "apple"),
9115        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9116     ok(!lstrcmpA(transforms, "banana"),
9117        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9118     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9119
9120     /* garbage szProduct */
9121     size = MAX_PATH;
9122     lstrcpyA(patch, "apple");
9123     lstrcpyA(transforms, "banana");
9124     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9125     ok(r == ERROR_INVALID_PARAMETER,
9126        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9127     ok(!lstrcmpA(patch, "apple"),
9128        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9129     ok(!lstrcmpA(transforms, "banana"),
9130        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9131     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9132
9133     /* guid without brackets */
9134     size = MAX_PATH;
9135     lstrcpyA(patch, "apple");
9136     lstrcpyA(transforms, "banana");
9137     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9138                         transforms, &size);
9139     ok(r == ERROR_INVALID_PARAMETER,
9140        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9141     ok(!lstrcmpA(patch, "apple"),
9142        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9143     ok(!lstrcmpA(transforms, "banana"),
9144        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9145     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9146
9147     /* guid with brackets */
9148     size = MAX_PATH;
9149     lstrcpyA(patch, "apple");
9150     lstrcpyA(transforms, "banana");
9151     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9152                         transforms, &size);
9153     ok(r == ERROR_UNKNOWN_PRODUCT,
9154        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9155     ok(!lstrcmpA(patch, "apple"),
9156        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9157     ok(!lstrcmpA(transforms, "banana"),
9158        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9159     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9160
9161     /* same length as guid, but random */
9162     size = MAX_PATH;
9163     lstrcpyA(patch, "apple");
9164     lstrcpyA(transforms, "banana");
9165     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9166                         transforms, &size);
9167     ok(r == ERROR_INVALID_PARAMETER,
9168        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9169     ok(!lstrcmpA(patch, "apple"),
9170        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9171     ok(!lstrcmpA(transforms, "banana"),
9172        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9173     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9174
9175     /* MSIINSTALLCONTEXT_USERMANAGED */
9176
9177     size = MAX_PATH;
9178     lstrcpyA(patch, "apple");
9179     lstrcpyA(transforms, "banana");
9180     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9181     ok(r == ERROR_UNKNOWN_PRODUCT,
9182        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9183     ok(!lstrcmpA(patch, "apple"),
9184        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9185     ok(!lstrcmpA(transforms, "banana"),
9186        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9187     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9188
9189     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9190     lstrcatA(keypath, usersid);
9191     lstrcatA(keypath, "\\Installer\\Products\\");
9192     lstrcatA(keypath, prod_squashed);
9193
9194     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9196
9197     /* managed product key exists */
9198     size = MAX_PATH;
9199     lstrcpyA(patch, "apple");
9200     lstrcpyA(transforms, "banana");
9201     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9202     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9203     ok(!lstrcmpA(patch, "apple"),
9204        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9205     ok(!lstrcmpA(transforms, "banana"),
9206        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9207     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9208
9209     res = RegCreateKeyA(prodkey, "Patches", &patches);
9210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9211
9212     /* patches key exists */
9213     size = MAX_PATH;
9214     lstrcpyA(patch, "apple");
9215     lstrcpyA(transforms, "banana");
9216     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9217     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9218     ok(!lstrcmpA(patch, "apple"),
9219        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9220     ok(!lstrcmpA(transforms, "banana"),
9221        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9222     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9223
9224     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9225                          (const BYTE *)patch_squashed,
9226                          lstrlenA(patch_squashed) + 1);
9227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9228
9229     /* Patches value exists, is not REG_MULTI_SZ */
9230     size = MAX_PATH;
9231     lstrcpyA(patch, "apple");
9232     lstrcpyA(transforms, "banana");
9233     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9234     ok(r == ERROR_BAD_CONFIGURATION,
9235        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9236     ok(!lstrcmpA(patch, "apple"),
9237        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9238     ok(!lstrcmpA(transforms, "banana"),
9239        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9240     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9241
9242     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9243                          (const BYTE *)"a\0b\0c\0\0", 7);
9244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9245
9246     /* Patches value exists, is not a squashed guid */
9247     size = MAX_PATH;
9248     lstrcpyA(patch, "apple");
9249     lstrcpyA(transforms, "banana");
9250     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9251     ok(r == ERROR_BAD_CONFIGURATION,
9252        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9253     ok(!lstrcmpA(patch, "apple"),
9254        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9255     ok(!lstrcmpA(transforms, "banana"),
9256        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9257     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9258
9259     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9260                          (const BYTE *)patch_squashed,
9261                          lstrlenA(patch_squashed) + 1);
9262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9263
9264     /* Patches value exists */
9265     size = MAX_PATH;
9266     lstrcpyA(patch, "apple");
9267     lstrcpyA(transforms, "banana");
9268     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9269     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9270     ok(!lstrcmpA(patch, "apple"),
9271        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9272     ok(!lstrcmpA(transforms, "banana"),
9273        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9274     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9275
9276     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9277                          (const BYTE *)"whatever", 9);
9278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9279
9280     /* patch squashed value exists */
9281     size = MAX_PATH;
9282     lstrcpyA(patch, "apple");
9283     lstrcpyA(transforms, "banana");
9284     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9286     ok(!lstrcmpA(patch, patchcode),
9287        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9288     ok(!lstrcmpA(transforms, "whatever"),
9289        "Expected \"whatever\", got \"%s\"\n", transforms);
9290     ok(size == 8, "Expected 8, got %d\n", size);
9291
9292     /* lpPatchBuf is NULL */
9293     size = MAX_PATH;
9294     lstrcpyA(transforms, "banana");
9295     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9296     ok(r == ERROR_INVALID_PARAMETER,
9297        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9298     ok(!lstrcmpA(transforms, "banana"),
9299        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9300     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9301
9302     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9303     size = MAX_PATH;
9304     lstrcpyA(patch, "apple");
9305     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9306     ok(r == ERROR_INVALID_PARAMETER,
9307        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9308     ok(!lstrcmpA(patch, "apple"),
9309        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9310     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9311
9312     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9313     lstrcpyA(patch, "apple");
9314     lstrcpyA(transforms, "banana");
9315     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9316     ok(r == ERROR_INVALID_PARAMETER,
9317        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9318     ok(!lstrcmpA(patch, "apple"),
9319        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9320     ok(!lstrcmpA(transforms, "banana"),
9321        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9322
9323     /* pcchTransformsBuf is too small */
9324     size = 6;
9325     lstrcpyA(patch, "apple");
9326     lstrcpyA(transforms, "banana");
9327     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9328     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9329     ok(!lstrcmpA(patch, patchcode),
9330        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9331     ok(!lstrcmpA(transforms, "whate"),
9332        "Expected \"whate\", got \"%s\"\n", transforms);
9333     ok(size == 16, "Expected 16, got %d\n", size);
9334
9335     /* increase the index */
9336     size = MAX_PATH;
9337     lstrcpyA(patch, "apple");
9338     lstrcpyA(transforms, "banana");
9339     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9340     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9341     ok(!lstrcmpA(patch, "apple"),
9342        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9343     ok(!lstrcmpA(transforms, "banana"),
9344        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9345     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9346
9347     /* increase again */
9348     size = MAX_PATH;
9349     lstrcpyA(patch, "apple");
9350     lstrcpyA(transforms, "banana");
9351     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9352     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9353     ok(!lstrcmpA(patch, "apple"),
9354        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9355     ok(!lstrcmpA(transforms, "banana"),
9356        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9357     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9358
9359     RegDeleteValueA(patches, "Patches");
9360     RegDeleteKeyA(patches, "");
9361     RegCloseKey(patches);
9362     RegDeleteKeyA(prodkey, "");
9363     RegCloseKey(prodkey);
9364
9365     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9366
9367     size = MAX_PATH;
9368     lstrcpyA(patch, "apple");
9369     lstrcpyA(transforms, "banana");
9370     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9371     ok(r == ERROR_UNKNOWN_PRODUCT,
9372        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9373     ok(!lstrcmpA(patch, "apple"),
9374        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9375     ok(!lstrcmpA(transforms, "banana"),
9376        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9377     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9378
9379     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9380     lstrcatA(keypath, prod_squashed);
9381
9382     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9384
9385     /* current user product key exists */
9386     size = MAX_PATH;
9387     lstrcpyA(patch, "apple");
9388     lstrcpyA(transforms, "banana");
9389     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9390     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9391     ok(!lstrcmpA(patch, "apple"),
9392        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9393     ok(!lstrcmpA(transforms, "banana"),
9394        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9395     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9396
9397     res = RegCreateKeyA(prodkey, "Patches", &patches);
9398     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9399
9400     /* Patches key exists */
9401     size = MAX_PATH;
9402     lstrcpyA(patch, "apple");
9403     lstrcpyA(transforms, "banana");
9404     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9405     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9406     ok(!lstrcmpA(patch, "apple"),
9407        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9408     ok(!lstrcmpA(transforms, "banana"),
9409        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9410     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9411
9412     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9413                          (const BYTE *)patch_squashed,
9414                          lstrlenA(patch_squashed) + 1);
9415     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9416
9417     /* Patches value exists, is not REG_MULTI_SZ */
9418     size = MAX_PATH;
9419     lstrcpyA(patch, "apple");
9420     lstrcpyA(transforms, "banana");
9421     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9422     ok(r == ERROR_BAD_CONFIGURATION,
9423        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9424     ok(!lstrcmpA(patch, "apple"),
9425        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9426     ok(!lstrcmpA(transforms, "banana"),
9427        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9428     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9429
9430     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9431                          (const BYTE *)"a\0b\0c\0\0", 7);
9432     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9433
9434     /* Patches value exists, is not a squashed guid */
9435     size = MAX_PATH;
9436     lstrcpyA(patch, "apple");
9437     lstrcpyA(transforms, "banana");
9438     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9439     ok(r == ERROR_BAD_CONFIGURATION,
9440        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9441     ok(!lstrcmpA(patch, "apple"),
9442        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9443     ok(!lstrcmpA(transforms, "banana"),
9444        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9445     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9446
9447     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9448                          (const BYTE *)patch_squashed,
9449                          lstrlenA(patch_squashed) + 1);
9450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9451
9452     /* Patches value exists */
9453     size = MAX_PATH;
9454     lstrcpyA(patch, "apple");
9455     lstrcpyA(transforms, "banana");
9456     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9457     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9458     ok(!lstrcmpA(patch, "apple"),
9459        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9460     ok(!lstrcmpA(transforms, "banana"),
9461        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9462     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9463
9464     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9465                          (const BYTE *)"whatever", 9);
9466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9467
9468     /* patch code value exists */
9469     size = MAX_PATH;
9470     lstrcpyA(patch, "apple");
9471     lstrcpyA(transforms, "banana");
9472     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9473     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9474     ok(!lstrcmpA(patch, "apple"),
9475        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9476     ok(!lstrcmpA(transforms, "banana"),
9477        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9478     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9479
9480     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9481     lstrcatA(keypath, usersid);
9482     lstrcatA(keypath, "\\Patches\\");
9483     lstrcatA(keypath, patch_squashed);
9484
9485     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9487
9488     /* userdata patch key exists */
9489     size = MAX_PATH;
9490     lstrcpyA(patch, "apple");
9491     lstrcpyA(transforms, "banana");
9492     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9494     ok(!lstrcmpA(patch, patchcode),
9495        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9496     ok(!lstrcmpA(transforms, "whatever"),
9497        "Expected \"whatever\", got \"%s\"\n", transforms);
9498     ok(size == 8, "Expected 8, got %d\n", size);
9499
9500     RegDeleteKeyA(userkey, "");
9501     RegCloseKey(userkey);
9502     RegDeleteValueA(patches, patch_squashed);
9503     RegDeleteValueA(patches, "Patches");
9504     RegDeleteKeyA(patches, "");
9505     RegCloseKey(patches);
9506     RegDeleteKeyA(prodkey, "");
9507     RegCloseKey(prodkey);
9508
9509     /* MSIINSTALLCONTEXT_MACHINE */
9510
9511     size = MAX_PATH;
9512     lstrcpyA(patch, "apple");
9513     lstrcpyA(transforms, "banana");
9514     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9515     ok(r == ERROR_UNKNOWN_PRODUCT,
9516        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9517     ok(!lstrcmpA(patch, "apple"),
9518        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9519     ok(!lstrcmpA(transforms, "banana"),
9520        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9521     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9522
9523     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9524     lstrcatA(keypath, prod_squashed);
9525
9526     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9528
9529     /* local product key exists */
9530     size = MAX_PATH;
9531     lstrcpyA(patch, "apple");
9532     lstrcpyA(transforms, "banana");
9533     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9534     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9535     ok(!lstrcmpA(patch, "apple"),
9536        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9537     ok(!lstrcmpA(transforms, "banana"),
9538        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9539     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9540
9541     res = RegCreateKeyA(prodkey, "Patches", &patches);
9542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9543
9544     /* Patches key exists */
9545     size = MAX_PATH;
9546     lstrcpyA(patch, "apple");
9547     lstrcpyA(transforms, "banana");
9548     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9549     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9550     ok(!lstrcmpA(patch, "apple"),
9551        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9552     ok(!lstrcmpA(transforms, "banana"),
9553        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9554     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9555
9556     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9557                          (const BYTE *)patch_squashed,
9558                          lstrlenA(patch_squashed) + 1);
9559     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9560
9561     /* Patches value exists, is not REG_MULTI_SZ */
9562     size = MAX_PATH;
9563     lstrcpyA(patch, "apple");
9564     lstrcpyA(transforms, "banana");
9565     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9566     ok(r == ERROR_BAD_CONFIGURATION,
9567        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9568     ok(!lstrcmpA(patch, "apple"),
9569        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9570     ok(!lstrcmpA(transforms, "banana"),
9571        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9573
9574     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9575                          (const BYTE *)"a\0b\0c\0\0", 7);
9576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9577
9578     /* Patches value exists, is not a squashed guid */
9579     size = MAX_PATH;
9580     lstrcpyA(patch, "apple");
9581     lstrcpyA(transforms, "banana");
9582     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9583     ok(r == ERROR_BAD_CONFIGURATION,
9584        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9585     ok(!lstrcmpA(patch, "apple"),
9586        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9587     ok(!lstrcmpA(transforms, "banana"),
9588        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9589     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9590
9591     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9592                          (const BYTE *)patch_squashed,
9593                          lstrlenA(patch_squashed) + 1);
9594     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9595
9596     /* Patches value exists */
9597     size = MAX_PATH;
9598     lstrcpyA(patch, "apple");
9599     lstrcpyA(transforms, "banana");
9600     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9601     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9602     ok(!lstrcmpA(patch, "apple"),
9603        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9604     ok(!lstrcmpA(transforms, "banana"),
9605        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9606     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9607
9608     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9609                          (const BYTE *)"whatever", 9);
9610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9611
9612     /* patch code value exists */
9613     size = MAX_PATH;
9614     lstrcpyA(patch, "apple");
9615     lstrcpyA(transforms, "banana");
9616     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9617     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9618     ok(!lstrcmpA(patch, patchcode),
9619        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9620     ok(!lstrcmpA(transforms, "whatever"),
9621        "Expected \"whatever\", got \"%s\"\n", transforms);
9622     ok(size == 8, "Expected 8, got %d\n", size);
9623
9624     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9625     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9626     lstrcatA(keypath, prod_squashed);
9627
9628     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9630
9631     /* local UserData product key exists */
9632     size = MAX_PATH;
9633     lstrcpyA(patch, "apple");
9634     lstrcpyA(transforms, "banana");
9635     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9637     ok(!lstrcmpA(patch, patchcode),
9638        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9639     ok(!lstrcmpA(transforms, "whatever"),
9640        "Expected \"whatever\", got \"%s\"\n", transforms);
9641     ok(size == 8, "Expected 8, got %d\n", size);
9642
9643     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9645
9646     /* local UserData Patches key exists */
9647     size = MAX_PATH;
9648     lstrcpyA(patch, "apple");
9649     lstrcpyA(transforms, "banana");
9650     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9651     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9652     ok(!lstrcmpA(patch, patchcode),
9653        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9654     ok(!lstrcmpA(transforms, "whatever"),
9655        "Expected \"whatever\", got \"%s\"\n", transforms);
9656     ok(size == 8, "Expected 8, got %d\n", size);
9657
9658     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9660
9661     /* local UserData Product patch key exists */
9662     size = MAX_PATH;
9663     lstrcpyA(patch, "apple");
9664     lstrcpyA(transforms, "banana");
9665     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9666     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9667     ok(!lstrcmpA(patch, "apple"),
9668        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9669     ok(!lstrcmpA(transforms, "banana"),
9670        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9672
9673     data = MSIPATCHSTATE_APPLIED;
9674     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9675                          (const BYTE *)&data, sizeof(DWORD));
9676     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9677
9678     /* State value exists */
9679     size = MAX_PATH;
9680     lstrcpyA(patch, "apple");
9681     lstrcpyA(transforms, "banana");
9682     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9684     ok(!lstrcmpA(patch, patchcode),
9685        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9686     ok(!lstrcmpA(transforms, "whatever"),
9687        "Expected \"whatever\", got \"%s\"\n", transforms);
9688     ok(size == 8, "Expected 8, got %d\n", size);
9689
9690     RegDeleteValueA(patches, patch_squashed);
9691     RegDeleteValueA(patches, "Patches");
9692     RegDeleteKeyA(patches, "");
9693     RegCloseKey(patches);
9694     RegDeleteValueA(hpatch, "State");
9695     RegDeleteKeyA(hpatch, "");
9696     RegCloseKey(hpatch);
9697     RegDeleteKeyA(udpatch, "");
9698     RegCloseKey(udpatch);
9699     RegDeleteKeyA(udprod, "");
9700     RegCloseKey(udprod);
9701     RegDeleteKeyA(prodkey, "");
9702     RegCloseKey(prodkey);
9703 }
9704
9705 static void test_MsiGetPatchInfoEx(void)
9706 {
9707     CHAR keypath[MAX_PATH], val[MAX_PATH];
9708     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9709     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9710     HKEY prodkey, patches, udprod, props;
9711     HKEY hpatch, udpatch, prodpatches;
9712     LPSTR usersid;
9713     DWORD size;
9714     LONG res;
9715     UINT r;
9716
9717     if (!pMsiGetPatchInfoExA)
9718     {
9719         win_skip("MsiGetPatchInfoEx not implemented\n");
9720         return;
9721     }
9722
9723     create_test_guid(prodcode, prod_squashed);
9724     create_test_guid(patchcode, patch_squashed);
9725     get_user_sid(&usersid);
9726
9727     /* NULL szPatchCode */
9728     lstrcpyA(val, "apple");
9729     size = MAX_PATH;
9730     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9731                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9732     ok(r == ERROR_INVALID_PARAMETER,
9733        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9734     ok(!lstrcmpA(val, "apple"),
9735        "Expected val to be unchanged, got \"%s\"\n", val);
9736     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9737
9738     /* empty szPatchCode */
9739     size = MAX_PATH;
9740     lstrcpyA(val, "apple");
9741     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9742                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9743     ok(r == ERROR_INVALID_PARAMETER,
9744        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9745     ok(!lstrcmpA(val, "apple"),
9746        "Expected val to be unchanged, got \"%s\"\n", val);
9747     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9748
9749     /* garbage szPatchCode */
9750     size = MAX_PATH;
9751     lstrcpyA(val, "apple");
9752     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9753                             MSIINSTALLCONTEXT_USERMANAGED,
9754                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9755     ok(r == ERROR_INVALID_PARAMETER,
9756        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9757     ok(!lstrcmpA(val, "apple"),
9758        "Expected val to be unchanged, got \"%s\"\n", val);
9759     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9760
9761     /* guid without brackets */
9762     size = MAX_PATH;
9763     lstrcpyA(val, "apple");
9764     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9765                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9766                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9767     ok(r == ERROR_INVALID_PARAMETER,
9768        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9769     ok(!lstrcmpA(val, "apple"),
9770        "Expected val to be unchanged, got \"%s\"\n", val);
9771     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9772
9773     /* guid with brackets */
9774     size = MAX_PATH;
9775     lstrcpyA(val, "apple");
9776     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9777                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9778                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9779     ok(r == ERROR_UNKNOWN_PRODUCT,
9780        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9781     ok(!lstrcmpA(val, "apple"),
9782        "Expected val to be unchanged, got \"%s\"\n", val);
9783     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9784
9785     /* same length as guid, but random */
9786     size = MAX_PATH;
9787     lstrcpyA(val, "apple");
9788     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9789                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9790                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9791     ok(r == ERROR_INVALID_PARAMETER,
9792        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9793     ok(!lstrcmpA(val, "apple"),
9794        "Expected val to be unchanged, got \"%s\"\n", val);
9795     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9796
9797     /* NULL szProductCode */
9798     lstrcpyA(val, "apple");
9799     size = MAX_PATH;
9800     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9801                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9802     ok(r == ERROR_INVALID_PARAMETER,
9803        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9804     ok(!lstrcmpA(val, "apple"),
9805        "Expected val to be unchanged, got \"%s\"\n", val);
9806     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9807
9808     /* empty szProductCode */
9809     size = MAX_PATH;
9810     lstrcpyA(val, "apple");
9811     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
9812                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9813     ok(r == ERROR_INVALID_PARAMETER,
9814        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9815     ok(!lstrcmpA(val, "apple"),
9816        "Expected val to be unchanged, got \"%s\"\n", val);
9817     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9818
9819     /* garbage szProductCode */
9820     size = MAX_PATH;
9821     lstrcpyA(val, "apple");
9822     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9823                             MSIINSTALLCONTEXT_USERMANAGED,
9824                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9825     ok(r == ERROR_INVALID_PARAMETER,
9826        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9827     ok(!lstrcmpA(val, "apple"),
9828        "Expected val to be unchanged, got \"%s\"\n", val);
9829     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9830
9831     /* guid without brackets */
9832     size = MAX_PATH;
9833     lstrcpyA(val, "apple");
9834     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
9835                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9836                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9837     ok(r == ERROR_INVALID_PARAMETER,
9838        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9839     ok(!lstrcmpA(val, "apple"),
9840        "Expected val to be unchanged, got \"%s\"\n", val);
9841     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9842
9843     /* guid with brackets */
9844     size = MAX_PATH;
9845     lstrcpyA(val, "apple");
9846     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
9847                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9848                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9849     ok(r == ERROR_UNKNOWN_PRODUCT,
9850        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9851     ok(!lstrcmpA(val, "apple"),
9852        "Expected val to be unchanged, got \"%s\"\n", val);
9853     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9854
9855     /* same length as guid, but random */
9856     size = MAX_PATH;
9857     lstrcpyA(val, "apple");
9858     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
9859                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9860                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9861     ok(r == ERROR_INVALID_PARAMETER,
9862        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9863     ok(!lstrcmpA(val, "apple"),
9864        "Expected val to be unchanged, got \"%s\"\n", val);
9865     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9866
9867     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
9868     size = MAX_PATH;
9869     lstrcpyA(val, "apple");
9870     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9871                             MSIINSTALLCONTEXT_USERMANAGED,
9872                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9873     ok(r == ERROR_INVALID_PARAMETER,
9874        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9875     ok(!lstrcmpA(val, "apple"),
9876        "Expected val to be unchanged, got \"%s\"\n", val);
9877     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9878
9879     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
9880     size = MAX_PATH;
9881     lstrcpyA(val, "apple");
9882     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9883                             MSIINSTALLCONTEXT_USERUNMANAGED,
9884                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9885     ok(r == ERROR_INVALID_PARAMETER,
9886        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9887     ok(!lstrcmpA(val, "apple"),
9888        "Expected val to be unchanged, got \"%s\"\n", val);
9889     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9890
9891     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
9892     size = MAX_PATH;
9893     lstrcpyA(val, "apple");
9894     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9895                             MSIINSTALLCONTEXT_MACHINE,
9896                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9897     ok(r == ERROR_INVALID_PARAMETER,
9898        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9899     ok(!lstrcmpA(val, "apple"),
9900        "Expected val to be unchanged, got \"%s\"\n", val);
9901     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9902
9903     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
9904     size = MAX_PATH;
9905     lstrcpyA(val, "apple");
9906     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9907                             MSIINSTALLCONTEXT_MACHINE,
9908                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9909     ok(r == ERROR_INVALID_PARAMETER,
9910        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9911     ok(!lstrcmpA(val, "apple"),
9912        "Expected val to be unchanged, got \"%s\"\n", val);
9913     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9914
9915     /* dwContext is out of range */
9916     size = MAX_PATH;
9917     lstrcpyA(val, "apple");
9918     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9919                             MSIINSTALLCONTEXT_NONE,
9920                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9921     ok(r == ERROR_INVALID_PARAMETER,
9922        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9923     ok(!lstrcmpA(val, "apple"),
9924        "Expected val to be unchanged, got \"%s\"\n", val);
9925     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9926
9927     /* dwContext is out of range */
9928     size = MAX_PATH;
9929     lstrcpyA(val, "apple");
9930     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9931                             MSIINSTALLCONTEXT_ALL,
9932                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9933     ok(r == ERROR_INVALID_PARAMETER,
9934        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9935     ok(!lstrcmpA(val, "apple"),
9936        "Expected val to be unchanged, got \"%s\"\n", val);
9937     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9938
9939     /* dwContext is invalid */
9940     size = MAX_PATH;
9941     lstrcpyA(val, "apple");
9942     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
9943                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9944     ok(r == ERROR_INVALID_PARAMETER,
9945        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9946     ok(!lstrcmpA(val, "apple"),
9947        "Expected val to be unchanged, got \"%s\"\n", val);
9948     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9949
9950     /* MSIINSTALLCONTEXT_USERMANAGED */
9951
9952     size = MAX_PATH;
9953     lstrcpyA(val, "apple");
9954     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9955                             MSIINSTALLCONTEXT_USERMANAGED,
9956                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9957     ok(r == ERROR_UNKNOWN_PRODUCT,
9958        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9959     ok(!lstrcmpA(val, "apple"),
9960        "Expected val to be unchanged, got \"%s\"\n", val);
9961     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9962
9963     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9964     lstrcatA(keypath, usersid);
9965     lstrcatA(keypath, "\\Products\\");
9966     lstrcatA(keypath, prod_squashed);
9967
9968     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9970
9971     /* local UserData product key exists */
9972     size = MAX_PATH;
9973     lstrcpyA(val, "apple");
9974     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9975                             MSIINSTALLCONTEXT_USERMANAGED,
9976                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9977     ok(r == ERROR_UNKNOWN_PRODUCT,
9978        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9979     ok(!lstrcmpA(val, "apple"),
9980        "Expected val to be unchanged, got \"%s\"\n", val);
9981     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9982
9983     res = RegCreateKeyA(udprod, "InstallProperties", &props);
9984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9985
9986     /* InstallProperties key exists */
9987     size = MAX_PATH;
9988     lstrcpyA(val, "apple");
9989     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9990                             MSIINSTALLCONTEXT_USERMANAGED,
9991                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9992     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
9993     ok(!lstrcmpA(val, "apple"),
9994        "Expected val to be unchanged, got \"%s\"\n", val);
9995     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9996
9997     res = RegCreateKeyA(udprod, "Patches", &patches);
9998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9999
10000     /* Patches key exists */
10001     size = MAX_PATH;
10002     lstrcpyA(val, "apple");
10003     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10004                             MSIINSTALLCONTEXT_USERMANAGED,
10005                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10006     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10007     ok(!lstrcmpA(val, "apple"),
10008        "Expected val to be unchanged, got \"%s\"\n", val);
10009     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10010
10011     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10013
10014     /* Patches key exists */
10015     size = MAX_PATH;
10016     lstrcpyA(val, "apple");
10017     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10018                             MSIINSTALLCONTEXT_USERMANAGED,
10019                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10020     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10021     ok(!lstrcmpA(val, "apple"),
10022        "Expected val to be unchanged, got \"%s\"\n", val);
10023     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10024
10025     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10026     lstrcatA(keypath, usersid);
10027     lstrcatA(keypath, "\\Installer\\Products\\");
10028     lstrcatA(keypath, prod_squashed);
10029
10030     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10032
10033     /* managed product key exists */
10034     size = MAX_PATH;
10035     lstrcpyA(val, "apple");
10036     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10037                             MSIINSTALLCONTEXT_USERMANAGED,
10038                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10039     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10040     ok(!lstrcmpA(val, "apple"),
10041        "Expected val to be unchanged, got \"%s\"\n", val);
10042     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10043
10044     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10046
10047     /* Patches key exists */
10048     size = MAX_PATH;
10049     lstrcpyA(val, "apple");
10050     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10051                             MSIINSTALLCONTEXT_USERMANAGED,
10052                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10053     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10054     ok(!lstrcmpA(val, "apple"),
10055        "Expected val to be unchanged, got \"%s\"\n", val);
10056     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10057
10058     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10059                          (const BYTE *)"transforms", 11);
10060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10061
10062     /* specific patch value exists */
10063     size = MAX_PATH;
10064     lstrcpyA(val, "apple");
10065     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10066                             MSIINSTALLCONTEXT_USERMANAGED,
10067                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10068     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10069     ok(!lstrcmpA(val, "apple"),
10070        "Expected val to be unchanged, got \"%s\"\n", val);
10071     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10072
10073     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10074     lstrcatA(keypath, usersid);
10075     lstrcatA(keypath, "\\Patches\\");
10076     lstrcatA(keypath, patch_squashed);
10077
10078     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10080
10081     /* UserData Patches key exists */
10082     size = MAX_PATH;
10083     lstrcpyA(val, "apple");
10084     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10085                             MSIINSTALLCONTEXT_USERMANAGED,
10086                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10087     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10088     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10089     ok(size == 0, "Expected 0, got %d\n", size);
10090
10091     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10092                          (const BYTE *)"pack", 5);
10093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10094
10095     /* ManagedLocalPatch value exists */
10096     size = MAX_PATH;
10097     lstrcpyA(val, "apple");
10098     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10099                             MSIINSTALLCONTEXT_USERMANAGED,
10100                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10102     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10103     ok(size == 4, "Expected 4, got %d\n", size);
10104
10105     size = MAX_PATH;
10106     lstrcpyA(val, "apple");
10107     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10108                             MSIINSTALLCONTEXT_USERMANAGED,
10109                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10110     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10111     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10112     ok(size == 10, "Expected 10, got %d\n", size);
10113
10114     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10115                          (const BYTE *)"mydate", 7);
10116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10117
10118     /* Installed value exists */
10119     size = MAX_PATH;
10120     lstrcpyA(val, "apple");
10121     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10122                             MSIINSTALLCONTEXT_USERMANAGED,
10123                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10125     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10126     ok(size == 6, "Expected 6, got %d\n", size);
10127
10128     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10129                          (const BYTE *)"yes", 4);
10130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10131
10132     /* Uninstallable value exists */
10133     size = MAX_PATH;
10134     lstrcpyA(val, "apple");
10135     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10136                             MSIINSTALLCONTEXT_USERMANAGED,
10137                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10139     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10140     ok(size == 3, "Expected 3, got %d\n", size);
10141
10142     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10143                          (const BYTE *)"good", 5);
10144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10145
10146     /* State value exists */
10147     size = MAX_PATH;
10148     lstrcpyA(val, "apple");
10149     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10150                             MSIINSTALLCONTEXT_USERMANAGED,
10151                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10152     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10153     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10154     ok(size == 4, "Expected 4, got %d\n", size);
10155
10156     size = 1;
10157     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10158                          (const BYTE *)&size, sizeof(DWORD));
10159     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10160
10161     /* State value exists */
10162     size = MAX_PATH;
10163     lstrcpyA(val, "apple");
10164     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10165                             MSIINSTALLCONTEXT_USERMANAGED,
10166                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10168     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10169     ok(size == 1, "Expected 1, got %d\n", size);
10170
10171     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10172                          (const BYTE *)"display", 8);
10173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10174
10175     /* DisplayName value exists */
10176     size = MAX_PATH;
10177     lstrcpyA(val, "apple");
10178     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10179                             MSIINSTALLCONTEXT_USERMANAGED,
10180                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10182     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10183     ok(size == 7, "Expected 7, got %d\n", size);
10184
10185     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10186                          (const BYTE *)"moreinfo", 9);
10187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10188
10189     /* MoreInfoURL value exists */
10190     size = MAX_PATH;
10191     lstrcpyA(val, "apple");
10192     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10193                             MSIINSTALLCONTEXT_USERMANAGED,
10194                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10196     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10197     ok(size == 8, "Expected 8, got %d\n", size);
10198
10199     /* szProperty is invalid */
10200     size = MAX_PATH;
10201     lstrcpyA(val, "apple");
10202     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10203                             MSIINSTALLCONTEXT_USERMANAGED,
10204                             "IDontExist", val, &size);
10205     ok(r == ERROR_UNKNOWN_PROPERTY,
10206        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10207     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10208     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10209
10210     /* lpValue is NULL, while pcchValue is non-NULL */
10211     size = MAX_PATH;
10212     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10213                             MSIINSTALLCONTEXT_USERMANAGED,
10214                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10216     ok(size == 16, "Expected 16, got %d\n", size);
10217
10218     /* pcchValue is NULL, while lpValue is non-NULL */
10219     lstrcpyA(val, "apple");
10220     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10221                             MSIINSTALLCONTEXT_USERMANAGED,
10222                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10223     ok(r == ERROR_INVALID_PARAMETER,
10224        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10225     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10226
10227     /* both lpValue and pcchValue are NULL */
10228     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10229                             MSIINSTALLCONTEXT_USERMANAGED,
10230                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10232
10233     /* pcchValue doesn't have enough room for NULL terminator */
10234     size = 8;
10235     lstrcpyA(val, "apple");
10236     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10237                             MSIINSTALLCONTEXT_USERMANAGED,
10238                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10239     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10240     ok(!lstrcmpA(val, "moreinf"),
10241        "Expected \"moreinf\", got \"%s\"\n", val);
10242     ok(size == 16, "Expected 16, got %d\n", size);
10243
10244     /* pcchValue has exactly enough room for NULL terminator */
10245     size = 9;
10246     lstrcpyA(val, "apple");
10247     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10248                             MSIINSTALLCONTEXT_USERMANAGED,
10249                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10251     ok(!lstrcmpA(val, "moreinfo"),
10252        "Expected \"moreinfo\", got \"%s\"\n", val);
10253     ok(size == 8, "Expected 8, got %d\n", size);
10254
10255     /* pcchValue is too small, lpValue is NULL */
10256     size = 0;
10257     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10258                             MSIINSTALLCONTEXT_USERMANAGED,
10259                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10261     ok(size == 16, "Expected 16, got %d\n", size);
10262
10263     RegDeleteValueA(prodpatches, patch_squashed);
10264     RegDeleteKeyA(prodpatches, "");
10265     RegCloseKey(prodpatches);
10266     RegDeleteKeyA(prodkey, "");
10267     RegCloseKey(prodkey);
10268
10269     /* UserData is sufficient for all properties
10270      * except INSTALLPROPERTY_TRANSFORMS
10271      */
10272     size = MAX_PATH;
10273     lstrcpyA(val, "apple");
10274     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10275                             MSIINSTALLCONTEXT_USERMANAGED,
10276                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10278     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10279     ok(size == 4, "Expected 4, got %d\n", size);
10280
10281     /* UserData is sufficient for all properties
10282      * except INSTALLPROPERTY_TRANSFORMS
10283      */
10284     size = MAX_PATH;
10285     lstrcpyA(val, "apple");
10286     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10287                             MSIINSTALLCONTEXT_USERMANAGED,
10288                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10289     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10290     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10291     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10292
10293     RegDeleteValueA(hpatch, "MoreInfoURL");
10294     RegDeleteValueA(hpatch, "Display");
10295     RegDeleteValueA(hpatch, "State");
10296     RegDeleteValueA(hpatch, "Uninstallable");
10297     RegDeleteValueA(hpatch, "Installed");
10298     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10299     RegDeleteKeyA(udpatch, "");
10300     RegCloseKey(udpatch);
10301     RegDeleteKeyA(hpatch, "");
10302     RegCloseKey(hpatch);
10303     RegDeleteKeyA(patches, "");
10304     RegCloseKey(patches);
10305     RegDeleteKeyA(props, "");
10306     RegCloseKey(props);
10307     RegDeleteKeyA(udprod, "");
10308     RegCloseKey(udprod);
10309
10310     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10311
10312     size = MAX_PATH;
10313     lstrcpyA(val, "apple");
10314     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10315                             MSIINSTALLCONTEXT_USERUNMANAGED,
10316                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10317     ok(r == ERROR_UNKNOWN_PRODUCT,
10318        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10319     ok(!lstrcmpA(val, "apple"),
10320        "Expected val to be unchanged, got \"%s\"\n", val);
10321     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10322
10323     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10324     lstrcatA(keypath, usersid);
10325     lstrcatA(keypath, "\\Products\\");
10326     lstrcatA(keypath, prod_squashed);
10327
10328     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10330
10331     /* local UserData product key exists */
10332     size = MAX_PATH;
10333     lstrcpyA(val, "apple");
10334     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10335                             MSIINSTALLCONTEXT_USERUNMANAGED,
10336                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10337     ok(r == ERROR_UNKNOWN_PRODUCT,
10338        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10339     ok(!lstrcmpA(val, "apple"),
10340        "Expected val to be unchanged, got \"%s\"\n", val);
10341     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10342
10343     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10345
10346     /* InstallProperties key exists */
10347     size = MAX_PATH;
10348     lstrcpyA(val, "apple");
10349     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10350                             MSIINSTALLCONTEXT_USERUNMANAGED,
10351                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10352     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10353     ok(!lstrcmpA(val, "apple"),
10354        "Expected val to be unchanged, got \"%s\"\n", val);
10355     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10356
10357     res = RegCreateKeyA(udprod, "Patches", &patches);
10358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10359
10360     /* Patches key exists */
10361     size = MAX_PATH;
10362     lstrcpyA(val, "apple");
10363     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10364                             MSIINSTALLCONTEXT_USERUNMANAGED,
10365                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10366     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10367     ok(!lstrcmpA(val, "apple"),
10368        "Expected val to be unchanged, got \"%s\"\n", val);
10369     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10370
10371     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10373
10374     /* Patches key exists */
10375     size = MAX_PATH;
10376     lstrcpyA(val, "apple");
10377     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10378                             MSIINSTALLCONTEXT_USERUNMANAGED,
10379                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10380     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10381     ok(!lstrcmpA(val, "apple"),
10382        "Expected val to be unchanged, got \"%s\"\n", val);
10383     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10384
10385     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10386     lstrcatA(keypath, prod_squashed);
10387
10388     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10390
10391     /* current user product key exists */
10392     size = MAX_PATH;
10393     lstrcpyA(val, "apple");
10394     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10395                             MSIINSTALLCONTEXT_USERUNMANAGED,
10396                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10397     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10398     ok(!lstrcmpA(val, "apple"),
10399        "Expected val to be unchanged, got \"%s\"\n", val);
10400     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10401
10402     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10404
10405     /* Patches key exists */
10406     size = MAX_PATH;
10407     lstrcpyA(val, "apple");
10408     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10409                             MSIINSTALLCONTEXT_USERUNMANAGED,
10410                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10411     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10412     ok(!lstrcmpA(val, "apple"),
10413        "Expected val to be unchanged, got \"%s\"\n", val);
10414     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10415
10416     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10417                          (const BYTE *)"transforms", 11);
10418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10419
10420     /* specific patch value exists */
10421     size = MAX_PATH;
10422     lstrcpyA(val, "apple");
10423     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10424                             MSIINSTALLCONTEXT_USERUNMANAGED,
10425                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10426     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10427     ok(!lstrcmpA(val, "apple"),
10428        "Expected val to be unchanged, got \"%s\"\n", val);
10429     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10430
10431     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10432     lstrcatA(keypath, usersid);
10433     lstrcatA(keypath, "\\Patches\\");
10434     lstrcatA(keypath, patch_squashed);
10435
10436     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10438
10439     /* UserData Patches key exists */
10440     size = MAX_PATH;
10441     lstrcpyA(val, "apple");
10442     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10443                             MSIINSTALLCONTEXT_USERUNMANAGED,
10444                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10446     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10447     ok(size == 0, "Expected 0, got %d\n", size);
10448
10449     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10450                          (const BYTE *)"pack", 5);
10451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10452
10453     /* LocalPatch value exists */
10454     size = MAX_PATH;
10455     lstrcpyA(val, "apple");
10456     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10457                             MSIINSTALLCONTEXT_USERUNMANAGED,
10458                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10460     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10461     ok(size == 4, "Expected 4, got %d\n", size);
10462
10463     size = MAX_PATH;
10464     lstrcpyA(val, "apple");
10465     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10466                             MSIINSTALLCONTEXT_USERUNMANAGED,
10467                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10468     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10469     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10470     ok(size == 10, "Expected 10, got %d\n", size);
10471
10472     RegDeleteValueA(prodpatches, patch_squashed);
10473     RegDeleteKeyA(prodpatches, "");
10474     RegCloseKey(prodpatches);
10475     RegDeleteKeyA(prodkey, "");
10476     RegCloseKey(prodkey);
10477
10478     /* UserData is sufficient for all properties
10479      * except INSTALLPROPERTY_TRANSFORMS
10480      */
10481     size = MAX_PATH;
10482     lstrcpyA(val, "apple");
10483     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10484                             MSIINSTALLCONTEXT_USERUNMANAGED,
10485                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10487     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10488     ok(size == 4, "Expected 4, got %d\n", size);
10489
10490     /* UserData is sufficient for all properties
10491      * except INSTALLPROPERTY_TRANSFORMS
10492      */
10493     size = MAX_PATH;
10494     lstrcpyA(val, "apple");
10495     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10496                             MSIINSTALLCONTEXT_USERUNMANAGED,
10497                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10498     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10499     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10500     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10501
10502     RegDeleteValueA(udpatch, "LocalPackage");
10503     RegDeleteKeyA(udpatch, "");
10504     RegCloseKey(udpatch);
10505     RegDeleteKeyA(hpatch, "");
10506     RegCloseKey(hpatch);
10507     RegDeleteKeyA(patches, "");
10508     RegCloseKey(patches);
10509     RegDeleteKeyA(props, "");
10510     RegCloseKey(props);
10511     RegDeleteKeyA(udprod, "");
10512     RegCloseKey(udprod);
10513
10514     /* MSIINSTALLCONTEXT_MACHINE */
10515
10516     size = MAX_PATH;
10517     lstrcpyA(val, "apple");
10518     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10519                             MSIINSTALLCONTEXT_MACHINE,
10520                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10521     ok(r == ERROR_UNKNOWN_PRODUCT,
10522        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10523     ok(!lstrcmpA(val, "apple"),
10524        "Expected val to be unchanged, got \"%s\"\n", val);
10525     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10526
10527     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10528     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10529     lstrcatA(keypath, prod_squashed);
10530
10531     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10533
10534     /* local UserData product key exists */
10535     size = MAX_PATH;
10536     lstrcpyA(val, "apple");
10537     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10538                             MSIINSTALLCONTEXT_MACHINE,
10539                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10540     ok(r == ERROR_UNKNOWN_PRODUCT,
10541        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10542     ok(!lstrcmpA(val, "apple"),
10543        "Expected val to be unchanged, got \"%s\"\n", val);
10544     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10545
10546     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10548
10549     /* InstallProperties key exists */
10550     size = MAX_PATH;
10551     lstrcpyA(val, "apple");
10552     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10553                             MSIINSTALLCONTEXT_MACHINE,
10554                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10555     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10556     ok(!lstrcmpA(val, "apple"),
10557        "Expected val to be unchanged, got \"%s\"\n", val);
10558     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10559
10560     res = RegCreateKeyA(udprod, "Patches", &patches);
10561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10562
10563     /* Patches key exists */
10564     size = MAX_PATH;
10565     lstrcpyA(val, "apple");
10566     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10567                             MSIINSTALLCONTEXT_MACHINE,
10568                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10569     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10570     ok(!lstrcmpA(val, "apple"),
10571        "Expected val to be unchanged, got \"%s\"\n", val);
10572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10573
10574     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10576
10577     /* Patches key exists */
10578     size = MAX_PATH;
10579     lstrcpyA(val, "apple");
10580     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10581                             MSIINSTALLCONTEXT_MACHINE,
10582                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10583     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10584     ok(!lstrcmpA(val, "apple"),
10585        "Expected val to be unchanged, got \"%s\"\n", val);
10586     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10587
10588     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10589     lstrcatA(keypath, prod_squashed);
10590
10591     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10593
10594     /* local product key exists */
10595     size = MAX_PATH;
10596     lstrcpyA(val, "apple");
10597     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10598                             MSIINSTALLCONTEXT_MACHINE,
10599                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10600     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10601     ok(!lstrcmpA(val, "apple"),
10602        "Expected val to be unchanged, got \"%s\"\n", val);
10603     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10604
10605     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10607
10608     /* Patches key exists */
10609     size = MAX_PATH;
10610     lstrcpyA(val, "apple");
10611     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10612                             MSIINSTALLCONTEXT_MACHINE,
10613                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10614     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10615     ok(!lstrcmpA(val, "apple"),
10616        "Expected val to be unchanged, got \"%s\"\n", val);
10617     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10618
10619     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10620                          (const BYTE *)"transforms", 11);
10621     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10622
10623     /* specific patch value exists */
10624     size = MAX_PATH;
10625     lstrcpyA(val, "apple");
10626     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10627                             MSIINSTALLCONTEXT_MACHINE,
10628                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10629     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10630     ok(!lstrcmpA(val, "apple"),
10631        "Expected val to be unchanged, got \"%s\"\n", val);
10632     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10633
10634     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10635     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10636     lstrcatA(keypath, patch_squashed);
10637
10638     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10640
10641     /* UserData Patches key exists */
10642     size = MAX_PATH;
10643     lstrcpyA(val, "apple");
10644     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10645                             MSIINSTALLCONTEXT_MACHINE,
10646                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10648     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10649     ok(size == 0, "Expected 0, got %d\n", size);
10650
10651     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10652                          (const BYTE *)"pack", 5);
10653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10654
10655     /* LocalPatch value exists */
10656     size = MAX_PATH;
10657     lstrcpyA(val, "apple");
10658     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10659                             MSIINSTALLCONTEXT_MACHINE,
10660                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10662     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10663     ok(size == 4, "Expected 4, got %d\n", size);
10664
10665     size = MAX_PATH;
10666     lstrcpyA(val, "apple");
10667     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10668                             MSIINSTALLCONTEXT_MACHINE,
10669                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10671     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10672     ok(size == 10, "Expected 10, got %d\n", size);
10673
10674     RegDeleteValueA(prodpatches, patch_squashed);
10675     RegDeleteKeyA(prodpatches, "");
10676     RegCloseKey(prodpatches);
10677     RegDeleteKeyA(prodkey, "");
10678     RegCloseKey(prodkey);
10679
10680     /* UserData is sufficient for all properties
10681      * except INSTALLPROPERTY_TRANSFORMS
10682      */
10683     size = MAX_PATH;
10684     lstrcpyA(val, "apple");
10685     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10686                             MSIINSTALLCONTEXT_MACHINE,
10687                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10689     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10690     ok(size == 4, "Expected 4, got %d\n", size);
10691
10692     /* UserData is sufficient for all properties
10693      * except INSTALLPROPERTY_TRANSFORMS
10694      */
10695     size = MAX_PATH;
10696     lstrcpyA(val, "apple");
10697     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10698                             MSIINSTALLCONTEXT_MACHINE,
10699                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10700     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10701     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10702     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10703
10704     RegDeleteValueA(udpatch, "LocalPackage");
10705     RegDeleteKeyA(udpatch, "");
10706     RegCloseKey(udpatch);
10707     RegDeleteKeyA(hpatch, "");
10708     RegCloseKey(hpatch);
10709     RegDeleteKeyA(patches, "");
10710     RegCloseKey(patches);
10711     RegDeleteKeyA(props, "");
10712     RegCloseKey(props);
10713     RegDeleteKeyA(udprod, "");
10714     RegCloseKey(udprod);
10715 }
10716
10717 START_TEST(msi)
10718 {
10719     init_functionpointers();
10720
10721     test_usefeature();
10722     test_null();
10723     test_getcomponentpath();
10724     test_MsiGetFileHash();
10725
10726     if (!pConvertSidToStringSidA)
10727         skip("ConvertSidToStringSidA not implemented\n");
10728     else
10729     {
10730         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10731         test_MsiQueryProductState();
10732         test_MsiQueryFeatureState();
10733         test_MsiQueryComponentState();
10734         test_MsiGetComponentPath();
10735         test_MsiGetProductCode();
10736         test_MsiEnumClients();
10737         test_MsiGetProductInfo();
10738         test_MsiGetProductInfoEx();
10739         test_MsiGetUserInfo();
10740         test_MsiOpenProduct();
10741         test_MsiEnumPatchesEx();
10742         test_MsiEnumPatches();
10743         test_MsiGetPatchInfoEx();
10744     }
10745
10746     test_MsiGetFileVersion();
10747 }