comctl32/tests: Destroy the window after the tests.
[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     RegCloseKey(installprop);
1764     DeleteFileA("C:\\imapath");
1765
1766     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1767     lstrcatA(keypath, prod_squashed);
1768
1769     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1771
1772     /* local classes product key exists */
1773     size = MAX_PATH;
1774     state = MsiGetComponentPathA(prodcode, component, path, &size);
1775     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1776     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1777
1778     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1779     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1780     lstrcatA(keypath, comp_squashed);
1781
1782     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1784
1785     /* local user component key exists */
1786     size = MAX_PATH;
1787     state = MsiGetComponentPathA(prodcode, component, path, &size);
1788     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1789     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1790
1791     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1793
1794     /* product value exists */
1795     size = MAX_PATH;
1796     state = MsiGetComponentPathA(prodcode, component, path, &size);
1797     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1798     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1799     ok(size == 10, "Expected 10, got %d\n", size);
1800
1801     create_file("C:\\imapath", "C:\\imapath", 11);
1802
1803     /* file exists */
1804     size = MAX_PATH;
1805     state = MsiGetComponentPathA(prodcode, component, path, &size);
1806     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1807     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1808     ok(size == 10, "Expected 10, got %d\n", size);
1809
1810     RegDeleteValueA(compkey, prod_squashed);
1811     RegDeleteKeyA(prodkey, "");
1812     RegDeleteKeyA(compkey, "");
1813     RegCloseKey(prodkey);
1814     RegCloseKey(compkey);
1815     DeleteFileA("C:\\imapath");
1816 }
1817
1818 static void test_MsiGetProductCode(void)
1819 {
1820     HKEY compkey, prodkey;
1821     CHAR prodcode[MAX_PATH];
1822     CHAR prod_squashed[MAX_PATH];
1823     CHAR prodcode2[MAX_PATH];
1824     CHAR prod2_squashed[MAX_PATH];
1825     CHAR component[MAX_PATH];
1826     CHAR comp_base85[MAX_PATH];
1827     CHAR comp_squashed[MAX_PATH];
1828     CHAR keypath[MAX_PATH];
1829     CHAR product[MAX_PATH];
1830     LPSTR usersid;
1831     LONG res;
1832     UINT r;
1833
1834     create_test_guid(prodcode, prod_squashed);
1835     create_test_guid(prodcode2, prod2_squashed);
1836     compose_base85_guid(component, comp_base85, comp_squashed);
1837     get_user_sid(&usersid);
1838
1839     /* szComponent is NULL */
1840     lstrcpyA(product, "prod");
1841     r = MsiGetProductCodeA(NULL, product);
1842     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1843     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1844
1845     /* szComponent is empty */
1846     lstrcpyA(product, "prod");
1847     r = MsiGetProductCodeA("", product);
1848     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1849     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1850
1851     /* garbage szComponent */
1852     lstrcpyA(product, "prod");
1853     r = MsiGetProductCodeA("garbage", product);
1854     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1855     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1856
1857     /* guid without brackets */
1858     lstrcpyA(product, "prod");
1859     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1860     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1861     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1862
1863     /* guid with brackets */
1864     lstrcpyA(product, "prod");
1865     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1866     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1867     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1868
1869     /* same length as guid, but random */
1870     lstrcpyA(product, "prod");
1871     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1872     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1873     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1874
1875     /* all params correct, szComponent not published */
1876     lstrcpyA(product, "prod");
1877     r = MsiGetProductCodeA(component, product);
1878     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1879     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1880
1881     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1882     lstrcatA(keypath, "Installer\\UserData\\");
1883     lstrcatA(keypath, usersid);
1884     lstrcatA(keypath, "\\Components\\");
1885     lstrcatA(keypath, comp_squashed);
1886
1887     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1889
1890     /* user unmanaged component key exists */
1891     lstrcpyA(product, "prod");
1892     r = MsiGetProductCodeA(component, product);
1893     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1894     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1895
1896     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1897     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1898
1899     /* product value exists */
1900     lstrcpyA(product, "prod");
1901     r = MsiGetProductCodeA(component, product);
1902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1903     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1904
1905     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1907
1908     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1909     lstrcatA(keypath, "Installer\\Managed\\");
1910     lstrcatA(keypath, usersid);
1911     lstrcatA(keypath, "\\Installer\\Products\\");
1912     lstrcatA(keypath, prod_squashed);
1913
1914     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1916
1917     /* user managed product key of first product exists */
1918     lstrcpyA(product, "prod");
1919     r = MsiGetProductCodeA(component, product);
1920     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1921     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1922
1923     RegDeleteKeyA(prodkey, "");
1924     RegCloseKey(prodkey);
1925
1926     RegDeleteKeyA(prodkey, "");
1927     RegCloseKey(prodkey);
1928
1929     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1930     lstrcatA(keypath, prod_squashed);
1931
1932     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1934
1935     /* user unmanaged product key exists */
1936     lstrcpyA(product, "prod");
1937     r = MsiGetProductCodeA(component, product);
1938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1939     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1940
1941     RegDeleteKeyA(prodkey, "");
1942     RegCloseKey(prodkey);
1943
1944     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1945     lstrcatA(keypath, prod_squashed);
1946
1947     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1949
1950     /* local classes product key exists */
1951     lstrcpyA(product, "prod");
1952     r = MsiGetProductCodeA(component, product);
1953     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1954     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1955
1956     RegDeleteKeyA(prodkey, "");
1957     RegCloseKey(prodkey);
1958
1959     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1960     lstrcatA(keypath, "Installer\\Managed\\");
1961     lstrcatA(keypath, usersid);
1962     lstrcatA(keypath, "\\Installer\\Products\\");
1963     lstrcatA(keypath, prod2_squashed);
1964
1965     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1967
1968     /* user managed product key of second product exists */
1969     lstrcpyA(product, "prod");
1970     r = MsiGetProductCodeA(component, product);
1971     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1972     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1973
1974     RegDeleteKeyA(prodkey, "");
1975     RegCloseKey(prodkey);
1976     RegDeleteValueA(compkey, prod_squashed);
1977     RegDeleteValueA(compkey, prod2_squashed);
1978     RegDeleteKeyA(compkey, "");
1979     RegCloseKey(compkey);
1980
1981     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1982     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1983     lstrcatA(keypath, comp_squashed);
1984
1985     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1987
1988     /* local user component key exists */
1989     lstrcpyA(product, "prod");
1990     r = MsiGetProductCodeA(component, product);
1991     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1992     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1993
1994     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1996
1997     /* product value exists */
1998     lstrcpyA(product, "prod");
1999     r = MsiGetProductCodeA(component, product);
2000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2001     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2002
2003     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2005
2006     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2007     lstrcatA(keypath, "Installer\\Managed\\");
2008     lstrcatA(keypath, usersid);
2009     lstrcatA(keypath, "\\Installer\\Products\\");
2010     lstrcatA(keypath, prod_squashed);
2011
2012     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2014
2015     /* user managed product key of first product exists */
2016     lstrcpyA(product, "prod");
2017     r = MsiGetProductCodeA(component, product);
2018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2019     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2020
2021     RegDeleteKeyA(prodkey, "");
2022     RegCloseKey(prodkey);
2023
2024     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2025     lstrcatA(keypath, prod_squashed);
2026
2027     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2029
2030     /* user unmanaged product key exists */
2031     lstrcpyA(product, "prod");
2032     r = MsiGetProductCodeA(component, product);
2033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2034     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2035
2036     RegDeleteKeyA(prodkey, "");
2037     RegCloseKey(prodkey);
2038
2039     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2040     lstrcatA(keypath, prod_squashed);
2041
2042     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2044
2045     /* local classes product key exists */
2046     lstrcpyA(product, "prod");
2047     r = MsiGetProductCodeA(component, product);
2048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2049     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2050
2051     RegDeleteKeyA(prodkey, "");
2052     RegCloseKey(prodkey);
2053
2054     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2055     lstrcatA(keypath, "Installer\\Managed\\");
2056     lstrcatA(keypath, usersid);
2057     lstrcatA(keypath, "\\Installer\\Products\\");
2058     lstrcatA(keypath, prod2_squashed);
2059
2060     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2062
2063     /* user managed product key of second product exists */
2064     lstrcpyA(product, "prod");
2065     r = MsiGetProductCodeA(component, product);
2066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2067     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2068
2069     RegDeleteKeyA(prodkey, "");
2070     RegCloseKey(prodkey);
2071     RegDeleteValueA(compkey, prod_squashed);
2072     RegDeleteValueA(compkey, prod2_squashed);
2073     RegDeleteKeyA(compkey, "");
2074     RegCloseKey(compkey);
2075 }
2076
2077 static void test_MsiEnumClients(void)
2078 {
2079     HKEY compkey;
2080     CHAR prodcode[MAX_PATH];
2081     CHAR prod_squashed[MAX_PATH];
2082     CHAR prodcode2[MAX_PATH];
2083     CHAR prod2_squashed[MAX_PATH];
2084     CHAR component[MAX_PATH];
2085     CHAR comp_base85[MAX_PATH];
2086     CHAR comp_squashed[MAX_PATH];
2087     CHAR product[MAX_PATH];
2088     CHAR keypath[MAX_PATH];
2089     LPSTR usersid;
2090     LONG res;
2091     UINT r;
2092
2093     create_test_guid(prodcode, prod_squashed);
2094     create_test_guid(prodcode2, prod2_squashed);
2095     compose_base85_guid(component, comp_base85, comp_squashed);
2096     get_user_sid(&usersid);
2097
2098     /* NULL szComponent */
2099     product[0] = '\0';
2100     r = MsiEnumClientsA(NULL, 0, product);
2101     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2102     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2103
2104     /* empty szComponent */
2105     product[0] = '\0';
2106     r = MsiEnumClientsA("", 0, product);
2107     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2108     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2109
2110     /* NULL lpProductBuf */
2111     r = MsiEnumClientsA(component, 0, NULL);
2112     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2113
2114     /* all params correct, component missing */
2115     product[0] = '\0';
2116     r = MsiEnumClientsA(component, 0, product);
2117     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2118     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2119
2120     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2121     lstrcatA(keypath, "Installer\\UserData\\");
2122     lstrcatA(keypath, usersid);
2123     lstrcatA(keypath, "\\Components\\");
2124     lstrcatA(keypath, comp_squashed);
2125
2126     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2128
2129     /* user unmanaged component key exists */
2130     product[0] = '\0';
2131     r = MsiEnumClientsA(component, 0, product);
2132     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2133     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2134
2135     /* index > 0, no products exist */
2136     product[0] = '\0';
2137     r = MsiEnumClientsA(component, 1, product);
2138     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2139     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2140
2141     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2143
2144     /* product value exists */
2145     r = MsiEnumClientsA(component, 0, product);
2146     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2147     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2148
2149     /* try index 0 again */
2150     product[0] = '\0';
2151     r = MsiEnumClientsA(component, 0, product);
2152     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2153     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2154
2155     /* try index 1, second product value does not exist */
2156     product[0] = '\0';
2157     r = MsiEnumClientsA(component, 1, product);
2158     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2159     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2160
2161     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2163
2164     /* try index 1, second product value does exist */
2165     product[0] = '\0';
2166     r = MsiEnumClientsA(component, 1, product);
2167     todo_wine
2168     {
2169         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2170         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2171     }
2172
2173     /* start the enumeration over */
2174     product[0] = '\0';
2175     r = MsiEnumClientsA(component, 0, product);
2176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2177     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2178        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2179
2180     /* correctly query second product */
2181     product[0] = '\0';
2182     r = MsiEnumClientsA(component, 1, product);
2183     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2184     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2185        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2186
2187     RegDeleteValueA(compkey, prod_squashed);
2188     RegDeleteValueA(compkey, prod2_squashed);
2189     RegDeleteKeyA(compkey, "");
2190     RegCloseKey(compkey);
2191
2192     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2193     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2194     lstrcatA(keypath, comp_squashed);
2195
2196     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2198
2199     /* user local component key exists */
2200     product[0] = '\0';
2201     r = MsiEnumClientsA(component, 0, product);
2202     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2203     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2204
2205     /* index > 0, no products exist */
2206     product[0] = '\0';
2207     r = MsiEnumClientsA(component, 1, product);
2208     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2209     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2210
2211     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2213
2214     /* product value exists */
2215     product[0] = '\0';
2216     r = MsiEnumClientsA(component, 0, product);
2217     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2218     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2219
2220     /* try index 0 again */
2221     product[0] = '\0';
2222     r = MsiEnumClientsA(component, 0, product);
2223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2224
2225     /* try index 1, second product value does not exist */
2226     product[0] = '\0';
2227     r = MsiEnumClientsA(component, 1, product);
2228     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2229     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2230
2231     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2233
2234     /* try index 1, second product value does exist */
2235     product[0] = '\0';
2236     r = MsiEnumClientsA(component, 1, product);
2237     todo_wine
2238     {
2239         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2240         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2241     }
2242
2243     /* start the enumeration over */
2244     product[0] = '\0';
2245     r = MsiEnumClientsA(component, 0, product);
2246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2247     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2248        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2249
2250     /* correctly query second product */
2251     product[0] = '\0';
2252     r = MsiEnumClientsA(component, 1, product);
2253     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2254     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2255        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2256
2257     RegDeleteValueA(compkey, prod_squashed);
2258     RegDeleteValueA(compkey, prod2_squashed);
2259     RegDeleteKeyA(compkey, "");
2260     RegCloseKey(compkey);
2261 }
2262
2263 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2264                              LPSTR *langcheck, LPDWORD langchecksz)
2265 {
2266     LPSTR version;
2267     VS_FIXEDFILEINFO *ffi;
2268     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2269     USHORT *lang;
2270
2271     version = HeapAlloc(GetProcessHeap(), 0, size);
2272     GetFileVersionInfoA(path, 0, size, version);
2273
2274     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2275     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2276     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2277             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2278             LOWORD(ffi->dwFileVersionLS));
2279     *verchecksz = lstrlenA(*vercheck);
2280
2281     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2282     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2283     sprintf(*langcheck, "%d", *lang);
2284     *langchecksz = lstrlenA(*langcheck);
2285
2286     HeapFree(GetProcessHeap(), 0, version);
2287 }
2288
2289 static void test_MsiGetFileVersion(void)
2290 {
2291     UINT r;
2292     DWORD versz, langsz;
2293     char version[MAX_PATH];
2294     char lang[MAX_PATH];
2295     char path[MAX_PATH];
2296     LPSTR vercheck, langcheck;
2297     DWORD verchecksz, langchecksz;
2298
2299     /* NULL szFilePath */
2300     versz = MAX_PATH;
2301     langsz = MAX_PATH;
2302     lstrcpyA(version, "version");
2303     lstrcpyA(lang, "lang");
2304     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2305     ok(r == ERROR_INVALID_PARAMETER,
2306        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2307     ok(!lstrcmpA(version, "version"),
2308        "Expected version to be unchanged, got %s\n", version);
2309     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2310     ok(!lstrcmpA(lang, "lang"),
2311        "Expected lang to be unchanged, got %s\n", lang);
2312     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2313
2314     /* empty szFilePath */
2315     versz = MAX_PATH;
2316     langsz = MAX_PATH;
2317     lstrcpyA(version, "version");
2318     lstrcpyA(lang, "lang");
2319     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2320     ok(r == ERROR_FILE_NOT_FOUND,
2321        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2322     ok(!lstrcmpA(version, "version"),
2323        "Expected version to be unchanged, got %s\n", version);
2324     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2325     ok(!lstrcmpA(lang, "lang"),
2326        "Expected lang to be unchanged, got %s\n", lang);
2327     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2328
2329     /* nonexistent szFilePath */
2330     versz = MAX_PATH;
2331     langsz = MAX_PATH;
2332     lstrcpyA(version, "version");
2333     lstrcpyA(lang, "lang");
2334     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2335     ok(r == ERROR_FILE_NOT_FOUND,
2336        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2337     ok(!lstrcmpA(version, "version"),
2338        "Expected version to be unchanged, got %s\n", version);
2339     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2340     ok(!lstrcmpA(lang, "lang"),
2341        "Expected lang to be unchanged, got %s\n", lang);
2342     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2343
2344     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2345     versz = MAX_PATH;
2346     langsz = MAX_PATH;
2347     lstrcpyA(version, "version");
2348     lstrcpyA(lang, "lang");
2349     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2350     ok(r == ERROR_INVALID_PARAMETER,
2351        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2352     ok(!lstrcmpA(version, "version"),
2353        "Expected version to be unchanged, got %s\n", version);
2354     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2355     ok(!lstrcmpA(lang, "lang"),
2356        "Expected lang to be unchanged, got %s\n", lang);
2357     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2358
2359     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2360     versz = MAX_PATH;
2361     langsz = MAX_PATH;
2362     lstrcpyA(version, "version");
2363     lstrcpyA(lang, "lang");
2364     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2365     ok(r == ERROR_INVALID_PARAMETER,
2366        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2367     ok(!lstrcmpA(version, "version"),
2368        "Expected version to be unchanged, got %s\n", version);
2369     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2370     ok(!lstrcmpA(lang, "lang"),
2371        "Expected lang to be unchanged, got %s\n", lang);
2372     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2373
2374     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2375     versz = 0;
2376     langsz = MAX_PATH;
2377     lstrcpyA(version, "version");
2378     lstrcpyA(lang, "lang");
2379     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2380     ok(r == ERROR_FILE_NOT_FOUND,
2381        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2382     ok(!lstrcmpA(version, "version"),
2383        "Expected version to be unchanged, got %s\n", version);
2384     ok(versz == 0, "Expected 0, got %d\n", versz);
2385     ok(!lstrcmpA(lang, "lang"),
2386        "Expected lang to be unchanged, got %s\n", lang);
2387     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2388
2389     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2390     versz = MAX_PATH;
2391     langsz = 0;
2392     lstrcpyA(version, "version");
2393     lstrcpyA(lang, "lang");
2394     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2395     ok(r == ERROR_FILE_NOT_FOUND,
2396        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2397     ok(!lstrcmpA(version, "version"),
2398        "Expected version to be unchanged, got %s\n", version);
2399     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2400     ok(!lstrcmpA(lang, "lang"),
2401        "Expected lang to be unchanged, got %s\n", lang);
2402     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2403
2404     /* nonexistent szFilePath, rest NULL */
2405     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2406     ok(r == ERROR_FILE_NOT_FOUND,
2407        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2408
2409     create_file("ver.txt", "ver.txt", 20);
2410
2411     /* file exists, no version information */
2412     versz = MAX_PATH;
2413     langsz = MAX_PATH;
2414     lstrcpyA(version, "version");
2415     lstrcpyA(lang, "lang");
2416     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2417     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2418     ok(!lstrcmpA(version, "version"),
2419        "Expected version to be unchanged, got %s\n", version);
2420     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2421     ok(!lstrcmpA(lang, "lang"),
2422        "Expected lang to be unchanged, got %s\n", lang);
2423     ok(r == ERROR_FILE_INVALID,
2424        "Expected ERROR_FILE_INVALID, got %d\n", r);
2425
2426     DeleteFileA("ver.txt");
2427
2428     /* relative path, has version information */
2429     versz = MAX_PATH;
2430     langsz = MAX_PATH;
2431     lstrcpyA(version, "version");
2432     lstrcpyA(lang, "lang");
2433     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2434     todo_wine
2435     {
2436         ok(r == ERROR_FILE_NOT_FOUND,
2437            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2438         ok(!lstrcmpA(version, "version"),
2439            "Expected version to be unchanged, got %s\n", version);
2440         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2441         ok(!lstrcmpA(lang, "lang"),
2442            "Expected lang to be unchanged, got %s\n", lang);
2443         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2444     }
2445
2446     GetSystemDirectoryA(path, MAX_PATH);
2447     lstrcatA(path, "\\kernel32.dll");
2448
2449     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2450
2451     /* absolute path, has version information */
2452     versz = MAX_PATH;
2453     langsz = MAX_PATH;
2454     lstrcpyA(version, "version");
2455     lstrcpyA(lang, "lang");
2456     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2458     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2459     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2460     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2461     ok(!lstrcmpA(version, vercheck),
2462         "Expected %s, got %s\n", vercheck, version);
2463
2464     /* only check version */
2465     versz = MAX_PATH;
2466     lstrcpyA(version, "version");
2467     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2468     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2469     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2470     ok(!lstrcmpA(version, vercheck),
2471        "Expected %s, got %s\n", vercheck, version);
2472
2473     /* only check language */
2474     langsz = MAX_PATH;
2475     lstrcpyA(lang, "lang");
2476     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2477     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2478     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2479     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2480
2481     /* check neither version nor language */
2482     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2484
2485     /* get pcchVersionBuf */
2486     versz = MAX_PATH;
2487     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2488     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2489     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2490
2491     /* get pcchLangBuf */
2492     langsz = MAX_PATH;
2493     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2494     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2495     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2496
2497     /* pcchVersionBuf not big enough */
2498     versz = 5;
2499     lstrcpyA(version, "version");
2500     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2501     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2502     ok(!strncmp(version, vercheck, 4),
2503        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2504     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2505
2506     /* pcchLangBuf not big enough */
2507     langsz = 3;
2508     lstrcpyA(lang, "lang");
2509     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2510     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2511     ok(!strncmp(lang, langcheck, 2),
2512        "Expected first character of %s, got %s\n", langcheck, lang);
2513     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2514
2515     HeapFree(GetProcessHeap(), 0, vercheck);
2516     HeapFree(GetProcessHeap(), 0, langcheck);
2517 }
2518
2519 static void test_MsiGetProductInfo(void)
2520 {
2521     UINT r;
2522     LONG res;
2523     HKEY propkey, source;
2524     HKEY prodkey, localkey;
2525     CHAR prodcode[MAX_PATH];
2526     CHAR prod_squashed[MAX_PATH];
2527     CHAR packcode[MAX_PATH];
2528     CHAR pack_squashed[MAX_PATH];
2529     CHAR buf[MAX_PATH];
2530     CHAR keypath[MAX_PATH];
2531     LPSTR usersid;
2532     DWORD sz, val = 42;
2533
2534     create_test_guid(prodcode, prod_squashed);
2535     create_test_guid(packcode, pack_squashed);
2536     get_user_sid(&usersid);
2537
2538     /* NULL szProduct */
2539     sz = MAX_PATH;
2540     lstrcpyA(buf, "apple");
2541     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2542     ok(r == ERROR_INVALID_PARAMETER,
2543        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2544     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2545     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2546
2547     /* empty szProduct */
2548     sz = MAX_PATH;
2549     lstrcpyA(buf, "apple");
2550     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2551     ok(r == ERROR_INVALID_PARAMETER,
2552        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2553     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2554     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2555
2556     /* garbage szProduct */
2557     sz = MAX_PATH;
2558     lstrcpyA(buf, "apple");
2559     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2560     ok(r == ERROR_INVALID_PARAMETER,
2561        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2562     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2563     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2564
2565     /* guid without brackets */
2566     sz = MAX_PATH;
2567     lstrcpyA(buf, "apple");
2568     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2569                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2570     ok(r == ERROR_INVALID_PARAMETER,
2571        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2572     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2573     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2574
2575     /* guid with brackets */
2576     sz = MAX_PATH;
2577     lstrcpyA(buf, "apple");
2578     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2579                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2580     ok(r == ERROR_UNKNOWN_PRODUCT,
2581        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2582     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2583     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2584
2585     /* same length as guid, but random */
2586     sz = MAX_PATH;
2587     lstrcpyA(buf, "apple");
2588     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2589                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2590     ok(r == ERROR_INVALID_PARAMETER,
2591        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2592     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2593     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2594
2595     /* not installed, NULL szAttribute */
2596     sz = MAX_PATH;
2597     lstrcpyA(buf, "apple");
2598     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2599     ok(r == ERROR_INVALID_PARAMETER,
2600        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2601     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2602     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2603
2604     /* not installed, NULL lpValueBuf */
2605     sz = MAX_PATH;
2606     lstrcpyA(buf, "apple");
2607     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2608     ok(r == ERROR_UNKNOWN_PRODUCT,
2609        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2610     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2611     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2612
2613     /* not installed, NULL pcchValueBuf */
2614     sz = MAX_PATH;
2615     lstrcpyA(buf, "apple");
2616     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2617     ok(r == ERROR_INVALID_PARAMETER,
2618        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2619     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2620     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2621
2622     /* created guid cannot possibly be an installed product code */
2623     sz = MAX_PATH;
2624     lstrcpyA(buf, "apple");
2625     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2626     ok(r == ERROR_UNKNOWN_PRODUCT,
2627        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2628     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2629     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2630
2631     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2632     lstrcatA(keypath, usersid);
2633     lstrcatA(keypath, "\\Installer\\Products\\");
2634     lstrcatA(keypath, prod_squashed);
2635
2636     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2638
2639     /* managed product code exists */
2640     sz = MAX_PATH;
2641     lstrcpyA(buf, "apple");
2642     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2643     ok(r == ERROR_UNKNOWN_PROPERTY,
2644        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2645     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2646     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2647
2648     RegDeleteKeyA(prodkey, "");
2649     RegCloseKey(prodkey);
2650
2651     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2652     lstrcatA(keypath, usersid);
2653     lstrcatA(keypath, "\\Products\\");
2654     lstrcatA(keypath, prod_squashed);
2655
2656     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2658
2659     /* local user product code exists */
2660     sz = MAX_PATH;
2661     lstrcpyA(buf, "apple");
2662     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2663     ok(r == ERROR_UNKNOWN_PRODUCT,
2664        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2665     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2666     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2667
2668     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2669     lstrcatA(keypath, usersid);
2670     lstrcatA(keypath, "\\Installer\\Products\\");
2671     lstrcatA(keypath, prod_squashed);
2672
2673     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2675
2676     /* both local and managed product code exist */
2677     sz = MAX_PATH;
2678     lstrcpyA(buf, "apple");
2679     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2680     ok(r == ERROR_UNKNOWN_PROPERTY,
2681        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2682     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2683     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2684
2685     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2687
2688     /* InstallProperties key exists */
2689     sz = MAX_PATH;
2690     lstrcpyA(buf, "apple");
2691     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2692     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2693     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2694     ok(sz == 0, "Expected 0, got %d\n", sz);
2695
2696     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2697     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2698
2699     /* HelpLink value exists */
2700     sz = MAX_PATH;
2701     lstrcpyA(buf, "apple");
2702     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2704     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2705     ok(sz == 4, "Expected 4, got %d\n", sz);
2706
2707     /* pcchBuf is NULL */
2708     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2709     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2710
2711     /* lpValueBuf is NULL */
2712     sz = MAX_PATH;
2713     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2715     ok(sz == 4, "Expected 4, got %d\n", sz);
2716
2717     /* lpValueBuf is NULL, pcchValueBuf is too small */
2718     sz = 2;
2719     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2720     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2721     ok(sz == 4, "Expected 4, got %d\n", sz);
2722
2723     /* lpValueBuf is NULL, pcchValueBuf is too small */
2724     sz = 2;
2725     lstrcpyA(buf, "apple");
2726     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2727     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2728     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2729     ok(sz == 4, "Expected 4, got %d\n", sz);
2730
2731     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2732     sz = 4;
2733     lstrcpyA(buf, "apple");
2734     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2735     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2736     ok(!lstrcmpA(buf, "apple"),
2737        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2738     ok(sz == 4, "Expected 4, got %d\n", sz);
2739
2740     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2742
2743     /* random property not supported by MSI, value exists */
2744     sz = MAX_PATH;
2745     lstrcpyA(buf, "apple");
2746     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2747     ok(r == ERROR_UNKNOWN_PROPERTY,
2748        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2749     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2750     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2751
2752     RegDeleteValueA(propkey, "IMadeThis");
2753     RegDeleteValueA(propkey, "HelpLink");
2754     RegDeleteKeyA(propkey, "");
2755     RegDeleteKeyA(localkey, "");
2756     RegDeleteKeyA(prodkey, "");
2757     RegCloseKey(propkey);
2758     RegCloseKey(localkey);
2759     RegCloseKey(prodkey);
2760
2761     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2762     lstrcatA(keypath, prod_squashed);
2763
2764     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2766
2767     /* user product key exists */
2768     sz = MAX_PATH;
2769     lstrcpyA(buf, "apple");
2770     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2771     ok(r == ERROR_UNKNOWN_PROPERTY,
2772        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2773     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2774     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2775
2776     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2777     lstrcatA(keypath, usersid);
2778     lstrcatA(keypath, "\\Products\\");
2779     lstrcatA(keypath, prod_squashed);
2780
2781     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2783
2784     /* local user product key exists */
2785     sz = MAX_PATH;
2786     lstrcpyA(buf, "apple");
2787     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2788     ok(r == ERROR_UNKNOWN_PROPERTY,
2789        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2790     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2791     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2792
2793     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2794     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2795
2796     /* InstallProperties key exists */
2797     sz = MAX_PATH;
2798     lstrcpyA(buf, "apple");
2799     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2801     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2802     ok(sz == 0, "Expected 0, got %d\n", sz);
2803
2804     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2805     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2806
2807     /* HelpLink value exists */
2808     sz = MAX_PATH;
2809     lstrcpyA(buf, "apple");
2810     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2812     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2813     ok(sz == 4, "Expected 4, got %d\n", sz);
2814
2815     RegDeleteValueA(propkey, "HelpLink");
2816     RegDeleteKeyA(propkey, "");
2817     RegDeleteKeyA(localkey, "");
2818     RegDeleteKeyA(prodkey, "");
2819     RegCloseKey(propkey);
2820     RegCloseKey(localkey);
2821     RegCloseKey(prodkey);
2822
2823     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2824     lstrcatA(keypath, prod_squashed);
2825
2826     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2827     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2828
2829     /* classes product key exists */
2830     sz = MAX_PATH;
2831     lstrcpyA(buf, "apple");
2832     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2833     ok(r == ERROR_UNKNOWN_PROPERTY,
2834        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2835     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2836     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2837
2838     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2839     lstrcatA(keypath, usersid);
2840     lstrcatA(keypath, "\\Products\\");
2841     lstrcatA(keypath, prod_squashed);
2842
2843     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2845
2846     /* local user product key exists */
2847     sz = MAX_PATH;
2848     lstrcpyA(buf, "apple");
2849     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2850     ok(r == ERROR_UNKNOWN_PROPERTY,
2851        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2852     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2853     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2854
2855     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2856     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2857
2858     /* InstallProperties key exists */
2859     sz = MAX_PATH;
2860     lstrcpyA(buf, "apple");
2861     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2862     ok(r == ERROR_UNKNOWN_PROPERTY,
2863        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2864     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2865     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2866
2867     RegDeleteKeyA(propkey, "");
2868     RegDeleteKeyA(localkey, "");
2869     RegCloseKey(propkey);
2870     RegCloseKey(localkey);
2871
2872     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2873     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2874     lstrcatA(keypath, prod_squashed);
2875
2876     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2878
2879     /* Local System product key exists */
2880     sz = MAX_PATH;
2881     lstrcpyA(buf, "apple");
2882     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2883     ok(r == ERROR_UNKNOWN_PROPERTY,
2884         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2885     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2886     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2887
2888     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2890
2891     /* InstallProperties key exists */
2892     sz = MAX_PATH;
2893     lstrcpyA(buf, "apple");
2894     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2895     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2896     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2897     ok(sz == 0, "Expected 0, got %d\n", sz);
2898
2899     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2901
2902     /* HelpLink value exists */
2903     sz = MAX_PATH;
2904     lstrcpyA(buf, "apple");
2905     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2906     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2907     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2908     ok(sz == 4, "Expected 4, got %d\n", sz);
2909
2910     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2911                          (const BYTE *)&val, sizeof(DWORD));
2912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2913
2914     /* HelpLink type is REG_DWORD */
2915     sz = MAX_PATH;
2916     lstrcpyA(buf, "apple");
2917     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2919     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2920     ok(sz == 2, "Expected 2, got %d\n", sz);
2921
2922     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2924
2925     /* DisplayName value exists */
2926     sz = MAX_PATH;
2927     lstrcpyA(buf, "apple");
2928     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2929     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2930     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2931     ok(sz == 4, "Expected 4, got %d\n", sz);
2932
2933     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2934                          (const BYTE *)&val, sizeof(DWORD));
2935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2936
2937     /* DisplayName type is REG_DWORD */
2938     sz = MAX_PATH;
2939     lstrcpyA(buf, "apple");
2940     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2942     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2943     ok(sz == 2, "Expected 2, got %d\n", sz);
2944
2945     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
2946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2947
2948     /* DisplayVersion value exists */
2949     sz = MAX_PATH;
2950     lstrcpyA(buf, "apple");
2951     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2953     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
2954     ok(sz == 5, "Expected 5, got %d\n", sz);
2955
2956     res = RegSetValueExA(propkey, "DisplayVersion", 0,
2957                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2959
2960     /* DisplayVersion type is REG_DWORD */
2961     sz = MAX_PATH;
2962     lstrcpyA(buf, "apple");
2963     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2965     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2966     ok(sz == 2, "Expected 2, got %d\n", sz);
2967
2968     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
2969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2970
2971     /* HelpTelephone value exists */
2972     sz = MAX_PATH;
2973     lstrcpyA(buf, "apple");
2974     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2975     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2976     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
2977     ok(sz == 4, "Expected 4, got %d\n", sz);
2978
2979     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
2980                          (const BYTE *)&val, sizeof(DWORD));
2981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2982
2983     /* HelpTelephone type is REG_DWORD */
2984     sz = MAX_PATH;
2985     lstrcpyA(buf, "apple");
2986     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2988     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2989     ok(sz == 2, "Expected 2, got %d\n", sz);
2990
2991     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
2992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2993
2994     /* InstallLocation value exists */
2995     sz = MAX_PATH;
2996     lstrcpyA(buf, "apple");
2997     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
2998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2999     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3000     ok(sz == 3, "Expected 3, got %d\n", sz);
3001
3002     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3003                          (const BYTE *)&val, sizeof(DWORD));
3004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3005
3006     /* InstallLocation type is REG_DWORD */
3007     sz = MAX_PATH;
3008     lstrcpyA(buf, "apple");
3009     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3010     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3011     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3012     ok(sz == 2, "Expected 2, got %d\n", sz);
3013
3014     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3015     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3016
3017     /* InstallSource value exists */
3018     sz = MAX_PATH;
3019     lstrcpyA(buf, "apple");
3020     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3022     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3023     ok(sz == 6, "Expected 6, got %d\n", sz);
3024
3025     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3026                          (const BYTE *)&val, sizeof(DWORD));
3027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3028
3029     /* InstallSource type is REG_DWORD */
3030     sz = MAX_PATH;
3031     lstrcpyA(buf, "apple");
3032     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3034     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3035     ok(sz == 2, "Expected 2, got %d\n", sz);
3036
3037     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3039
3040     /* InstallDate value exists */
3041     sz = MAX_PATH;
3042     lstrcpyA(buf, "apple");
3043     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3044     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3045     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3046     ok(sz == 4, "Expected 4, got %d\n", sz);
3047
3048     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3049                          (const BYTE *)&val, sizeof(DWORD));
3050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3051
3052     /* InstallDate type is REG_DWORD */
3053     sz = MAX_PATH;
3054     lstrcpyA(buf, "apple");
3055     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3056     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3057     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3058     ok(sz == 2, "Expected 2, got %d\n", sz);
3059
3060     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3062
3063     /* Publisher value exists */
3064     sz = MAX_PATH;
3065     lstrcpyA(buf, "apple");
3066     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3067     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3068     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3069     ok(sz == 3, "Expected 3, got %d\n", sz);
3070
3071     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3072                          (const BYTE *)&val, sizeof(DWORD));
3073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3074
3075     /* Publisher type is REG_DWORD */
3076     sz = MAX_PATH;
3077     lstrcpyA(buf, "apple");
3078     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3080     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3081     ok(sz == 2, "Expected 2, got %d\n", sz);
3082
3083     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3084     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3085
3086     /* LocalPackage value exists */
3087     sz = MAX_PATH;
3088     lstrcpyA(buf, "apple");
3089     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3091     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3092     ok(sz == 4, "Expected 4, got %d\n", sz);
3093
3094     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3095                          (const BYTE *)&val, sizeof(DWORD));
3096     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3097
3098     /* LocalPackage type is REG_DWORD */
3099     sz = MAX_PATH;
3100     lstrcpyA(buf, "apple");
3101     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3102     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3103     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3104     ok(sz == 2, "Expected 2, got %d\n", sz);
3105
3106     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3107     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3108
3109     /* UrlInfoAbout value exists */
3110     sz = MAX_PATH;
3111     lstrcpyA(buf, "apple");
3112     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3113     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3114     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3115     ok(sz == 5, "Expected 5, got %d\n", sz);
3116
3117     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3118                          (const BYTE *)&val, sizeof(DWORD));
3119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3120
3121     /* UrlInfoAbout type is REG_DWORD */
3122     sz = MAX_PATH;
3123     lstrcpyA(buf, "apple");
3124     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3126     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3127     ok(sz == 2, "Expected 2, got %d\n", sz);
3128
3129     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3131
3132     /* UrlUpdateInfo value exists */
3133     sz = MAX_PATH;
3134     lstrcpyA(buf, "apple");
3135     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3136     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3137     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3138     ok(sz == 4, "Expected 4, got %d\n", sz);
3139
3140     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3141                          (const BYTE *)&val, sizeof(DWORD));
3142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3143
3144     /* UrlUpdateInfo type is REG_DWORD */
3145     sz = MAX_PATH;
3146     lstrcpyA(buf, "apple");
3147     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3148     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3149     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3150     ok(sz == 2, "Expected 2, got %d\n", sz);
3151
3152     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3153     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3154
3155     /* VersionMinor value exists */
3156     sz = MAX_PATH;
3157     lstrcpyA(buf, "apple");
3158     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3160     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3161     ok(sz == 1, "Expected 1, got %d\n", sz);
3162
3163     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3164                          (const BYTE *)&val, sizeof(DWORD));
3165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3166
3167     /* VersionMinor type is REG_DWORD */
3168     sz = MAX_PATH;
3169     lstrcpyA(buf, "apple");
3170     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3171     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3172     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3173     ok(sz == 2, "Expected 2, got %d\n", sz);
3174
3175     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3177
3178     /* VersionMajor value exists */
3179     sz = MAX_PATH;
3180     lstrcpyA(buf, "apple");
3181     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3183     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3184     ok(sz == 1, "Expected 1, got %d\n", sz);
3185
3186     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3187                          (const BYTE *)&val, sizeof(DWORD));
3188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3189
3190     /* VersionMajor type is REG_DWORD */
3191     sz = MAX_PATH;
3192     lstrcpyA(buf, "apple");
3193     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3194     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3195     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3196     ok(sz == 2, "Expected 2, got %d\n", sz);
3197
3198     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3200
3201     /* ProductID value exists */
3202     sz = MAX_PATH;
3203     lstrcpyA(buf, "apple");
3204     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3205     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3206     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3207     ok(sz == 2, "Expected 2, got %d\n", sz);
3208
3209     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3210                          (const BYTE *)&val, sizeof(DWORD));
3211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3212
3213     /* ProductID type is REG_DWORD */
3214     sz = MAX_PATH;
3215     lstrcpyA(buf, "apple");
3216     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3217     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3218     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3219     ok(sz == 2, "Expected 2, got %d\n", sz);
3220
3221     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3223
3224     /* RegCompany value exists */
3225     sz = MAX_PATH;
3226     lstrcpyA(buf, "apple");
3227     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3229     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3230     ok(sz == 4, "Expected 4, got %d\n", sz);
3231
3232     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3233                          (const BYTE *)&val, sizeof(DWORD));
3234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3235
3236     /* RegCompany type is REG_DWORD */
3237     sz = MAX_PATH;
3238     lstrcpyA(buf, "apple");
3239     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3241     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3242     ok(sz == 2, "Expected 2, got %d\n", sz);
3243
3244     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3245     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3246
3247     /* RegOwner value exists */
3248     sz = MAX_PATH;
3249     lstrcpyA(buf, "apple");
3250     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3252     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3253     ok(sz == 3, "Expected 3, got %d\n", sz);
3254
3255     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3256                          (const BYTE *)&val, sizeof(DWORD));
3257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3258
3259     /* RegOwner type is REG_DWORD */
3260     sz = MAX_PATH;
3261     lstrcpyA(buf, "apple");
3262     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3263     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3264     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3265     ok(sz == 2, "Expected 2, got %d\n", sz);
3266
3267     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3269
3270     /* InstanceType value exists */
3271     sz = MAX_PATH;
3272     lstrcpyA(buf, "apple");
3273     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3274     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3275     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3276     ok(sz == 0, "Expected 0, got %d\n", sz);
3277
3278     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3279                          (const BYTE *)&val, sizeof(DWORD));
3280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3281
3282     /* InstanceType type is REG_DWORD */
3283     sz = MAX_PATH;
3284     lstrcpyA(buf, "apple");
3285     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3287     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3288     ok(sz == 0, "Expected 0, got %d\n", sz);
3289
3290     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3292
3293     /* InstanceType value exists */
3294     sz = MAX_PATH;
3295     lstrcpyA(buf, "apple");
3296     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3297     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3298     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3299     ok(sz == 4, "Expected 4, got %d\n", sz);
3300
3301     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3302                          (const BYTE *)&val, sizeof(DWORD));
3303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3304
3305     /* InstanceType type is REG_DWORD */
3306     sz = MAX_PATH;
3307     lstrcpyA(buf, "apple");
3308     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3310     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3311     ok(sz == 2, "Expected 2, got %d\n", sz);
3312
3313     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3315
3316     /* Transforms value exists */
3317     sz = MAX_PATH;
3318     lstrcpyA(buf, "apple");
3319     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3321     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3322     ok(sz == 0, "Expected 0, got %d\n", sz);
3323
3324     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3325                          (const BYTE *)&val, sizeof(DWORD));
3326     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3327
3328     /* Transforms type is REG_DWORD */
3329     sz = MAX_PATH;
3330     lstrcpyA(buf, "apple");
3331     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3332     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3333     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3334     ok(sz == 0, "Expected 0, got %d\n", sz);
3335
3336     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3338
3339     /* Transforms value exists */
3340     sz = MAX_PATH;
3341     lstrcpyA(buf, "apple");
3342     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3344     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3345     ok(sz == 6, "Expected 6, got %d\n", sz);
3346
3347     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3348                          (const BYTE *)&val, sizeof(DWORD));
3349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3350
3351     /* Transforms type is REG_DWORD */
3352     sz = MAX_PATH;
3353     lstrcpyA(buf, "apple");
3354     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3356     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3357     ok(sz == 2, "Expected 2, got %d\n", sz);
3358
3359     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3361
3362     /* Language value exists */
3363     sz = MAX_PATH;
3364     lstrcpyA(buf, "apple");
3365     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3366     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3367     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3368     ok(sz == 0, "Expected 0, got %d\n", sz);
3369
3370     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3371                          (const BYTE *)&val, sizeof(DWORD));
3372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3373
3374     /* Language type is REG_DWORD */
3375     sz = MAX_PATH;
3376     lstrcpyA(buf, "apple");
3377     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3378     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3379     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3380     ok(sz == 0, "Expected 0, got %d\n", sz);
3381
3382     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3384
3385     /* Language value exists */
3386     sz = MAX_PATH;
3387     lstrcpyA(buf, "apple");
3388     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3390     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3391     ok(sz == 4, "Expected 4, got %d\n", sz);
3392
3393     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3394                          (const BYTE *)&val, sizeof(DWORD));
3395     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3396
3397     /* Language type is REG_DWORD */
3398     sz = MAX_PATH;
3399     lstrcpyA(buf, "apple");
3400     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3402     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3403     ok(sz == 2, "Expected 2, got %d\n", sz);
3404
3405     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3406     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3407
3408     /* ProductName value exists */
3409     sz = MAX_PATH;
3410     lstrcpyA(buf, "apple");
3411     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3413     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3414     ok(sz == 0, "Expected 0, got %d\n", sz);
3415
3416     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3417                          (const BYTE *)&val, sizeof(DWORD));
3418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3419
3420     /* ProductName type is REG_DWORD */
3421     sz = MAX_PATH;
3422     lstrcpyA(buf, "apple");
3423     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3425     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3426     ok(sz == 0, "Expected 0, got %d\n", sz);
3427
3428     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3430
3431     /* ProductName value exists */
3432     sz = MAX_PATH;
3433     lstrcpyA(buf, "apple");
3434     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3435     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3436     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3437     ok(sz == 4, "Expected 4, got %d\n", sz);
3438
3439     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3440                          (const BYTE *)&val, sizeof(DWORD));
3441     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3442
3443     /* ProductName type is REG_DWORD */
3444     sz = MAX_PATH;
3445     lstrcpyA(buf, "apple");
3446     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3448     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3449     ok(sz == 2, "Expected 2, got %d\n", sz);
3450
3451     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3453
3454     /* Assignment value exists */
3455     sz = MAX_PATH;
3456     lstrcpyA(buf, "apple");
3457     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3458     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3459     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3460     ok(sz == 0, "Expected 0, got %d\n", sz);
3461
3462     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3463                          (const BYTE *)&val, sizeof(DWORD));
3464     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3465
3466     /* Assignment type is REG_DWORD */
3467     sz = MAX_PATH;
3468     lstrcpyA(buf, "apple");
3469     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3471     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3472     ok(sz == 0, "Expected 0, got %d\n", sz);
3473
3474     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3476
3477     /* Assignment value exists */
3478     sz = MAX_PATH;
3479     lstrcpyA(buf, "apple");
3480     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3482     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3483     ok(sz == 2, "Expected 2, got %d\n", sz);
3484
3485     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3486                          (const BYTE *)&val, sizeof(DWORD));
3487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3488
3489     /* Assignment type is REG_DWORD */
3490     sz = MAX_PATH;
3491     lstrcpyA(buf, "apple");
3492     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3494     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3495     ok(sz == 2, "Expected 2, got %d\n", sz);
3496
3497     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3499
3500     /* PackageCode value exists */
3501     sz = MAX_PATH;
3502     lstrcpyA(buf, "apple");
3503     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3504     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3505     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3506     ok(sz == 0, "Expected 0, got %d\n", sz);
3507
3508     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3509                          (const BYTE *)&val, sizeof(DWORD));
3510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3511
3512     /* PackageCode type is REG_DWORD */
3513     sz = MAX_PATH;
3514     lstrcpyA(buf, "apple");
3515     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3517     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3518     ok(sz == 0, "Expected 0, got %d\n", sz);
3519
3520     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3521     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3522
3523     /* PackageCode value exists */
3524     sz = MAX_PATH;
3525     lstrcpyA(buf, "apple");
3526     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3527     ok(r == ERROR_BAD_CONFIGURATION,
3528        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3529     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3530     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3531
3532     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3533                          (const BYTE *)&val, sizeof(DWORD));
3534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3535
3536     /* PackageCode type is REG_DWORD */
3537     sz = MAX_PATH;
3538     lstrcpyA(buf, "apple");
3539     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3541     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3542     ok(sz == 2, "Expected 2, got %d\n", sz);
3543
3544     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3546
3547     /* PackageCode value exists */
3548     sz = MAX_PATH;
3549     lstrcpyA(buf, "apple");
3550     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3551     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3552     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3553     ok(sz == 38, "Expected 38, got %d\n", sz);
3554
3555     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3557
3558     /* Version value exists */
3559     sz = MAX_PATH;
3560     lstrcpyA(buf, "apple");
3561     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3562     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3563     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3564     ok(sz == 0, "Expected 0, got %d\n", sz);
3565
3566     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3567                          (const BYTE *)&val, sizeof(DWORD));
3568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3569
3570     /* Version type is REG_DWORD */
3571     sz = MAX_PATH;
3572     lstrcpyA(buf, "apple");
3573     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3574     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3575     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3576     ok(sz == 0, "Expected 0, got %d\n", sz);
3577
3578     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3580
3581     /* Version value exists */
3582     sz = MAX_PATH;
3583     lstrcpyA(buf, "apple");
3584     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3585     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3586     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3587     ok(sz == 3, "Expected 3, got %d\n", sz);
3588
3589     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3590                          (const BYTE *)&val, sizeof(DWORD));
3591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3592
3593     /* Version type is REG_DWORD */
3594     sz = MAX_PATH;
3595     lstrcpyA(buf, "apple");
3596     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3597     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3598     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3599     ok(sz == 2, "Expected 2, got %d\n", sz);
3600
3601     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3603
3604     /* ProductIcon value exists */
3605     sz = MAX_PATH;
3606     lstrcpyA(buf, "apple");
3607     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3609     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3610     ok(sz == 0, "Expected 0, got %d\n", sz);
3611
3612     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3613                          (const BYTE *)&val, sizeof(DWORD));
3614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3615
3616     /* ProductIcon type is REG_DWORD */
3617     sz = MAX_PATH;
3618     lstrcpyA(buf, "apple");
3619     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3621     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3622     ok(sz == 0, "Expected 0, got %d\n", sz);
3623
3624     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3626
3627     /* ProductIcon value exists */
3628     sz = MAX_PATH;
3629     lstrcpyA(buf, "apple");
3630     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3631     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3632     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3633     ok(sz == 3, "Expected 3, got %d\n", sz);
3634
3635     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3636                          (const BYTE *)&val, sizeof(DWORD));
3637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3638
3639     /* ProductIcon type is REG_DWORD */
3640     sz = MAX_PATH;
3641     lstrcpyA(buf, "apple");
3642     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3643     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3644     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3645     ok(sz == 2, "Expected 2, got %d\n", sz);
3646
3647     res = RegCreateKeyA(prodkey, "SourceList", &source);
3648     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3649
3650     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3652
3653     sz = MAX_PATH;
3654     lstrcpyA(buf, "apple");
3655     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3657     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3658     ok(sz == 8, "Expected 8, got %d\n", sz);
3659
3660     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3661                          (const BYTE *)&val, sizeof(DWORD));
3662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3663
3664     /* PackageName type is REG_DWORD */
3665     sz = MAX_PATH;
3666     lstrcpyA(buf, "apple");
3667     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3669     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3670     ok(sz == 2, "Expected 2, got %d\n", sz);
3671
3672     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3674
3675     /* Authorized value exists */
3676     sz = MAX_PATH;
3677     lstrcpyA(buf, "apple");
3678     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3679     if (r != ERROR_UNKNOWN_PROPERTY)
3680     {
3681         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3682         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3683         ok(sz == 0, "Expected 0, got %d\n", sz);
3684     }
3685
3686     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3687                          (const BYTE *)&val, sizeof(DWORD));
3688     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3689
3690     /* AuthorizedLUAApp type is REG_DWORD */
3691     sz = MAX_PATH;
3692     lstrcpyA(buf, "apple");
3693     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3694     if (r != ERROR_UNKNOWN_PROPERTY)
3695     {
3696         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3697         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3698         ok(sz == 0, "Expected 0, got %d\n", sz);
3699     }
3700
3701     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3703
3704     /* Authorized value exists */
3705     sz = MAX_PATH;
3706     lstrcpyA(buf, "apple");
3707     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3708     if (r != ERROR_UNKNOWN_PROPERTY)
3709     {
3710         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3711         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3712         ok(sz == 4, "Expected 4, got %d\n", sz);
3713     }
3714
3715     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3716                          (const BYTE *)&val, sizeof(DWORD));
3717     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3718
3719     /* AuthorizedLUAApp type is REG_DWORD */
3720     sz = MAX_PATH;
3721     lstrcpyA(buf, "apple");
3722     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3723     if (r != ERROR_UNKNOWN_PROPERTY)
3724     {
3725         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3726         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3727         ok(sz == 2, "Expected 2, got %d\n", sz);
3728     }
3729
3730     RegDeleteValueA(propkey, "HelpLink");
3731     RegDeleteValueA(propkey, "DisplayName");
3732     RegDeleteValueA(propkey, "DisplayVersion");
3733     RegDeleteValueA(propkey, "HelpTelephone");
3734     RegDeleteValueA(propkey, "InstallLocation");
3735     RegDeleteValueA(propkey, "InstallSource");
3736     RegDeleteValueA(propkey, "InstallDate");
3737     RegDeleteValueA(propkey, "Publisher");
3738     RegDeleteValueA(propkey, "LocalPackage");
3739     RegDeleteValueA(propkey, "UrlInfoAbout");
3740     RegDeleteValueA(propkey, "UrlUpdateInfo");
3741     RegDeleteValueA(propkey, "VersionMinor");
3742     RegDeleteValueA(propkey, "VersionMajor");
3743     RegDeleteValueA(propkey, "ProductID");
3744     RegDeleteValueA(propkey, "RegCompany");
3745     RegDeleteValueA(propkey, "RegOwner");
3746     RegDeleteValueA(propkey, "InstanceType");
3747     RegDeleteValueA(propkey, "Transforms");
3748     RegDeleteValueA(propkey, "Language");
3749     RegDeleteValueA(propkey, "ProductName");
3750     RegDeleteValueA(propkey, "Assignment");
3751     RegDeleteValueA(propkey, "PackageCode");
3752     RegDeleteValueA(propkey, "Version");
3753     RegDeleteValueA(propkey, "ProductIcon");
3754     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3755     RegDeleteKeyA(propkey, "");
3756     RegDeleteKeyA(localkey, "");
3757     RegDeleteValueA(prodkey, "InstanceType");
3758     RegDeleteValueA(prodkey, "Transforms");
3759     RegDeleteValueA(prodkey, "Language");
3760     RegDeleteValueA(prodkey, "ProductName");
3761     RegDeleteValueA(prodkey, "Assignment");
3762     RegDeleteValueA(prodkey, "PackageCode");
3763     RegDeleteValueA(prodkey, "Version");
3764     RegDeleteValueA(prodkey, "ProductIcon");
3765     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3766     RegDeleteValueA(source, "PackageName");
3767     RegDeleteKeyA(source, "");
3768     RegDeleteKeyA(prodkey, "");
3769     RegCloseKey(propkey);
3770     RegCloseKey(localkey);
3771     RegCloseKey(source);
3772     RegCloseKey(prodkey);
3773 }
3774
3775 static void test_MsiGetProductInfoEx(void)
3776 {
3777     UINT r;
3778     LONG res;
3779     HKEY propkey, userkey;
3780     HKEY prodkey, localkey;
3781     CHAR prodcode[MAX_PATH];
3782     CHAR prod_squashed[MAX_PATH];
3783     CHAR packcode[MAX_PATH];
3784     CHAR pack_squashed[MAX_PATH];
3785     CHAR buf[MAX_PATH];
3786     CHAR keypath[MAX_PATH];
3787     LPSTR usersid;
3788     DWORD sz;
3789
3790     if (!pMsiGetProductInfoExA)
3791     {
3792         skip("MsiGetProductInfoExA is not available\n");
3793         return;
3794     }
3795
3796     create_test_guid(prodcode, prod_squashed);
3797     create_test_guid(packcode, pack_squashed);
3798     get_user_sid(&usersid);
3799
3800     /* NULL szProductCode */
3801     sz = MAX_PATH;
3802     lstrcpyA(buf, "apple");
3803     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3804                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3805     ok(r == ERROR_INVALID_PARAMETER,
3806        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3807     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3808     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3809
3810     /* empty szProductCode */
3811     sz = MAX_PATH;
3812     lstrcpyA(buf, "apple");
3813     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3814                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3815     ok(r == ERROR_INVALID_PARAMETER,
3816        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3817     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3818     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3819
3820     /* garbage szProductCode */
3821     sz = MAX_PATH;
3822     lstrcpyA(buf, "apple");
3823     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3824                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3825     ok(r == ERROR_INVALID_PARAMETER,
3826        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3827     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3828     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3829
3830     /* guid without brackets */
3831     sz = MAX_PATH;
3832     lstrcpyA(buf, "apple");
3833     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3834                               MSIINSTALLCONTEXT_USERUNMANAGED,
3835                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3836     ok(r == ERROR_INVALID_PARAMETER,
3837        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3838     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3839     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3840
3841     /* guid with brackets */
3842     sz = MAX_PATH;
3843     lstrcpyA(buf, "apple");
3844     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3845                               MSIINSTALLCONTEXT_USERUNMANAGED,
3846                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3847     ok(r == ERROR_UNKNOWN_PRODUCT,
3848        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3849     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3850     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3851
3852     /* szValue is non-NULL while pcchValue is NULL */
3853     lstrcpyA(buf, "apple");
3854     r = pMsiGetProductInfoExA(prodcode, usersid,
3855                               MSIINSTALLCONTEXT_USERUNMANAGED,
3856                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3857     ok(r == ERROR_INVALID_PARAMETER,
3858        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3859     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3860
3861     /* dwContext is out of range */
3862     sz = MAX_PATH;
3863     lstrcpyA(buf, "apple");
3864     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3865                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3866     ok(r == ERROR_INVALID_PARAMETER,
3867        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3868     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3869     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3870
3871     /* szProperty is NULL */
3872     sz = MAX_PATH;
3873     lstrcpyA(buf, "apple");
3874     r = pMsiGetProductInfoExA(prodcode, usersid,
3875                               MSIINSTALLCONTEXT_USERUNMANAGED,
3876                               NULL, buf, &sz);
3877     ok(r == ERROR_INVALID_PARAMETER,
3878        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3879     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3880     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3881
3882     /* szProperty is empty */
3883     sz = MAX_PATH;
3884     lstrcpyA(buf, "apple");
3885     r = pMsiGetProductInfoExA(prodcode, usersid,
3886                               MSIINSTALLCONTEXT_USERUNMANAGED,
3887                               "", buf, &sz);
3888     ok(r == ERROR_INVALID_PARAMETER,
3889        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3890     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3891     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3892
3893     /* szProperty is not a valid property */
3894     sz = MAX_PATH;
3895     lstrcpyA(buf, "apple");
3896     r = pMsiGetProductInfoExA(prodcode, usersid,
3897                               MSIINSTALLCONTEXT_USERUNMANAGED,
3898                               "notvalid", buf, &sz);
3899     ok(r == ERROR_UNKNOWN_PRODUCT,
3900        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3901     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3902     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3903
3904     /* same length as guid, but random */
3905     sz = MAX_PATH;
3906     lstrcpyA(buf, "apple");
3907     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3908                               MSIINSTALLCONTEXT_USERUNMANAGED,
3909                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3910     ok(r == ERROR_INVALID_PARAMETER,
3911        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3912     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3913     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3914
3915     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3916
3917     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3918     lstrcatA(keypath, usersid);
3919     lstrcatA(keypath, "\\Products\\");
3920     lstrcatA(keypath, prod_squashed);
3921
3922     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3924
3925     /* local user product key exists */
3926     sz = MAX_PATH;
3927     lstrcpyA(buf, "apple");
3928     r = pMsiGetProductInfoExA(prodcode, usersid,
3929                               MSIINSTALLCONTEXT_USERUNMANAGED,
3930                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3931     ok(r == ERROR_UNKNOWN_PRODUCT,
3932        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3933     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3934     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3935
3936     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3938
3939     /* InstallProperties key exists */
3940     sz = MAX_PATH;
3941     lstrcpyA(buf, "apple");
3942     r = pMsiGetProductInfoExA(prodcode, usersid,
3943                               MSIINSTALLCONTEXT_USERUNMANAGED,
3944                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3945     ok(r == ERROR_UNKNOWN_PRODUCT,
3946        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3947     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3948     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3949
3950     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3952
3953     /* LocalPackage value exists */
3954     sz = MAX_PATH;
3955     lstrcpyA(buf, "apple");
3956     r = pMsiGetProductInfoExA(prodcode, usersid,
3957                               MSIINSTALLCONTEXT_USERUNMANAGED,
3958                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3959     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3960     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
3961     ok(sz == 1, "Expected 1, got %d\n", sz);
3962
3963     RegDeleteValueA(propkey, "LocalPackage");
3964
3965     /* LocalPackage value must exist */
3966     sz = MAX_PATH;
3967     lstrcpyA(buf, "apple");
3968     r = pMsiGetProductInfoExA(prodcode, usersid,
3969                               MSIINSTALLCONTEXT_USERUNMANAGED,
3970                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3971     ok(r == ERROR_UNKNOWN_PRODUCT,
3972        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3973     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3974     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3975
3976     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3978
3979     /* LocalPackage exists, but HelpLink does not exist */
3980     sz = MAX_PATH;
3981     lstrcpyA(buf, "apple");
3982     r = pMsiGetProductInfoExA(prodcode, usersid,
3983                               MSIINSTALLCONTEXT_USERUNMANAGED,
3984                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3986     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3987     ok(sz == 0, "Expected 0, got %d\n", sz);
3988
3989     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3991
3992     /* HelpLink value exists */
3993     sz = MAX_PATH;
3994     lstrcpyA(buf, "apple");
3995     r = pMsiGetProductInfoExA(prodcode, usersid,
3996                               MSIINSTALLCONTEXT_USERUNMANAGED,
3997                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3999     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4000     ok(sz == 4, "Expected 4, got %d\n", sz);
4001
4002     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4004
4005     /* HelpTelephone value exists */
4006     sz = MAX_PATH;
4007     lstrcpyA(buf, "apple");
4008     r = pMsiGetProductInfoExA(prodcode, usersid,
4009                               MSIINSTALLCONTEXT_USERUNMANAGED,
4010                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4012     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4013     ok(sz == 5, "Expected 5, got %d\n", sz);
4014
4015     /* szValue and pcchValue are NULL */
4016     r = pMsiGetProductInfoExA(prodcode, usersid,
4017                               MSIINSTALLCONTEXT_USERUNMANAGED,
4018                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4019     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4020
4021     /* pcchValue is exactly 5 */
4022     sz = 5;
4023     lstrcpyA(buf, "apple");
4024     r = pMsiGetProductInfoExA(prodcode, usersid,
4025                               MSIINSTALLCONTEXT_USERUNMANAGED,
4026                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4027     ok(r == ERROR_MORE_DATA,
4028        "Expected ERROR_MORE_DATA, got %d\n", r);
4029     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4030     ok(sz == 10, "Expected 10, got %d\n", sz);
4031
4032     /* szValue is NULL, pcchValue is exactly 5 */
4033     sz = 5;
4034     r = pMsiGetProductInfoExA(prodcode, usersid,
4035                               MSIINSTALLCONTEXT_USERUNMANAGED,
4036                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4037     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4038     ok(sz == 10, "Expected 10, got %d\n", sz);
4039
4040     /* szValue is NULL, pcchValue is MAX_PATH */
4041     sz = MAX_PATH;
4042     r = pMsiGetProductInfoExA(prodcode, usersid,
4043                               MSIINSTALLCONTEXT_USERUNMANAGED,
4044                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4045     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4046     ok(sz == 10, "Expected 10, got %d\n", sz);
4047
4048     /* pcchValue is exactly 0 */
4049     sz = 0;
4050     lstrcpyA(buf, "apple");
4051     r = pMsiGetProductInfoExA(prodcode, usersid,
4052                               MSIINSTALLCONTEXT_USERUNMANAGED,
4053                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4054     ok(r == ERROR_MORE_DATA,
4055        "Expected ERROR_MORE_DATA, got %d\n", r);
4056     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4057     ok(sz == 10, "Expected 10, got %d\n", sz);
4058
4059     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4061
4062     /* szProperty is not a valid property */
4063     sz = MAX_PATH;
4064     lstrcpyA(buf, "apple");
4065     r = pMsiGetProductInfoExA(prodcode, usersid,
4066                               MSIINSTALLCONTEXT_USERUNMANAGED,
4067                               "notvalid", buf, &sz);
4068     ok(r == ERROR_UNKNOWN_PROPERTY,
4069        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4070     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4071     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4072
4073     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4075
4076     /* InstallDate value exists */
4077     sz = MAX_PATH;
4078     lstrcpyA(buf, "apple");
4079     r = pMsiGetProductInfoExA(prodcode, usersid,
4080                               MSIINSTALLCONTEXT_USERUNMANAGED,
4081                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4083     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4084     ok(sz == 4, "Expected 4, got %d\n", sz);
4085
4086     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4088
4089     /* DisplayName value exists */
4090     sz = MAX_PATH;
4091     lstrcpyA(buf, "apple");
4092     r = pMsiGetProductInfoExA(prodcode, usersid,
4093                               MSIINSTALLCONTEXT_USERUNMANAGED,
4094                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4096     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4097     ok(sz == 4, "Expected 4, got %d\n", sz);
4098
4099     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4101
4102     /* InstallLocation value exists */
4103     sz = MAX_PATH;
4104     lstrcpyA(buf, "apple");
4105     r = pMsiGetProductInfoExA(prodcode, usersid,
4106                               MSIINSTALLCONTEXT_USERUNMANAGED,
4107                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4109     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4110     ok(sz == 3, "Expected 3, got %d\n", sz);
4111
4112     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4114
4115     /* InstallSource value exists */
4116     sz = MAX_PATH;
4117     lstrcpyA(buf, "apple");
4118     r = pMsiGetProductInfoExA(prodcode, usersid,
4119                               MSIINSTALLCONTEXT_USERUNMANAGED,
4120                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4121     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4122     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4123     ok(sz == 6, "Expected 6, got %d\n", sz);
4124
4125     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4127
4128     /* LocalPackage value exists */
4129     sz = MAX_PATH;
4130     lstrcpyA(buf, "apple");
4131     r = pMsiGetProductInfoExA(prodcode, usersid,
4132                               MSIINSTALLCONTEXT_USERUNMANAGED,
4133                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4135     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4136     ok(sz == 5, "Expected 5, got %d\n", sz);
4137
4138     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4140
4141     /* Publisher value exists */
4142     sz = MAX_PATH;
4143     lstrcpyA(buf, "apple");
4144     r = pMsiGetProductInfoExA(prodcode, usersid,
4145                               MSIINSTALLCONTEXT_USERUNMANAGED,
4146                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4148     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4149     ok(sz == 3, "Expected 3, got %d\n", sz);
4150
4151     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4153
4154     /* URLInfoAbout value exists */
4155     sz = MAX_PATH;
4156     lstrcpyA(buf, "apple");
4157     r = pMsiGetProductInfoExA(prodcode, usersid,
4158                               MSIINSTALLCONTEXT_USERUNMANAGED,
4159                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4160     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4161     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4162     ok(sz == 5, "Expected 5, got %d\n", sz);
4163
4164     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4166
4167     /* URLUpdateInfo value exists */
4168     sz = MAX_PATH;
4169     lstrcpyA(buf, "apple");
4170     r = pMsiGetProductInfoExA(prodcode, usersid,
4171                               MSIINSTALLCONTEXT_USERUNMANAGED,
4172                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4173     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4174     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4175     ok(sz == 6, "Expected 6, got %d\n", sz);
4176
4177     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4179
4180     /* VersionMinor value exists */
4181     sz = MAX_PATH;
4182     lstrcpyA(buf, "apple");
4183     r = pMsiGetProductInfoExA(prodcode, usersid,
4184                               MSIINSTALLCONTEXT_USERUNMANAGED,
4185                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4186     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4187     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4188     ok(sz == 1, "Expected 1, got %d\n", sz);
4189
4190     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4191     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4192
4193     /* VersionMajor value exists */
4194     sz = MAX_PATH;
4195     lstrcpyA(buf, "apple");
4196     r = pMsiGetProductInfoExA(prodcode, usersid,
4197                               MSIINSTALLCONTEXT_USERUNMANAGED,
4198                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4200     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4201     ok(sz == 1, "Expected 1, got %d\n", sz);
4202
4203     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4205
4206     /* DisplayVersion value exists */
4207     sz = MAX_PATH;
4208     lstrcpyA(buf, "apple");
4209     r = pMsiGetProductInfoExA(prodcode, usersid,
4210                               MSIINSTALLCONTEXT_USERUNMANAGED,
4211                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4213     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4214     ok(sz == 5, "Expected 5, got %d\n", sz);
4215
4216     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4218
4219     /* ProductID value exists */
4220     sz = MAX_PATH;
4221     lstrcpyA(buf, "apple");
4222     r = pMsiGetProductInfoExA(prodcode, usersid,
4223                               MSIINSTALLCONTEXT_USERUNMANAGED,
4224                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4225     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4226     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4227     ok(sz == 2, "Expected 2, got %d\n", sz);
4228
4229     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4231
4232     /* RegCompany value exists */
4233     sz = MAX_PATH;
4234     lstrcpyA(buf, "apple");
4235     r = pMsiGetProductInfoExA(prodcode, usersid,
4236                               MSIINSTALLCONTEXT_USERUNMANAGED,
4237                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4239     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4240     ok(sz == 4, "Expected 4, got %d\n", sz);
4241
4242     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4244
4245     /* RegOwner value exists */
4246     sz = MAX_PATH;
4247     lstrcpyA(buf, "apple");
4248     r = pMsiGetProductInfoExA(prodcode, usersid,
4249                               MSIINSTALLCONTEXT_USERUNMANAGED,
4250                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4252     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4253     ok(sz == 5, "Expected 5, got %d\n", sz);
4254
4255     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4257
4258     /* Transforms value exists */
4259     sz = MAX_PATH;
4260     lstrcpyA(buf, "apple");
4261     r = pMsiGetProductInfoExA(prodcode, usersid,
4262                               MSIINSTALLCONTEXT_USERUNMANAGED,
4263                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4264     ok(r == ERROR_UNKNOWN_PRODUCT,
4265        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4266     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4267     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4268
4269     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4270     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4271
4272     /* Language value exists */
4273     sz = MAX_PATH;
4274     lstrcpyA(buf, "apple");
4275     r = pMsiGetProductInfoExA(prodcode, usersid,
4276                               MSIINSTALLCONTEXT_USERUNMANAGED,
4277                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4278     ok(r == ERROR_UNKNOWN_PRODUCT,
4279        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4280     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4281     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4282
4283     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4285
4286     /* ProductName value exists */
4287     sz = MAX_PATH;
4288     lstrcpyA(buf, "apple");
4289     r = pMsiGetProductInfoExA(prodcode, usersid,
4290                               MSIINSTALLCONTEXT_USERUNMANAGED,
4291                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4292     ok(r == ERROR_UNKNOWN_PRODUCT,
4293        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4294     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4295     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4296
4297     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4299
4300     /* FIXME */
4301
4302     /* AssignmentType value exists */
4303     sz = MAX_PATH;
4304     lstrcpyA(buf, "apple");
4305     r = pMsiGetProductInfoExA(prodcode, usersid,
4306                               MSIINSTALLCONTEXT_USERUNMANAGED,
4307                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4308     ok(r == ERROR_UNKNOWN_PRODUCT,
4309        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4310     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4311     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4312
4313     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4315
4316     /* PackageCode value exists */
4317     sz = MAX_PATH;
4318     lstrcpyA(buf, "apple");
4319     r = pMsiGetProductInfoExA(prodcode, usersid,
4320                               MSIINSTALLCONTEXT_USERUNMANAGED,
4321                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4322     ok(r == ERROR_UNKNOWN_PRODUCT,
4323        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4324     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4325     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4326
4327     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4329
4330     /* Version value exists */
4331     sz = MAX_PATH;
4332     lstrcpyA(buf, "apple");
4333     r = pMsiGetProductInfoExA(prodcode, usersid,
4334                               MSIINSTALLCONTEXT_USERUNMANAGED,
4335                               INSTALLPROPERTY_VERSION, buf, &sz);
4336     ok(r == ERROR_UNKNOWN_PRODUCT,
4337        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4338     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4339     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4340
4341     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4343
4344     /* ProductIcon value exists */
4345     sz = MAX_PATH;
4346     lstrcpyA(buf, "apple");
4347     r = pMsiGetProductInfoExA(prodcode, usersid,
4348                               MSIINSTALLCONTEXT_USERUNMANAGED,
4349                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4350     ok(r == ERROR_UNKNOWN_PRODUCT,
4351        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4352     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4353     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4354
4355     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4357
4358     /* PackageName value exists */
4359     sz = MAX_PATH;
4360     lstrcpyA(buf, "apple");
4361     r = pMsiGetProductInfoExA(prodcode, usersid,
4362                               MSIINSTALLCONTEXT_USERUNMANAGED,
4363                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4364     ok(r == ERROR_UNKNOWN_PRODUCT,
4365        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4366     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4367     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4368
4369     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4371
4372     /* AuthorizedLUAApp value exists */
4373     sz = MAX_PATH;
4374     lstrcpyA(buf, "apple");
4375     r = pMsiGetProductInfoExA(prodcode, usersid,
4376                               MSIINSTALLCONTEXT_USERUNMANAGED,
4377                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4378     ok(r == ERROR_UNKNOWN_PRODUCT,
4379        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4380     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4381     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4382
4383     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4384     RegDeleteValueA(propkey, "PackageName");
4385     RegDeleteValueA(propkey, "ProductIcon");
4386     RegDeleteValueA(propkey, "Version");
4387     RegDeleteValueA(propkey, "PackageCode");
4388     RegDeleteValueA(propkey, "AssignmentType");
4389     RegDeleteValueA(propkey, "ProductName");
4390     RegDeleteValueA(propkey, "Language");
4391     RegDeleteValueA(propkey, "Transforms");
4392     RegDeleteValueA(propkey, "RegOwner");
4393     RegDeleteValueA(propkey, "RegCompany");
4394     RegDeleteValueA(propkey, "ProductID");
4395     RegDeleteValueA(propkey, "DisplayVersion");
4396     RegDeleteValueA(propkey, "VersionMajor");
4397     RegDeleteValueA(propkey, "VersionMinor");
4398     RegDeleteValueA(propkey, "URLUpdateInfo");
4399     RegDeleteValueA(propkey, "URLInfoAbout");
4400     RegDeleteValueA(propkey, "Publisher");
4401     RegDeleteValueA(propkey, "LocalPackage");
4402     RegDeleteValueA(propkey, "InstallSource");
4403     RegDeleteValueA(propkey, "InstallLocation");
4404     RegDeleteValueA(propkey, "DisplayName");
4405     RegDeleteValueA(propkey, "InstallDate");
4406     RegDeleteValueA(propkey, "HelpTelephone");
4407     RegDeleteValueA(propkey, "HelpLink");
4408     RegDeleteValueA(propkey, "LocalPackage");
4409     RegDeleteKeyA(propkey, "");
4410     RegCloseKey(propkey);
4411     RegDeleteKeyA(localkey, "");
4412     RegCloseKey(localkey);
4413
4414     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4415     lstrcatA(keypath, usersid);
4416     lstrcatA(keypath, "\\Installer\\Products\\");
4417     lstrcatA(keypath, prod_squashed);
4418
4419     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4421
4422     /* user product key exists */
4423     sz = MAX_PATH;
4424     lstrcpyA(buf, "apple");
4425     r = pMsiGetProductInfoExA(prodcode, usersid,
4426                               MSIINSTALLCONTEXT_USERUNMANAGED,
4427                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4428     ok(r == ERROR_UNKNOWN_PRODUCT,
4429        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4430     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4431     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4432
4433     RegDeleteKeyA(userkey, "");
4434     RegCloseKey(userkey);
4435
4436     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4437     lstrcatA(keypath, prod_squashed);
4438
4439     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4441
4442     sz = MAX_PATH;
4443     lstrcpyA(buf, "apple");
4444     r = pMsiGetProductInfoExA(prodcode, usersid,
4445                               MSIINSTALLCONTEXT_USERUNMANAGED,
4446                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4448     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4449     ok(sz == 1, "Expected 1, got %d\n", sz);
4450
4451     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4453
4454     /* HelpLink value exists */
4455     sz = MAX_PATH;
4456     lstrcpyA(buf, "apple");
4457     r = pMsiGetProductInfoExA(prodcode, usersid,
4458                               MSIINSTALLCONTEXT_USERUNMANAGED,
4459                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4460     ok(r == ERROR_UNKNOWN_PROPERTY,
4461        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4462     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4463     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4464
4465     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4467
4468     /* HelpTelephone value exists */
4469     sz = MAX_PATH;
4470     lstrcpyA(buf, "apple");
4471     r = pMsiGetProductInfoExA(prodcode, usersid,
4472                               MSIINSTALLCONTEXT_USERUNMANAGED,
4473                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4474     ok(r == ERROR_UNKNOWN_PROPERTY,
4475        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4476     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4477     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4478
4479     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4481
4482     /* InstallDate value exists */
4483     sz = MAX_PATH;
4484     lstrcpyA(buf, "apple");
4485     r = pMsiGetProductInfoExA(prodcode, usersid,
4486                               MSIINSTALLCONTEXT_USERUNMANAGED,
4487                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4488     ok(r == ERROR_UNKNOWN_PROPERTY,
4489        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4490     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4491     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4492
4493     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4495
4496     /* DisplayName value exists */
4497     sz = MAX_PATH;
4498     lstrcpyA(buf, "apple");
4499     r = pMsiGetProductInfoExA(prodcode, usersid,
4500                               MSIINSTALLCONTEXT_USERUNMANAGED,
4501                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4502     ok(r == ERROR_UNKNOWN_PROPERTY,
4503        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4504     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4505     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4506
4507     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4509
4510     /* InstallLocation value exists */
4511     sz = MAX_PATH;
4512     lstrcpyA(buf, "apple");
4513     r = pMsiGetProductInfoExA(prodcode, usersid,
4514                               MSIINSTALLCONTEXT_USERUNMANAGED,
4515                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4516     ok(r == ERROR_UNKNOWN_PROPERTY,
4517        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4518     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4519     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4520
4521     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4523
4524     /* InstallSource value exists */
4525     sz = MAX_PATH;
4526     lstrcpyA(buf, "apple");
4527     r = pMsiGetProductInfoExA(prodcode, usersid,
4528                               MSIINSTALLCONTEXT_USERUNMANAGED,
4529                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4530     ok(r == ERROR_UNKNOWN_PROPERTY,
4531        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4532     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4533     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4534
4535     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4536     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4537
4538     /* LocalPackage value exists */
4539     sz = MAX_PATH;
4540     lstrcpyA(buf, "apple");
4541     r = pMsiGetProductInfoExA(prodcode, usersid,
4542                               MSIINSTALLCONTEXT_USERUNMANAGED,
4543                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4544     ok(r == ERROR_UNKNOWN_PROPERTY,
4545        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4546     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4547     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4548
4549     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4551
4552     /* Publisher value exists */
4553     sz = MAX_PATH;
4554     lstrcpyA(buf, "apple");
4555     r = pMsiGetProductInfoExA(prodcode, usersid,
4556                               MSIINSTALLCONTEXT_USERUNMANAGED,
4557                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4558     ok(r == ERROR_UNKNOWN_PROPERTY,
4559        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4560     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4561     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4562
4563     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4564     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4565
4566     /* URLInfoAbout value exists */
4567     sz = MAX_PATH;
4568     lstrcpyA(buf, "apple");
4569     r = pMsiGetProductInfoExA(prodcode, usersid,
4570                               MSIINSTALLCONTEXT_USERUNMANAGED,
4571                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4572     ok(r == ERROR_UNKNOWN_PROPERTY,
4573        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4574     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4575     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4576
4577     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4579
4580     /* URLUpdateInfo value exists */
4581     sz = MAX_PATH;
4582     lstrcpyA(buf, "apple");
4583     r = pMsiGetProductInfoExA(prodcode, usersid,
4584                               MSIINSTALLCONTEXT_USERUNMANAGED,
4585                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4586     ok(r == ERROR_UNKNOWN_PROPERTY,
4587        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4588     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4589     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4590
4591     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4593
4594     /* VersionMinor value exists */
4595     sz = MAX_PATH;
4596     lstrcpyA(buf, "apple");
4597     r = pMsiGetProductInfoExA(prodcode, usersid,
4598                               MSIINSTALLCONTEXT_USERUNMANAGED,
4599                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4600     ok(r == ERROR_UNKNOWN_PROPERTY,
4601        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4602     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4603     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4604
4605     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4607
4608     /* VersionMajor value exists */
4609     sz = MAX_PATH;
4610     lstrcpyA(buf, "apple");
4611     r = pMsiGetProductInfoExA(prodcode, usersid,
4612                               MSIINSTALLCONTEXT_USERUNMANAGED,
4613                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4614     ok(r == ERROR_UNKNOWN_PROPERTY,
4615        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4616     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4617     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4618
4619     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4621
4622     /* DisplayVersion value exists */
4623     sz = MAX_PATH;
4624     lstrcpyA(buf, "apple");
4625     r = pMsiGetProductInfoExA(prodcode, usersid,
4626                               MSIINSTALLCONTEXT_USERUNMANAGED,
4627                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4628     ok(r == ERROR_UNKNOWN_PROPERTY,
4629        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4630     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4631     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4632
4633     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4635
4636     /* ProductID value exists */
4637     sz = MAX_PATH;
4638     lstrcpyA(buf, "apple");
4639     r = pMsiGetProductInfoExA(prodcode, usersid,
4640                               MSIINSTALLCONTEXT_USERUNMANAGED,
4641                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4642     ok(r == ERROR_UNKNOWN_PROPERTY,
4643        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4644     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4645     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4646
4647     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4648     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4649
4650     /* RegCompany value exists */
4651     sz = MAX_PATH;
4652     lstrcpyA(buf, "apple");
4653     r = pMsiGetProductInfoExA(prodcode, usersid,
4654                               MSIINSTALLCONTEXT_USERUNMANAGED,
4655                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4656     ok(r == ERROR_UNKNOWN_PROPERTY,
4657        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4658     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4659     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4660
4661     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4663
4664     /* RegOwner value exists */
4665     sz = MAX_PATH;
4666     lstrcpyA(buf, "apple");
4667     r = pMsiGetProductInfoExA(prodcode, usersid,
4668                               MSIINSTALLCONTEXT_USERUNMANAGED,
4669                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4670     ok(r == ERROR_UNKNOWN_PROPERTY,
4671        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4672     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4673     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4674
4675     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4676     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4677
4678     /* Transforms value exists */
4679     sz = MAX_PATH;
4680     lstrcpyA(buf, "apple");
4681     r = pMsiGetProductInfoExA(prodcode, usersid,
4682                               MSIINSTALLCONTEXT_USERUNMANAGED,
4683                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4684     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4685     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4686     ok(sz == 5, "Expected 5, got %d\n", sz);
4687
4688     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4690
4691     /* Language value exists */
4692     sz = MAX_PATH;
4693     lstrcpyA(buf, "apple");
4694     r = pMsiGetProductInfoExA(prodcode, usersid,
4695                               MSIINSTALLCONTEXT_USERUNMANAGED,
4696                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4697     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4698     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4699     ok(sz == 4, "Expected 4, got %d\n", sz);
4700
4701     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4703
4704     /* ProductName value exists */
4705     sz = MAX_PATH;
4706     lstrcpyA(buf, "apple");
4707     r = pMsiGetProductInfoExA(prodcode, usersid,
4708                               MSIINSTALLCONTEXT_USERUNMANAGED,
4709                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4710     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4711     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4712     ok(sz == 4, "Expected 4, got %d\n", sz);
4713
4714     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4716
4717     /* FIXME */
4718
4719     /* AssignmentType value exists */
4720     sz = MAX_PATH;
4721     lstrcpyA(buf, "apple");
4722     r = pMsiGetProductInfoExA(prodcode, usersid,
4723                               MSIINSTALLCONTEXT_USERUNMANAGED,
4724                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4726     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4727     ok(sz == 0, "Expected 0, got %d\n", sz);
4728
4729     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4731
4732     /* FIXME */
4733
4734     /* PackageCode value exists */
4735     sz = MAX_PATH;
4736     lstrcpyA(buf, "apple");
4737     r = pMsiGetProductInfoExA(prodcode, usersid,
4738                               MSIINSTALLCONTEXT_USERUNMANAGED,
4739                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4740     todo_wine
4741     {
4742         ok(r == ERROR_BAD_CONFIGURATION,
4743            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4744         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4745         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4746     }
4747
4748     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4750
4751     /* Version value exists */
4752     sz = MAX_PATH;
4753     lstrcpyA(buf, "apple");
4754     r = pMsiGetProductInfoExA(prodcode, usersid,
4755                               MSIINSTALLCONTEXT_USERUNMANAGED,
4756                               INSTALLPROPERTY_VERSION, buf, &sz);
4757     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4758     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4759     ok(sz == 3, "Expected 3, got %d\n", sz);
4760
4761     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4763
4764     /* ProductIcon value exists */
4765     sz = MAX_PATH;
4766     lstrcpyA(buf, "apple");
4767     r = pMsiGetProductInfoExA(prodcode, usersid,
4768                               MSIINSTALLCONTEXT_USERUNMANAGED,
4769                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4770     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4771     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4772     ok(sz == 4, "Expected 4, got %d\n", sz);
4773
4774     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4776
4777     /* PackageName value exists */
4778     sz = MAX_PATH;
4779     lstrcpyA(buf, "apple");
4780     r = pMsiGetProductInfoExA(prodcode, usersid,
4781                               MSIINSTALLCONTEXT_USERUNMANAGED,
4782                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4783     todo_wine
4784     {
4785         ok(r == ERROR_UNKNOWN_PRODUCT,
4786            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4787         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4788         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4789     }
4790
4791     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4793
4794     /* AuthorizedLUAApp value exists */
4795     sz = MAX_PATH;
4796     lstrcpyA(buf, "apple");
4797     r = pMsiGetProductInfoExA(prodcode, usersid,
4798                               MSIINSTALLCONTEXT_USERUNMANAGED,
4799                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4801     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4802     ok(sz == 4, "Expected 4, got %d\n", sz);
4803
4804     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4805     RegDeleteValueA(prodkey, "PackageName");
4806     RegDeleteValueA(prodkey, "ProductIcon");
4807     RegDeleteValueA(prodkey, "Version");
4808     RegDeleteValueA(prodkey, "PackageCode");
4809     RegDeleteValueA(prodkey, "AssignmentType");
4810     RegDeleteValueA(prodkey, "ProductName");
4811     RegDeleteValueA(prodkey, "Language");
4812     RegDeleteValueA(prodkey, "Transforms");
4813     RegDeleteValueA(prodkey, "RegOwner");
4814     RegDeleteValueA(prodkey, "RegCompany");
4815     RegDeleteValueA(prodkey, "ProductID");
4816     RegDeleteValueA(prodkey, "DisplayVersion");
4817     RegDeleteValueA(prodkey, "VersionMajor");
4818     RegDeleteValueA(prodkey, "VersionMinor");
4819     RegDeleteValueA(prodkey, "URLUpdateInfo");
4820     RegDeleteValueA(prodkey, "URLInfoAbout");
4821     RegDeleteValueA(prodkey, "Publisher");
4822     RegDeleteValueA(prodkey, "LocalPackage");
4823     RegDeleteValueA(prodkey, "InstallSource");
4824     RegDeleteValueA(prodkey, "InstallLocation");
4825     RegDeleteValueA(prodkey, "DisplayName");
4826     RegDeleteValueA(prodkey, "InstallDate");
4827     RegDeleteValueA(prodkey, "HelpTelephone");
4828     RegDeleteValueA(prodkey, "HelpLink");
4829     RegDeleteValueA(prodkey, "LocalPackage");
4830     RegDeleteKeyA(prodkey, "");
4831     RegCloseKey(prodkey);
4832
4833     /* MSIINSTALLCONTEXT_USERMANAGED */
4834
4835     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4836     lstrcatA(keypath, usersid);
4837     lstrcatA(keypath, "\\Products\\");
4838     lstrcatA(keypath, prod_squashed);
4839
4840     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4842
4843     /* local user product key exists */
4844     sz = MAX_PATH;
4845     lstrcpyA(buf, "apple");
4846     r = pMsiGetProductInfoExA(prodcode, usersid,
4847                               MSIINSTALLCONTEXT_USERMANAGED,
4848                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4849     ok(r == ERROR_UNKNOWN_PRODUCT,
4850        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4851     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4852     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4853
4854     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4856
4857     /* InstallProperties key exists */
4858     sz = MAX_PATH;
4859     lstrcpyA(buf, "apple");
4860     r = pMsiGetProductInfoExA(prodcode, usersid,
4861                               MSIINSTALLCONTEXT_USERMANAGED,
4862                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4863     ok(r == ERROR_UNKNOWN_PRODUCT,
4864        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4865     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4866     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4867
4868     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4869     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4870
4871     /* ManagedLocalPackage value exists */
4872     sz = MAX_PATH;
4873     lstrcpyA(buf, "apple");
4874     r = pMsiGetProductInfoExA(prodcode, usersid,
4875                               MSIINSTALLCONTEXT_USERMANAGED,
4876                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4877     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4878     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4879     ok(sz == 1, "Expected 1, got %d\n", sz);
4880
4881     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4883
4884     /* HelpLink value exists */
4885     sz = MAX_PATH;
4886     lstrcpyA(buf, "apple");
4887     r = pMsiGetProductInfoExA(prodcode, usersid,
4888                               MSIINSTALLCONTEXT_USERMANAGED,
4889                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4890     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4891     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4892     ok(sz == 4, "Expected 4, got %d\n", sz);
4893
4894     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4896
4897     /* HelpTelephone value exists */
4898     sz = MAX_PATH;
4899     lstrcpyA(buf, "apple");
4900     r = pMsiGetProductInfoExA(prodcode, usersid,
4901                               MSIINSTALLCONTEXT_USERMANAGED,
4902                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4903     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4904     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4905     ok(sz == 5, "Expected 5, got %d\n", sz);
4906
4907     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4909
4910     /* InstallDate value exists */
4911     sz = MAX_PATH;
4912     lstrcpyA(buf, "apple");
4913     r = pMsiGetProductInfoExA(prodcode, usersid,
4914                               MSIINSTALLCONTEXT_USERMANAGED,
4915                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4917     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4918     ok(sz == 4, "Expected 4, got %d\n", sz);
4919
4920     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4922
4923     /* DisplayName value exists */
4924     sz = MAX_PATH;
4925     lstrcpyA(buf, "apple");
4926     r = pMsiGetProductInfoExA(prodcode, usersid,
4927                               MSIINSTALLCONTEXT_USERMANAGED,
4928                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4929     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4930     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4931     ok(sz == 4, "Expected 4, got %d\n", sz);
4932
4933     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4934     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4935
4936     /* InstallLocation value exists */
4937     sz = MAX_PATH;
4938     lstrcpyA(buf, "apple");
4939     r = pMsiGetProductInfoExA(prodcode, usersid,
4940                               MSIINSTALLCONTEXT_USERMANAGED,
4941                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4942     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4943     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4944     ok(sz == 3, "Expected 3, got %d\n", sz);
4945
4946     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4948
4949     /* InstallSource value exists */
4950     sz = MAX_PATH;
4951     lstrcpyA(buf, "apple");
4952     r = pMsiGetProductInfoExA(prodcode, usersid,
4953                               MSIINSTALLCONTEXT_USERMANAGED,
4954                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4955     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4956     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4957     ok(sz == 6, "Expected 6, got %d\n", sz);
4958
4959     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4960     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4961
4962     /* LocalPackage value exists */
4963     sz = MAX_PATH;
4964     lstrcpyA(buf, "apple");
4965     r = pMsiGetProductInfoExA(prodcode, usersid,
4966                               MSIINSTALLCONTEXT_USERMANAGED,
4967                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4969     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4970     ok(sz == 5, "Expected 5, got %d\n", sz);
4971
4972     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4974
4975     /* Publisher value exists */
4976     sz = MAX_PATH;
4977     lstrcpyA(buf, "apple");
4978     r = pMsiGetProductInfoExA(prodcode, usersid,
4979                               MSIINSTALLCONTEXT_USERMANAGED,
4980                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4982     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4983     ok(sz == 3, "Expected 3, got %d\n", sz);
4984
4985     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4987
4988     /* URLInfoAbout value exists */
4989     sz = MAX_PATH;
4990     lstrcpyA(buf, "apple");
4991     r = pMsiGetProductInfoExA(prodcode, usersid,
4992                               MSIINSTALLCONTEXT_USERMANAGED,
4993                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4995     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4996     ok(sz == 5, "Expected 5, got %d\n", sz);
4997
4998     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5000
5001     /* URLUpdateInfo value exists */
5002     sz = MAX_PATH;
5003     lstrcpyA(buf, "apple");
5004     r = pMsiGetProductInfoExA(prodcode, usersid,
5005                               MSIINSTALLCONTEXT_USERMANAGED,
5006                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5007     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5008     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5009     ok(sz == 6, "Expected 6, got %d\n", sz);
5010
5011     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5013
5014     /* VersionMinor value exists */
5015     sz = MAX_PATH;
5016     lstrcpyA(buf, "apple");
5017     r = pMsiGetProductInfoExA(prodcode, usersid,
5018                               MSIINSTALLCONTEXT_USERMANAGED,
5019                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5020     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5021     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5022     ok(sz == 1, "Expected 1, got %d\n", sz);
5023
5024     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5026
5027     /* VersionMajor value exists */
5028     sz = MAX_PATH;
5029     lstrcpyA(buf, "apple");
5030     r = pMsiGetProductInfoExA(prodcode, usersid,
5031                               MSIINSTALLCONTEXT_USERMANAGED,
5032                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5034     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5035     ok(sz == 1, "Expected 1, got %d\n", sz);
5036
5037     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5039
5040     /* DisplayVersion value exists */
5041     sz = MAX_PATH;
5042     lstrcpyA(buf, "apple");
5043     r = pMsiGetProductInfoExA(prodcode, usersid,
5044                               MSIINSTALLCONTEXT_USERMANAGED,
5045                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5047     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5048     ok(sz == 5, "Expected 5, got %d\n", sz);
5049
5050     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5051     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5052
5053     /* ProductID value exists */
5054     sz = MAX_PATH;
5055     lstrcpyA(buf, "apple");
5056     r = pMsiGetProductInfoExA(prodcode, usersid,
5057                               MSIINSTALLCONTEXT_USERMANAGED,
5058                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5060     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5061     ok(sz == 2, "Expected 2, got %d\n", sz);
5062
5063     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5065
5066     /* RegCompany value exists */
5067     sz = MAX_PATH;
5068     lstrcpyA(buf, "apple");
5069     r = pMsiGetProductInfoExA(prodcode, usersid,
5070                               MSIINSTALLCONTEXT_USERMANAGED,
5071                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5073     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5074     ok(sz == 4, "Expected 4, got %d\n", sz);
5075
5076     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5078
5079     /* RegOwner value exists */
5080     sz = MAX_PATH;
5081     lstrcpyA(buf, "apple");
5082     r = pMsiGetProductInfoExA(prodcode, usersid,
5083                               MSIINSTALLCONTEXT_USERMANAGED,
5084                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5085     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5086     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5087     ok(sz == 5, "Expected 5, got %d\n", sz);
5088
5089     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5091
5092     /* Transforms value exists */
5093     sz = MAX_PATH;
5094     lstrcpyA(buf, "apple");
5095     r = pMsiGetProductInfoExA(prodcode, usersid,
5096                               MSIINSTALLCONTEXT_USERMANAGED,
5097                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5098     ok(r == ERROR_UNKNOWN_PRODUCT,
5099        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5100     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5101     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5102
5103     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5105
5106     /* Language value exists */
5107     sz = MAX_PATH;
5108     lstrcpyA(buf, "apple");
5109     r = pMsiGetProductInfoExA(prodcode, usersid,
5110                               MSIINSTALLCONTEXT_USERMANAGED,
5111                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5112     ok(r == ERROR_UNKNOWN_PRODUCT,
5113        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5114     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5115     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5116
5117     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5119
5120     /* ProductName value exists */
5121     sz = MAX_PATH;
5122     lstrcpyA(buf, "apple");
5123     r = pMsiGetProductInfoExA(prodcode, usersid,
5124                               MSIINSTALLCONTEXT_USERMANAGED,
5125                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5126     ok(r == ERROR_UNKNOWN_PRODUCT,
5127        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5128     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5129     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5130
5131     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5133
5134     /* FIXME */
5135
5136     /* AssignmentType value exists */
5137     sz = MAX_PATH;
5138     lstrcpyA(buf, "apple");
5139     r = pMsiGetProductInfoExA(prodcode, usersid,
5140                               MSIINSTALLCONTEXT_USERMANAGED,
5141                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5142     ok(r == ERROR_UNKNOWN_PRODUCT,
5143        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5144     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5145     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5146
5147     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5149
5150     /* PackageCode value exists */
5151     sz = MAX_PATH;
5152     lstrcpyA(buf, "apple");
5153     r = pMsiGetProductInfoExA(prodcode, usersid,
5154                               MSIINSTALLCONTEXT_USERMANAGED,
5155                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5156     ok(r == ERROR_UNKNOWN_PRODUCT,
5157        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5158     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5159     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5160
5161     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5163
5164     /* Version value exists */
5165     sz = MAX_PATH;
5166     lstrcpyA(buf, "apple");
5167     r = pMsiGetProductInfoExA(prodcode, usersid,
5168                               MSIINSTALLCONTEXT_USERMANAGED,
5169                               INSTALLPROPERTY_VERSION, buf, &sz);
5170     ok(r == ERROR_UNKNOWN_PRODUCT,
5171        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5172     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5173     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5174
5175     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5177
5178     /* ProductIcon value exists */
5179     sz = MAX_PATH;
5180     lstrcpyA(buf, "apple");
5181     r = pMsiGetProductInfoExA(prodcode, usersid,
5182                               MSIINSTALLCONTEXT_USERMANAGED,
5183                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5184     ok(r == ERROR_UNKNOWN_PRODUCT,
5185        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5186     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5187     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5188
5189     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5190     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5191
5192     /* PackageName value exists */
5193     sz = MAX_PATH;
5194     lstrcpyA(buf, "apple");
5195     r = pMsiGetProductInfoExA(prodcode, usersid,
5196                               MSIINSTALLCONTEXT_USERMANAGED,
5197                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5198     ok(r == ERROR_UNKNOWN_PRODUCT,
5199        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5200     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5201     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5202
5203     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5205
5206     /* AuthorizedLUAApp value exists */
5207     sz = MAX_PATH;
5208     lstrcpyA(buf, "apple");
5209     r = pMsiGetProductInfoExA(prodcode, usersid,
5210                               MSIINSTALLCONTEXT_USERMANAGED,
5211                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5212     ok(r == ERROR_UNKNOWN_PRODUCT,
5213        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5214     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5215     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5216
5217     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5218     RegDeleteValueA(propkey, "PackageName");
5219     RegDeleteValueA(propkey, "ProductIcon");
5220     RegDeleteValueA(propkey, "Version");
5221     RegDeleteValueA(propkey, "PackageCode");
5222     RegDeleteValueA(propkey, "AssignmentType");
5223     RegDeleteValueA(propkey, "ProductName");
5224     RegDeleteValueA(propkey, "Language");
5225     RegDeleteValueA(propkey, "Transforms");
5226     RegDeleteValueA(propkey, "RegOwner");
5227     RegDeleteValueA(propkey, "RegCompany");
5228     RegDeleteValueA(propkey, "ProductID");
5229     RegDeleteValueA(propkey, "DisplayVersion");
5230     RegDeleteValueA(propkey, "VersionMajor");
5231     RegDeleteValueA(propkey, "VersionMinor");
5232     RegDeleteValueA(propkey, "URLUpdateInfo");
5233     RegDeleteValueA(propkey, "URLInfoAbout");
5234     RegDeleteValueA(propkey, "Publisher");
5235     RegDeleteValueA(propkey, "LocalPackage");
5236     RegDeleteValueA(propkey, "InstallSource");
5237     RegDeleteValueA(propkey, "InstallLocation");
5238     RegDeleteValueA(propkey, "DisplayName");
5239     RegDeleteValueA(propkey, "InstallDate");
5240     RegDeleteValueA(propkey, "HelpTelephone");
5241     RegDeleteValueA(propkey, "HelpLink");
5242     RegDeleteValueA(propkey, "ManagedLocalPackage");
5243     RegDeleteKeyA(propkey, "");
5244     RegCloseKey(propkey);
5245     RegDeleteKeyA(localkey, "");
5246     RegCloseKey(localkey);
5247
5248     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5249     lstrcatA(keypath, usersid);
5250     lstrcatA(keypath, "\\Installer\\Products\\");
5251     lstrcatA(keypath, prod_squashed);
5252
5253     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5255
5256     /* user product key exists */
5257     sz = MAX_PATH;
5258     lstrcpyA(buf, "apple");
5259     r = pMsiGetProductInfoExA(prodcode, usersid,
5260                               MSIINSTALLCONTEXT_USERMANAGED,
5261                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5262     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5263     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5264     ok(sz == 1, "Expected 1, got %d\n", sz);
5265
5266     RegDeleteKeyA(userkey, "");
5267     RegCloseKey(userkey);
5268
5269     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5270     lstrcatA(keypath, prod_squashed);
5271
5272     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5274
5275     /* current user product key exists */
5276     sz = MAX_PATH;
5277     lstrcpyA(buf, "apple");
5278     r = pMsiGetProductInfoExA(prodcode, usersid,
5279                               MSIINSTALLCONTEXT_USERMANAGED,
5280                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5281     ok(r == ERROR_UNKNOWN_PRODUCT,
5282        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5283     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5284     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5285
5286     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5288
5289     /* HelpLink value exists, user product key does not exist */
5290     sz = MAX_PATH;
5291     lstrcpyA(buf, "apple");
5292     r = pMsiGetProductInfoExA(prodcode, usersid,
5293                               MSIINSTALLCONTEXT_USERMANAGED,
5294                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5295     ok(r == ERROR_UNKNOWN_PRODUCT,
5296        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5297     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5298     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5299
5300     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5301     lstrcatA(keypath, usersid);
5302     lstrcatA(keypath, "\\Installer\\Products\\");
5303     lstrcatA(keypath, prod_squashed);
5304
5305     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5307
5308     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5310
5311     /* HelpLink value exists, user product key does exist */
5312     sz = MAX_PATH;
5313     lstrcpyA(buf, "apple");
5314     r = pMsiGetProductInfoExA(prodcode, usersid,
5315                               MSIINSTALLCONTEXT_USERMANAGED,
5316                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5317     ok(r == ERROR_UNKNOWN_PROPERTY,
5318        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5319     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5320     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5321
5322     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5324
5325     /* HelpTelephone value exists */
5326     sz = MAX_PATH;
5327     lstrcpyA(buf, "apple");
5328     r = pMsiGetProductInfoExA(prodcode, usersid,
5329                               MSIINSTALLCONTEXT_USERMANAGED,
5330                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5331     ok(r == ERROR_UNKNOWN_PROPERTY,
5332        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5333     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5334     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5335
5336     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5338
5339     /* InstallDate value exists */
5340     sz = MAX_PATH;
5341     lstrcpyA(buf, "apple");
5342     r = pMsiGetProductInfoExA(prodcode, usersid,
5343                               MSIINSTALLCONTEXT_USERMANAGED,
5344                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5345     ok(r == ERROR_UNKNOWN_PROPERTY,
5346        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5347     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5348     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5349
5350     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5352
5353     /* DisplayName value exists */
5354     sz = MAX_PATH;
5355     lstrcpyA(buf, "apple");
5356     r = pMsiGetProductInfoExA(prodcode, usersid,
5357                               MSIINSTALLCONTEXT_USERMANAGED,
5358                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5359     ok(r == ERROR_UNKNOWN_PROPERTY,
5360        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5361     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5362     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5363
5364     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5366
5367     /* InstallLocation value exists */
5368     sz = MAX_PATH;
5369     lstrcpyA(buf, "apple");
5370     r = pMsiGetProductInfoExA(prodcode, usersid,
5371                               MSIINSTALLCONTEXT_USERMANAGED,
5372                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5373     ok(r == ERROR_UNKNOWN_PROPERTY,
5374        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5375     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5376     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5377
5378     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5380
5381     /* InstallSource value exists */
5382     sz = MAX_PATH;
5383     lstrcpyA(buf, "apple");
5384     r = pMsiGetProductInfoExA(prodcode, usersid,
5385                               MSIINSTALLCONTEXT_USERMANAGED,
5386                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5387     ok(r == ERROR_UNKNOWN_PROPERTY,
5388        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5389     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5390     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5391
5392     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5394
5395     /* LocalPackage value exists */
5396     sz = MAX_PATH;
5397     lstrcpyA(buf, "apple");
5398     r = pMsiGetProductInfoExA(prodcode, usersid,
5399                               MSIINSTALLCONTEXT_USERMANAGED,
5400                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5401     ok(r == ERROR_UNKNOWN_PROPERTY,
5402        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5403     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5404     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5405
5406     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5408
5409     /* Publisher value exists */
5410     sz = MAX_PATH;
5411     lstrcpyA(buf, "apple");
5412     r = pMsiGetProductInfoExA(prodcode, usersid,
5413                               MSIINSTALLCONTEXT_USERMANAGED,
5414                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5415     ok(r == ERROR_UNKNOWN_PROPERTY,
5416        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5417     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5418     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5419
5420     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5422
5423     /* URLInfoAbout value exists */
5424     sz = MAX_PATH;
5425     lstrcpyA(buf, "apple");
5426     r = pMsiGetProductInfoExA(prodcode, usersid,
5427                               MSIINSTALLCONTEXT_USERMANAGED,
5428                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5429     ok(r == ERROR_UNKNOWN_PROPERTY,
5430        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5431     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5432     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5433
5434     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5436
5437     /* URLUpdateInfo value exists */
5438     sz = MAX_PATH;
5439     lstrcpyA(buf, "apple");
5440     r = pMsiGetProductInfoExA(prodcode, usersid,
5441                               MSIINSTALLCONTEXT_USERMANAGED,
5442                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5443     ok(r == ERROR_UNKNOWN_PROPERTY,
5444        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5445     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5446     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5447
5448     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5449     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5450
5451     /* VersionMinor value exists */
5452     sz = MAX_PATH;
5453     lstrcpyA(buf, "apple");
5454     r = pMsiGetProductInfoExA(prodcode, usersid,
5455                               MSIINSTALLCONTEXT_USERMANAGED,
5456                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5457     ok(r == ERROR_UNKNOWN_PROPERTY,
5458        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5459     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5460     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5461
5462     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5463     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5464
5465     /* VersionMajor value exists */
5466     sz = MAX_PATH;
5467     lstrcpyA(buf, "apple");
5468     r = pMsiGetProductInfoExA(prodcode, usersid,
5469                               MSIINSTALLCONTEXT_USERMANAGED,
5470                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5471     ok(r == ERROR_UNKNOWN_PROPERTY,
5472        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5473     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5474     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5475
5476     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5478
5479     /* DisplayVersion value exists */
5480     sz = MAX_PATH;
5481     lstrcpyA(buf, "apple");
5482     r = pMsiGetProductInfoExA(prodcode, usersid,
5483                               MSIINSTALLCONTEXT_USERMANAGED,
5484                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5485     ok(r == ERROR_UNKNOWN_PROPERTY,
5486        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5487     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5488     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5489
5490     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5491     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5492
5493     /* ProductID value exists */
5494     sz = MAX_PATH;
5495     lstrcpyA(buf, "apple");
5496     r = pMsiGetProductInfoExA(prodcode, usersid,
5497                               MSIINSTALLCONTEXT_USERMANAGED,
5498                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5499     ok(r == ERROR_UNKNOWN_PROPERTY,
5500        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5501     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5502     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5503
5504     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5505     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5506
5507     /* RegCompany value exists */
5508     sz = MAX_PATH;
5509     lstrcpyA(buf, "apple");
5510     r = pMsiGetProductInfoExA(prodcode, usersid,
5511                               MSIINSTALLCONTEXT_USERMANAGED,
5512                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5513     ok(r == ERROR_UNKNOWN_PROPERTY,
5514        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5515     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5516     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5517
5518     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5519     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5520
5521     /* RegOwner value exists */
5522     sz = MAX_PATH;
5523     lstrcpyA(buf, "apple");
5524     r = pMsiGetProductInfoExA(prodcode, usersid,
5525                               MSIINSTALLCONTEXT_USERMANAGED,
5526                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5527     ok(r == ERROR_UNKNOWN_PROPERTY,
5528        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5529     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5530     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5531
5532     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5534
5535     /* Transforms value exists */
5536     sz = MAX_PATH;
5537     lstrcpyA(buf, "apple");
5538     r = pMsiGetProductInfoExA(prodcode, usersid,
5539                               MSIINSTALLCONTEXT_USERMANAGED,
5540                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5542     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5543     ok(sz == 5, "Expected 5, got %d\n", sz);
5544
5545     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5547
5548     /* Language value exists */
5549     sz = MAX_PATH;
5550     lstrcpyA(buf, "apple");
5551     r = pMsiGetProductInfoExA(prodcode, usersid,
5552                               MSIINSTALLCONTEXT_USERMANAGED,
5553                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5554     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5555     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5556     ok(sz == 4, "Expected 4, got %d\n", sz);
5557
5558     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5559     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5560
5561     /* ProductName value exists */
5562     sz = MAX_PATH;
5563     lstrcpyA(buf, "apple");
5564     r = pMsiGetProductInfoExA(prodcode, usersid,
5565                               MSIINSTALLCONTEXT_USERMANAGED,
5566                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5568     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5569     ok(sz == 4, "Expected 4, got %d\n", sz);
5570
5571     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5573
5574     /* FIXME */
5575
5576     /* AssignmentType value exists */
5577     sz = MAX_PATH;
5578     lstrcpyA(buf, "apple");
5579     r = pMsiGetProductInfoExA(prodcode, usersid,
5580                               MSIINSTALLCONTEXT_USERMANAGED,
5581                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5583     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5584     ok(sz == 0, "Expected 0, got %d\n", sz);
5585
5586     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5588
5589     /* FIXME */
5590
5591     /* PackageCode value exists */
5592     sz = MAX_PATH;
5593     lstrcpyA(buf, "apple");
5594     r = pMsiGetProductInfoExA(prodcode, usersid,
5595                               MSIINSTALLCONTEXT_USERMANAGED,
5596                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5597     todo_wine
5598     {
5599         ok(r == ERROR_BAD_CONFIGURATION,
5600            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5601         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5602         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5603     }
5604
5605     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5607
5608     /* Version value exists */
5609     sz = MAX_PATH;
5610     lstrcpyA(buf, "apple");
5611     r = pMsiGetProductInfoExA(prodcode, usersid,
5612                               MSIINSTALLCONTEXT_USERMANAGED,
5613                               INSTALLPROPERTY_VERSION, buf, &sz);
5614     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5615     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5616     ok(sz == 3, "Expected 3, got %d\n", sz);
5617
5618     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5620
5621     /* ProductIcon value exists */
5622     sz = MAX_PATH;
5623     lstrcpyA(buf, "apple");
5624     r = pMsiGetProductInfoExA(prodcode, usersid,
5625                               MSIINSTALLCONTEXT_USERMANAGED,
5626                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5627     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5628     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5629     ok(sz == 4, "Expected 4, got %d\n", sz);
5630
5631     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5632     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5633
5634     /* PackageName value exists */
5635     sz = MAX_PATH;
5636     lstrcpyA(buf, "apple");
5637     r = pMsiGetProductInfoExA(prodcode, usersid,
5638                               MSIINSTALLCONTEXT_USERMANAGED,
5639                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5640     todo_wine
5641     {
5642         ok(r == ERROR_UNKNOWN_PRODUCT,
5643            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5644         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5645         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5646     }
5647
5648     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5649     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5650
5651     /* AuthorizedLUAApp value exists */
5652     sz = MAX_PATH;
5653     lstrcpyA(buf, "apple");
5654     r = pMsiGetProductInfoExA(prodcode, usersid,
5655                               MSIINSTALLCONTEXT_USERMANAGED,
5656                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5657     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5658     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5659     ok(sz == 4, "Expected 4, got %d\n", sz);
5660
5661     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5662     RegDeleteValueA(userkey, "PackageName");
5663     RegDeleteValueA(userkey, "ProductIcon");
5664     RegDeleteValueA(userkey, "Version");
5665     RegDeleteValueA(userkey, "PackageCode");
5666     RegDeleteValueA(userkey, "AssignmentType");
5667     RegDeleteValueA(userkey, "ProductName");
5668     RegDeleteValueA(userkey, "Language");
5669     RegDeleteValueA(userkey, "Transforms");
5670     RegDeleteValueA(userkey, "RegOwner");
5671     RegDeleteValueA(userkey, "RegCompany");
5672     RegDeleteValueA(userkey, "ProductID");
5673     RegDeleteValueA(userkey, "DisplayVersion");
5674     RegDeleteValueA(userkey, "VersionMajor");
5675     RegDeleteValueA(userkey, "VersionMinor");
5676     RegDeleteValueA(userkey, "URLUpdateInfo");
5677     RegDeleteValueA(userkey, "URLInfoAbout");
5678     RegDeleteValueA(userkey, "Publisher");
5679     RegDeleteValueA(userkey, "LocalPackage");
5680     RegDeleteValueA(userkey, "InstallSource");
5681     RegDeleteValueA(userkey, "InstallLocation");
5682     RegDeleteValueA(userkey, "DisplayName");
5683     RegDeleteValueA(userkey, "InstallDate");
5684     RegDeleteValueA(userkey, "HelpTelephone");
5685     RegDeleteValueA(userkey, "HelpLink");
5686     RegDeleteKeyA(userkey, "");
5687     RegCloseKey(userkey);
5688     RegDeleteKeyA(prodkey, "");
5689     RegCloseKey(prodkey);
5690
5691     /* MSIINSTALLCONTEXT_MACHINE */
5692
5693     /* szUserSid is non-NULL */
5694     sz = MAX_PATH;
5695     lstrcpyA(buf, "apple");
5696     r = pMsiGetProductInfoExA(prodcode, usersid,
5697                               MSIINSTALLCONTEXT_MACHINE,
5698                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5699     ok(r == ERROR_INVALID_PARAMETER,
5700        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5701     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5702     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5703
5704     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5705     lstrcatA(keypath, prod_squashed);
5706
5707     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5709
5710     /* local system product key exists */
5711     sz = MAX_PATH;
5712     lstrcpyA(buf, "apple");
5713     r = pMsiGetProductInfoExA(prodcode, NULL,
5714                               MSIINSTALLCONTEXT_MACHINE,
5715                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5716     ok(r == ERROR_UNKNOWN_PRODUCT,
5717        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5718     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5719     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5720
5721     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5723
5724     /* InstallProperties key exists */
5725     sz = MAX_PATH;
5726     lstrcpyA(buf, "apple");
5727     r = pMsiGetProductInfoExA(prodcode, NULL,
5728                               MSIINSTALLCONTEXT_MACHINE,
5729                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5730     ok(r == ERROR_UNKNOWN_PRODUCT,
5731        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5732     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5733     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5734
5735     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5737
5738     /* LocalPackage value exists */
5739     sz = MAX_PATH;
5740     lstrcpyA(buf, "apple");
5741     r = pMsiGetProductInfoExA(prodcode, NULL,
5742                               MSIINSTALLCONTEXT_MACHINE,
5743                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5744     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5745     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5746     ok(sz == 1, "Expected 1, got %d\n", sz);
5747
5748     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5750
5751     /* HelpLink value exists */
5752     sz = MAX_PATH;
5753     lstrcpyA(buf, "apple");
5754     r = pMsiGetProductInfoExA(prodcode, NULL,
5755                               MSIINSTALLCONTEXT_MACHINE,
5756                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5757     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5758     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5759     ok(sz == 4, "Expected 4, got %d\n", sz);
5760
5761     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5763
5764     /* HelpTelephone value exists */
5765     sz = MAX_PATH;
5766     lstrcpyA(buf, "apple");
5767     r = pMsiGetProductInfoExA(prodcode, NULL,
5768                               MSIINSTALLCONTEXT_MACHINE,
5769                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5770     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5771     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5772     ok(sz == 5, "Expected 5, got %d\n", sz);
5773
5774     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5776
5777     /* InstallDate value exists */
5778     sz = MAX_PATH;
5779     lstrcpyA(buf, "apple");
5780     r = pMsiGetProductInfoExA(prodcode, NULL,
5781                               MSIINSTALLCONTEXT_MACHINE,
5782                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5783     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5784     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5785     ok(sz == 4, "Expected 4, got %d\n", sz);
5786
5787     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5789
5790     /* DisplayName value exists */
5791     sz = MAX_PATH;
5792     lstrcpyA(buf, "apple");
5793     r = pMsiGetProductInfoExA(prodcode, NULL,
5794                               MSIINSTALLCONTEXT_MACHINE,
5795                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5796     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5797     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5798     ok(sz == 4, "Expected 4, got %d\n", sz);
5799
5800     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5801     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5802
5803     /* InstallLocation value exists */
5804     sz = MAX_PATH;
5805     lstrcpyA(buf, "apple");
5806     r = pMsiGetProductInfoExA(prodcode, NULL,
5807                               MSIINSTALLCONTEXT_MACHINE,
5808                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5809     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5810     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5811     ok(sz == 3, "Expected 3, got %d\n", sz);
5812
5813     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5815
5816     /* InstallSource value exists */
5817     sz = MAX_PATH;
5818     lstrcpyA(buf, "apple");
5819     r = pMsiGetProductInfoExA(prodcode, NULL,
5820                               MSIINSTALLCONTEXT_MACHINE,
5821                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5822     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5823     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5824     ok(sz == 6, "Expected 6, got %d\n", sz);
5825
5826     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5827     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5828
5829     /* LocalPackage value exists */
5830     sz = MAX_PATH;
5831     lstrcpyA(buf, "apple");
5832     r = pMsiGetProductInfoExA(prodcode, NULL,
5833                               MSIINSTALLCONTEXT_MACHINE,
5834                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5835     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5836     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5837     ok(sz == 5, "Expected 5, got %d\n", sz);
5838
5839     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5841
5842     /* Publisher value exists */
5843     sz = MAX_PATH;
5844     lstrcpyA(buf, "apple");
5845     r = pMsiGetProductInfoExA(prodcode, NULL,
5846                               MSIINSTALLCONTEXT_MACHINE,
5847                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5848     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5849     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5850     ok(sz == 3, "Expected 3, got %d\n", sz);
5851
5852     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5854
5855     /* URLInfoAbout value exists */
5856     sz = MAX_PATH;
5857     lstrcpyA(buf, "apple");
5858     r = pMsiGetProductInfoExA(prodcode, NULL,
5859                               MSIINSTALLCONTEXT_MACHINE,
5860                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5861     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5862     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5863     ok(sz == 5, "Expected 5, got %d\n", sz);
5864
5865     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5867
5868     /* URLUpdateInfo value exists */
5869     sz = MAX_PATH;
5870     lstrcpyA(buf, "apple");
5871     r = pMsiGetProductInfoExA(prodcode, NULL,
5872                               MSIINSTALLCONTEXT_MACHINE,
5873                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5875     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5876     ok(sz == 6, "Expected 6, got %d\n", sz);
5877
5878     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5880
5881     /* VersionMinor value exists */
5882     sz = MAX_PATH;
5883     lstrcpyA(buf, "apple");
5884     r = pMsiGetProductInfoExA(prodcode, NULL,
5885                               MSIINSTALLCONTEXT_MACHINE,
5886                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5887     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5888     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5889     ok(sz == 1, "Expected 1, got %d\n", sz);
5890
5891     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5892     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5893
5894     /* VersionMajor value exists */
5895     sz = MAX_PATH;
5896     lstrcpyA(buf, "apple");
5897     r = pMsiGetProductInfoExA(prodcode, NULL,
5898                               MSIINSTALLCONTEXT_MACHINE,
5899                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5901     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5902     ok(sz == 1, "Expected 1, got %d\n", sz);
5903
5904     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5906
5907     /* DisplayVersion value exists */
5908     sz = MAX_PATH;
5909     lstrcpyA(buf, "apple");
5910     r = pMsiGetProductInfoExA(prodcode, NULL,
5911                               MSIINSTALLCONTEXT_MACHINE,
5912                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5913     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5914     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5915     ok(sz == 5, "Expected 5, got %d\n", sz);
5916
5917     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5919
5920     /* ProductID value exists */
5921     sz = MAX_PATH;
5922     lstrcpyA(buf, "apple");
5923     r = pMsiGetProductInfoExA(prodcode, NULL,
5924                               MSIINSTALLCONTEXT_MACHINE,
5925                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5927     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5928     ok(sz == 2, "Expected 2, got %d\n", sz);
5929
5930     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5932
5933     /* RegCompany value exists */
5934     sz = MAX_PATH;
5935     lstrcpyA(buf, "apple");
5936     r = pMsiGetProductInfoExA(prodcode, NULL,
5937                               MSIINSTALLCONTEXT_MACHINE,
5938                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5940     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5941     ok(sz == 4, "Expected 4, got %d\n", sz);
5942
5943     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5945
5946     /* RegOwner value exists */
5947     sz = MAX_PATH;
5948     lstrcpyA(buf, "apple");
5949     r = pMsiGetProductInfoExA(prodcode, NULL,
5950                               MSIINSTALLCONTEXT_MACHINE,
5951                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5953     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5954     ok(sz == 5, "Expected 5, got %d\n", sz);
5955
5956     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5958
5959     /* Transforms value exists */
5960     sz = MAX_PATH;
5961     lstrcpyA(buf, "apple");
5962     r = pMsiGetProductInfoExA(prodcode, NULL,
5963                               MSIINSTALLCONTEXT_MACHINE,
5964                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5965     ok(r == ERROR_UNKNOWN_PRODUCT,
5966        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5967     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5968     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5969
5970     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5972
5973     /* Language value exists */
5974     sz = MAX_PATH;
5975     lstrcpyA(buf, "apple");
5976     r = pMsiGetProductInfoExA(prodcode, NULL,
5977                               MSIINSTALLCONTEXT_MACHINE,
5978                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5979     ok(r == ERROR_UNKNOWN_PRODUCT,
5980        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5981     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5982     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5983
5984     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5986
5987     /* ProductName value exists */
5988     sz = MAX_PATH;
5989     lstrcpyA(buf, "apple");
5990     r = pMsiGetProductInfoExA(prodcode, NULL,
5991                               MSIINSTALLCONTEXT_MACHINE,
5992                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5993     ok(r == ERROR_UNKNOWN_PRODUCT,
5994        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5995     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5996     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5997
5998     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6000
6001     /* FIXME */
6002
6003     /* AssignmentType value exists */
6004     sz = MAX_PATH;
6005     lstrcpyA(buf, "apple");
6006     r = pMsiGetProductInfoExA(prodcode, NULL,
6007                               MSIINSTALLCONTEXT_MACHINE,
6008                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6009     ok(r == ERROR_UNKNOWN_PRODUCT,
6010        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6011     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6012     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6013
6014     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6015     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6016
6017     /* PackageCode value exists */
6018     sz = MAX_PATH;
6019     lstrcpyA(buf, "apple");
6020     r = pMsiGetProductInfoExA(prodcode, NULL,
6021                               MSIINSTALLCONTEXT_MACHINE,
6022                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6023     ok(r == ERROR_UNKNOWN_PRODUCT,
6024        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6025     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6026     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6027
6028     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6030
6031     /* Version value exists */
6032     sz = MAX_PATH;
6033     lstrcpyA(buf, "apple");
6034     r = pMsiGetProductInfoExA(prodcode, NULL,
6035                               MSIINSTALLCONTEXT_MACHINE,
6036                               INSTALLPROPERTY_VERSION, buf, &sz);
6037     ok(r == ERROR_UNKNOWN_PRODUCT,
6038        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6039     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6040     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6041
6042     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6044
6045     /* ProductIcon value exists */
6046     sz = MAX_PATH;
6047     lstrcpyA(buf, "apple");
6048     r = pMsiGetProductInfoExA(prodcode, NULL,
6049                               MSIINSTALLCONTEXT_MACHINE,
6050                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6051     ok(r == ERROR_UNKNOWN_PRODUCT,
6052        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6053     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6054     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6055
6056     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6057     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6058
6059     /* PackageName value exists */
6060     sz = MAX_PATH;
6061     lstrcpyA(buf, "apple");
6062     r = pMsiGetProductInfoExA(prodcode, NULL,
6063                               MSIINSTALLCONTEXT_MACHINE,
6064                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6065     ok(r == ERROR_UNKNOWN_PRODUCT,
6066        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6067     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6068     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6069
6070     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6072
6073     /* AuthorizedLUAApp value exists */
6074     sz = MAX_PATH;
6075     lstrcpyA(buf, "apple");
6076     r = pMsiGetProductInfoExA(prodcode, NULL,
6077                               MSIINSTALLCONTEXT_MACHINE,
6078                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6079     ok(r == ERROR_UNKNOWN_PRODUCT,
6080        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6081     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6082     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6083
6084     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6085     RegDeleteValueA(propkey, "PackageName");
6086     RegDeleteValueA(propkey, "ProductIcon");
6087     RegDeleteValueA(propkey, "Version");
6088     RegDeleteValueA(propkey, "PackageCode");
6089     RegDeleteValueA(propkey, "AssignmentType");
6090     RegDeleteValueA(propkey, "ProductName");
6091     RegDeleteValueA(propkey, "Language");
6092     RegDeleteValueA(propkey, "Transforms");
6093     RegDeleteValueA(propkey, "RegOwner");
6094     RegDeleteValueA(propkey, "RegCompany");
6095     RegDeleteValueA(propkey, "ProductID");
6096     RegDeleteValueA(propkey, "DisplayVersion");
6097     RegDeleteValueA(propkey, "VersionMajor");
6098     RegDeleteValueA(propkey, "VersionMinor");
6099     RegDeleteValueA(propkey, "URLUpdateInfo");
6100     RegDeleteValueA(propkey, "URLInfoAbout");
6101     RegDeleteValueA(propkey, "Publisher");
6102     RegDeleteValueA(propkey, "LocalPackage");
6103     RegDeleteValueA(propkey, "InstallSource");
6104     RegDeleteValueA(propkey, "InstallLocation");
6105     RegDeleteValueA(propkey, "DisplayName");
6106     RegDeleteValueA(propkey, "InstallDate");
6107     RegDeleteValueA(propkey, "HelpTelephone");
6108     RegDeleteValueA(propkey, "HelpLink");
6109     RegDeleteValueA(propkey, "LocalPackage");
6110     RegDeleteKeyA(propkey, "");
6111     RegCloseKey(propkey);
6112     RegDeleteKeyA(localkey, "");
6113     RegCloseKey(localkey);
6114
6115     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6116     lstrcatA(keypath, prod_squashed);
6117
6118     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6120
6121     /* local classes product key exists */
6122     sz = MAX_PATH;
6123     lstrcpyA(buf, "apple");
6124     r = pMsiGetProductInfoExA(prodcode, NULL,
6125                               MSIINSTALLCONTEXT_MACHINE,
6126                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6128     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6129     ok(sz == 1, "Expected 1, got %d\n", sz);
6130
6131     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6133
6134     /* HelpLink value exists */
6135     sz = MAX_PATH;
6136     lstrcpyA(buf, "apple");
6137     r = pMsiGetProductInfoExA(prodcode, NULL,
6138                               MSIINSTALLCONTEXT_MACHINE,
6139                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6140     ok(r == ERROR_UNKNOWN_PROPERTY,
6141        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6142     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6143     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6144
6145     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6146     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6147
6148     /* HelpTelephone value exists */
6149     sz = MAX_PATH;
6150     lstrcpyA(buf, "apple");
6151     r = pMsiGetProductInfoExA(prodcode, NULL,
6152                               MSIINSTALLCONTEXT_MACHINE,
6153                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6154     ok(r == ERROR_UNKNOWN_PROPERTY,
6155        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6156     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6157     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6158
6159     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6161
6162     /* InstallDate value exists */
6163     sz = MAX_PATH;
6164     lstrcpyA(buf, "apple");
6165     r = pMsiGetProductInfoExA(prodcode, NULL,
6166                               MSIINSTALLCONTEXT_MACHINE,
6167                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6168     ok(r == ERROR_UNKNOWN_PROPERTY,
6169        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6170     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6171     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6172
6173     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6175
6176     /* DisplayName value exists */
6177     sz = MAX_PATH;
6178     lstrcpyA(buf, "apple");
6179     r = pMsiGetProductInfoExA(prodcode, NULL,
6180                               MSIINSTALLCONTEXT_MACHINE,
6181                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6182     ok(r == ERROR_UNKNOWN_PROPERTY,
6183        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6184     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6185     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6186
6187     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6189
6190     /* InstallLocation value exists */
6191     sz = MAX_PATH;
6192     lstrcpyA(buf, "apple");
6193     r = pMsiGetProductInfoExA(prodcode, NULL,
6194                               MSIINSTALLCONTEXT_MACHINE,
6195                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6196     ok(r == ERROR_UNKNOWN_PROPERTY,
6197        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6198     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6199     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6200
6201     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6203
6204     /* InstallSource value exists */
6205     sz = MAX_PATH;
6206     lstrcpyA(buf, "apple");
6207     r = pMsiGetProductInfoExA(prodcode, NULL,
6208                               MSIINSTALLCONTEXT_MACHINE,
6209                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6210     ok(r == ERROR_UNKNOWN_PROPERTY,
6211        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6212     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6213     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6214
6215     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6217
6218     /* LocalPackage value exists */
6219     sz = MAX_PATH;
6220     lstrcpyA(buf, "apple");
6221     r = pMsiGetProductInfoExA(prodcode, NULL,
6222                               MSIINSTALLCONTEXT_MACHINE,
6223                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6224     ok(r == ERROR_UNKNOWN_PROPERTY,
6225        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6226     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6227     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6228
6229     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6231
6232     /* Publisher value exists */
6233     sz = MAX_PATH;
6234     lstrcpyA(buf, "apple");
6235     r = pMsiGetProductInfoExA(prodcode, NULL,
6236                               MSIINSTALLCONTEXT_MACHINE,
6237                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6238     ok(r == ERROR_UNKNOWN_PROPERTY,
6239        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6240     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6241     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6242
6243     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6245
6246     /* URLInfoAbout value exists */
6247     sz = MAX_PATH;
6248     lstrcpyA(buf, "apple");
6249     r = pMsiGetProductInfoExA(prodcode, NULL,
6250                               MSIINSTALLCONTEXT_MACHINE,
6251                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6252     ok(r == ERROR_UNKNOWN_PROPERTY,
6253        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6254     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6255     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6256
6257     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6259
6260     /* URLUpdateInfo value exists */
6261     sz = MAX_PATH;
6262     lstrcpyA(buf, "apple");
6263     r = pMsiGetProductInfoExA(prodcode, NULL,
6264                               MSIINSTALLCONTEXT_MACHINE,
6265                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6266     ok(r == ERROR_UNKNOWN_PROPERTY,
6267        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6268     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6269     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6270
6271     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6273
6274     /* VersionMinor value exists */
6275     sz = MAX_PATH;
6276     lstrcpyA(buf, "apple");
6277     r = pMsiGetProductInfoExA(prodcode, NULL,
6278                               MSIINSTALLCONTEXT_MACHINE,
6279                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6280     ok(r == ERROR_UNKNOWN_PROPERTY,
6281        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6282     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6283     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6284
6285     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6286     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6287
6288     /* VersionMajor value exists */
6289     sz = MAX_PATH;
6290     lstrcpyA(buf, "apple");
6291     r = pMsiGetProductInfoExA(prodcode, NULL,
6292                               MSIINSTALLCONTEXT_MACHINE,
6293                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6294     ok(r == ERROR_UNKNOWN_PROPERTY,
6295        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6296     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6297     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6298
6299     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6301
6302     /* DisplayVersion value exists */
6303     sz = MAX_PATH;
6304     lstrcpyA(buf, "apple");
6305     r = pMsiGetProductInfoExA(prodcode, NULL,
6306                               MSIINSTALLCONTEXT_MACHINE,
6307                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6308     ok(r == ERROR_UNKNOWN_PROPERTY,
6309        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6310     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6311     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6312
6313     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6315
6316     /* ProductID value exists */
6317     sz = MAX_PATH;
6318     lstrcpyA(buf, "apple");
6319     r = pMsiGetProductInfoExA(prodcode, NULL,
6320                               MSIINSTALLCONTEXT_MACHINE,
6321                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6322     ok(r == ERROR_UNKNOWN_PROPERTY,
6323        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6324     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6325     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6326
6327     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6329
6330     /* RegCompany value exists */
6331     sz = MAX_PATH;
6332     lstrcpyA(buf, "apple");
6333     r = pMsiGetProductInfoExA(prodcode, NULL,
6334                               MSIINSTALLCONTEXT_MACHINE,
6335                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6336     ok(r == ERROR_UNKNOWN_PROPERTY,
6337        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6338     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6339     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6340
6341     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6343
6344     /* RegOwner value exists */
6345     sz = MAX_PATH;
6346     lstrcpyA(buf, "apple");
6347     r = pMsiGetProductInfoExA(prodcode, NULL,
6348                               MSIINSTALLCONTEXT_MACHINE,
6349                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6350     ok(r == ERROR_UNKNOWN_PROPERTY,
6351        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6352     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6353     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6354
6355     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6357
6358     /* Transforms value exists */
6359     sz = MAX_PATH;
6360     lstrcpyA(buf, "apple");
6361     r = pMsiGetProductInfoExA(prodcode, NULL,
6362                               MSIINSTALLCONTEXT_MACHINE,
6363                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6364     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6365     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6366     ok(sz == 5, "Expected 5, got %d\n", sz);
6367
6368     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6369     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6370
6371     /* Language value exists */
6372     sz = MAX_PATH;
6373     lstrcpyA(buf, "apple");
6374     r = pMsiGetProductInfoExA(prodcode, NULL,
6375                               MSIINSTALLCONTEXT_MACHINE,
6376                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6378     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6379     ok(sz == 4, "Expected 4, got %d\n", sz);
6380
6381     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6383
6384     /* ProductName value exists */
6385     sz = MAX_PATH;
6386     lstrcpyA(buf, "apple");
6387     r = pMsiGetProductInfoExA(prodcode, NULL,
6388                               MSIINSTALLCONTEXT_MACHINE,
6389                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6390     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6391     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6392     ok(sz == 4, "Expected 4, got %d\n", sz);
6393
6394     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6395     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6396
6397     /* FIXME */
6398
6399     /* AssignmentType value exists */
6400     sz = MAX_PATH;
6401     lstrcpyA(buf, "apple");
6402     r = pMsiGetProductInfoExA(prodcode, NULL,
6403                               MSIINSTALLCONTEXT_MACHINE,
6404                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6405     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6406     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6407     ok(sz == 0, "Expected 0, got %d\n", sz);
6408
6409     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6410     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6411
6412     /* FIXME */
6413
6414     /* PackageCode value exists */
6415     sz = MAX_PATH;
6416     lstrcpyA(buf, "apple");
6417     r = pMsiGetProductInfoExA(prodcode, NULL,
6418                               MSIINSTALLCONTEXT_MACHINE,
6419                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6420     todo_wine
6421     {
6422         ok(r == ERROR_BAD_CONFIGURATION,
6423            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6424         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6425         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6426     }
6427
6428     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6430
6431     /* Version value exists */
6432     sz = MAX_PATH;
6433     lstrcpyA(buf, "apple");
6434     r = pMsiGetProductInfoExA(prodcode, NULL,
6435                               MSIINSTALLCONTEXT_MACHINE,
6436                               INSTALLPROPERTY_VERSION, buf, &sz);
6437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6438     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6439     ok(sz == 3, "Expected 3, got %d\n", sz);
6440
6441     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6443
6444     /* ProductIcon value exists */
6445     sz = MAX_PATH;
6446     lstrcpyA(buf, "apple");
6447     r = pMsiGetProductInfoExA(prodcode, NULL,
6448                               MSIINSTALLCONTEXT_MACHINE,
6449                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6451     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6452     ok(sz == 4, "Expected 4, got %d\n", sz);
6453
6454     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6456
6457     /* PackageName value exists */
6458     sz = MAX_PATH;
6459     lstrcpyA(buf, "apple");
6460     r = pMsiGetProductInfoExA(prodcode, NULL,
6461                               MSIINSTALLCONTEXT_MACHINE,
6462                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6463     todo_wine
6464     {
6465         ok(r == ERROR_UNKNOWN_PRODUCT,
6466            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6467         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6468         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6469     }
6470
6471     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6473
6474     /* AuthorizedLUAApp value exists */
6475     sz = MAX_PATH;
6476     lstrcpyA(buf, "apple");
6477     r = pMsiGetProductInfoExA(prodcode, NULL,
6478                               MSIINSTALLCONTEXT_MACHINE,
6479                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6480     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6481     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6482     ok(sz == 4, "Expected 4, got %d\n", sz);
6483
6484     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6485     RegDeleteValueA(prodkey, "PackageName");
6486     RegDeleteValueA(prodkey, "ProductIcon");
6487     RegDeleteValueA(prodkey, "Version");
6488     RegDeleteValueA(prodkey, "PackageCode");
6489     RegDeleteValueA(prodkey, "AssignmentType");
6490     RegDeleteValueA(prodkey, "ProductName");
6491     RegDeleteValueA(prodkey, "Language");
6492     RegDeleteValueA(prodkey, "Transforms");
6493     RegDeleteValueA(prodkey, "RegOwner");
6494     RegDeleteValueA(prodkey, "RegCompany");
6495     RegDeleteValueA(prodkey, "ProductID");
6496     RegDeleteValueA(prodkey, "DisplayVersion");
6497     RegDeleteValueA(prodkey, "VersionMajor");
6498     RegDeleteValueA(prodkey, "VersionMinor");
6499     RegDeleteValueA(prodkey, "URLUpdateInfo");
6500     RegDeleteValueA(prodkey, "URLInfoAbout");
6501     RegDeleteValueA(prodkey, "Publisher");
6502     RegDeleteValueA(prodkey, "LocalPackage");
6503     RegDeleteValueA(prodkey, "InstallSource");
6504     RegDeleteValueA(prodkey, "InstallLocation");
6505     RegDeleteValueA(prodkey, "DisplayName");
6506     RegDeleteValueA(prodkey, "InstallDate");
6507     RegDeleteValueA(prodkey, "HelpTelephone");
6508     RegDeleteValueA(prodkey, "HelpLink");
6509     RegDeleteKeyA(prodkey, "");
6510     RegCloseKey(prodkey);
6511 }
6512
6513 #define INIT_USERINFO() \
6514     lstrcpyA(user, "apple"); \
6515     lstrcpyA(org, "orange"); \
6516     lstrcpyA(serial, "banana"); \
6517     usersz = orgsz = serialsz = MAX_PATH;
6518
6519 static void test_MsiGetUserInfo(void)
6520 {
6521     USERINFOSTATE state;
6522     CHAR user[MAX_PATH];
6523     CHAR org[MAX_PATH];
6524     CHAR serial[MAX_PATH];
6525     DWORD usersz, orgsz, serialsz;
6526     CHAR keypath[MAX_PATH * 2];
6527     CHAR prodcode[MAX_PATH];
6528     CHAR prod_squashed[MAX_PATH];
6529     HKEY prodkey, userprod, props;
6530     LPSTR usersid;
6531     LONG res;
6532
6533     create_test_guid(prodcode, prod_squashed);
6534     get_user_sid(&usersid);
6535
6536     /* NULL szProduct */
6537     INIT_USERINFO();
6538     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6539     ok(state == USERINFOSTATE_INVALIDARG,
6540        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6541     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6542     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6543     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6544     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6545     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6546     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6547
6548     /* empty szProductCode */
6549     INIT_USERINFO();
6550     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6551     ok(state == USERINFOSTATE_INVALIDARG,
6552        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6553     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6554     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6555     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6556     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6557     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6558     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6559
6560     /* garbage szProductCode */
6561     INIT_USERINFO();
6562     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6563     ok(state == USERINFOSTATE_INVALIDARG,
6564        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6565     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6566     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6567     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6568     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6569     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6570     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6571
6572     /* guid without brackets */
6573     INIT_USERINFO();
6574     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6575                             user, &usersz, org, &orgsz, serial, &serialsz);
6576     ok(state == USERINFOSTATE_INVALIDARG,
6577        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6578     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6579     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6580     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6581     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6582     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6583     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6584
6585     /* guid with brackets */
6586     INIT_USERINFO();
6587     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6588                             user, &usersz, org, &orgsz, serial, &serialsz);
6589     ok(state == USERINFOSTATE_UNKNOWN,
6590        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6591     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6592     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6593     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6594     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6595     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6596     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6597
6598     /* NULL lpUserNameBuf */
6599     INIT_USERINFO();
6600     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6601     ok(state == USERINFOSTATE_UNKNOWN,
6602        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6603     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6604     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6605     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6606     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6607     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6608
6609     /* NULL pcchUserNameBuf */
6610     INIT_USERINFO();
6611     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6612     ok(state == USERINFOSTATE_INVALIDARG,
6613        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6614     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6615     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6616     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6617     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6618     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6619
6620     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6621     INIT_USERINFO();
6622     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6623     ok(state == USERINFOSTATE_UNKNOWN,
6624        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6625     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6626     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6627     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6628     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6629
6630     /* NULL lpOrgNameBuf */
6631     INIT_USERINFO();
6632     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6633     ok(state == USERINFOSTATE_UNKNOWN,
6634        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6635     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6636     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6637     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6638     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6639     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6640
6641     /* NULL pcchOrgNameBuf */
6642     INIT_USERINFO();
6643     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6644     ok(state == USERINFOSTATE_INVALIDARG,
6645        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6646     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6647     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6648     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6649     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6650     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6651
6652     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6653     INIT_USERINFO();
6654     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6655     ok(state == USERINFOSTATE_UNKNOWN,
6656        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6657     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6658     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6659     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6660     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6661
6662     /* NULL lpSerialBuf */
6663     INIT_USERINFO();
6664     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6665     ok(state == USERINFOSTATE_UNKNOWN,
6666        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6667     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6668     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6669     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6670     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6671     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6672
6673     /* NULL pcchSerialBuf */
6674     INIT_USERINFO();
6675     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6676     ok(state == USERINFOSTATE_INVALIDARG,
6677        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6678     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6679     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6680     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6681     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6682     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6683
6684     /* both lpSerialBuf and pcchSerialBuf NULL */
6685     INIT_USERINFO();
6686     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6687     ok(state == USERINFOSTATE_UNKNOWN,
6688        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6689     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6690     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6691     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6692     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6693
6694     /* MSIINSTALLCONTEXT_USERMANAGED */
6695
6696     /* create local system product key */
6697     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6698     lstrcatA(keypath, usersid);
6699     lstrcatA(keypath, "\\Installer\\Products\\");
6700     lstrcatA(keypath, prod_squashed);
6701
6702     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6704
6705     /* managed product key exists */
6706     INIT_USERINFO();
6707     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6708     ok(state == USERINFOSTATE_ABSENT,
6709        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6710     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6711     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6712     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6713     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6714     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6715     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6716
6717     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6718     lstrcatA(keypath, "Installer\\UserData\\");
6719     lstrcatA(keypath, usersid);
6720     lstrcatA(keypath, "\\Products\\");
6721     lstrcatA(keypath, prod_squashed);
6722
6723     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6725
6726     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6728
6729     /* InstallProperties key exists */
6730     INIT_USERINFO();
6731     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6732     ok(state == USERINFOSTATE_ABSENT,
6733        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6734     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6735     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6736     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6737     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6738     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6739     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6740
6741     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6742     INIT_USERINFO();
6743     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6744     ok(state == USERINFOSTATE_ABSENT,
6745        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6746     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6747     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6748     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6749     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6750
6751     /* RegOwner, RegCompany don't exist, out params are NULL */
6752     INIT_USERINFO();
6753     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6754     ok(state == USERINFOSTATE_ABSENT,
6755        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6756     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6757     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6758
6759     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6761
6762     /* RegOwner value exists */
6763     INIT_USERINFO();
6764     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6765     ok(state == USERINFOSTATE_ABSENT,
6766        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6767     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6768     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6769     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6770     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6771     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6772     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6773
6774     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6776
6777     /* RegCompany value exists */
6778     INIT_USERINFO();
6779     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6780     ok(state == USERINFOSTATE_ABSENT,
6781        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6782     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6783     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6784     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6785     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6786     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6787     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6788
6789     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6790     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6791
6792     /* ProductID value exists */
6793     INIT_USERINFO();
6794     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6795     ok(state == USERINFOSTATE_PRESENT,
6796        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6797     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6798     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6799     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6800     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6801     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6802     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6803
6804     /* pcchUserNameBuf is too small */
6805     INIT_USERINFO();
6806     usersz = 0;
6807     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6808     ok(state == USERINFOSTATE_MOREDATA,
6809        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6810     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6811     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6812     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6813     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6814     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6815     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6816
6817     /* pcchUserNameBuf has no room for NULL terminator */
6818     INIT_USERINFO();
6819     usersz = 5;
6820     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6821     ok(state == USERINFOSTATE_MOREDATA,
6822        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6823     todo_wine
6824     {
6825         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6826     }
6827     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6828     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6829     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6830     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6831     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6832
6833     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6834     INIT_USERINFO();
6835     usersz = 0;
6836     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6837     ok(state == USERINFOSTATE_PRESENT,
6838        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6839     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6840     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6841     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6842     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6843     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6844     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6845
6846     RegDeleteValueA(props, "ProductID");
6847     RegDeleteValueA(props, "RegCompany");
6848     RegDeleteValueA(props, "RegOwner");
6849     RegDeleteKeyA(props, "");
6850     RegCloseKey(props);
6851     RegDeleteKeyA(userprod, "");
6852     RegCloseKey(userprod);
6853     RegDeleteKeyA(prodkey, "");
6854     RegCloseKey(prodkey);
6855
6856     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6857
6858     /* create local system product key */
6859     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6860     lstrcatA(keypath, prod_squashed);
6861
6862     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6864
6865     /* product key exists */
6866     INIT_USERINFO();
6867     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6868     ok(state == USERINFOSTATE_ABSENT,
6869        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6870     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6871     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6872     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6873     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6874     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6875     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6876
6877     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6878     lstrcatA(keypath, "Installer\\UserData\\");
6879     lstrcatA(keypath, usersid);
6880     lstrcatA(keypath, "\\Products\\");
6881     lstrcatA(keypath, prod_squashed);
6882
6883     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6884     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6885
6886     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6888
6889     /* InstallProperties key exists */
6890     INIT_USERINFO();
6891     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6892     ok(state == USERINFOSTATE_ABSENT,
6893        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6894     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6895     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6896     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6897     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6898     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6899     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6900
6901     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6902     INIT_USERINFO();
6903     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6904     ok(state == USERINFOSTATE_ABSENT,
6905        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6906     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6907     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6908     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6909     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6910
6911     /* RegOwner, RegCompany don't exist, out params are NULL */
6912     INIT_USERINFO();
6913     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6914     ok(state == USERINFOSTATE_ABSENT,
6915        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6916     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6917     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6918
6919     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6921
6922     /* RegOwner value exists */
6923     INIT_USERINFO();
6924     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6925     ok(state == USERINFOSTATE_ABSENT,
6926        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6927     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6928     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6929     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6930     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6931     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6932     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6933
6934     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6936
6937     /* RegCompany value exists */
6938     INIT_USERINFO();
6939     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6940     ok(state == USERINFOSTATE_ABSENT,
6941        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6942     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6943     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6944     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6945     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6946     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6947     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6948
6949     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6951
6952     /* ProductID value exists */
6953     INIT_USERINFO();
6954     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6955     ok(state == USERINFOSTATE_PRESENT,
6956        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6957     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6958     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6959     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6960     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6961     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6962     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6963
6964     RegDeleteValueA(props, "ProductID");
6965     RegDeleteValueA(props, "RegCompany");
6966     RegDeleteValueA(props, "RegOwner");
6967     RegDeleteKeyA(props, "");
6968     RegCloseKey(props);
6969     RegDeleteKeyA(userprod, "");
6970     RegCloseKey(userprod);
6971     RegDeleteKeyA(prodkey, "");
6972     RegCloseKey(prodkey);
6973
6974     /* MSIINSTALLCONTEXT_MACHINE */
6975
6976     /* create local system product key */
6977     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6978     lstrcatA(keypath, prod_squashed);
6979
6980     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6982
6983     /* product key exists */
6984     INIT_USERINFO();
6985     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6986     ok(state == USERINFOSTATE_ABSENT,
6987        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6988     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6989     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6990     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6991     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6992     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6993     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6994
6995     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6996     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
6997     lstrcatA(keypath, "\\Products\\");
6998     lstrcatA(keypath, prod_squashed);
6999
7000     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7002
7003     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7005
7006     /* InstallProperties key exists */
7007     INIT_USERINFO();
7008     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7009     ok(state == USERINFOSTATE_ABSENT,
7010        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7011     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7012     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7013     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7014     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7015     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7016     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7017
7018     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7019     INIT_USERINFO();
7020     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7021     ok(state == USERINFOSTATE_ABSENT,
7022        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7023     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7024     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7025     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7026     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7027
7028     /* RegOwner, RegCompany don't exist, out params are NULL */
7029     INIT_USERINFO();
7030     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7031     ok(state == USERINFOSTATE_ABSENT,
7032        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7033     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7034     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7035
7036     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7038
7039     /* RegOwner value exists */
7040     INIT_USERINFO();
7041     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7042     ok(state == USERINFOSTATE_ABSENT,
7043        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7044     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7045     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7046     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7047     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7048     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7049     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7050
7051     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7053
7054     /* RegCompany value exists */
7055     INIT_USERINFO();
7056     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7057     ok(state == USERINFOSTATE_ABSENT,
7058        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7059     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7060     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7061     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7062     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7063     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7064     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7065
7066     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7068
7069     /* ProductID value exists */
7070     INIT_USERINFO();
7071     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7072     ok(state == USERINFOSTATE_PRESENT,
7073        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7074     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7075     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7076     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7077     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7078     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7079     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7080
7081     RegDeleteValueA(props, "ProductID");
7082     RegDeleteValueA(props, "RegCompany");
7083     RegDeleteValueA(props, "RegOwner");
7084     RegDeleteKeyA(props, "");
7085     RegCloseKey(props);
7086     RegDeleteKeyA(userprod, "");
7087     RegCloseKey(userprod);
7088     RegDeleteKeyA(prodkey, "");
7089     RegCloseKey(prodkey);
7090 }
7091
7092 static void test_MsiOpenProduct(void)
7093 {
7094     MSIHANDLE hprod, hdb;
7095     CHAR val[MAX_PATH];
7096     CHAR path[MAX_PATH];
7097     CHAR keypath[MAX_PATH*2];
7098     CHAR prodcode[MAX_PATH];
7099     CHAR prod_squashed[MAX_PATH];
7100     HKEY prodkey, userkey, props;
7101     LPSTR usersid;
7102     DWORD size;
7103     LONG res;
7104     UINT r;
7105
7106     GetCurrentDirectoryA(MAX_PATH, path);
7107     lstrcatA(path, "\\");
7108
7109     create_test_guid(prodcode, prod_squashed);
7110     get_user_sid(&usersid);
7111
7112     hdb = create_package_db(prodcode);
7113     MsiCloseHandle(hdb);
7114
7115     /* NULL szProduct */
7116     hprod = 0xdeadbeef;
7117     r = MsiOpenProductA(NULL, &hprod);
7118     ok(r == ERROR_INVALID_PARAMETER,
7119        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7120     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7121
7122     /* empty szProduct */
7123     hprod = 0xdeadbeef;
7124     r = MsiOpenProductA("", &hprod);
7125     ok(r == ERROR_INVALID_PARAMETER,
7126        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7127     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7128
7129     /* garbage szProduct */
7130     hprod = 0xdeadbeef;
7131     r = MsiOpenProductA("garbage", &hprod);
7132     ok(r == ERROR_INVALID_PARAMETER,
7133        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7134     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7135
7136     /* guid without brackets */
7137     hprod = 0xdeadbeef;
7138     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7139     ok(r == ERROR_INVALID_PARAMETER,
7140        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7141     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7142
7143     /* guid with brackets */
7144     hprod = 0xdeadbeef;
7145     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7146     ok(r == ERROR_UNKNOWN_PRODUCT,
7147        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7148     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7149
7150     /* same length as guid, but random */
7151     hprod = 0xdeadbeef;
7152     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7153     ok(r == ERROR_INVALID_PARAMETER,
7154        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7155     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7156
7157     /* hProduct is NULL */
7158     hprod = 0xdeadbeef;
7159     r = MsiOpenProductA(prodcode, NULL);
7160     ok(r == ERROR_INVALID_PARAMETER,
7161        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7162     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7163
7164     /* MSIINSTALLCONTEXT_USERMANAGED */
7165
7166     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7167     lstrcatA(keypath, "Installer\\Managed\\");
7168     lstrcatA(keypath, usersid);
7169     lstrcatA(keypath, "\\Installer\\Products\\");
7170     lstrcatA(keypath, prod_squashed);
7171
7172     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7174
7175     /* managed product key exists */
7176     hprod = 0xdeadbeef;
7177     r = MsiOpenProductA(prodcode, &hprod);
7178     ok(r == ERROR_UNKNOWN_PRODUCT,
7179        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7180     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7181
7182     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7183     lstrcatA(keypath, "Installer\\UserData\\");
7184     lstrcatA(keypath, usersid);
7185     lstrcatA(keypath, "\\Products\\");
7186     lstrcatA(keypath, prod_squashed);
7187
7188     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7190
7191     /* user product key exists */
7192     hprod = 0xdeadbeef;
7193     r = MsiOpenProductA(prodcode, &hprod);
7194     ok(r == ERROR_UNKNOWN_PRODUCT,
7195        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7196     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7197
7198     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7200
7201     /* InstallProperties key exists */
7202     hprod = 0xdeadbeef;
7203     r = MsiOpenProductA(prodcode, &hprod);
7204     ok(r == ERROR_UNKNOWN_PRODUCT,
7205        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7206     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7207
7208     lstrcpyA(val, path);
7209     lstrcatA(val, "\\winetest.msi");
7210     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7211                          (const BYTE *)val, lstrlenA(val) + 1);
7212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7213
7214     /* ManagedLocalPackage value exists */
7215     hprod = 0xdeadbeef;
7216     r = MsiOpenProductA(prodcode, &hprod);
7217     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7218     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7219
7220     size = MAX_PATH;
7221     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7223     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7224     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7225
7226     MsiCloseHandle(hprod);
7227
7228     RegDeleteValueA(props, "ManagedLocalPackage");
7229     RegDeleteKeyA(props, "");
7230     RegCloseKey(props);
7231     RegDeleteKeyA(userkey, "");
7232     RegCloseKey(userkey);
7233     RegDeleteKeyA(prodkey, "");
7234     RegCloseKey(prodkey);
7235
7236     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7237
7238     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7239     lstrcatA(keypath, prod_squashed);
7240
7241     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7243
7244     /* unmanaged product key exists */
7245     hprod = 0xdeadbeef;
7246     r = MsiOpenProductA(prodcode, &hprod);
7247     ok(r == ERROR_UNKNOWN_PRODUCT,
7248        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7249     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7250
7251     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7252     lstrcatA(keypath, "Installer\\UserData\\");
7253     lstrcatA(keypath, usersid);
7254     lstrcatA(keypath, "\\Products\\");
7255     lstrcatA(keypath, prod_squashed);
7256
7257     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7259
7260     /* user product key exists */
7261     hprod = 0xdeadbeef;
7262     r = MsiOpenProductA(prodcode, &hprod);
7263     ok(r == ERROR_UNKNOWN_PRODUCT,
7264        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7265     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7266
7267     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7269
7270     /* InstallProperties key exists */
7271     hprod = 0xdeadbeef;
7272     r = MsiOpenProductA(prodcode, &hprod);
7273     ok(r == ERROR_UNKNOWN_PRODUCT,
7274        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7275     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7276
7277     lstrcpyA(val, path);
7278     lstrcatA(val, "\\winetest.msi");
7279     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7280                          (const BYTE *)val, lstrlenA(val) + 1);
7281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7282
7283     /* LocalPackage value exists */
7284     hprod = 0xdeadbeef;
7285     r = MsiOpenProductA(prodcode, &hprod);
7286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7287     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7288
7289     size = MAX_PATH;
7290     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7292     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7293     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7294
7295     MsiCloseHandle(hprod);
7296
7297     RegDeleteValueA(props, "LocalPackage");
7298     RegDeleteKeyA(props, "");
7299     RegCloseKey(props);
7300     RegDeleteKeyA(userkey, "");
7301     RegCloseKey(userkey);
7302     RegDeleteKeyA(prodkey, "");
7303     RegCloseKey(prodkey);
7304
7305     /* MSIINSTALLCONTEXT_MACHINE */
7306
7307     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7308     lstrcatA(keypath, prod_squashed);
7309
7310     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7311     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7312
7313     /* managed product key exists */
7314     hprod = 0xdeadbeef;
7315     r = MsiOpenProductA(prodcode, &hprod);
7316     ok(r == ERROR_UNKNOWN_PRODUCT,
7317        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7318     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7319
7320     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7321     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7322     lstrcatA(keypath, prod_squashed);
7323
7324     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7326
7327     /* user product key exists */
7328     hprod = 0xdeadbeef;
7329     r = MsiOpenProductA(prodcode, &hprod);
7330     ok(r == ERROR_UNKNOWN_PRODUCT,
7331        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7332     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7333
7334     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7336
7337     /* InstallProperties key exists */
7338     hprod = 0xdeadbeef;
7339     r = MsiOpenProductA(prodcode, &hprod);
7340     ok(r == ERROR_UNKNOWN_PRODUCT,
7341        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7342     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7343
7344     lstrcpyA(val, path);
7345     lstrcatA(val, "\\winetest.msi");
7346     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7347                          (const BYTE *)val, lstrlenA(val) + 1);
7348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7349
7350     /* LocalPackage value exists */
7351     hprod = 0xdeadbeef;
7352     r = MsiOpenProductA(prodcode, &hprod);
7353     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7354     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7355
7356     size = MAX_PATH;
7357     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7358     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7359     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7360     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7361
7362     MsiCloseHandle(hprod);
7363
7364     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7365                          (const BYTE *)"winetest.msi", 13);
7366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7367
7368     /* LocalPackage has just the package name */
7369     hprod = 0xdeadbeef;
7370     r = MsiOpenProductA(prodcode, &hprod);
7371     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED,
7372        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED, got %d\n", r);
7373     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7374
7375     lstrcpyA(val, path);
7376     lstrcatA(val, "\\winetest.msi");
7377     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7378                          (const BYTE *)val, lstrlenA(val) + 1);
7379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7380
7381     DeleteFileA(msifile);
7382
7383     /* local package does not exist */
7384     hprod = 0xdeadbeef;
7385     r = MsiOpenProductA(prodcode, &hprod);
7386     ok(r == ERROR_UNKNOWN_PRODUCT,
7387        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7388     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7389
7390     RegDeleteValueA(props, "LocalPackage");
7391     RegDeleteKeyA(props, "");
7392     RegCloseKey(props);
7393     RegDeleteKeyA(userkey, "");
7394     RegCloseKey(userkey);
7395     RegDeleteKeyA(prodkey, "");
7396     RegCloseKey(prodkey);
7397
7398     DeleteFileA(msifile);
7399 }
7400
7401 static void test_MsiEnumPatchesEx(void)
7402 {
7403     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7404     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7405     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7406     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7407     HKEY prodkey, patches, udprod, udpatch;
7408     HKEY userkey, hpatch;
7409     MSIINSTALLCONTEXT context;
7410     DWORD size, data;
7411     LPSTR usersid;
7412     LONG res;
7413     UINT r;
7414
7415     if (!pMsiEnumPatchesExA)
7416     {
7417         win_skip("MsiEnumPatchesExA not implemented\n");
7418         return;
7419     }
7420
7421     create_test_guid(prodcode, prod_squashed);
7422     create_test_guid(patch, patch_squashed);
7423     get_user_sid(&usersid);
7424
7425     /* empty szProductCode */
7426     lstrcpyA(patchcode, "apple");
7427     lstrcpyA(targetprod, "banana");
7428     context = 0xdeadbeef;
7429     lstrcpyA(targetsid, "kiwi");
7430     size = MAX_PATH;
7431     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7432                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7433                            targetsid, &size);
7434     ok(r == ERROR_INVALID_PARAMETER,
7435        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7436     ok(!lstrcmpA(patchcode, "apple"),
7437        "Expected patchcode to be unchanged, got %s\n", patchcode);
7438     ok(!lstrcmpA(targetprod, "banana"),
7439        "Expected targetprod to be unchanged, got %s\n", targetprod);
7440     ok(context == 0xdeadbeef,
7441        "Expected context to be unchanged, got %d\n", context);
7442     ok(!lstrcmpA(targetsid, "kiwi"),
7443        "Expected targetsid to be unchanged, got %s\n", targetsid);
7444     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7445
7446     /* garbage szProductCode */
7447     lstrcpyA(patchcode, "apple");
7448     lstrcpyA(targetprod, "banana");
7449     context = 0xdeadbeef;
7450     lstrcpyA(targetsid, "kiwi");
7451     size = MAX_PATH;
7452     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7453                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7454                            targetsid, &size);
7455     ok(r == ERROR_INVALID_PARAMETER,
7456        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7457     ok(!lstrcmpA(patchcode, "apple"),
7458        "Expected patchcode to be unchanged, got %s\n", patchcode);
7459     ok(!lstrcmpA(targetprod, "banana"),
7460        "Expected targetprod to be unchanged, got %s\n", targetprod);
7461     ok(context == 0xdeadbeef,
7462        "Expected context to be unchanged, got %d\n", context);
7463     ok(!lstrcmpA(targetsid, "kiwi"),
7464        "Expected targetsid to be unchanged, got %s\n", targetsid);
7465     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7466
7467     /* guid without brackets */
7468     lstrcpyA(patchcode, "apple");
7469     lstrcpyA(targetprod, "banana");
7470     context = 0xdeadbeef;
7471     lstrcpyA(targetsid, "kiwi");
7472     size = MAX_PATH;
7473     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
7474                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7475                            0, patchcode, targetprod, &context,
7476                            targetsid, &size);
7477     ok(r == ERROR_INVALID_PARAMETER,
7478        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7479     ok(!lstrcmpA(patchcode, "apple"),
7480        "Expected patchcode to be unchanged, got %s\n", patchcode);
7481     ok(!lstrcmpA(targetprod, "banana"),
7482        "Expected targetprod to be unchanged, got %s\n", targetprod);
7483     ok(context == 0xdeadbeef,
7484        "Expected context to be unchanged, got %d\n", context);
7485     ok(!lstrcmpA(targetsid, "kiwi"),
7486        "Expected targetsid to be unchanged, got %s\n", targetsid);
7487     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7488
7489     /* guid with brackets */
7490     lstrcpyA(patchcode, "apple");
7491     lstrcpyA(targetprod, "banana");
7492     context = 0xdeadbeef;
7493     lstrcpyA(targetsid, "kiwi");
7494     size = MAX_PATH;
7495     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
7496                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7497                            0, patchcode, targetprod, &context,
7498                            targetsid, &size);
7499     ok(r == ERROR_NO_MORE_ITEMS,
7500        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7501     ok(!lstrcmpA(patchcode, "apple"),
7502        "Expected patchcode to be unchanged, got %s\n", patchcode);
7503     ok(!lstrcmpA(targetprod, "banana"),
7504        "Expected targetprod to be unchanged, got %s\n", targetprod);
7505     ok(context == 0xdeadbeef,
7506        "Expected context to be unchanged, got %d\n", context);
7507     ok(!lstrcmpA(targetsid, "kiwi"),
7508        "Expected targetsid to be unchanged, got %s\n", targetsid);
7509     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7510
7511     /* szUserSid is S-1-5-18 */
7512     lstrcpyA(patchcode, "apple");
7513     lstrcpyA(targetprod, "banana");
7514     context = 0xdeadbeef;
7515     lstrcpyA(targetsid, "kiwi");
7516     size = MAX_PATH;
7517     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
7518                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7519                            0, patchcode, targetprod, &context,
7520                            targetsid, &size);
7521     ok(r == ERROR_INVALID_PARAMETER,
7522        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7523     ok(!lstrcmpA(patchcode, "apple"),
7524        "Expected patchcode to be unchanged, got %s\n", patchcode);
7525     ok(!lstrcmpA(targetprod, "banana"),
7526        "Expected targetprod to be unchanged, got %s\n", targetprod);
7527     ok(context == 0xdeadbeef,
7528        "Expected context to be unchanged, got %d\n", context);
7529     ok(!lstrcmpA(targetsid, "kiwi"),
7530        "Expected targetsid to be unchanged, got %s\n", targetsid);
7531     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7532
7533     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
7534     lstrcpyA(patchcode, "apple");
7535     lstrcpyA(targetprod, "banana");
7536     context = 0xdeadbeef;
7537     lstrcpyA(targetsid, "kiwi");
7538     size = MAX_PATH;
7539     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
7540                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7541                            &context, targetsid, &size);
7542     ok(r == ERROR_INVALID_PARAMETER,
7543        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7544     ok(!lstrcmpA(patchcode, "apple"),
7545        "Expected patchcode to be unchanged, got %s\n", patchcode);
7546     ok(!lstrcmpA(targetprod, "banana"),
7547        "Expected targetprod to be unchanged, got %s\n", targetprod);
7548     ok(context == 0xdeadbeef,
7549        "Expected context to be unchanged, got %d\n", context);
7550     ok(!lstrcmpA(targetsid, "kiwi"),
7551        "Expected targetsid to be unchanged, got %s\n", targetsid);
7552     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7553
7554     /* dwContext is out of bounds */
7555     lstrcpyA(patchcode, "apple");
7556     lstrcpyA(targetprod, "banana");
7557     context = 0xdeadbeef;
7558     lstrcpyA(targetsid, "kiwi");
7559     size = MAX_PATH;
7560     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
7561                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7562                            &context, targetsid, &size);
7563     ok(r == ERROR_INVALID_PARAMETER,
7564        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7565     ok(!lstrcmpA(patchcode, "apple"),
7566        "Expected patchcode to be unchanged, got %s\n", patchcode);
7567     ok(!lstrcmpA(targetprod, "banana"),
7568        "Expected targetprod to be unchanged, got %s\n", targetprod);
7569     ok(context == 0xdeadbeef,
7570        "Expected context to be unchanged, got %d\n", context);
7571     ok(!lstrcmpA(targetsid, "kiwi"),
7572        "Expected targetsid to be unchanged, got %s\n", targetsid);
7573     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7574
7575     /* dwContext is out of bounds */
7576     lstrcpyA(patchcode, "apple");
7577     lstrcpyA(targetprod, "banana");
7578     context = 0xdeadbeef;
7579     lstrcpyA(targetsid, "kiwi");
7580     size = MAX_PATH;
7581     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
7582                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7583                            &context, targetsid, &size);
7584     ok(r == ERROR_INVALID_PARAMETER,
7585        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7586     ok(!lstrcmpA(patchcode, "apple"),
7587        "Expected patchcode to be unchanged, got %s\n", patchcode);
7588     ok(!lstrcmpA(targetprod, "banana"),
7589        "Expected targetprod to be unchanged, got %s\n", targetprod);
7590     ok(context == 0xdeadbeef,
7591        "Expected context to be unchanged, got %d\n", context);
7592     ok(!lstrcmpA(targetsid, "kiwi"),
7593        "Expected targetsid to be unchanged, got %s\n", targetsid);
7594     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7595
7596     /* dwFilter is out of bounds */
7597     lstrcpyA(patchcode, "apple");
7598     lstrcpyA(targetprod, "banana");
7599     context = 0xdeadbeef;
7600     lstrcpyA(targetsid, "kiwi");
7601     size = MAX_PATH;
7602     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7603                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
7604                            &context, targetsid, &size);
7605     ok(r == ERROR_INVALID_PARAMETER,
7606        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7607     ok(!lstrcmpA(patchcode, "apple"),
7608        "Expected patchcode to be unchanged, got %s\n", patchcode);
7609     ok(!lstrcmpA(targetprod, "banana"),
7610        "Expected targetprod to be unchanged, got %s\n", targetprod);
7611     ok(context == 0xdeadbeef,
7612        "Expected context to be unchanged, got %d\n", context);
7613     ok(!lstrcmpA(targetsid, "kiwi"),
7614        "Expected targetsid to be unchanged, got %s\n", targetsid);
7615     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7616
7617     /* dwFilter is out of bounds */
7618     lstrcpyA(patchcode, "apple");
7619     lstrcpyA(targetprod, "banana");
7620     context = 0xdeadbeef;
7621     lstrcpyA(targetsid, "kiwi");
7622     size = MAX_PATH;
7623     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7624                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
7625                            &context, targetsid, &size);
7626     ok(r == ERROR_INVALID_PARAMETER,
7627        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7628     ok(!lstrcmpA(patchcode, "apple"),
7629        "Expected patchcode to be unchanged, got %s\n", patchcode);
7630     ok(!lstrcmpA(targetprod, "banana"),
7631        "Expected targetprod to be unchanged, got %s\n", targetprod);
7632     ok(context == 0xdeadbeef,
7633        "Expected context to be unchanged, got %d\n", context);
7634     ok(!lstrcmpA(targetsid, "kiwi"),
7635        "Expected targetsid to be unchanged, got %s\n", targetsid);
7636     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7637
7638     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
7639     lstrcpyA(patchcode, "apple");
7640     lstrcpyA(targetprod, "banana");
7641     context = 0xdeadbeef;
7642     lstrcpyA(targetsid, "kiwi");
7643     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7644                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7645                            &context, targetsid, NULL);
7646     ok(r == ERROR_INVALID_PARAMETER,
7647        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7648     ok(!lstrcmpA(patchcode, "apple"),
7649        "Expected patchcode to be unchanged, got %s\n", patchcode);
7650     ok(!lstrcmpA(targetprod, "banana"),
7651        "Expected targetprod to be unchanged, got %s\n", targetprod);
7652     ok(context == 0xdeadbeef,
7653        "Expected context to be unchanged, got %d\n", context);
7654     ok(!lstrcmpA(targetsid, "kiwi"),
7655        "Expected targetsid to be unchanged, got %s\n", targetsid);
7656
7657     /* MSIINSTALLCONTEXT_USERMANAGED */
7658
7659     /* MSIPATCHSTATE_APPLIED */
7660
7661     lstrcpyA(patchcode, "apple");
7662     lstrcpyA(targetprod, "banana");
7663     context = 0xdeadbeef;
7664     lstrcpyA(targetsid, "kiwi");
7665     size = MAX_PATH;
7666     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7667                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7668                            &context, targetsid, &size);
7669     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7670     ok(!lstrcmpA(patchcode, "apple"),
7671        "Expected patchcode to be unchanged, got %s\n", patchcode);
7672     ok(!lstrcmpA(targetprod, "banana"),
7673        "Expected targetprod to be unchanged, got %s\n", targetprod);
7674     ok(context == 0xdeadbeef,
7675        "Expected context to be unchanged, got %d\n", context);
7676     ok(!lstrcmpA(targetsid, "kiwi"),
7677        "Expected targetsid to be unchanged, got %s\n", targetsid);
7678     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7679
7680     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7681     lstrcatA(keypath, usersid);
7682     lstrcatA(keypath, "\\Installer\\Products\\");
7683     lstrcatA(keypath, prod_squashed);
7684
7685     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7687
7688     /* managed product key exists */
7689     lstrcpyA(patchcode, "apple");
7690     lstrcpyA(targetprod, "banana");
7691     context = 0xdeadbeef;
7692     lstrcpyA(targetsid, "kiwi");
7693     size = MAX_PATH;
7694     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7695                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7696                            &context, targetsid, &size);
7697     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7698     ok(!lstrcmpA(patchcode, "apple"),
7699        "Expected patchcode to be unchanged, got %s\n", patchcode);
7700     ok(!lstrcmpA(targetprod, "banana"),
7701        "Expected targetprod to be unchanged, got %s\n", targetprod);
7702     ok(context == 0xdeadbeef,
7703        "Expected context to be unchanged, got %d\n", context);
7704     ok(!lstrcmpA(targetsid, "kiwi"),
7705        "Expected targetsid to be unchanged, got %s\n", targetsid);
7706     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7707
7708     res = RegCreateKeyA(prodkey, "Patches", &patches);
7709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7710
7711     /* patches key exists */
7712     lstrcpyA(patchcode, "apple");
7713     lstrcpyA(targetprod, "banana");
7714     context = 0xdeadbeef;
7715     lstrcpyA(targetsid, "kiwi");
7716     size = MAX_PATH;
7717     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7718                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7719                            &context, targetsid, &size);
7720     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7721     ok(!lstrcmpA(patchcode, "apple"),
7722        "Expected patchcode to be unchanged, got %s\n", patchcode);
7723     ok(!lstrcmpA(targetprod, "banana"),
7724        "Expected targetprod to be unchanged, got %s\n", targetprod);
7725     ok(context == 0xdeadbeef,
7726        "Expected context to be unchanged, got %d\n", context);
7727     ok(!lstrcmpA(targetsid, "kiwi"),
7728        "Expected targetsid to be unchanged, got %s\n", targetsid);
7729     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7730
7731     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7732                          (const BYTE *)patch_squashed,
7733                          lstrlenA(patch_squashed) + 1);
7734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7735
7736     /* Patches value exists, is not REG_MULTI_SZ */
7737     lstrcpyA(patchcode, "apple");
7738     lstrcpyA(targetprod, "banana");
7739     context = 0xdeadbeef;
7740     lstrcpyA(targetsid, "kiwi");
7741     size = MAX_PATH;
7742     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7743                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7744                            &context, targetsid, &size);
7745     ok(r == ERROR_BAD_CONFIGURATION,
7746        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7747     ok(!lstrcmpA(patchcode, "apple"),
7748        "Expected patchcode to be unchanged, got %s\n", patchcode);
7749     ok(!lstrcmpA(targetprod, "banana"),
7750        "Expected targetprod to be unchanged, got %s\n", targetprod);
7751     ok(context == 0xdeadbeef,
7752        "Expected context to be unchanged, got %d\n", context);
7753     ok(!lstrcmpA(targetsid, "kiwi"),
7754        "Expected targetsid to be unchanged, got %s\n", targetsid);
7755     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7756
7757     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7758                          (const BYTE *)"a\0b\0c\0\0", 7);
7759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7760
7761     /* Patches value exists, is not a squashed guid */
7762     lstrcpyA(patchcode, "apple");
7763     lstrcpyA(targetprod, "banana");
7764     context = 0xdeadbeef;
7765     lstrcpyA(targetsid, "kiwi");
7766     size = MAX_PATH;
7767     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
7768                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7769                            &context, targetsid, &size);
7770     ok(r == ERROR_BAD_CONFIGURATION,
7771        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7772     ok(!lstrcmpA(patchcode, "apple"),
7773        "Expected patchcode to be unchanged, got %s\n", patchcode);
7774     ok(!lstrcmpA(targetprod, "banana"),
7775        "Expected targetprod to be unchanged, got %s\n", targetprod);
7776     ok(context == 0xdeadbeef,
7777        "Expected context to be unchanged, got %d\n", context);
7778     ok(!lstrcmpA(targetsid, "kiwi"),
7779        "Expected targetsid to be unchanged, got %s\n", targetsid);
7780     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7781
7782     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7783                          (const BYTE *)patch_squashed,
7784                          lstrlenA(patch_squashed) + 1);
7785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7786
7787     /* Patches value exists */
7788     lstrcpyA(patchcode, "apple");
7789     lstrcpyA(targetprod, "banana");
7790     context = 0xdeadbeef;
7791     lstrcpyA(targetsid, "kiwi");
7792     size = MAX_PATH;
7793     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7794                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7795                            &context, targetsid, &size);
7796     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7797     ok(!lstrcmpA(patchcode, "apple"),
7798        "Expected patchcode to be unchanged, got %s\n", patchcode);
7799     ok(!lstrcmpA(targetprod, "banana"),
7800        "Expected targetprod to be unchanged, got %s\n", targetprod);
7801     ok(context == 0xdeadbeef,
7802        "Expected context to be unchanged, got %d\n", context);
7803     ok(!lstrcmpA(targetsid, "kiwi"),
7804        "Expected targetsid to be unchanged, got %s\n", targetsid);
7805     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7806
7807     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7808                          (const BYTE *)"whatever", 9);
7809     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7810
7811     /* patch squashed value exists */
7812     lstrcpyA(patchcode, "apple");
7813     lstrcpyA(targetprod, "banana");
7814     context = 0xdeadbeef;
7815     lstrcpyA(targetsid, "kiwi");
7816     size = MAX_PATH;
7817     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7818                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7819                            &context, targetsid, &size);
7820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7821     ok(!lstrcmpA(patchcode, patch),
7822        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7823     ok(!lstrcmpA(targetprod, prodcode),
7824        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7825     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7826        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7827     ok(!lstrcmpA(targetsid, usersid),
7828        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7829     ok(size == lstrlenA(usersid),
7830        "Expected %d, got %d\n", lstrlenA(usersid), size);
7831
7832     /* increase the index */
7833     lstrcpyA(patchcode, "apple");
7834     lstrcpyA(targetprod, "banana");
7835     context = 0xdeadbeef;
7836     lstrcpyA(targetsid, "kiwi");
7837     size = MAX_PATH;
7838     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7839                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7840                            &context, targetsid, &size);
7841     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7842     ok(!lstrcmpA(patchcode, "apple"),
7843        "Expected patchcode to be unchanged, got %s\n", patchcode);
7844     ok(!lstrcmpA(targetprod, "banana"),
7845        "Expected targetprod to be unchanged, got %s\n", targetprod);
7846     ok(context == 0xdeadbeef,
7847        "Expected context to be unchanged, got %d\n", context);
7848     ok(!lstrcmpA(targetsid, "kiwi"),
7849        "Expected targetsid to be unchanged, got %s\n", targetsid);
7850     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7851
7852     /* increase again */
7853     lstrcpyA(patchcode, "apple");
7854     lstrcpyA(targetprod, "banana");
7855     context = 0xdeadbeef;
7856     lstrcpyA(targetsid, "kiwi");
7857     size = MAX_PATH;
7858     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7859                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7860                            &context, targetsid, &size);
7861     ok(r == ERROR_INVALID_PARAMETER,
7862        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7863     ok(!lstrcmpA(patchcode, "apple"),
7864        "Expected patchcode to be unchanged, got %s\n", patchcode);
7865     ok(!lstrcmpA(targetprod, "banana"),
7866        "Expected targetprod to be unchanged, got %s\n", targetprod);
7867     ok(context == 0xdeadbeef,
7868        "Expected context to be unchanged, got %d\n", context);
7869     ok(!lstrcmpA(targetsid, "kiwi"),
7870        "Expected targetsid to be unchanged, got %s\n", targetsid);
7871     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7872
7873     /* szPatchCode is NULL */
7874     lstrcpyA(targetprod, "banana");
7875     context = 0xdeadbeef;
7876     lstrcpyA(targetsid, "kiwi");
7877     size = MAX_PATH;
7878     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7879                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7880                            &context, targetsid, &size);
7881     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7882     ok(!lstrcmpA(targetprod, prodcode),
7883        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7884     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7885        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7886     ok(!lstrcmpA(targetsid, usersid),
7887        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7888     ok(size == lstrlenA(usersid),
7889        "Expected %d, got %d\n", lstrlenA(usersid), size);
7890
7891     /* szTargetProductCode is NULL */
7892     lstrcpyA(patchcode, "apple");
7893     context = 0xdeadbeef;
7894     lstrcpyA(targetsid, "kiwi");
7895     size = MAX_PATH;
7896     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7897                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7898                            &context, targetsid, &size);
7899     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7900     ok(!lstrcmpA(patchcode, patch),
7901        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7902     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7903        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7904     ok(!lstrcmpA(targetsid, usersid),
7905        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7906     ok(size == lstrlenA(usersid),
7907        "Expected %d, got %d\n", lstrlenA(usersid), size);
7908
7909     /* pdwTargetProductContext is NULL */
7910     lstrcpyA(patchcode, "apple");
7911     lstrcpyA(targetprod, "banana");
7912     lstrcpyA(targetsid, "kiwi");
7913     size = MAX_PATH;
7914     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7915                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7916                            NULL, targetsid, &size);
7917     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7918     ok(!lstrcmpA(patchcode, patch),
7919        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7920     ok(!lstrcmpA(targetprod, prodcode),
7921        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7922     ok(!lstrcmpA(targetsid, usersid),
7923        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7924     ok(size == lstrlenA(usersid),
7925        "Expected %d, got %d\n", lstrlenA(usersid), size);
7926
7927     /* szTargetUserSid is NULL */
7928     lstrcpyA(patchcode, "apple");
7929     lstrcpyA(targetprod, "banana");
7930     context = 0xdeadbeef;
7931     size = MAX_PATH;
7932     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7933                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7934                            &context, NULL, &size);
7935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7936     ok(!lstrcmpA(patchcode, patch),
7937        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7938     ok(!lstrcmpA(targetprod, prodcode),
7939        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7940     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7941        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7942     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7943        "Expected %d, got %d\n", lstrlenA(usersid) * sizeof(WCHAR), size);
7944
7945     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7946     lstrcpyA(patchcode, "apple");
7947     lstrcpyA(targetprod, "banana");
7948     context = 0xdeadbeef;
7949     lstrcpyA(targetsid, "kiwi");
7950     size = lstrlenA(usersid);
7951     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7952                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7953                            &context, targetsid, &size);
7954     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7955     ok(!lstrcmpA(patchcode, patch),
7956        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7957     ok(!lstrcmpA(targetprod, prodcode),
7958        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7959     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7960        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7961     ok(!strncmp(targetsid, usersid, lstrlenA(usersid) - 1),
7962        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7963     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7964        "Expected %d, got %d\n", lstrlenA(usersid) * sizeof(WCHAR), size);
7965
7966     /* pcchTargetUserSid has enough room for NULL terminator */
7967     lstrcpyA(patchcode, "apple");
7968     lstrcpyA(targetprod, "banana");
7969     context = 0xdeadbeef;
7970     lstrcpyA(targetsid, "kiwi");
7971     size = lstrlenA(usersid) + 1;
7972     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7973                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7974                            &context, targetsid, &size);
7975     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7976     ok(!lstrcmpA(patchcode, patch),
7977        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7978     ok(!lstrcmpA(targetprod, prodcode),
7979        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7980     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7981        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7982     ok(!lstrcmpA(targetsid, usersid),
7983        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7984     ok(size == lstrlenA(usersid),
7985        "Expected %d, got %d\n", lstrlenA(usersid), size);
7986
7987     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7988     lstrcpyA(patchcode, "apple");
7989     lstrcpyA(targetprod, "banana");
7990     context = 0xdeadbeef;
7991     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7992                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7993                            &context, NULL, NULL);
7994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7995     ok(!lstrcmpA(patchcode, patch),
7996        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7997     ok(!lstrcmpA(targetprod, prodcode),
7998        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7999     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8000        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8001
8002     /* MSIPATCHSTATE_SUPERSEDED */
8003
8004     lstrcpyA(patchcode, "apple");
8005     lstrcpyA(targetprod, "banana");
8006     context = 0xdeadbeef;
8007     lstrcpyA(targetsid, "kiwi");
8008     size = MAX_PATH;
8009     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8010                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8011                            &context, targetsid, &size);
8012     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8013     ok(!lstrcmpA(patchcode, "apple"),
8014        "Expected patchcode to be unchanged, got %s\n", patchcode);
8015     ok(!lstrcmpA(targetprod, "banana"),
8016        "Expected targetprod to be unchanged, got %s\n", targetprod);
8017     ok(context == 0xdeadbeef,
8018        "Expected context to be unchanged, got %d\n", context);
8019     ok(!lstrcmpA(targetsid, "kiwi"),
8020        "Expected targetsid to be unchanged, got %s\n", targetsid);
8021     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8022
8023     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8024     lstrcatA(keypath, usersid);
8025     lstrcatA(keypath, "\\Products\\");
8026     lstrcatA(keypath, prod_squashed);
8027
8028     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8030
8031     /* UserData product key exists */
8032     lstrcpyA(patchcode, "apple");
8033     lstrcpyA(targetprod, "banana");
8034     context = 0xdeadbeef;
8035     lstrcpyA(targetsid, "kiwi");
8036     size = MAX_PATH;
8037     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8038                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8039                            &context, targetsid, &size);
8040     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8041     ok(!lstrcmpA(patchcode, "apple"),
8042        "Expected patchcode to be unchanged, got %s\n", patchcode);
8043     ok(!lstrcmpA(targetprod, "banana"),
8044        "Expected targetprod to be unchanged, got %s\n", targetprod);
8045     ok(context == 0xdeadbeef,
8046        "Expected context to be unchanged, got %d\n", context);
8047     ok(!lstrcmpA(targetsid, "kiwi"),
8048        "Expected targetsid to be unchanged, got %s\n", targetsid);
8049     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8050
8051     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8053
8054     /* UserData patches key exists */
8055     lstrcpyA(patchcode, "apple");
8056     lstrcpyA(targetprod, "banana");
8057     context = 0xdeadbeef;
8058     lstrcpyA(targetsid, "kiwi");
8059     size = MAX_PATH;
8060     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8061                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8062                            &context, targetsid, &size);
8063     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8064     ok(!lstrcmpA(patchcode, "apple"),
8065        "Expected patchcode to be unchanged, got %s\n", patchcode);
8066     ok(!lstrcmpA(targetprod, "banana"),
8067        "Expected targetprod to be unchanged, got %s\n", targetprod);
8068     ok(context == 0xdeadbeef,
8069        "Expected context to be unchanged, got %d\n", context);
8070     ok(!lstrcmpA(targetsid, "kiwi"),
8071        "Expected targetsid to be unchanged, got %s\n", targetsid);
8072     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8073
8074     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8076
8077     /* specific UserData patch key exists */
8078     lstrcpyA(patchcode, "apple");
8079     lstrcpyA(targetprod, "banana");
8080     context = 0xdeadbeef;
8081     lstrcpyA(targetsid, "kiwi");
8082     size = MAX_PATH;
8083     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8084                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8085                            &context, targetsid, &size);
8086     ok(r == ERROR_BAD_CONFIGURATION,
8087        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8088     ok(!lstrcmpA(patchcode, "apple"),
8089        "Expected patchcode to be unchanged, got %s\n", patchcode);
8090     ok(!lstrcmpA(targetprod, "banana"),
8091        "Expected targetprod to be unchanged, got %s\n", targetprod);
8092     ok(context == 0xdeadbeef,
8093        "Expected context to be unchanged, got %d\n", context);
8094     ok(!lstrcmpA(targetsid, "kiwi"),
8095        "Expected targetsid to be unchanged, got %s\n", targetsid);
8096     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8097
8098     data = MSIPATCHSTATE_SUPERSEDED;
8099     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8100                          (const BYTE *)&data, sizeof(DWORD));
8101     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8102
8103     /* State value exists */
8104     lstrcpyA(patchcode, "apple");
8105     lstrcpyA(targetprod, "banana");
8106     context = 0xdeadbeef;
8107     lstrcpyA(targetsid, "kiwi");
8108     size = MAX_PATH;
8109     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8110                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8111                            &context, targetsid, &size);
8112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8113     ok(!lstrcmpA(patchcode, patch),
8114        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8115     ok(!lstrcmpA(targetprod, prodcode),
8116        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8117     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8118        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8119     ok(!lstrcmpA(targetsid, usersid),
8120        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8121     ok(size == lstrlenA(usersid),
8122        "Expected %d, got %d\n", lstrlenA(usersid), size);
8123
8124     /* MSIPATCHSTATE_OBSOLETED */
8125
8126     lstrcpyA(patchcode, "apple");
8127     lstrcpyA(targetprod, "banana");
8128     context = 0xdeadbeef;
8129     lstrcpyA(targetsid, "kiwi");
8130     size = MAX_PATH;
8131     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8132                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8133                            &context, targetsid, &size);
8134     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8135     ok(!lstrcmpA(patchcode, "apple"),
8136        "Expected patchcode to be unchanged, got %s\n", patchcode);
8137     ok(!lstrcmpA(targetprod, "banana"),
8138        "Expected targetprod to be unchanged, got %s\n", targetprod);
8139     ok(context == 0xdeadbeef,
8140        "Expected context to be unchanged, got %d\n", context);
8141     ok(!lstrcmpA(targetsid, "kiwi"),
8142        "Expected targetsid to be unchanged, got %s\n", targetsid);
8143     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8144
8145     data = MSIPATCHSTATE_OBSOLETED;
8146     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8147                          (const BYTE *)&data, sizeof(DWORD));
8148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8149
8150     /* State value is obsoleted */
8151     lstrcpyA(patchcode, "apple");
8152     lstrcpyA(targetprod, "banana");
8153     context = 0xdeadbeef;
8154     lstrcpyA(targetsid, "kiwi");
8155     size = MAX_PATH;
8156     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8157                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8158                            &context, targetsid, &size);
8159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8160     ok(!lstrcmpA(patchcode, patch),
8161        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8162     ok(!lstrcmpA(targetprod, prodcode),
8163        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8164     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8165        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8166     ok(!lstrcmpA(targetsid, usersid),
8167        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8168     ok(size == lstrlenA(usersid),
8169        "Expected %d, got %d\n", lstrlenA(usersid), size);
8170
8171     /* MSIPATCHSTATE_REGISTERED */
8172     /* FIXME */
8173
8174     /* MSIPATCHSTATE_ALL */
8175
8176     /* 1st */
8177     lstrcpyA(patchcode, "apple");
8178     lstrcpyA(targetprod, "banana");
8179     context = 0xdeadbeef;
8180     lstrcpyA(targetsid, "kiwi");
8181     size = MAX_PATH;
8182     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8183                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8184                            &context, targetsid, &size);
8185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8186     ok(!lstrcmpA(patchcode, patch),
8187        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8188     ok(!lstrcmpA(targetprod, prodcode),
8189        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8190     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8191        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8192     ok(!lstrcmpA(targetsid, usersid),
8193        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8194     ok(size == lstrlenA(usersid),
8195        "Expected %d, got %d\n", lstrlenA(usersid), size);
8196
8197     /* same patch in multiple places, only one is enumerated */
8198     lstrcpyA(patchcode, "apple");
8199     lstrcpyA(targetprod, "banana");
8200     context = 0xdeadbeef;
8201     lstrcpyA(targetsid, "kiwi");
8202     size = MAX_PATH;
8203     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8204                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8205                            &context, targetsid, &size);
8206     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8207     ok(!lstrcmpA(patchcode, "apple"),
8208        "Expected patchcode to be unchanged, got %s\n", patchcode);
8209     ok(!lstrcmpA(targetprod, "banana"),
8210        "Expected targetprod to be unchanged, got %s\n", targetprod);
8211     ok(context == 0xdeadbeef,
8212        "Expected context to be unchanged, got %d\n", context);
8213     ok(!lstrcmpA(targetsid, "kiwi"),
8214        "Expected targetsid to be unchanged, got %s\n", targetsid);
8215     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8216
8217     RegDeleteValueA(hpatch, "State");
8218     RegDeleteKeyA(hpatch, "");
8219     RegCloseKey(hpatch);
8220     RegDeleteKeyA(udpatch, "");
8221     RegCloseKey(udpatch);
8222     RegDeleteKeyA(udprod, "");
8223     RegCloseKey(udprod);
8224     RegDeleteValueA(patches, "Patches");
8225     RegDeleteKeyA(patches, "");
8226     RegCloseKey(patches);
8227     RegDeleteKeyA(prodkey, "");
8228     RegCloseKey(prodkey);
8229
8230     /* MSIINSTALLCONTEXT_USERUNMANAGED */
8231
8232     /* MSIPATCHSTATE_APPLIED */
8233
8234     lstrcpyA(patchcode, "apple");
8235     lstrcpyA(targetprod, "banana");
8236     context = 0xdeadbeef;
8237     lstrcpyA(targetsid, "kiwi");
8238     size = MAX_PATH;
8239     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8240                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8241                            &context, targetsid, &size);
8242     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8243     ok(!lstrcmpA(patchcode, "apple"),
8244        "Expected patchcode to be unchanged, got %s\n", patchcode);
8245     ok(!lstrcmpA(targetprod, "banana"),
8246        "Expected targetprod to be unchanged, got %s\n", targetprod);
8247     ok(context == 0xdeadbeef,
8248        "Expected context to be unchanged, got %d\n", context);
8249     ok(!lstrcmpA(targetsid, "kiwi"),
8250        "Expected targetsid to be unchanged, got %s\n", targetsid);
8251     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8252
8253     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8254     lstrcatA(keypath, prod_squashed);
8255
8256     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8258
8259     /* current user product key exists */
8260     lstrcpyA(patchcode, "apple");
8261     lstrcpyA(targetprod, "banana");
8262     context = 0xdeadbeef;
8263     lstrcpyA(targetsid, "kiwi");
8264     size = MAX_PATH;
8265     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8266                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8267                            &context, targetsid, &size);
8268     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8269     ok(!lstrcmpA(patchcode, "apple"),
8270        "Expected patchcode to be unchanged, got %s\n", patchcode);
8271     ok(!lstrcmpA(targetprod, "banana"),
8272        "Expected targetprod to be unchanged, got %s\n", targetprod);
8273     ok(context == 0xdeadbeef,
8274        "Expected context to be unchanged, got %d\n", context);
8275     ok(!lstrcmpA(targetsid, "kiwi"),
8276        "Expected targetsid to be unchanged, got %s\n", targetsid);
8277     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8278
8279     res = RegCreateKeyA(prodkey, "Patches", &patches);
8280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8281
8282     /* Patches key exists */
8283     lstrcpyA(patchcode, "apple");
8284     lstrcpyA(targetprod, "banana");
8285     context = 0xdeadbeef;
8286     lstrcpyA(targetsid, "kiwi");
8287     size = MAX_PATH;
8288     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8289                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8290                            &context, targetsid, &size);
8291     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8292     ok(!lstrcmpA(patchcode, "apple"),
8293        "Expected patchcode to be unchanged, got %s\n", patchcode);
8294     ok(!lstrcmpA(targetprod, "banana"),
8295        "Expected targetprod to be unchanged, got %s\n", targetprod);
8296     ok(context == 0xdeadbeef,
8297        "Expected context to be unchanged, got %d\n", context);
8298     ok(!lstrcmpA(targetsid, "kiwi"),
8299        "Expected targetsid to be unchanged, got %s\n", targetsid);
8300     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8301
8302     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8303                          (const BYTE *)patch_squashed,
8304                          lstrlenA(patch_squashed) + 1);
8305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8306
8307     /* Patches value exists, is not REG_MULTI_SZ */
8308     lstrcpyA(patchcode, "apple");
8309     lstrcpyA(targetprod, "banana");
8310     context = 0xdeadbeef;
8311     lstrcpyA(targetsid, "kiwi");
8312     size = MAX_PATH;
8313     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8314                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8315                            &context, targetsid, &size);
8316     ok(r == ERROR_BAD_CONFIGURATION,
8317        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8318     ok(!lstrcmpA(patchcode, "apple"),
8319        "Expected patchcode to be unchanged, got %s\n", patchcode);
8320     ok(!lstrcmpA(targetprod, "banana"),
8321        "Expected targetprod to be unchanged, got %s\n", targetprod);
8322     ok(context == 0xdeadbeef,
8323        "Expected context to be unchanged, got %d\n", context);
8324     ok(!lstrcmpA(targetsid, "kiwi"),
8325        "Expected targetsid to be unchanged, got %s\n", targetsid);
8326     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8327
8328     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8329                          (const BYTE *)"a\0b\0c\0\0", 7);
8330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8331
8332     /* Patches value exists, is not a squashed guid */
8333     lstrcpyA(patchcode, "apple");
8334     lstrcpyA(targetprod, "banana");
8335     context = 0xdeadbeef;
8336     lstrcpyA(targetsid, "kiwi");
8337     size = MAX_PATH;
8338     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8339                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8340                            &context, targetsid, &size);
8341     ok(r == ERROR_BAD_CONFIGURATION,
8342        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8343     ok(!lstrcmpA(patchcode, "apple"),
8344        "Expected patchcode to be unchanged, got %s\n", patchcode);
8345     ok(!lstrcmpA(targetprod, "banana"),
8346        "Expected targetprod to be unchanged, got %s\n", targetprod);
8347     ok(context == 0xdeadbeef,
8348        "Expected context to be unchanged, got %d\n", context);
8349     ok(!lstrcmpA(targetsid, "kiwi"),
8350        "Expected targetsid to be unchanged, got %s\n", targetsid);
8351     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8352
8353     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8354                          (const BYTE *)patch_squashed,
8355                          lstrlenA(patch_squashed) + 1);
8356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8357
8358     /* Patches value exists */
8359     lstrcpyA(patchcode, "apple");
8360     lstrcpyA(targetprod, "banana");
8361     context = 0xdeadbeef;
8362     lstrcpyA(targetsid, "kiwi");
8363     size = MAX_PATH;
8364     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8365                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8366                            &context, targetsid, &size);
8367     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8368     ok(!lstrcmpA(patchcode, "apple"),
8369        "Expected patchcode to be unchanged, got %s\n", patchcode);
8370     ok(!lstrcmpA(targetprod, "banana"),
8371        "Expected targetprod to be unchanged, got %s\n", targetprod);
8372     ok(context == 0xdeadbeef,
8373        "Expected context to be unchanged, got %d\n", context);
8374     ok(!lstrcmpA(targetsid, "kiwi"),
8375        "Expected targetsid to be unchanged, got %s\n", targetsid);
8376     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8377
8378     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8379                          (const BYTE *)"whatever", 9);
8380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8381
8382     /* patch code value exists */
8383     lstrcpyA(patchcode, "apple");
8384     lstrcpyA(targetprod, "banana");
8385     context = 0xdeadbeef;
8386     lstrcpyA(targetsid, "kiwi");
8387     size = MAX_PATH;
8388     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8389                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8390                            &context, targetsid, &size);
8391     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8392     ok(!lstrcmpA(patchcode, "apple"),
8393        "Expected patchcode to be unchanged, got %s\n", patchcode);
8394     ok(!lstrcmpA(targetprod, "banana"),
8395        "Expected targetprod to be unchanged, got %s\n", targetprod);
8396     ok(context == 0xdeadbeef,
8397        "Expected context to be unchanged, got %d\n", context);
8398     ok(!lstrcmpA(targetsid, "kiwi"),
8399        "Expected targetsid to be unchanged, got %s\n", targetsid);
8400     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8401
8402     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8403     lstrcatA(keypath, usersid);
8404     lstrcatA(keypath, "\\Patches\\");
8405     lstrcatA(keypath, patch_squashed);
8406
8407     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8409
8410     /* userdata patch key exists */
8411     lstrcpyA(patchcode, "apple");
8412     lstrcpyA(targetprod, "banana");
8413     context = 0xdeadbeef;
8414     lstrcpyA(targetsid, "kiwi");
8415     size = MAX_PATH;
8416     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8417                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8418                            &context, targetsid, &size);
8419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8420     ok(!lstrcmpA(patchcode, patch),
8421        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8422     ok(!lstrcmpA(targetprod, prodcode),
8423        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8424     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8425        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8426     ok(!lstrcmpA(targetsid, usersid),
8427        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8428     ok(size == lstrlenA(usersid),
8429        "Expected %d, got %d\n", lstrlenA(usersid), size);
8430
8431     /* MSIPATCHSTATE_SUPERSEDED */
8432
8433     lstrcpyA(patchcode, "apple");
8434     lstrcpyA(targetprod, "banana");
8435     context = 0xdeadbeef;
8436     lstrcpyA(targetsid, "kiwi");
8437     size = MAX_PATH;
8438     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8439                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8440                            &context, targetsid, &size);
8441     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8442     ok(!lstrcmpA(patchcode, "apple"),
8443        "Expected patchcode to be unchanged, got %s\n", patchcode);
8444     ok(!lstrcmpA(targetprod, "banana"),
8445        "Expected targetprod to be unchanged, got %s\n", targetprod);
8446     ok(context == 0xdeadbeef,
8447        "Expected context to be unchanged, got %d\n", context);
8448     ok(!lstrcmpA(targetsid, "kiwi"),
8449        "Expected targetsid to be unchanged, got %s\n", targetsid);
8450     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8451
8452     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8453     lstrcatA(keypath, usersid);
8454     lstrcatA(keypath, "\\Products\\");
8455     lstrcatA(keypath, prod_squashed);
8456
8457     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8459
8460     /* UserData product key exists */
8461     lstrcpyA(patchcode, "apple");
8462     lstrcpyA(targetprod, "banana");
8463     context = 0xdeadbeef;
8464     lstrcpyA(targetsid, "kiwi");
8465     size = MAX_PATH;
8466     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8467                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8468                            &context, targetsid, &size);
8469     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8470     ok(!lstrcmpA(patchcode, "apple"),
8471        "Expected patchcode to be unchanged, got %s\n", patchcode);
8472     ok(!lstrcmpA(targetprod, "banana"),
8473        "Expected targetprod to be unchanged, got %s\n", targetprod);
8474     ok(context == 0xdeadbeef,
8475        "Expected context to be unchanged, got %d\n", context);
8476     ok(!lstrcmpA(targetsid, "kiwi"),
8477        "Expected targetsid to be unchanged, got %s\n", targetsid);
8478     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8479
8480     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8481     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8482
8483     /* UserData patches key exists */
8484     lstrcpyA(patchcode, "apple");
8485     lstrcpyA(targetprod, "banana");
8486     context = 0xdeadbeef;
8487     lstrcpyA(targetsid, "kiwi");
8488     size = MAX_PATH;
8489     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8490                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8491                            &context, targetsid, &size);
8492     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8493     ok(!lstrcmpA(patchcode, "apple"),
8494        "Expected patchcode to be unchanged, got %s\n", patchcode);
8495     ok(!lstrcmpA(targetprod, "banana"),
8496        "Expected targetprod to be unchanged, got %s\n", targetprod);
8497     ok(context == 0xdeadbeef,
8498        "Expected context to be unchanged, got %d\n", context);
8499     ok(!lstrcmpA(targetsid, "kiwi"),
8500        "Expected targetsid to be unchanged, got %s\n", targetsid);
8501     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8502
8503     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8504     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8505
8506     /* specific UserData patch key exists */
8507     lstrcpyA(patchcode, "apple");
8508     lstrcpyA(targetprod, "banana");
8509     context = 0xdeadbeef;
8510     lstrcpyA(targetsid, "kiwi");
8511     size = MAX_PATH;
8512     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8513                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8514                            &context, targetsid, &size);
8515     ok(r == ERROR_BAD_CONFIGURATION,
8516        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8517     ok(!lstrcmpA(patchcode, "apple"),
8518        "Expected patchcode to be unchanged, got %s\n", patchcode);
8519     ok(!lstrcmpA(targetprod, "banana"),
8520        "Expected targetprod to be unchanged, got %s\n", targetprod);
8521     ok(context == 0xdeadbeef,
8522        "Expected context to be unchanged, got %d\n", context);
8523     ok(!lstrcmpA(targetsid, "kiwi"),
8524        "Expected targetsid to be unchanged, got %s\n", targetsid);
8525     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8526
8527     data = MSIPATCHSTATE_SUPERSEDED;
8528     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8529                          (const BYTE *)&data, sizeof(DWORD));
8530     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8531
8532     /* State value exists */
8533     lstrcpyA(patchcode, "apple");
8534     lstrcpyA(targetprod, "banana");
8535     context = 0xdeadbeef;
8536     lstrcpyA(targetsid, "kiwi");
8537     size = MAX_PATH;
8538     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8539                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8540                            &context, targetsid, &size);
8541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8542     ok(!lstrcmpA(patchcode, patch),
8543        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8544     ok(!lstrcmpA(targetprod, prodcode),
8545        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8546     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8547        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8548     ok(!lstrcmpA(targetsid, usersid),
8549        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8550     ok(size == lstrlenA(usersid),
8551        "Expected %d, got %d\n", lstrlenA(usersid), size);
8552
8553     /* MSIPATCHSTATE_OBSOLETED */
8554
8555     lstrcpyA(patchcode, "apple");
8556     lstrcpyA(targetprod, "banana");
8557     context = 0xdeadbeef;
8558     lstrcpyA(targetsid, "kiwi");
8559     size = MAX_PATH;
8560     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8561                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8562                            &context, targetsid, &size);
8563     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8564     ok(!lstrcmpA(patchcode, "apple"),
8565        "Expected patchcode to be unchanged, got %s\n", patchcode);
8566     ok(!lstrcmpA(targetprod, "banana"),
8567        "Expected targetprod to be unchanged, got %s\n", targetprod);
8568     ok(context == 0xdeadbeef,
8569        "Expected context to be unchanged, got %d\n", context);
8570     ok(!lstrcmpA(targetsid, "kiwi"),
8571        "Expected targetsid to be unchanged, got %s\n", targetsid);
8572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8573
8574     data = MSIPATCHSTATE_OBSOLETED;
8575     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8576                          (const BYTE *)&data, sizeof(DWORD));
8577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8578
8579     /* State value is obsoleted */
8580     lstrcpyA(patchcode, "apple");
8581     lstrcpyA(targetprod, "banana");
8582     context = 0xdeadbeef;
8583     lstrcpyA(targetsid, "kiwi");
8584     size = MAX_PATH;
8585     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8586                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8587                            &context, targetsid, &size);
8588     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8589     ok(!lstrcmpA(patchcode, patch),
8590        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8591     ok(!lstrcmpA(targetprod, prodcode),
8592        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8593     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8594        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8595     ok(!lstrcmpA(targetsid, usersid),
8596        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8597     ok(size == lstrlenA(usersid),
8598        "Expected %d, got %d\n", lstrlenA(usersid), size);
8599
8600     /* MSIPATCHSTATE_REGISTERED */
8601     /* FIXME */
8602
8603     /* MSIPATCHSTATE_ALL */
8604
8605     /* 1st */
8606     lstrcpyA(patchcode, "apple");
8607     lstrcpyA(targetprod, "banana");
8608     context = 0xdeadbeef;
8609     lstrcpyA(targetsid, "kiwi");
8610     size = MAX_PATH;
8611     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8612                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8613                            &context, targetsid, &size);
8614     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8615     ok(!lstrcmpA(patchcode, patch),
8616        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8617     ok(!lstrcmpA(targetprod, prodcode),
8618        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8619     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8620        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8621     ok(!lstrcmpA(targetsid, usersid),
8622        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8623     ok(size == lstrlenA(usersid),
8624        "Expected %d, got %d\n", lstrlenA(usersid), size);
8625
8626     /* same patch in multiple places, only one is enumerated */
8627     lstrcpyA(patchcode, "apple");
8628     lstrcpyA(targetprod, "banana");
8629     context = 0xdeadbeef;
8630     lstrcpyA(targetsid, "kiwi");
8631     size = MAX_PATH;
8632     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8633                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8634                            &context, targetsid, &size);
8635     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8636     ok(!lstrcmpA(patchcode, "apple"),
8637        "Expected patchcode to be unchanged, got %s\n", patchcode);
8638     ok(!lstrcmpA(targetprod, "banana"),
8639        "Expected targetprod to be unchanged, got %s\n", targetprod);
8640     ok(context == 0xdeadbeef,
8641        "Expected context to be unchanged, got %d\n", context);
8642     ok(!lstrcmpA(targetsid, "kiwi"),
8643        "Expected targetsid to be unchanged, got %s\n", targetsid);
8644     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8645
8646     RegDeleteValueA(hpatch, "State");
8647     RegDeleteKeyA(hpatch, "");
8648     RegCloseKey(hpatch);
8649     RegDeleteKeyA(udpatch, "");
8650     RegCloseKey(udpatch);
8651     RegDeleteKeyA(userkey, "");
8652     RegCloseKey(userkey);
8653     RegDeleteValueA(patches, patch_squashed);
8654     RegDeleteValueA(patches, "Patches");
8655     RegDeleteKeyA(patches, "");
8656     RegCloseKey(patches);
8657     RegDeleteKeyA(prodkey, "");
8658     RegCloseKey(prodkey);
8659
8660     /* MSIINSTALLCONTEXT_MACHINE */
8661
8662     /* MSIPATCHSTATE_APPLIED */
8663
8664     lstrcpyA(patchcode, "apple");
8665     lstrcpyA(targetprod, "banana");
8666     context = 0xdeadbeef;
8667     lstrcpyA(targetsid, "kiwi");
8668     size = MAX_PATH;
8669     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8670                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8671                            &context, targetsid, &size);
8672     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8673     ok(!lstrcmpA(patchcode, "apple"),
8674        "Expected patchcode to be unchanged, got %s\n", patchcode);
8675     ok(!lstrcmpA(targetprod, "banana"),
8676        "Expected targetprod to be unchanged, got %s\n", targetprod);
8677     ok(context == 0xdeadbeef,
8678        "Expected context to be unchanged, got %d\n", context);
8679     ok(!lstrcmpA(targetsid, "kiwi"),
8680        "Expected targetsid to be unchanged, got %s\n", targetsid);
8681     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8682
8683     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8684     lstrcatA(keypath, prod_squashed);
8685
8686     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8688
8689     /* local product key exists */
8690     lstrcpyA(patchcode, "apple");
8691     lstrcpyA(targetprod, "banana");
8692     context = 0xdeadbeef;
8693     lstrcpyA(targetsid, "kiwi");
8694     size = MAX_PATH;
8695     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8696                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8697                            &context, targetsid, &size);
8698     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8699     ok(!lstrcmpA(patchcode, "apple"),
8700        "Expected patchcode to be unchanged, got %s\n", patchcode);
8701     ok(!lstrcmpA(targetprod, "banana"),
8702        "Expected targetprod to be unchanged, got %s\n", targetprod);
8703     ok(context == 0xdeadbeef,
8704        "Expected context to be unchanged, got %d\n", context);
8705     ok(!lstrcmpA(targetsid, "kiwi"),
8706        "Expected targetsid to be unchanged, got %s\n", targetsid);
8707     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8708
8709     res = RegCreateKeyA(prodkey, "Patches", &patches);
8710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8711
8712     /* Patches key exists */
8713     lstrcpyA(patchcode, "apple");
8714     lstrcpyA(targetprod, "banana");
8715     context = 0xdeadbeef;
8716     lstrcpyA(targetsid, "kiwi");
8717     size = MAX_PATH;
8718     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8719                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8720                            &context, targetsid, &size);
8721     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8722     ok(!lstrcmpA(patchcode, "apple"),
8723        "Expected patchcode to be unchanged, got %s\n", patchcode);
8724     ok(!lstrcmpA(targetprod, "banana"),
8725        "Expected targetprod to be unchanged, got %s\n", targetprod);
8726     ok(context == 0xdeadbeef,
8727        "Expected context to be unchanged, got %d\n", context);
8728     ok(!lstrcmpA(targetsid, "kiwi"),
8729        "Expected targetsid to be unchanged, got %s\n", targetsid);
8730     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8731
8732     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8733                          (const BYTE *)patch_squashed,
8734                          lstrlenA(patch_squashed) + 1);
8735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8736
8737     /* Patches value exists, is not REG_MULTI_SZ */
8738     lstrcpyA(patchcode, "apple");
8739     lstrcpyA(targetprod, "banana");
8740     context = 0xdeadbeef;
8741     lstrcpyA(targetsid, "kiwi");
8742     size = MAX_PATH;
8743     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8744                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8745                            &context, targetsid, &size);
8746     ok(r == ERROR_BAD_CONFIGURATION,
8747        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8748     ok(!lstrcmpA(patchcode, "apple"),
8749        "Expected patchcode to be unchanged, got %s\n", patchcode);
8750     ok(!lstrcmpA(targetprod, "banana"),
8751        "Expected targetprod to be unchanged, got %s\n", targetprod);
8752     ok(context == 0xdeadbeef,
8753        "Expected context to be unchanged, got %d\n", context);
8754     ok(!lstrcmpA(targetsid, "kiwi"),
8755        "Expected targetsid to be unchanged, got %s\n", targetsid);
8756     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8757
8758     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8759                          (const BYTE *)"a\0b\0c\0\0", 7);
8760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8761
8762     /* Patches value exists, is not a squashed guid */
8763     lstrcpyA(patchcode, "apple");
8764     lstrcpyA(targetprod, "banana");
8765     context = 0xdeadbeef;
8766     lstrcpyA(targetsid, "kiwi");
8767     size = MAX_PATH;
8768     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8769                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8770                            &context, targetsid, &size);
8771     ok(r == ERROR_BAD_CONFIGURATION,
8772        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8773     ok(!lstrcmpA(patchcode, "apple"),
8774        "Expected patchcode to be unchanged, got %s\n", patchcode);
8775     ok(!lstrcmpA(targetprod, "banana"),
8776        "Expected targetprod to be unchanged, got %s\n", targetprod);
8777     ok(context == 0xdeadbeef,
8778        "Expected context to be unchanged, got %d\n", context);
8779     ok(!lstrcmpA(targetsid, "kiwi"),
8780        "Expected targetsid to be unchanged, got %s\n", targetsid);
8781     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8782
8783     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8784                          (const BYTE *)patch_squashed,
8785                          lstrlenA(patch_squashed) + 1);
8786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8787
8788     /* Patches value exists */
8789     lstrcpyA(patchcode, "apple");
8790     lstrcpyA(targetprod, "banana");
8791     context = 0xdeadbeef;
8792     lstrcpyA(targetsid, "kiwi");
8793     size = MAX_PATH;
8794     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8795                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8796                            &context, targetsid, &size);
8797     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8798     ok(!lstrcmpA(patchcode, "apple"),
8799        "Expected patchcode to be unchanged, got %s\n", patchcode);
8800     ok(!lstrcmpA(targetprod, "banana"),
8801        "Expected targetprod to be unchanged, got %s\n", targetprod);
8802     ok(context == 0xdeadbeef,
8803        "Expected context to be unchanged, got %d\n", context);
8804     ok(!lstrcmpA(targetsid, "kiwi"),
8805        "Expected targetsid to be unchanged, got %s\n", targetsid);
8806     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8807
8808     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8809                          (const BYTE *)"whatever", 9);
8810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8811
8812     /* patch code value exists */
8813     lstrcpyA(patchcode, "apple");
8814     lstrcpyA(targetprod, "banana");
8815     context = 0xdeadbeef;
8816     lstrcpyA(targetsid, "kiwi");
8817     size = MAX_PATH;
8818     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8819                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8820                            &context, targetsid, &size);
8821     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8822     ok(!lstrcmpA(patchcode, patch),
8823        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8824     ok(!lstrcmpA(targetprod, prodcode),
8825        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8826     ok(context == MSIINSTALLCONTEXT_MACHINE,
8827        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8828     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8829     ok(size == 0, "Expected 0, got %d\n", size);
8830
8831     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8832     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8833     lstrcatA(keypath, prod_squashed);
8834
8835     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8837
8838     /* local UserData product key exists */
8839     lstrcpyA(patchcode, "apple");
8840     lstrcpyA(targetprod, "banana");
8841     context = 0xdeadbeef;
8842     lstrcpyA(targetsid, "kiwi");
8843     size = MAX_PATH;
8844     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8845                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8846                            &context, targetsid, &size);
8847     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8848     ok(!lstrcmpA(patchcode, patch),
8849        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8850     ok(!lstrcmpA(targetprod, prodcode),
8851        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8852     ok(context == MSIINSTALLCONTEXT_MACHINE,
8853        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8854     ok(!lstrcmpA(targetsid, ""),
8855        "Expected \"\", got \"%s\"\n", targetsid);
8856     ok(size == 0, "Expected 0, got %d\n", size);
8857
8858     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8860
8861     /* local UserData Patches key exists */
8862     lstrcpyA(patchcode, "apple");
8863     lstrcpyA(targetprod, "banana");
8864     context = 0xdeadbeef;
8865     lstrcpyA(targetsid, "kiwi");
8866     size = MAX_PATH;
8867     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8868                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8869                            &context, targetsid, &size);
8870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8871     ok(!lstrcmpA(patchcode, patch),
8872        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8873     ok(!lstrcmpA(targetprod, prodcode),
8874        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8875     ok(context == MSIINSTALLCONTEXT_MACHINE,
8876        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8877     ok(!lstrcmpA(targetsid, ""),
8878        "Expected \"\", got \"%s\"\n", targetsid);
8879     ok(size == 0, "Expected 0, got %d\n", size);
8880
8881     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8883
8884     /* local UserData Product patch key exists */
8885     lstrcpyA(patchcode, "apple");
8886     lstrcpyA(targetprod, "banana");
8887     context = 0xdeadbeef;
8888     lstrcpyA(targetsid, "kiwi");
8889     size = MAX_PATH;
8890     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8891                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8892                            &context, targetsid, &size);
8893     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8894     ok(!lstrcmpA(patchcode, "apple"),
8895        "Expected patchcode to be unchanged, got %s\n", patchcode);
8896     ok(!lstrcmpA(targetprod, "banana"),
8897        "Expected targetprod to be unchanged, got %s\n", targetprod);
8898     ok(context == 0xdeadbeef,
8899        "Expected context to be unchanged, got %d\n", context);
8900     ok(!lstrcmpA(targetsid, "kiwi"),
8901        "Expected targetsid to be unchanged, got %s\n", targetsid);
8902     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8903
8904     data = MSIPATCHSTATE_APPLIED;
8905     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8906                          (const BYTE *)&data, sizeof(DWORD));
8907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8908
8909     /* State value exists */
8910     lstrcpyA(patchcode, "apple");
8911     lstrcpyA(targetprod, "banana");
8912     context = 0xdeadbeef;
8913     lstrcpyA(targetsid, "kiwi");
8914     size = MAX_PATH;
8915     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8916                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8917                            &context, targetsid, &size);
8918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8919     ok(!lstrcmpA(patchcode, patch),
8920        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8921     ok(!lstrcmpA(targetprod, prodcode),
8922        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8923     ok(context == MSIINSTALLCONTEXT_MACHINE,
8924        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8925     ok(!lstrcmpA(targetsid, ""),
8926        "Expected \"\", got \"%s\"\n", targetsid);
8927     ok(size == 0, "Expected 0, got %d\n", size);
8928
8929     /* MSIPATCHSTATE_SUPERSEDED */
8930
8931     lstrcpyA(patchcode, "apple");
8932     lstrcpyA(targetprod, "banana");
8933     context = 0xdeadbeef;
8934     lstrcpyA(targetsid, "kiwi");
8935     size = MAX_PATH;
8936     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8937                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8938                            &context, targetsid, &size);
8939     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8940     ok(!lstrcmpA(patchcode, "apple"),
8941        "Expected patchcode to be unchanged, got %s\n", patchcode);
8942     ok(!lstrcmpA(targetprod, "banana"),
8943        "Expected targetprod to be unchanged, got %s\n", targetprod);
8944     ok(context == 0xdeadbeef,
8945        "Expected context to be unchanged, got %d\n", context);
8946     ok(!lstrcmpA(targetsid, "kiwi"),
8947        "Expected targetsid to be unchanged, got %s\n", targetsid);
8948     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8949
8950     data = MSIPATCHSTATE_SUPERSEDED;
8951     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8952                          (const BYTE *)&data, sizeof(DWORD));
8953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8954
8955     /* State value is MSIPATCHSTATE_SUPERSEDED */
8956     lstrcpyA(patchcode, "apple");
8957     lstrcpyA(targetprod, "banana");
8958     context = 0xdeadbeef;
8959     lstrcpyA(targetsid, "kiwi");
8960     size = MAX_PATH;
8961     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8962                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8963                            &context, targetsid, &size);
8964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8965     ok(!lstrcmpA(patchcode, patch),
8966        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8967     ok(!lstrcmpA(targetprod, prodcode),
8968        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8969     ok(context == MSIINSTALLCONTEXT_MACHINE,
8970        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8971     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8972     ok(size == 0, "Expected 0, got %d\n", size);
8973
8974     /* MSIPATCHSTATE_OBSOLETED */
8975
8976     lstrcpyA(patchcode, "apple");
8977     lstrcpyA(targetprod, "banana");
8978     context = 0xdeadbeef;
8979     lstrcpyA(targetsid, "kiwi");
8980     size = MAX_PATH;
8981     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8982                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8983                            &context, targetsid, &size);
8984     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8985     ok(!lstrcmpA(patchcode, "apple"),
8986        "Expected patchcode to be unchanged, got %s\n", patchcode);
8987     ok(!lstrcmpA(targetprod, "banana"),
8988        "Expected targetprod to be unchanged, got %s\n", targetprod);
8989     ok(context == 0xdeadbeef,
8990        "Expected context to be unchanged, got %d\n", context);
8991     ok(!lstrcmpA(targetsid, "kiwi"),
8992        "Expected targetsid to be unchanged, got %s\n", targetsid);
8993     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8994
8995     data = MSIPATCHSTATE_OBSOLETED;
8996     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8997                          (const BYTE *)&data, sizeof(DWORD));
8998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8999
9000     /* State value is obsoleted */
9001     lstrcpyA(patchcode, "apple");
9002     lstrcpyA(targetprod, "banana");
9003     context = 0xdeadbeef;
9004     lstrcpyA(targetsid, "kiwi");
9005     size = MAX_PATH;
9006     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9007                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9008                            &context, targetsid, &size);
9009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9010     ok(!lstrcmpA(patchcode, patch),
9011        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9012     ok(!lstrcmpA(targetprod, prodcode),
9013        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9014     ok(context == MSIINSTALLCONTEXT_MACHINE,
9015        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9016     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9017     ok(size == 0, "Expected 0, got %d\n", size);
9018
9019     /* MSIPATCHSTATE_REGISTERED */
9020     /* FIXME */
9021
9022     /* MSIPATCHSTATE_ALL */
9023
9024     /* 1st */
9025     lstrcpyA(patchcode, "apple");
9026     lstrcpyA(targetprod, "banana");
9027     context = 0xdeadbeef;
9028     lstrcpyA(targetsid, "kiwi");
9029     size = MAX_PATH;
9030     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9031                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9032                            &context, targetsid, &size);
9033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9034     ok(!lstrcmpA(patchcode, patch),
9035        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9036     ok(!lstrcmpA(targetprod, prodcode),
9037        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9038     ok(context == MSIINSTALLCONTEXT_MACHINE,
9039        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9040     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9041     ok(size == 0, "Expected 0, got %d\n", size);
9042
9043     /* same patch in multiple places, only one is enumerated */
9044     lstrcpyA(patchcode, "apple");
9045     lstrcpyA(targetprod, "banana");
9046     context = 0xdeadbeef;
9047     lstrcpyA(targetsid, "kiwi");
9048     size = MAX_PATH;
9049     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9050                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9051                            &context, targetsid, &size);
9052     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9053     ok(!lstrcmpA(patchcode, "apple"),
9054        "Expected patchcode to be unchanged, got %s\n", patchcode);
9055     ok(!lstrcmpA(targetprod, "banana"),
9056        "Expected targetprod to be unchanged, got %s\n", targetprod);
9057     ok(context == 0xdeadbeef,
9058        "Expected context to be unchanged, got %d\n", context);
9059     ok(!lstrcmpA(targetsid, "kiwi"),
9060        "Expected targetsid to be unchanged, got %s\n", targetsid);
9061     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9062
9063     RegDeleteValueA(patches, patch_squashed);
9064     RegDeleteValueA(patches, "Patches");
9065     RegDeleteKeyA(patches, "");
9066     RegCloseKey(patches);
9067     RegDeleteValueA(hpatch, "State");
9068     RegDeleteKeyA(hpatch, "");
9069     RegCloseKey(hpatch);
9070     RegDeleteKeyA(udpatch, "");
9071     RegCloseKey(udpatch);
9072     RegDeleteKeyA(udprod, "");
9073     RegCloseKey(udprod);
9074     RegDeleteKeyA(prodkey, "");
9075     RegCloseKey(prodkey);
9076 }
9077
9078 static void test_MsiEnumPatches(void)
9079 {
9080     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9081     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9082     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9083     CHAR transforms[MAX_PATH];
9084     HKEY prodkey, patches, udprod;
9085     HKEY userkey, hpatch, udpatch;
9086     DWORD size, data;
9087     LPSTR usersid;
9088     LONG res;
9089     UINT r;
9090
9091     create_test_guid(prodcode, prod_squashed);
9092     create_test_guid(patchcode, patch_squashed);
9093     get_user_sid(&usersid);
9094
9095     /* NULL szProduct */
9096     size = MAX_PATH;
9097     lstrcpyA(patch, "apple");
9098     lstrcpyA(transforms, "banana");
9099     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9100     ok(r == ERROR_INVALID_PARAMETER,
9101        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9102     ok(!lstrcmpA(patch, "apple"),
9103        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9104     ok(!lstrcmpA(transforms, "banana"),
9105        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9106     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9107
9108     /* empty szProduct */
9109     size = MAX_PATH;
9110     lstrcpyA(patch, "apple");
9111     lstrcpyA(transforms, "banana");
9112     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9113     ok(r == ERROR_INVALID_PARAMETER,
9114        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9115     ok(!lstrcmpA(patch, "apple"),
9116        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9117     ok(!lstrcmpA(transforms, "banana"),
9118        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9119     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9120
9121     /* garbage szProduct */
9122     size = MAX_PATH;
9123     lstrcpyA(patch, "apple");
9124     lstrcpyA(transforms, "banana");
9125     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9126     ok(r == ERROR_INVALID_PARAMETER,
9127        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9128     ok(!lstrcmpA(patch, "apple"),
9129        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9130     ok(!lstrcmpA(transforms, "banana"),
9131        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9132     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9133
9134     /* guid without brackets */
9135     size = MAX_PATH;
9136     lstrcpyA(patch, "apple");
9137     lstrcpyA(transforms, "banana");
9138     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9139                         transforms, &size);
9140     ok(r == ERROR_INVALID_PARAMETER,
9141        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9142     ok(!lstrcmpA(patch, "apple"),
9143        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9144     ok(!lstrcmpA(transforms, "banana"),
9145        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9146     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9147
9148     /* guid with brackets */
9149     size = MAX_PATH;
9150     lstrcpyA(patch, "apple");
9151     lstrcpyA(transforms, "banana");
9152     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9153                         transforms, &size);
9154     ok(r == ERROR_UNKNOWN_PRODUCT,
9155        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9156     ok(!lstrcmpA(patch, "apple"),
9157        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9158     ok(!lstrcmpA(transforms, "banana"),
9159        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9160     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9161
9162     /* same length as guid, but random */
9163     size = MAX_PATH;
9164     lstrcpyA(patch, "apple");
9165     lstrcpyA(transforms, "banana");
9166     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9167                         transforms, &size);
9168     ok(r == ERROR_INVALID_PARAMETER,
9169        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9170     ok(!lstrcmpA(patch, "apple"),
9171        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9172     ok(!lstrcmpA(transforms, "banana"),
9173        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9174     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9175
9176     /* MSIINSTALLCONTEXT_USERMANAGED */
9177
9178     size = MAX_PATH;
9179     lstrcpyA(patch, "apple");
9180     lstrcpyA(transforms, "banana");
9181     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9182     ok(r == ERROR_UNKNOWN_PRODUCT,
9183        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9184     ok(!lstrcmpA(patch, "apple"),
9185        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9186     ok(!lstrcmpA(transforms, "banana"),
9187        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9188     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9189
9190     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9191     lstrcatA(keypath, usersid);
9192     lstrcatA(keypath, "\\Installer\\Products\\");
9193     lstrcatA(keypath, prod_squashed);
9194
9195     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9197
9198     /* managed product key exists */
9199     size = MAX_PATH;
9200     lstrcpyA(patch, "apple");
9201     lstrcpyA(transforms, "banana");
9202     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9203     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9204     ok(!lstrcmpA(patch, "apple"),
9205        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9206     ok(!lstrcmpA(transforms, "banana"),
9207        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9208     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9209
9210     res = RegCreateKeyA(prodkey, "Patches", &patches);
9211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9212
9213     /* patches key exists */
9214     size = MAX_PATH;
9215     lstrcpyA(patch, "apple");
9216     lstrcpyA(transforms, "banana");
9217     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9218     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9219     ok(!lstrcmpA(patch, "apple"),
9220        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9221     ok(!lstrcmpA(transforms, "banana"),
9222        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9223     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9224
9225     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9226                          (const BYTE *)patch_squashed,
9227                          lstrlenA(patch_squashed) + 1);
9228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9229
9230     /* Patches value exists, is not REG_MULTI_SZ */
9231     size = MAX_PATH;
9232     lstrcpyA(patch, "apple");
9233     lstrcpyA(transforms, "banana");
9234     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9235     ok(r == ERROR_BAD_CONFIGURATION,
9236        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9237     ok(!lstrcmpA(patch, "apple"),
9238        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9239     ok(!lstrcmpA(transforms, "banana"),
9240        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9241     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9242
9243     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9244                          (const BYTE *)"a\0b\0c\0\0", 7);
9245     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9246
9247     /* Patches value exists, is not a squashed guid */
9248     size = MAX_PATH;
9249     lstrcpyA(patch, "apple");
9250     lstrcpyA(transforms, "banana");
9251     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9252     ok(r == ERROR_BAD_CONFIGURATION,
9253        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9254     ok(!lstrcmpA(patch, "apple"),
9255        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9256     ok(!lstrcmpA(transforms, "banana"),
9257        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9258     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9259
9260     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9261                          (const BYTE *)patch_squashed,
9262                          lstrlenA(patch_squashed) + 1);
9263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9264
9265     /* Patches value exists */
9266     size = MAX_PATH;
9267     lstrcpyA(patch, "apple");
9268     lstrcpyA(transforms, "banana");
9269     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9270     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9271     ok(!lstrcmpA(patch, "apple"),
9272        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9273     ok(!lstrcmpA(transforms, "banana"),
9274        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9275     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9276
9277     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9278                          (const BYTE *)"whatever", 9);
9279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9280
9281     /* patch squashed value exists */
9282     size = MAX_PATH;
9283     lstrcpyA(patch, "apple");
9284     lstrcpyA(transforms, "banana");
9285     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9287     ok(!lstrcmpA(patch, patchcode),
9288        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9289     ok(!lstrcmpA(transforms, "whatever"),
9290        "Expected \"whatever\", got \"%s\"\n", transforms);
9291     ok(size == 8, "Expected 8, got %d\n", size);
9292
9293     /* lpPatchBuf is NULL */
9294     size = MAX_PATH;
9295     lstrcpyA(transforms, "banana");
9296     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9297     ok(r == ERROR_INVALID_PARAMETER,
9298        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9299     ok(!lstrcmpA(transforms, "banana"),
9300        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9301     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9302
9303     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9304     size = MAX_PATH;
9305     lstrcpyA(patch, "apple");
9306     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9307     ok(r == ERROR_INVALID_PARAMETER,
9308        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9309     ok(!lstrcmpA(patch, "apple"),
9310        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9311     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9312
9313     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9314     lstrcpyA(patch, "apple");
9315     lstrcpyA(transforms, "banana");
9316     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9317     ok(r == ERROR_INVALID_PARAMETER,
9318        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9319     ok(!lstrcmpA(patch, "apple"),
9320        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9321     ok(!lstrcmpA(transforms, "banana"),
9322        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9323
9324     /* pcchTransformsBuf is too small */
9325     size = 6;
9326     lstrcpyA(patch, "apple");
9327     lstrcpyA(transforms, "banana");
9328     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9329     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9330     ok(!lstrcmpA(patch, patchcode),
9331        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9332     ok(!lstrcmpA(transforms, "whate"),
9333        "Expected \"whate\", got \"%s\"\n", transforms);
9334     ok(size == 16, "Expected 16, got %d\n", size);
9335
9336     /* increase the index */
9337     size = MAX_PATH;
9338     lstrcpyA(patch, "apple");
9339     lstrcpyA(transforms, "banana");
9340     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9341     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9342     ok(!lstrcmpA(patch, "apple"),
9343        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9344     ok(!lstrcmpA(transforms, "banana"),
9345        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9346     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9347
9348     /* increase again */
9349     size = MAX_PATH;
9350     lstrcpyA(patch, "apple");
9351     lstrcpyA(transforms, "banana");
9352     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9353     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9354     ok(!lstrcmpA(patch, "apple"),
9355        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9356     ok(!lstrcmpA(transforms, "banana"),
9357        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9358     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9359
9360     RegDeleteValueA(patches, "Patches");
9361     RegDeleteKeyA(patches, "");
9362     RegCloseKey(patches);
9363     RegDeleteKeyA(prodkey, "");
9364     RegCloseKey(prodkey);
9365
9366     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9367
9368     size = MAX_PATH;
9369     lstrcpyA(patch, "apple");
9370     lstrcpyA(transforms, "banana");
9371     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9372     ok(r == ERROR_UNKNOWN_PRODUCT,
9373        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9374     ok(!lstrcmpA(patch, "apple"),
9375        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9376     ok(!lstrcmpA(transforms, "banana"),
9377        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9378     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9379
9380     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9381     lstrcatA(keypath, prod_squashed);
9382
9383     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9384     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9385
9386     /* current user product key exists */
9387     size = MAX_PATH;
9388     lstrcpyA(patch, "apple");
9389     lstrcpyA(transforms, "banana");
9390     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9391     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9392     ok(!lstrcmpA(patch, "apple"),
9393        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9394     ok(!lstrcmpA(transforms, "banana"),
9395        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9396     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9397
9398     res = RegCreateKeyA(prodkey, "Patches", &patches);
9399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9400
9401     /* Patches key exists */
9402     size = MAX_PATH;
9403     lstrcpyA(patch, "apple");
9404     lstrcpyA(transforms, "banana");
9405     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9406     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9407     ok(!lstrcmpA(patch, "apple"),
9408        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9409     ok(!lstrcmpA(transforms, "banana"),
9410        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9411     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9412
9413     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9414                          (const BYTE *)patch_squashed,
9415                          lstrlenA(patch_squashed) + 1);
9416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9417
9418     /* Patches value exists, is not REG_MULTI_SZ */
9419     size = MAX_PATH;
9420     lstrcpyA(patch, "apple");
9421     lstrcpyA(transforms, "banana");
9422     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9423     ok(r == ERROR_BAD_CONFIGURATION,
9424        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9425     ok(!lstrcmpA(patch, "apple"),
9426        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9427     ok(!lstrcmpA(transforms, "banana"),
9428        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9429     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9430
9431     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9432                          (const BYTE *)"a\0b\0c\0\0", 7);
9433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9434
9435     /* Patches value exists, is not a squashed guid */
9436     size = MAX_PATH;
9437     lstrcpyA(patch, "apple");
9438     lstrcpyA(transforms, "banana");
9439     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9440     ok(r == ERROR_BAD_CONFIGURATION,
9441        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9442     ok(!lstrcmpA(patch, "apple"),
9443        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9444     ok(!lstrcmpA(transforms, "banana"),
9445        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9446     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9447
9448     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9449                          (const BYTE *)patch_squashed,
9450                          lstrlenA(patch_squashed) + 1);
9451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9452
9453     /* Patches value exists */
9454     size = MAX_PATH;
9455     lstrcpyA(patch, "apple");
9456     lstrcpyA(transforms, "banana");
9457     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9458     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9459     ok(!lstrcmpA(patch, "apple"),
9460        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9461     ok(!lstrcmpA(transforms, "banana"),
9462        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9463     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9464
9465     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9466                          (const BYTE *)"whatever", 9);
9467     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9468
9469     /* patch code value exists */
9470     size = MAX_PATH;
9471     lstrcpyA(patch, "apple");
9472     lstrcpyA(transforms, "banana");
9473     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9474     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9475     ok(!lstrcmpA(patch, "apple"),
9476        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9477     ok(!lstrcmpA(transforms, "banana"),
9478        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9479     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9480
9481     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9482     lstrcatA(keypath, usersid);
9483     lstrcatA(keypath, "\\Patches\\");
9484     lstrcatA(keypath, patch_squashed);
9485
9486     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9488
9489     /* userdata patch key exists */
9490     size = MAX_PATH;
9491     lstrcpyA(patch, "apple");
9492     lstrcpyA(transforms, "banana");
9493     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9494     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9495     ok(!lstrcmpA(patch, patchcode),
9496        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9497     ok(!lstrcmpA(transforms, "whatever"),
9498        "Expected \"whatever\", got \"%s\"\n", transforms);
9499     ok(size == 8, "Expected 8, got %d\n", size);
9500
9501     RegDeleteKeyA(userkey, "");
9502     RegCloseKey(userkey);
9503     RegDeleteValueA(patches, patch_squashed);
9504     RegDeleteValueA(patches, "Patches");
9505     RegDeleteKeyA(patches, "");
9506     RegCloseKey(patches);
9507     RegDeleteKeyA(prodkey, "");
9508     RegCloseKey(prodkey);
9509
9510     /* MSIINSTALLCONTEXT_MACHINE */
9511
9512     size = MAX_PATH;
9513     lstrcpyA(patch, "apple");
9514     lstrcpyA(transforms, "banana");
9515     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9516     ok(r == ERROR_UNKNOWN_PRODUCT,
9517        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9518     ok(!lstrcmpA(patch, "apple"),
9519        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9520     ok(!lstrcmpA(transforms, "banana"),
9521        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9522     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9523
9524     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9525     lstrcatA(keypath, prod_squashed);
9526
9527     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9529
9530     /* local product key exists */
9531     size = MAX_PATH;
9532     lstrcpyA(patch, "apple");
9533     lstrcpyA(transforms, "banana");
9534     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9535     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9536     ok(!lstrcmpA(patch, "apple"),
9537        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9538     ok(!lstrcmpA(transforms, "banana"),
9539        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9540     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9541
9542     res = RegCreateKeyA(prodkey, "Patches", &patches);
9543     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9544
9545     /* Patches key exists */
9546     size = MAX_PATH;
9547     lstrcpyA(patch, "apple");
9548     lstrcpyA(transforms, "banana");
9549     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9550     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9551     ok(!lstrcmpA(patch, "apple"),
9552        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9553     ok(!lstrcmpA(transforms, "banana"),
9554        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9555     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9556
9557     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9558                          (const BYTE *)patch_squashed,
9559                          lstrlenA(patch_squashed) + 1);
9560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9561
9562     /* Patches value exists, is not REG_MULTI_SZ */
9563     size = MAX_PATH;
9564     lstrcpyA(patch, "apple");
9565     lstrcpyA(transforms, "banana");
9566     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9567     ok(r == ERROR_BAD_CONFIGURATION,
9568        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9569     ok(!lstrcmpA(patch, "apple"),
9570        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9571     ok(!lstrcmpA(transforms, "banana"),
9572        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9573     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9574
9575     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9576                          (const BYTE *)"a\0b\0c\0\0", 7);
9577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9578
9579     /* Patches value exists, is not a squashed guid */
9580     size = MAX_PATH;
9581     lstrcpyA(patch, "apple");
9582     lstrcpyA(transforms, "banana");
9583     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9584     ok(r == ERROR_BAD_CONFIGURATION,
9585        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9586     ok(!lstrcmpA(patch, "apple"),
9587        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9588     ok(!lstrcmpA(transforms, "banana"),
9589        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9590     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9591
9592     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9593                          (const BYTE *)patch_squashed,
9594                          lstrlenA(patch_squashed) + 1);
9595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9596
9597     /* Patches value exists */
9598     size = MAX_PATH;
9599     lstrcpyA(patch, "apple");
9600     lstrcpyA(transforms, "banana");
9601     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9602     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9603     ok(!lstrcmpA(patch, "apple"),
9604        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9605     ok(!lstrcmpA(transforms, "banana"),
9606        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9607     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9608
9609     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9610                          (const BYTE *)"whatever", 9);
9611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9612
9613     /* patch code value exists */
9614     size = MAX_PATH;
9615     lstrcpyA(patch, "apple");
9616     lstrcpyA(transforms, "banana");
9617     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9619     ok(!lstrcmpA(patch, patchcode),
9620        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9621     ok(!lstrcmpA(transforms, "whatever"),
9622        "Expected \"whatever\", got \"%s\"\n", transforms);
9623     ok(size == 8, "Expected 8, got %d\n", size);
9624
9625     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9626     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9627     lstrcatA(keypath, prod_squashed);
9628
9629     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9631
9632     /* local UserData product key exists */
9633     size = MAX_PATH;
9634     lstrcpyA(patch, "apple");
9635     lstrcpyA(transforms, "banana");
9636     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9637     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9638     ok(!lstrcmpA(patch, patchcode),
9639        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9640     ok(!lstrcmpA(transforms, "whatever"),
9641        "Expected \"whatever\", got \"%s\"\n", transforms);
9642     ok(size == 8, "Expected 8, got %d\n", size);
9643
9644     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9646
9647     /* local UserData Patches key exists */
9648     size = MAX_PATH;
9649     lstrcpyA(patch, "apple");
9650     lstrcpyA(transforms, "banana");
9651     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9652     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9653     ok(!lstrcmpA(patch, patchcode),
9654        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9655     ok(!lstrcmpA(transforms, "whatever"),
9656        "Expected \"whatever\", got \"%s\"\n", transforms);
9657     ok(size == 8, "Expected 8, got %d\n", size);
9658
9659     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9661
9662     /* local UserData Product patch key exists */
9663     size = MAX_PATH;
9664     lstrcpyA(patch, "apple");
9665     lstrcpyA(transforms, "banana");
9666     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9667     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9668     ok(!lstrcmpA(patch, "apple"),
9669        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9670     ok(!lstrcmpA(transforms, "banana"),
9671        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9672     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9673
9674     data = MSIPATCHSTATE_APPLIED;
9675     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9676                          (const BYTE *)&data, sizeof(DWORD));
9677     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9678
9679     /* State value exists */
9680     size = MAX_PATH;
9681     lstrcpyA(patch, "apple");
9682     lstrcpyA(transforms, "banana");
9683     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9684     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9685     ok(!lstrcmpA(patch, patchcode),
9686        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9687     ok(!lstrcmpA(transforms, "whatever"),
9688        "Expected \"whatever\", got \"%s\"\n", transforms);
9689     ok(size == 8, "Expected 8, got %d\n", size);
9690
9691     RegDeleteValueA(patches, patch_squashed);
9692     RegDeleteValueA(patches, "Patches");
9693     RegDeleteKeyA(patches, "");
9694     RegCloseKey(patches);
9695     RegDeleteValueA(hpatch, "State");
9696     RegDeleteKeyA(hpatch, "");
9697     RegCloseKey(hpatch);
9698     RegDeleteKeyA(udpatch, "");
9699     RegCloseKey(udpatch);
9700     RegDeleteKeyA(udprod, "");
9701     RegCloseKey(udprod);
9702     RegDeleteKeyA(prodkey, "");
9703     RegCloseKey(prodkey);
9704 }
9705
9706 static void test_MsiGetPatchInfoEx(void)
9707 {
9708     CHAR keypath[MAX_PATH], val[MAX_PATH];
9709     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9710     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9711     HKEY prodkey, patches, udprod, props;
9712     HKEY hpatch, udpatch, prodpatches;
9713     LPSTR usersid;
9714     DWORD size;
9715     LONG res;
9716     UINT r;
9717
9718     if (!pMsiGetPatchInfoExA)
9719     {
9720         win_skip("MsiGetPatchInfoEx not implemented\n");
9721         return;
9722     }
9723
9724     create_test_guid(prodcode, prod_squashed);
9725     create_test_guid(patchcode, patch_squashed);
9726     get_user_sid(&usersid);
9727
9728     /* NULL szPatchCode */
9729     lstrcpyA(val, "apple");
9730     size = MAX_PATH;
9731     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9732                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9733     ok(r == ERROR_INVALID_PARAMETER,
9734        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9735     ok(!lstrcmpA(val, "apple"),
9736        "Expected val to be unchanged, got \"%s\"\n", val);
9737     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9738
9739     /* empty szPatchCode */
9740     size = MAX_PATH;
9741     lstrcpyA(val, "apple");
9742     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9743                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9744     ok(r == ERROR_INVALID_PARAMETER,
9745        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9746     ok(!lstrcmpA(val, "apple"),
9747        "Expected val to be unchanged, got \"%s\"\n", val);
9748     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9749
9750     /* garbage szPatchCode */
9751     size = MAX_PATH;
9752     lstrcpyA(val, "apple");
9753     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9754                             MSIINSTALLCONTEXT_USERMANAGED,
9755                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9756     ok(r == ERROR_INVALID_PARAMETER,
9757        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9758     ok(!lstrcmpA(val, "apple"),
9759        "Expected val to be unchanged, got \"%s\"\n", val);
9760     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9761
9762     /* guid without brackets */
9763     size = MAX_PATH;
9764     lstrcpyA(val, "apple");
9765     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9766                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9767                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9768     ok(r == ERROR_INVALID_PARAMETER,
9769        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9770     ok(!lstrcmpA(val, "apple"),
9771        "Expected val to be unchanged, got \"%s\"\n", val);
9772     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9773
9774     /* guid with brackets */
9775     size = MAX_PATH;
9776     lstrcpyA(val, "apple");
9777     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9778                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9779                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9780     ok(r == ERROR_UNKNOWN_PRODUCT,
9781        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9782     ok(!lstrcmpA(val, "apple"),
9783        "Expected val to be unchanged, got \"%s\"\n", val);
9784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9785
9786     /* same length as guid, but random */
9787     size = MAX_PATH;
9788     lstrcpyA(val, "apple");
9789     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9790                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9791                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9792     ok(r == ERROR_INVALID_PARAMETER,
9793        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9794     ok(!lstrcmpA(val, "apple"),
9795        "Expected val to be unchanged, got \"%s\"\n", val);
9796     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9797
9798     /* NULL szProductCode */
9799     lstrcpyA(val, "apple");
9800     size = MAX_PATH;
9801     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9802                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9803     ok(r == ERROR_INVALID_PARAMETER,
9804        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9805     ok(!lstrcmpA(val, "apple"),
9806        "Expected val to be unchanged, got \"%s\"\n", val);
9807     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9808
9809     /* empty szProductCode */
9810     size = MAX_PATH;
9811     lstrcpyA(val, "apple");
9812     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
9813                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9814     ok(r == ERROR_INVALID_PARAMETER,
9815        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9816     ok(!lstrcmpA(val, "apple"),
9817        "Expected val to be unchanged, got \"%s\"\n", val);
9818     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9819
9820     /* garbage szProductCode */
9821     size = MAX_PATH;
9822     lstrcpyA(val, "apple");
9823     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9824                             MSIINSTALLCONTEXT_USERMANAGED,
9825                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9826     ok(r == ERROR_INVALID_PARAMETER,
9827        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9828     ok(!lstrcmpA(val, "apple"),
9829        "Expected val to be unchanged, got \"%s\"\n", val);
9830     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9831
9832     /* guid without brackets */
9833     size = MAX_PATH;
9834     lstrcpyA(val, "apple");
9835     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
9836                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9837                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9838     ok(r == ERROR_INVALID_PARAMETER,
9839        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9840     ok(!lstrcmpA(val, "apple"),
9841        "Expected val to be unchanged, got \"%s\"\n", val);
9842     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9843
9844     /* guid with brackets */
9845     size = MAX_PATH;
9846     lstrcpyA(val, "apple");
9847     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
9848                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9849                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9850     ok(r == ERROR_UNKNOWN_PRODUCT,
9851        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9852     ok(!lstrcmpA(val, "apple"),
9853        "Expected val to be unchanged, got \"%s\"\n", val);
9854     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9855
9856     /* same length as guid, but random */
9857     size = MAX_PATH;
9858     lstrcpyA(val, "apple");
9859     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
9860                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9861                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9862     ok(r == ERROR_INVALID_PARAMETER,
9863        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9864     ok(!lstrcmpA(val, "apple"),
9865        "Expected val to be unchanged, got \"%s\"\n", val);
9866     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9867
9868     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
9869     size = MAX_PATH;
9870     lstrcpyA(val, "apple");
9871     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9872                             MSIINSTALLCONTEXT_USERMANAGED,
9873                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9874     ok(r == ERROR_INVALID_PARAMETER,
9875        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9876     ok(!lstrcmpA(val, "apple"),
9877        "Expected val to be unchanged, got \"%s\"\n", val);
9878     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9879
9880     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
9881     size = MAX_PATH;
9882     lstrcpyA(val, "apple");
9883     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9884                             MSIINSTALLCONTEXT_USERUNMANAGED,
9885                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9886     ok(r == ERROR_INVALID_PARAMETER,
9887        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9888     ok(!lstrcmpA(val, "apple"),
9889        "Expected val to be unchanged, got \"%s\"\n", val);
9890     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9891
9892     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
9893     size = MAX_PATH;
9894     lstrcpyA(val, "apple");
9895     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9896                             MSIINSTALLCONTEXT_MACHINE,
9897                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9898     ok(r == ERROR_INVALID_PARAMETER,
9899        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9900     ok(!lstrcmpA(val, "apple"),
9901        "Expected val to be unchanged, got \"%s\"\n", val);
9902     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9903
9904     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
9905     size = MAX_PATH;
9906     lstrcpyA(val, "apple");
9907     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9908                             MSIINSTALLCONTEXT_MACHINE,
9909                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9910     ok(r == ERROR_INVALID_PARAMETER,
9911        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9912     ok(!lstrcmpA(val, "apple"),
9913        "Expected val to be unchanged, got \"%s\"\n", val);
9914     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9915
9916     /* dwContext is out of range */
9917     size = MAX_PATH;
9918     lstrcpyA(val, "apple");
9919     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9920                             MSIINSTALLCONTEXT_NONE,
9921                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9922     ok(r == ERROR_INVALID_PARAMETER,
9923        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9924     ok(!lstrcmpA(val, "apple"),
9925        "Expected val to be unchanged, got \"%s\"\n", val);
9926     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9927
9928     /* dwContext is out of range */
9929     size = MAX_PATH;
9930     lstrcpyA(val, "apple");
9931     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9932                             MSIINSTALLCONTEXT_ALL,
9933                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9934     ok(r == ERROR_INVALID_PARAMETER,
9935        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9936     ok(!lstrcmpA(val, "apple"),
9937        "Expected val to be unchanged, got \"%s\"\n", val);
9938     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9939
9940     /* dwContext is invalid */
9941     size = MAX_PATH;
9942     lstrcpyA(val, "apple");
9943     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
9944                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9945     ok(r == ERROR_INVALID_PARAMETER,
9946        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9947     ok(!lstrcmpA(val, "apple"),
9948        "Expected val to be unchanged, got \"%s\"\n", val);
9949     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9950
9951     /* MSIINSTALLCONTEXT_USERMANAGED */
9952
9953     size = MAX_PATH;
9954     lstrcpyA(val, "apple");
9955     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9956                             MSIINSTALLCONTEXT_USERMANAGED,
9957                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9958     ok(r == ERROR_UNKNOWN_PRODUCT,
9959        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9960     ok(!lstrcmpA(val, "apple"),
9961        "Expected val to be unchanged, got \"%s\"\n", val);
9962     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9963
9964     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9965     lstrcatA(keypath, usersid);
9966     lstrcatA(keypath, "\\Products\\");
9967     lstrcatA(keypath, prod_squashed);
9968
9969     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9971
9972     /* local UserData product key exists */
9973     size = MAX_PATH;
9974     lstrcpyA(val, "apple");
9975     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9976                             MSIINSTALLCONTEXT_USERMANAGED,
9977                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9978     ok(r == ERROR_UNKNOWN_PRODUCT,
9979        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9980     ok(!lstrcmpA(val, "apple"),
9981        "Expected val to be unchanged, got \"%s\"\n", val);
9982     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9983
9984     res = RegCreateKeyA(udprod, "InstallProperties", &props);
9985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9986
9987     /* InstallProperties key exists */
9988     size = MAX_PATH;
9989     lstrcpyA(val, "apple");
9990     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9991                             MSIINSTALLCONTEXT_USERMANAGED,
9992                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9993     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
9994     ok(!lstrcmpA(val, "apple"),
9995        "Expected val to be unchanged, got \"%s\"\n", val);
9996     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9997
9998     res = RegCreateKeyA(udprod, "Patches", &patches);
9999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10000
10001     /* Patches key exists */
10002     size = MAX_PATH;
10003     lstrcpyA(val, "apple");
10004     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10005                             MSIINSTALLCONTEXT_USERMANAGED,
10006                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10007     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10008     ok(!lstrcmpA(val, "apple"),
10009        "Expected val to be unchanged, got \"%s\"\n", val);
10010     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10011
10012     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10014
10015     /* Patches key exists */
10016     size = MAX_PATH;
10017     lstrcpyA(val, "apple");
10018     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10019                             MSIINSTALLCONTEXT_USERMANAGED,
10020                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10021     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10022     ok(!lstrcmpA(val, "apple"),
10023        "Expected val to be unchanged, got \"%s\"\n", val);
10024     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10025
10026     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10027     lstrcatA(keypath, usersid);
10028     lstrcatA(keypath, "\\Installer\\Products\\");
10029     lstrcatA(keypath, prod_squashed);
10030
10031     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10032     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10033
10034     /* managed product key exists */
10035     size = MAX_PATH;
10036     lstrcpyA(val, "apple");
10037     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10038                             MSIINSTALLCONTEXT_USERMANAGED,
10039                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10040     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10041     ok(!lstrcmpA(val, "apple"),
10042        "Expected val to be unchanged, got \"%s\"\n", val);
10043     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10044
10045     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10046     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10047
10048     /* Patches key exists */
10049     size = MAX_PATH;
10050     lstrcpyA(val, "apple");
10051     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10052                             MSIINSTALLCONTEXT_USERMANAGED,
10053                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10054     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10055     ok(!lstrcmpA(val, "apple"),
10056        "Expected val to be unchanged, got \"%s\"\n", val);
10057     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10058
10059     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10060                          (const BYTE *)"transforms", 11);
10061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10062
10063     /* specific patch value exists */
10064     size = MAX_PATH;
10065     lstrcpyA(val, "apple");
10066     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10067                             MSIINSTALLCONTEXT_USERMANAGED,
10068                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10069     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10070     ok(!lstrcmpA(val, "apple"),
10071        "Expected val to be unchanged, got \"%s\"\n", val);
10072     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10073
10074     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10075     lstrcatA(keypath, usersid);
10076     lstrcatA(keypath, "\\Patches\\");
10077     lstrcatA(keypath, patch_squashed);
10078
10079     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10081
10082     /* UserData Patches key exists */
10083     size = MAX_PATH;
10084     lstrcpyA(val, "apple");
10085     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10086                             MSIINSTALLCONTEXT_USERMANAGED,
10087                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10088     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10089     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10090     ok(size == 0, "Expected 0, got %d\n", size);
10091
10092     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10093                          (const BYTE *)"pack", 5);
10094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10095
10096     /* ManagedLocalPatch value exists */
10097     size = MAX_PATH;
10098     lstrcpyA(val, "apple");
10099     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10100                             MSIINSTALLCONTEXT_USERMANAGED,
10101                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10102     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10103     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10104     ok(size == 4, "Expected 4, got %d\n", size);
10105
10106     size = MAX_PATH;
10107     lstrcpyA(val, "apple");
10108     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10109                             MSIINSTALLCONTEXT_USERMANAGED,
10110                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10112     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10113     ok(size == 10, "Expected 10, got %d\n", size);
10114
10115     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10116                          (const BYTE *)"mydate", 7);
10117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10118
10119     /* Installed value exists */
10120     size = MAX_PATH;
10121     lstrcpyA(val, "apple");
10122     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10123                             MSIINSTALLCONTEXT_USERMANAGED,
10124                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10126     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10127     ok(size == 6, "Expected 6, got %d\n", size);
10128
10129     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10130                          (const BYTE *)"yes", 4);
10131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10132
10133     /* Uninstallable value exists */
10134     size = MAX_PATH;
10135     lstrcpyA(val, "apple");
10136     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10137                             MSIINSTALLCONTEXT_USERMANAGED,
10138                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10140     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10141     ok(size == 3, "Expected 3, got %d\n", size);
10142
10143     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10144                          (const BYTE *)"good", 5);
10145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10146
10147     /* State value exists */
10148     size = MAX_PATH;
10149     lstrcpyA(val, "apple");
10150     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10151                             MSIINSTALLCONTEXT_USERMANAGED,
10152                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10154     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10155     ok(size == 4, "Expected 4, got %d\n", size);
10156
10157     size = 1;
10158     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10159                          (const BYTE *)&size, sizeof(DWORD));
10160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10161
10162     /* State value exists */
10163     size = MAX_PATH;
10164     lstrcpyA(val, "apple");
10165     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10166                             MSIINSTALLCONTEXT_USERMANAGED,
10167                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10168     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10169     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10170     ok(size == 1, "Expected 1, got %d\n", size);
10171
10172     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10173                          (const BYTE *)"display", 8);
10174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10175
10176     /* DisplayName value exists */
10177     size = MAX_PATH;
10178     lstrcpyA(val, "apple");
10179     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10180                             MSIINSTALLCONTEXT_USERMANAGED,
10181                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10183     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10184     ok(size == 7, "Expected 7, got %d\n", size);
10185
10186     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10187                          (const BYTE *)"moreinfo", 9);
10188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10189
10190     /* MoreInfoURL value exists */
10191     size = MAX_PATH;
10192     lstrcpyA(val, "apple");
10193     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10194                             MSIINSTALLCONTEXT_USERMANAGED,
10195                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10196     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10197     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10198     ok(size == 8, "Expected 8, got %d\n", size);
10199
10200     /* szProperty is invalid */
10201     size = MAX_PATH;
10202     lstrcpyA(val, "apple");
10203     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10204                             MSIINSTALLCONTEXT_USERMANAGED,
10205                             "IDontExist", val, &size);
10206     ok(r == ERROR_UNKNOWN_PROPERTY,
10207        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10208     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10209     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10210
10211     /* lpValue is NULL, while pcchValue is non-NULL */
10212     size = MAX_PATH;
10213     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10214                             MSIINSTALLCONTEXT_USERMANAGED,
10215                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10217     ok(size == 16, "Expected 16, got %d\n", size);
10218
10219     /* pcchValue is NULL, while lpValue is non-NULL */
10220     lstrcpyA(val, "apple");
10221     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10222                             MSIINSTALLCONTEXT_USERMANAGED,
10223                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10224     ok(r == ERROR_INVALID_PARAMETER,
10225        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10226     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10227
10228     /* both lpValue and pcchValue are NULL */
10229     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10230                             MSIINSTALLCONTEXT_USERMANAGED,
10231                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10232     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10233
10234     /* pcchValue doesn't have enough room for NULL terminator */
10235     size = 8;
10236     lstrcpyA(val, "apple");
10237     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10238                             MSIINSTALLCONTEXT_USERMANAGED,
10239                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10240     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10241     ok(!lstrcmpA(val, "moreinf"),
10242        "Expected \"moreinf\", got \"%s\"\n", val);
10243     ok(size == 16, "Expected 16, got %d\n", size);
10244
10245     /* pcchValue has exactly enough room for NULL terminator */
10246     size = 9;
10247     lstrcpyA(val, "apple");
10248     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10249                             MSIINSTALLCONTEXT_USERMANAGED,
10250                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10252     ok(!lstrcmpA(val, "moreinfo"),
10253        "Expected \"moreinfo\", got \"%s\"\n", val);
10254     ok(size == 8, "Expected 8, got %d\n", size);
10255
10256     /* pcchValue is too small, lpValue is NULL */
10257     size = 0;
10258     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10259                             MSIINSTALLCONTEXT_USERMANAGED,
10260                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10262     ok(size == 16, "Expected 16, got %d\n", size);
10263
10264     RegDeleteValueA(prodpatches, patch_squashed);
10265     RegDeleteKeyA(prodpatches, "");
10266     RegCloseKey(prodpatches);
10267     RegDeleteKeyA(prodkey, "");
10268     RegCloseKey(prodkey);
10269
10270     /* UserData is sufficient for all properties
10271      * except INSTALLPROPERTY_TRANSFORMS
10272      */
10273     size = MAX_PATH;
10274     lstrcpyA(val, "apple");
10275     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10276                             MSIINSTALLCONTEXT_USERMANAGED,
10277                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10279     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10280     ok(size == 4, "Expected 4, got %d\n", size);
10281
10282     /* UserData is sufficient for all properties
10283      * except INSTALLPROPERTY_TRANSFORMS
10284      */
10285     size = MAX_PATH;
10286     lstrcpyA(val, "apple");
10287     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10288                             MSIINSTALLCONTEXT_USERMANAGED,
10289                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10290     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10291     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10292     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10293
10294     RegDeleteValueA(hpatch, "MoreInfoURL");
10295     RegDeleteValueA(hpatch, "Display");
10296     RegDeleteValueA(hpatch, "State");
10297     RegDeleteValueA(hpatch, "Uninstallable");
10298     RegDeleteValueA(hpatch, "Installed");
10299     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10300     RegDeleteKeyA(udpatch, "");
10301     RegCloseKey(udpatch);
10302     RegDeleteKeyA(hpatch, "");
10303     RegCloseKey(hpatch);
10304     RegDeleteKeyA(patches, "");
10305     RegCloseKey(patches);
10306     RegDeleteKeyA(props, "");
10307     RegCloseKey(props);
10308     RegDeleteKeyA(udprod, "");
10309     RegCloseKey(udprod);
10310
10311     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10312
10313     size = MAX_PATH;
10314     lstrcpyA(val, "apple");
10315     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10316                             MSIINSTALLCONTEXT_USERUNMANAGED,
10317                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10318     ok(r == ERROR_UNKNOWN_PRODUCT,
10319        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10320     ok(!lstrcmpA(val, "apple"),
10321        "Expected val to be unchanged, got \"%s\"\n", val);
10322     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10323
10324     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10325     lstrcatA(keypath, usersid);
10326     lstrcatA(keypath, "\\Products\\");
10327     lstrcatA(keypath, prod_squashed);
10328
10329     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10331
10332     /* local UserData product key exists */
10333     size = MAX_PATH;
10334     lstrcpyA(val, "apple");
10335     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10336                             MSIINSTALLCONTEXT_USERUNMANAGED,
10337                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10338     ok(r == ERROR_UNKNOWN_PRODUCT,
10339        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10340     ok(!lstrcmpA(val, "apple"),
10341        "Expected val to be unchanged, got \"%s\"\n", val);
10342     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10343
10344     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10346
10347     /* InstallProperties key exists */
10348     size = MAX_PATH;
10349     lstrcpyA(val, "apple");
10350     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10351                             MSIINSTALLCONTEXT_USERUNMANAGED,
10352                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10353     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10354     ok(!lstrcmpA(val, "apple"),
10355        "Expected val to be unchanged, got \"%s\"\n", val);
10356     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10357
10358     res = RegCreateKeyA(udprod, "Patches", &patches);
10359     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10360
10361     /* Patches key exists */
10362     size = MAX_PATH;
10363     lstrcpyA(val, "apple");
10364     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10365                             MSIINSTALLCONTEXT_USERUNMANAGED,
10366                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10367     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10368     ok(!lstrcmpA(val, "apple"),
10369        "Expected val to be unchanged, got \"%s\"\n", val);
10370     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10371
10372     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10373     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10374
10375     /* Patches key exists */
10376     size = MAX_PATH;
10377     lstrcpyA(val, "apple");
10378     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10379                             MSIINSTALLCONTEXT_USERUNMANAGED,
10380                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10381     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10382     ok(!lstrcmpA(val, "apple"),
10383        "Expected val to be unchanged, got \"%s\"\n", val);
10384     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10385
10386     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10387     lstrcatA(keypath, prod_squashed);
10388
10389     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10390     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10391
10392     /* current user product key exists */
10393     size = MAX_PATH;
10394     lstrcpyA(val, "apple");
10395     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10396                             MSIINSTALLCONTEXT_USERUNMANAGED,
10397                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10398     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10399     ok(!lstrcmpA(val, "apple"),
10400        "Expected val to be unchanged, got \"%s\"\n", val);
10401     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10402
10403     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10405
10406     /* Patches key exists */
10407     size = MAX_PATH;
10408     lstrcpyA(val, "apple");
10409     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10410                             MSIINSTALLCONTEXT_USERUNMANAGED,
10411                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10412     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10413     ok(!lstrcmpA(val, "apple"),
10414        "Expected val to be unchanged, got \"%s\"\n", val);
10415     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10416
10417     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10418                          (const BYTE *)"transforms", 11);
10419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10420
10421     /* specific patch value exists */
10422     size = MAX_PATH;
10423     lstrcpyA(val, "apple");
10424     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10425                             MSIINSTALLCONTEXT_USERUNMANAGED,
10426                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10427     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10428     ok(!lstrcmpA(val, "apple"),
10429        "Expected val to be unchanged, got \"%s\"\n", val);
10430     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10431
10432     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10433     lstrcatA(keypath, usersid);
10434     lstrcatA(keypath, "\\Patches\\");
10435     lstrcatA(keypath, patch_squashed);
10436
10437     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10439
10440     /* UserData Patches key exists */
10441     size = MAX_PATH;
10442     lstrcpyA(val, "apple");
10443     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10444                             MSIINSTALLCONTEXT_USERUNMANAGED,
10445                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10447     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10448     ok(size == 0, "Expected 0, got %d\n", size);
10449
10450     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10451                          (const BYTE *)"pack", 5);
10452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10453
10454     /* LocalPatch value exists */
10455     size = MAX_PATH;
10456     lstrcpyA(val, "apple");
10457     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10458                             MSIINSTALLCONTEXT_USERUNMANAGED,
10459                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10461     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10462     ok(size == 4, "Expected 4, got %d\n", size);
10463
10464     size = MAX_PATH;
10465     lstrcpyA(val, "apple");
10466     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10467                             MSIINSTALLCONTEXT_USERUNMANAGED,
10468                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10470     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10471     ok(size == 10, "Expected 10, got %d\n", size);
10472
10473     RegDeleteValueA(prodpatches, patch_squashed);
10474     RegDeleteKeyA(prodpatches, "");
10475     RegCloseKey(prodpatches);
10476     RegDeleteKeyA(prodkey, "");
10477     RegCloseKey(prodkey);
10478
10479     /* UserData is sufficient for all properties
10480      * except INSTALLPROPERTY_TRANSFORMS
10481      */
10482     size = MAX_PATH;
10483     lstrcpyA(val, "apple");
10484     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10485                             MSIINSTALLCONTEXT_USERUNMANAGED,
10486                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10487     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10488     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10489     ok(size == 4, "Expected 4, got %d\n", size);
10490
10491     /* UserData is sufficient for all properties
10492      * except INSTALLPROPERTY_TRANSFORMS
10493      */
10494     size = MAX_PATH;
10495     lstrcpyA(val, "apple");
10496     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10497                             MSIINSTALLCONTEXT_USERUNMANAGED,
10498                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10499     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10500     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10501     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10502
10503     RegDeleteValueA(udpatch, "LocalPackage");
10504     RegDeleteKeyA(udpatch, "");
10505     RegCloseKey(udpatch);
10506     RegDeleteKeyA(hpatch, "");
10507     RegCloseKey(hpatch);
10508     RegDeleteKeyA(patches, "");
10509     RegCloseKey(patches);
10510     RegDeleteKeyA(props, "");
10511     RegCloseKey(props);
10512     RegDeleteKeyA(udprod, "");
10513     RegCloseKey(udprod);
10514
10515     /* MSIINSTALLCONTEXT_MACHINE */
10516
10517     size = MAX_PATH;
10518     lstrcpyA(val, "apple");
10519     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10520                             MSIINSTALLCONTEXT_MACHINE,
10521                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10522     ok(r == ERROR_UNKNOWN_PRODUCT,
10523        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10524     ok(!lstrcmpA(val, "apple"),
10525        "Expected val to be unchanged, got \"%s\"\n", val);
10526     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10527
10528     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10529     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10530     lstrcatA(keypath, prod_squashed);
10531
10532     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10534
10535     /* local UserData product key exists */
10536     size = MAX_PATH;
10537     lstrcpyA(val, "apple");
10538     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10539                             MSIINSTALLCONTEXT_MACHINE,
10540                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10541     ok(r == ERROR_UNKNOWN_PRODUCT,
10542        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10543     ok(!lstrcmpA(val, "apple"),
10544        "Expected val to be unchanged, got \"%s\"\n", val);
10545     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10546
10547     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10549
10550     /* InstallProperties key exists */
10551     size = MAX_PATH;
10552     lstrcpyA(val, "apple");
10553     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10554                             MSIINSTALLCONTEXT_MACHINE,
10555                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10556     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10557     ok(!lstrcmpA(val, "apple"),
10558        "Expected val to be unchanged, got \"%s\"\n", val);
10559     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10560
10561     res = RegCreateKeyA(udprod, "Patches", &patches);
10562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10563
10564     /* Patches key exists */
10565     size = MAX_PATH;
10566     lstrcpyA(val, "apple");
10567     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10568                             MSIINSTALLCONTEXT_MACHINE,
10569                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10570     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10571     ok(!lstrcmpA(val, "apple"),
10572        "Expected val to be unchanged, got \"%s\"\n", val);
10573     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10574
10575     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10577
10578     /* Patches key exists */
10579     size = MAX_PATH;
10580     lstrcpyA(val, "apple");
10581     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10582                             MSIINSTALLCONTEXT_MACHINE,
10583                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10584     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10585     ok(!lstrcmpA(val, "apple"),
10586        "Expected val to be unchanged, got \"%s\"\n", val);
10587     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10588
10589     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10590     lstrcatA(keypath, prod_squashed);
10591
10592     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10594
10595     /* local product key exists */
10596     size = MAX_PATH;
10597     lstrcpyA(val, "apple");
10598     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10599                             MSIINSTALLCONTEXT_MACHINE,
10600                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10601     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10602     ok(!lstrcmpA(val, "apple"),
10603        "Expected val to be unchanged, got \"%s\"\n", val);
10604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10605
10606     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10608
10609     /* Patches key exists */
10610     size = MAX_PATH;
10611     lstrcpyA(val, "apple");
10612     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10613                             MSIINSTALLCONTEXT_MACHINE,
10614                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10615     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10616     ok(!lstrcmpA(val, "apple"),
10617        "Expected val to be unchanged, got \"%s\"\n", val);
10618     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10619
10620     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10621                          (const BYTE *)"transforms", 11);
10622     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10623
10624     /* specific patch value exists */
10625     size = MAX_PATH;
10626     lstrcpyA(val, "apple");
10627     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10628                             MSIINSTALLCONTEXT_MACHINE,
10629                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10630     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10631     ok(!lstrcmpA(val, "apple"),
10632        "Expected val to be unchanged, got \"%s\"\n", val);
10633     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10634
10635     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10636     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10637     lstrcatA(keypath, patch_squashed);
10638
10639     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10641
10642     /* UserData Patches key exists */
10643     size = MAX_PATH;
10644     lstrcpyA(val, "apple");
10645     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10646                             MSIINSTALLCONTEXT_MACHINE,
10647                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10649     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10650     ok(size == 0, "Expected 0, got %d\n", size);
10651
10652     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10653                          (const BYTE *)"pack", 5);
10654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10655
10656     /* LocalPatch value exists */
10657     size = MAX_PATH;
10658     lstrcpyA(val, "apple");
10659     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10660                             MSIINSTALLCONTEXT_MACHINE,
10661                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10663     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10664     ok(size == 4, "Expected 4, got %d\n", size);
10665
10666     size = MAX_PATH;
10667     lstrcpyA(val, "apple");
10668     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10669                             MSIINSTALLCONTEXT_MACHINE,
10670                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10671     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10672     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10673     ok(size == 10, "Expected 10, got %d\n", size);
10674
10675     RegDeleteValueA(prodpatches, patch_squashed);
10676     RegDeleteKeyA(prodpatches, "");
10677     RegCloseKey(prodpatches);
10678     RegDeleteKeyA(prodkey, "");
10679     RegCloseKey(prodkey);
10680
10681     /* UserData is sufficient for all properties
10682      * except INSTALLPROPERTY_TRANSFORMS
10683      */
10684     size = MAX_PATH;
10685     lstrcpyA(val, "apple");
10686     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10687                             MSIINSTALLCONTEXT_MACHINE,
10688                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10689     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10690     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10691     ok(size == 4, "Expected 4, got %d\n", size);
10692
10693     /* UserData is sufficient for all properties
10694      * except INSTALLPROPERTY_TRANSFORMS
10695      */
10696     size = MAX_PATH;
10697     lstrcpyA(val, "apple");
10698     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10699                             MSIINSTALLCONTEXT_MACHINE,
10700                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10701     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10702     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10703     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10704
10705     RegDeleteValueA(udpatch, "LocalPackage");
10706     RegDeleteKeyA(udpatch, "");
10707     RegCloseKey(udpatch);
10708     RegDeleteKeyA(hpatch, "");
10709     RegCloseKey(hpatch);
10710     RegDeleteKeyA(patches, "");
10711     RegCloseKey(patches);
10712     RegDeleteKeyA(props, "");
10713     RegCloseKey(props);
10714     RegDeleteKeyA(udprod, "");
10715     RegCloseKey(udprod);
10716 }
10717
10718 START_TEST(msi)
10719 {
10720     init_functionpointers();
10721
10722     test_usefeature();
10723     test_null();
10724     test_getcomponentpath();
10725     test_MsiGetFileHash();
10726
10727     if (!pConvertSidToStringSidA)
10728         skip("ConvertSidToStringSidA not implemented\n");
10729     else
10730     {
10731         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10732         test_MsiQueryProductState();
10733         test_MsiQueryFeatureState();
10734         test_MsiQueryComponentState();
10735         test_MsiGetComponentPath();
10736         test_MsiGetProductCode();
10737         test_MsiEnumClients();
10738         test_MsiGetProductInfo();
10739         test_MsiGetProductInfoEx();
10740         test_MsiGetUserInfo();
10741         test_MsiOpenProduct();
10742         test_MsiEnumPatchesEx();
10743         test_MsiEnumPatches();
10744         test_MsiGetPatchInfoEx();
10745     }
10746
10747     test_MsiGetFileVersion();
10748 }