atl80: Added AtlComModuleRegisterServer implementation (based on AtlModuleRegisterSer...
[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 BOOL is_wow64;
33 static const char msifile[] = "winetest.msi";
34
35 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
36 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
37 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
38
39 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
40     (LPCSTR, LPCSTR, LPSTR, DWORD*);
41 static UINT (WINAPI *pMsiGetFileHashA)
42     (LPCSTR, DWORD, PMSIFILEHASHINFO);
43 static UINT (WINAPI *pMsiGetProductInfoExA)
44     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
45 static UINT (WINAPI *pMsiOpenPackageExA)
46     (LPCSTR, DWORD, MSIHANDLE*);
47 static UINT (WINAPI *pMsiOpenPackageExW)
48     (LPCWSTR, DWORD, MSIHANDLE*);
49 static UINT (WINAPI *pMsiEnumPatchesExA)
50     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
51     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
52 static UINT (WINAPI *pMsiQueryComponentStateA)
53     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
54 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
55     (LPCSTR, LPCSTR ,DWORD, DWORD);
56 static UINT (WINAPI *pMsiGetPatchInfoExA)
57     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
58 static UINT (WINAPI *pMsiEnumProductsExA)
59     (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
60 static UINT (WINAPI *pMsiEnumComponentsExA)
61     (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
62
63 static void init_functionpointers(void)
64 {
65     HMODULE hmsi = GetModuleHandleA("msi.dll");
66     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
67     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
68
69 #define GET_PROC(dll, func) \
70     p ## func = (void *)GetProcAddress(dll, #func); \
71     if(!p ## func) \
72       trace("GetProcAddress(%s) failed\n", #func);
73
74     GET_PROC(hmsi, MsiGetComponentPathA)
75     GET_PROC(hmsi, MsiGetFileHashA)
76     GET_PROC(hmsi, MsiGetProductInfoExA)
77     GET_PROC(hmsi, MsiOpenPackageExA)
78     GET_PROC(hmsi, MsiOpenPackageExW)
79     GET_PROC(hmsi, MsiEnumPatchesExA)
80     GET_PROC(hmsi, MsiQueryComponentStateA)
81     GET_PROC(hmsi, MsiUseFeatureExA)
82     GET_PROC(hmsi, MsiGetPatchInfoExA)
83     GET_PROC(hmsi, MsiEnumProductsExA)
84     GET_PROC(hmsi, MsiEnumComponentsExA)
85
86     GET_PROC(hadvapi32, ConvertSidToStringSidA)
87     GET_PROC(hadvapi32, RegDeleteKeyExA)
88     GET_PROC(hkernel32, IsWow64Process)
89
90 #undef GET_PROC
91 }
92
93 static UINT run_query(MSIHANDLE hdb, const char *query)
94 {
95     MSIHANDLE hview = 0;
96     UINT r;
97
98     r = MsiDatabaseOpenView(hdb, query, &hview);
99     if (r != ERROR_SUCCESS)
100         return r;
101
102     r = MsiViewExecute(hview, 0);
103     if (r == ERROR_SUCCESS)
104         r = MsiViewClose(hview);
105     MsiCloseHandle(hview);
106     return r;
107 }
108
109 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
110 {
111     UINT res;
112     MSIHANDLE suminfo;
113
114     /* build summary info */
115     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
116     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
117
118     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
119                                     "Installation Database");
120     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
121
122     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
123                                     "Installation Database");
124     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
125
126     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
127                                     "Wine Hackers");
128     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
129
130     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
131                                     ";1033");
132     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
133
134     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
135                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
136     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
137
138     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
139     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
140
141     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
142     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
143
144     res = MsiSummaryInfoPersist(suminfo);
145     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
146
147     res = MsiCloseHandle(suminfo);
148     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
149
150     return res;
151 }
152
153 static MSIHANDLE create_package_db(LPSTR prodcode)
154 {
155     MSIHANDLE hdb = 0;
156     CHAR query[MAX_PATH];
157     UINT res;
158
159     DeleteFile(msifile);
160
161     /* create an empty database */
162     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
163     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
164     if (res != ERROR_SUCCESS)
165         return hdb;
166
167     res = MsiDatabaseCommit(hdb);
168     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
169
170     set_summary_info(hdb, prodcode);
171
172     res = run_query(hdb,
173             "CREATE TABLE `Directory` ( "
174             "`Directory` CHAR(255) NOT NULL, "
175             "`Directory_Parent` CHAR(255), "
176             "`DefaultDir` CHAR(255) NOT NULL "
177             "PRIMARY KEY `Directory`)");
178     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
179
180     res = run_query(hdb,
181             "CREATE TABLE `Property` ( "
182             "`Property` CHAR(72) NOT NULL, "
183             "`Value` CHAR(255) "
184             "PRIMARY KEY `Property`)");
185     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
186
187     sprintf(query, "INSERT INTO `Property` "
188             "(`Property`, `Value`) "
189             "VALUES( 'ProductCode', '%s' )", prodcode);
190     res = run_query(hdb, query);
191     ok(res == ERROR_SUCCESS , "Failed\n");
192
193     res = MsiDatabaseCommit(hdb);
194     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
195
196     return hdb;
197 }
198
199 static void test_usefeature(void)
200 {
201     INSTALLSTATE r;
202
203     if (!pMsiUseFeatureExA)
204     {
205         win_skip("MsiUseFeatureExA not implemented\n");
206         return;
207     }
208
209     r = MsiQueryFeatureState(NULL,NULL);
210     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
211
212     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
213     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
214
215     r = pMsiUseFeatureExA(NULL,NULL,0,0);
216     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
217
218     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
219     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
220
221     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
222                          NULL, -2, 0 );
223     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
224
225     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
226                          "WORDVIEWFiles", -2, 0 );
227     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
228
229     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
230                          "WORDVIEWFiles", -2, 0 );
231     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
232
233     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
234                          "WORDVIEWFiles", -2, 1 );
235     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
236 }
237
238 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
239 {
240     if (pRegDeleteKeyExA)
241         return pRegDeleteKeyExA( key, subkey, access, 0 );
242     return RegDeleteKeyA( key, subkey );
243 }
244
245 static void test_null(void)
246 {
247     MSIHANDLE hpkg;
248     UINT r;
249     HKEY hkey;
250     DWORD dwType, cbData;
251     LPBYTE lpData = NULL;
252     INSTALLSTATE state;
253     REGSAM access = KEY_ALL_ACCESS;
254
255     if (is_wow64)
256         access |= KEY_WOW64_64KEY;
257
258     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
259     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
260
261     state = MsiQueryProductStateW(NULL);
262     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
263
264     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
265     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
266
267     r = MsiConfigureFeatureW(NULL, NULL, 0);
268     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
269
270     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
271     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
272
273     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
274     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
275
276     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
277     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
278
279     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
280      * necessary registry values */
281
282     /* empty product string */
283     r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
284     if (r == ERROR_ACCESS_DENIED)
285     {
286         skip("Not enough rights to perform tests\n");
287         return;
288     }
289     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
290
291     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
292     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
293     if ( r == ERROR_SUCCESS )
294     {
295         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
296         if (!lpData)
297             skip("Out of memory\n");
298         else
299         {
300             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
301             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
302         }
303     }
304
305     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
306     if (r == ERROR_ACCESS_DENIED)
307     {
308         skip("Not enough rights to perform tests\n");
309         HeapFree(GetProcessHeap(), 0, lpData);
310         RegCloseKey(hkey);
311         return;
312     }
313     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
314
315     r = MsiGetProductInfoA("", "", NULL, NULL);
316     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
317
318     if (lpData)
319     {
320         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
321         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
322
323         HeapFree(GetProcessHeap(), 0, lpData);
324     }
325     else
326     {
327         r = RegDeleteValueA(hkey, NULL);
328         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
329     }
330
331     r = RegCloseKey(hkey);
332     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
333
334     /* empty attribute */
335     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
336                         0, NULL, 0, access, NULL, &hkey, NULL);
337     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
338
339     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
340     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
341
342     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
343     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
344
345     r = RegCloseKey(hkey);
346     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
347
348     r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
349                    access & KEY_WOW64_64KEY);
350     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
351 }
352
353 static void test_getcomponentpath(void)
354 {
355     INSTALLSTATE r;
356     char buffer[0x100];
357     DWORD sz;
358
359     if(!pMsiGetComponentPathA)
360         return;
361
362     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
363     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
364
365     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
366     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
367
368     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
369     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
370
371     sz = sizeof buffer;
372     buffer[0]=0;
373     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
374     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
375
376     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
377         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
378     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
379
380     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
381         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
382     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
383
384     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
385         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
386     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
387
388     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
389                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
390     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
391 }
392
393 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
394 {
395     HANDLE file;
396     DWORD written;
397
398     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
399     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
400     WriteFile(file, data, strlen(data), &written, NULL);
401
402     if (size)
403     {
404         SetFilePointer(file, size, NULL, FILE_BEGIN);
405         SetEndOfFile(file);
406     }
407
408     CloseHandle(file);
409 }
410
411 #define HASHSIZE sizeof(MSIFILEHASHINFO)
412
413 static const struct
414 {
415     LPCSTR data;
416     DWORD size;
417     MSIFILEHASHINFO hash;
418 } hash_data[] =
419 {
420     { "", 0,
421       { HASHSIZE,
422         { 0, 0, 0, 0 },
423       },
424     },
425
426     { "abc", 0,
427       { HASHSIZE,
428         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
429       },
430     },
431
432     { "C:\\Program Files\\msitest\\caesar\n", 0,
433       { HASHSIZE,
434         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
435       },
436     },
437
438     { "C:\\Program Files\\msitest\\caesar\n", 500,
439       { HASHSIZE,
440         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
441       },
442     },
443 };
444
445 static void test_MsiGetFileHash(void)
446 {
447     const char name[] = "msitest.bin";
448     UINT r;
449     MSIFILEHASHINFO hash;
450     DWORD i;
451
452     if (!pMsiGetFileHashA)
453     {
454         win_skip("MsiGetFileHash not implemented\n");
455         return;
456     }
457
458     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
459
460     /* szFilePath is NULL */
461     r = pMsiGetFileHashA(NULL, 0, &hash);
462     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
463
464     /* szFilePath is empty */
465     r = pMsiGetFileHashA("", 0, &hash);
466     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
467        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
468
469     /* szFilePath is nonexistent */
470     r = pMsiGetFileHashA(name, 0, &hash);
471     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
472
473     /* dwOptions is non-zero */
474     r = pMsiGetFileHashA(name, 1, &hash);
475     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
476
477     /* pHash.dwFileHashInfoSize is not correct */
478     hash.dwFileHashInfoSize = 0;
479     r = pMsiGetFileHashA(name, 0, &hash);
480     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
481
482     /* pHash is NULL */
483     r = pMsiGetFileHashA(name, 0, NULL);
484     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
485
486     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
487     {
488         int ret;
489
490         create_file(name, hash_data[i].data, hash_data[i].size);
491
492         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
493         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
494
495         r = pMsiGetFileHashA(name, 0, &hash);
496         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
497
498         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
499         ok(!ret, "Hash incorrect\n");
500
501         DeleteFile(name);
502     }
503 }
504
505 /* copied from dlls/msi/registry.c */
506 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
507 {
508     DWORD i,n=1;
509     GUID guid;
510
511     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
512         return FALSE;
513
514     for(i=0; i<8; i++)
515         out[7-i] = in[n++];
516     n++;
517     for(i=0; i<4; i++)
518         out[11-i] = in[n++];
519     n++;
520     for(i=0; i<4; i++)
521         out[15-i] = in[n++];
522     n++;
523     for(i=0; i<2; i++)
524     {
525         out[17+i*2] = in[n++];
526         out[16+i*2] = in[n++];
527     }
528     n++;
529     for( ; i<8; i++)
530     {
531         out[17+i*2] = in[n++];
532         out[16+i*2] = in[n++];
533     }
534     out[32]=0;
535     return TRUE;
536 }
537
538 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
539 {
540     WCHAR guidW[MAX_PATH];
541     WCHAR squashedW[MAX_PATH];
542     GUID guid;
543     HRESULT hr;
544     int size;
545
546     hr = CoCreateGuid(&guid);
547     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
548
549     size = StringFromGUID2(&guid, guidW, MAX_PATH);
550     ok(size == 39, "Expected 39, got %d\n", hr);
551
552     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
553     if (squashed)
554     {
555         squash_guid(guidW, squashedW);
556         WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
557     }
558 }
559
560 static char *get_user_sid(void)
561 {
562     HANDLE token;
563     DWORD size = 0;
564     TOKEN_USER *user;
565     char *usersid = NULL;
566
567     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
568     GetTokenInformation(token, TokenUser, NULL, size, &size);
569
570     user = HeapAlloc(GetProcessHeap(), 0, size);
571     GetTokenInformation(token, TokenUser, user, size, &size);
572     pConvertSidToStringSidA(user->User.Sid, &usersid);
573     HeapFree(GetProcessHeap(), 0, user);
574
575     CloseHandle(token);
576     return usersid;
577 }
578
579 static void test_MsiQueryProductState(void)
580 {
581     CHAR prodcode[MAX_PATH];
582     CHAR prod_squashed[MAX_PATH];
583     CHAR keypath[MAX_PATH*2];
584     LPSTR usersid;
585     INSTALLSTATE state;
586     LONG res;
587     HKEY userkey, localkey, props;
588     HKEY prodkey;
589     DWORD data, error;
590     REGSAM access = KEY_ALL_ACCESS;
591
592     create_test_guid(prodcode, prod_squashed);
593     usersid = get_user_sid();
594
595     if (is_wow64)
596         access |= KEY_WOW64_64KEY;
597
598     /* NULL prodcode */
599     SetLastError(0xdeadbeef);
600     state = MsiQueryProductStateA(NULL);
601     error = GetLastError();
602     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
603     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
604
605     /* empty prodcode */
606     SetLastError(0xdeadbeef);
607     state = MsiQueryProductStateA("");
608     error = GetLastError();
609     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
610     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
611
612     /* garbage prodcode */
613     SetLastError(0xdeadbeef);
614     state = MsiQueryProductStateA("garbage");
615     error = GetLastError();
616     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
617     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
618
619     /* guid without brackets */
620     SetLastError(0xdeadbeef);
621     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
622     error = GetLastError();
623     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
624     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
625
626     /* guid with brackets */
627     SetLastError(0xdeadbeef);
628     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
629     error = GetLastError();
630     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
631     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
632        "expected ERROR_SUCCESS, got %u\n", error);
633
634     /* same length as guid, but random */
635     SetLastError(0xdeadbeef);
636     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
637     error = GetLastError();
638     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
639     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
640
641     /* MSIINSTALLCONTEXT_USERUNMANAGED */
642
643     SetLastError(0xdeadbeef);
644     state = MsiQueryProductStateA(prodcode);
645     error = GetLastError();
646     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
647     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
648        "expected ERROR_SUCCESS, got %u\n", error);
649
650     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
651     lstrcatA(keypath, prod_squashed);
652
653     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
655
656     /* user product key exists */
657     SetLastError(0xdeadbeef);
658     state = MsiQueryProductStateA(prodcode);
659     error = GetLastError();
660     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
661     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
662        "expected ERROR_SUCCESS, got %u\n", error);
663
664     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
665     lstrcatA(keypath, prodcode);
666
667     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
668     if (res == ERROR_ACCESS_DENIED)
669     {
670         skip("Not enough rights to perform tests\n");
671         RegDeleteKeyA(userkey, "");
672         LocalFree(usersid);
673         return;
674     }
675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
676
677     /* local uninstall key exists */
678     SetLastError(0xdeadbeef);
679     state = MsiQueryProductStateA(prodcode);
680     error = GetLastError();
681     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
682     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
683        "expected ERROR_SUCCESS, got %u\n", error);
684
685     data = 1;
686     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
688
689     /* WindowsInstaller value exists */
690     SetLastError(0xdeadbeef);
691     state = MsiQueryProductStateA(prodcode);
692     error = GetLastError();
693     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
694     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
695        "expected ERROR_SUCCESS, got %u\n", error);
696
697     RegDeleteValueA(localkey, "WindowsInstaller");
698     delete_key(localkey, "", access & KEY_WOW64_64KEY);
699
700     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
701     lstrcatA(keypath, usersid);
702     lstrcatA(keypath, "\\Products\\");
703     lstrcatA(keypath, prod_squashed);
704
705     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
707
708     /* local product key exists */
709     SetLastError(0xdeadbeef);
710     state = MsiQueryProductStateA(prodcode);
711     error = GetLastError();
712     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
713     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
714        "expected ERROR_SUCCESS, got %u\n", error);
715
716     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
717     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
718
719     /* install properties key exists */
720     SetLastError(0xdeadbeef);
721     state = MsiQueryProductStateA(prodcode);
722     error = GetLastError();
723     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
724     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
725        "expected ERROR_SUCCESS, got %u\n", error);
726
727     data = 1;
728     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
730
731     /* WindowsInstaller value exists */
732     SetLastError(0xdeadbeef);
733     state = MsiQueryProductStateA(prodcode);
734     error = GetLastError();
735     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
736     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
737        "expected ERROR_SUCCESS, got %u\n", error);
738
739     data = 2;
740     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
742
743     /* WindowsInstaller value is not 1 */
744     SetLastError(0xdeadbeef);
745     state = MsiQueryProductStateA(prodcode);
746     error = GetLastError();
747     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
748     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
749        "expected ERROR_SUCCESS, got %u\n", error);
750
751     RegDeleteKeyA(userkey, "");
752
753     /* user product key does not exist */
754     SetLastError(0xdeadbeef);
755     state = MsiQueryProductStateA(prodcode);
756     error = GetLastError();
757     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
758     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
759        "expected ERROR_SUCCESS, got %u\n", error);
760
761     RegDeleteValueA(props, "WindowsInstaller");
762     delete_key(props, "", access & KEY_WOW64_64KEY);
763     RegCloseKey(props);
764     delete_key(localkey, "", access & KEY_WOW64_64KEY);
765     RegCloseKey(localkey);
766     RegDeleteKeyA(userkey, "");
767     RegCloseKey(userkey);
768
769     /* MSIINSTALLCONTEXT_USERMANAGED */
770
771     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
772     lstrcatA(keypath, usersid);
773     lstrcatA(keypath, "\\Installer\\Products\\");
774     lstrcatA(keypath, prod_squashed);
775
776     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
778
779     state = MsiQueryProductStateA(prodcode);
780     ok(state == INSTALLSTATE_ADVERTISED,
781        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
782
783     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
784     lstrcatA(keypath, usersid);
785     lstrcatA(keypath, "\\Products\\");
786     lstrcatA(keypath, prod_squashed);
787
788     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
789     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
790
791     state = MsiQueryProductStateA(prodcode);
792     ok(state == INSTALLSTATE_ADVERTISED,
793        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
794
795     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
797
798     state = MsiQueryProductStateA(prodcode);
799     ok(state == INSTALLSTATE_ADVERTISED,
800        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
801
802     data = 1;
803     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
804     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
805
806     /* WindowsInstaller value exists */
807     state = MsiQueryProductStateA(prodcode);
808     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
809
810     RegDeleteValueA(props, "WindowsInstaller");
811     delete_key(props, "", access & KEY_WOW64_64KEY);
812     RegCloseKey(props);
813     delete_key(localkey, "", access & KEY_WOW64_64KEY);
814     RegCloseKey(localkey);
815     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
816     RegCloseKey(prodkey);
817
818     /* MSIINSTALLCONTEXT_MACHINE */
819
820     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
821     lstrcatA(keypath, prod_squashed);
822
823     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
824     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
825
826     state = MsiQueryProductStateA(prodcode);
827     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
828
829     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
830     lstrcatA(keypath, "S-1-5-18\\Products\\");
831     lstrcatA(keypath, prod_squashed);
832
833     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
835
836     state = MsiQueryProductStateA(prodcode);
837     ok(state == INSTALLSTATE_ADVERTISED,
838        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
839
840     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
842
843     state = MsiQueryProductStateA(prodcode);
844     ok(state == INSTALLSTATE_ADVERTISED,
845        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
846
847     data = 1;
848     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
850
851     /* WindowsInstaller value exists */
852     state = MsiQueryProductStateA(prodcode);
853     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
854
855     RegDeleteValueA(props, "WindowsInstaller");
856     delete_key(props, "", access & KEY_WOW64_64KEY);
857     RegCloseKey(props);
858     delete_key(localkey, "", access & KEY_WOW64_64KEY);
859     RegCloseKey(localkey);
860     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
861     RegCloseKey(prodkey);
862
863     LocalFree(usersid);
864 }
865
866 static const char table_enc85[] =
867 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
868 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
869 "yz{}~";
870
871 /*
872  *  Encodes a base85 guid given a GUID pointer
873  *  Caller should provide a 21 character buffer for the encoded string.
874  */
875 static void encode_base85_guid( GUID *guid, LPWSTR str )
876 {
877     unsigned int x, *p, i;
878
879     p = (unsigned int*) guid;
880     for( i=0; i<4; i++ )
881     {
882         x = p[i];
883         *str++ = table_enc85[x%85];
884         x = x/85;
885         *str++ = table_enc85[x%85];
886         x = x/85;
887         *str++ = table_enc85[x%85];
888         x = x/85;
889         *str++ = table_enc85[x%85];
890         x = x/85;
891         *str++ = table_enc85[x%85];
892     }
893     *str = 0;
894 }
895
896 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
897 {
898     WCHAR guidW[MAX_PATH];
899     WCHAR base85W[MAX_PATH];
900     WCHAR squashedW[MAX_PATH];
901     GUID guid;
902     HRESULT hr;
903     int size;
904
905     hr = CoCreateGuid(&guid);
906     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
907
908     size = StringFromGUID2(&guid, guidW, MAX_PATH);
909     ok(size == 39, "Expected 39, got %d\n", hr);
910
911     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
912     encode_base85_guid(&guid, base85W);
913     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
914     squash_guid(guidW, squashedW);
915     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
916 }
917
918 static void test_MsiQueryFeatureState(void)
919 {
920     HKEY userkey, localkey, compkey, compkey2;
921     CHAR prodcode[MAX_PATH];
922     CHAR prod_squashed[MAX_PATH];
923     CHAR component[MAX_PATH];
924     CHAR comp_base85[MAX_PATH];
925     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
926     CHAR keypath[MAX_PATH*2];
927     INSTALLSTATE state;
928     LPSTR usersid;
929     LONG res;
930     REGSAM access = KEY_ALL_ACCESS;
931     DWORD error;
932
933     create_test_guid(prodcode, prod_squashed);
934     compose_base85_guid(component, comp_base85, comp_squashed);
935     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
936     usersid = get_user_sid();
937
938     if (is_wow64)
939         access |= KEY_WOW64_64KEY;
940
941     /* NULL prodcode */
942     SetLastError(0xdeadbeef);
943     state = MsiQueryFeatureStateA(NULL, "feature");
944     error = GetLastError();
945     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
946     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
947
948     /* empty prodcode */
949     SetLastError(0xdeadbeef);
950     state = MsiQueryFeatureStateA("", "feature");
951     error = GetLastError();
952     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
953     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
954
955     /* garbage prodcode */
956     SetLastError(0xdeadbeef);
957     state = MsiQueryFeatureStateA("garbage", "feature");
958     error = GetLastError();
959     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
960     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
961
962     /* guid without brackets */
963     SetLastError(0xdeadbeef);
964     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
965     error = GetLastError();
966     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
967     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
968
969     /* guid with brackets */
970     SetLastError(0xdeadbeef);
971     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
972     error = GetLastError();
973     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
974     ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
975        "expected ERROR_SUCCESS, got %u\n", error);
976
977     /* same length as guid, but random */
978     SetLastError(0xdeadbeef);
979     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
980     error = GetLastError();
981     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
982     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
983
984     /* NULL szFeature */
985     SetLastError(0xdeadbeef);
986     state = MsiQueryFeatureStateA(prodcode, NULL);
987     error = GetLastError();
988     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
989     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
990
991     /* empty szFeature */
992     SetLastError(0xdeadbeef);
993     state = MsiQueryFeatureStateA(prodcode, "");
994     error = GetLastError();
995     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
996     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
997        "expected ERROR_SUCCESS, got %u\n", error);
998
999     /* feature key does not exist yet */
1000     SetLastError(0xdeadbeef);
1001     state = MsiQueryFeatureStateA(prodcode, "feature");
1002     error = GetLastError();
1003     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1004     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1005        "expected ERROR_SUCCESS, got %u\n", error);
1006
1007     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1008
1009     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
1010     lstrcatA(keypath, prod_squashed);
1011
1012     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1014
1015     /* feature key exists */
1016     SetLastError(0xdeadbeef);
1017     state = MsiQueryFeatureStateA(prodcode, "feature");
1018     error = GetLastError();
1019     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1020     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1021        "expected ERROR_SUCCESS, got %u\n", error);
1022
1023     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1025
1026     /* feature value exists */
1027     SetLastError(0xdeadbeef);
1028     state = MsiQueryFeatureStateA(prodcode, "feature");
1029     error = GetLastError();
1030     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1031     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1032        "expected ERROR_SUCCESS, got %u\n", error);
1033
1034     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1035     lstrcatA(keypath, usersid);
1036     lstrcatA(keypath, "\\Products\\");
1037     lstrcatA(keypath, prod_squashed);
1038     lstrcatA(keypath, "\\Features");
1039
1040     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1041     if (res == ERROR_ACCESS_DENIED)
1042     {
1043         skip("Not enough rights to perform tests\n");
1044         RegDeleteKeyA(userkey, "");
1045         RegCloseKey(userkey);
1046         LocalFree(usersid);
1047         return;
1048     }
1049     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1050
1051     /* userdata features key exists */
1052     SetLastError(0xdeadbeef);
1053     state = MsiQueryFeatureStateA(prodcode, "feature");
1054     error = GetLastError();
1055     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1056     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1057        "expected ERROR_SUCCESS, got %u\n", error);
1058
1059     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1061
1062     SetLastError(0xdeadbeef);
1063     state = MsiQueryFeatureStateA(prodcode, "feature");
1064     error = GetLastError();
1065     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1066     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1067        "expected ERROR_SUCCESS, got %u\n", error);
1068
1069     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1071
1072     SetLastError(0xdeadbeef);
1073     state = MsiQueryFeatureStateA(prodcode, "feature");
1074     error = GetLastError();
1075     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1076     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1077        "expected ERROR_SUCCESS, got %u\n", error);
1078
1079     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082     SetLastError(0xdeadbeef);
1083     state = MsiQueryFeatureStateA(prodcode, "feature");
1084     error = GetLastError();
1085     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1086     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1087        "expected ERROR_SUCCESS, got %u\n", error);
1088
1089     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1091
1092     SetLastError(0xdeadbeef);
1093     state = MsiQueryFeatureStateA(prodcode, "feature");
1094     error = GetLastError();
1095     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1096     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1097        "expected ERROR_SUCCESS, got %u\n", error);
1098
1099     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1100     lstrcatA(keypath, usersid);
1101     lstrcatA(keypath, "\\Components\\");
1102     lstrcatA(keypath, comp_squashed);
1103
1104     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1106
1107     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1108     lstrcatA(keypath, usersid);
1109     lstrcatA(keypath, "\\Components\\");
1110     lstrcatA(keypath, comp_squashed2);
1111
1112     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1114
1115     SetLastError(0xdeadbeef);
1116     state = MsiQueryFeatureStateA(prodcode, "feature");
1117     error = GetLastError();
1118     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1119     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1120        "expected ERROR_SUCCESS, got %u\n", error);
1121
1122     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1124
1125     SetLastError(0xdeadbeef);
1126     state = MsiQueryFeatureStateA(prodcode, "feature");
1127     error = GetLastError();
1128     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1129     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1130        "expected ERROR_SUCCESS, got %u\n", error);
1131
1132     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1134
1135     SetLastError(0xdeadbeef);
1136     state = MsiQueryFeatureStateA(prodcode, "feature");
1137     error = GetLastError();
1138     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1139     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1140        "expected ERROR_SUCCESS, got %u\n", error);
1141
1142     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1144
1145     /* INSTALLSTATE_LOCAL */
1146     SetLastError(0xdeadbeef);
1147     state = MsiQueryFeatureStateA(prodcode, "feature");
1148     error = GetLastError();
1149     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1150     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1151        "expected ERROR_SUCCESS, got %u\n", error);
1152
1153     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1155
1156     /* INSTALLSTATE_SOURCE */
1157     SetLastError(0xdeadbeef);
1158     state = MsiQueryFeatureStateA(prodcode, "feature");
1159     error = GetLastError();
1160     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1161     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1162        "expected ERROR_SUCCESS, got %u\n", error);
1163
1164     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1166
1167     /* bad INSTALLSTATE_SOURCE */
1168     SetLastError(0xdeadbeef);
1169     state = MsiQueryFeatureStateA(prodcode, "feature");
1170     error = GetLastError();
1171     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1172     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1173        "expected ERROR_SUCCESS, got %u\n", error);
1174
1175     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1177
1178     /* INSTALLSTATE_SOURCE */
1179     SetLastError(0xdeadbeef);
1180     state = MsiQueryFeatureStateA(prodcode, "feature");
1181     error = GetLastError();
1182     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1183     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1184        "expected ERROR_SUCCESS, got %u\n", error);
1185
1186     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1188
1189     /* bad INSTALLSTATE_SOURCE */
1190     SetLastError(0xdeadbeef);
1191     state = MsiQueryFeatureStateA(prodcode, "feature");
1192     error = GetLastError();
1193     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1194     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1195        "expected ERROR_SUCCESS, got %u\n", error);
1196
1197     RegDeleteValueA(compkey, prod_squashed);
1198     RegDeleteValueA(compkey2, prod_squashed);
1199     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1200     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1201     RegDeleteValueA(localkey, "feature");
1202     RegDeleteValueA(userkey, "feature");
1203     RegDeleteKeyA(userkey, "");
1204     RegCloseKey(compkey);
1205     RegCloseKey(compkey2);
1206     RegCloseKey(localkey);
1207     RegCloseKey(userkey);
1208
1209     /* MSIINSTALLCONTEXT_USERMANAGED */
1210
1211     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1212     lstrcatA(keypath, usersid);
1213     lstrcatA(keypath, "\\Installer\\Features\\");
1214     lstrcatA(keypath, prod_squashed);
1215
1216     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1218
1219     /* feature key exists */
1220     state = MsiQueryFeatureStateA(prodcode, "feature");
1221     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1222
1223     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1225
1226     /* feature value exists */
1227     state = MsiQueryFeatureStateA(prodcode, "feature");
1228     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1229
1230     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1231     lstrcatA(keypath, usersid);
1232     lstrcatA(keypath, "\\Products\\");
1233     lstrcatA(keypath, prod_squashed);
1234     lstrcatA(keypath, "\\Features");
1235
1236     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1238
1239     /* userdata features key exists */
1240     state = MsiQueryFeatureStateA(prodcode, "feature");
1241     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1242
1243     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1245
1246     state = MsiQueryFeatureStateA(prodcode, "feature");
1247     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1248
1249     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1251
1252     state = MsiQueryFeatureStateA(prodcode, "feature");
1253     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1254
1255     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1257
1258     state = MsiQueryFeatureStateA(prodcode, "feature");
1259     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1260
1261     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1263
1264     state = MsiQueryFeatureStateA(prodcode, "feature");
1265     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1266
1267     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1268     lstrcatA(keypath, usersid);
1269     lstrcatA(keypath, "\\Components\\");
1270     lstrcatA(keypath, comp_squashed);
1271
1272     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1274
1275     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1276     lstrcatA(keypath, usersid);
1277     lstrcatA(keypath, "\\Components\\");
1278     lstrcatA(keypath, comp_squashed2);
1279
1280     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1282
1283     state = MsiQueryFeatureStateA(prodcode, "feature");
1284     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1285
1286     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1288
1289     state = MsiQueryFeatureStateA(prodcode, "feature");
1290     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1291
1292     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1294
1295     state = MsiQueryFeatureStateA(prodcode, "feature");
1296     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1297
1298     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1300
1301     state = MsiQueryFeatureStateA(prodcode, "feature");
1302     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1303
1304     RegDeleteValueA(compkey, prod_squashed);
1305     RegDeleteValueA(compkey2, prod_squashed);
1306     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1307     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1308     RegDeleteValueA(localkey, "feature");
1309     RegDeleteValueA(userkey, "feature");
1310     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1311     RegCloseKey(compkey);
1312     RegCloseKey(compkey2);
1313     RegCloseKey(localkey);
1314     RegCloseKey(userkey);
1315
1316     /* MSIINSTALLCONTEXT_MACHINE */
1317
1318     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1319     lstrcatA(keypath, prod_squashed);
1320
1321     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1322     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1323
1324     /* feature key exists */
1325     state = MsiQueryFeatureStateA(prodcode, "feature");
1326     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1327
1328     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1330
1331     /* feature value exists */
1332     state = MsiQueryFeatureStateA(prodcode, "feature");
1333     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1334
1335     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1336     lstrcatA(keypath, "S-1-5-18\\Products\\");
1337     lstrcatA(keypath, prod_squashed);
1338     lstrcatA(keypath, "\\Features");
1339
1340     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1342
1343     /* userdata features key exists */
1344     state = MsiQueryFeatureStateA(prodcode, "feature");
1345     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1346
1347     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1349
1350     state = MsiQueryFeatureStateA(prodcode, "feature");
1351     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1352
1353     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1355
1356     state = MsiQueryFeatureStateA(prodcode, "feature");
1357     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1358
1359     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1361
1362     state = MsiQueryFeatureStateA(prodcode, "feature");
1363     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1364
1365     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1367
1368     state = MsiQueryFeatureStateA(prodcode, "feature");
1369     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1370
1371     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1372     lstrcatA(keypath, "S-1-5-18\\Components\\");
1373     lstrcatA(keypath, comp_squashed);
1374
1375     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1377
1378     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1379     lstrcatA(keypath, "S-1-5-18\\Components\\");
1380     lstrcatA(keypath, comp_squashed2);
1381
1382     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1384
1385     state = MsiQueryFeatureStateA(prodcode, "feature");
1386     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1387
1388     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1390
1391     state = MsiQueryFeatureStateA(prodcode, "feature");
1392     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1393
1394     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1395     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1396
1397     state = MsiQueryFeatureStateA(prodcode, "feature");
1398     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1399
1400     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1401     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1402
1403     state = MsiQueryFeatureStateA(prodcode, "feature");
1404     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1405
1406     RegDeleteValueA(compkey, prod_squashed);
1407     RegDeleteValueA(compkey2, prod_squashed);
1408     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1409     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1410     RegDeleteValueA(localkey, "feature");
1411     RegDeleteValueA(userkey, "feature");
1412     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1413     RegCloseKey(compkey);
1414     RegCloseKey(compkey2);
1415     RegCloseKey(localkey);
1416     RegCloseKey(userkey);
1417     LocalFree(usersid);
1418 }
1419
1420 static void test_MsiQueryComponentState(void)
1421 {
1422     HKEY compkey, prodkey;
1423     CHAR prodcode[MAX_PATH];
1424     CHAR prod_squashed[MAX_PATH];
1425     CHAR component[MAX_PATH];
1426     CHAR comp_base85[MAX_PATH];
1427     CHAR comp_squashed[MAX_PATH];
1428     CHAR keypath[MAX_PATH];
1429     INSTALLSTATE state;
1430     LPSTR usersid;
1431     LONG res;
1432     UINT r;
1433     REGSAM access = KEY_ALL_ACCESS;
1434     DWORD error;
1435
1436     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1437
1438     if (!pMsiQueryComponentStateA)
1439     {
1440         win_skip("MsiQueryComponentStateA not implemented\n");
1441         return;
1442     }
1443
1444     create_test_guid(prodcode, prod_squashed);
1445     compose_base85_guid(component, comp_base85, comp_squashed);
1446     usersid = get_user_sid();
1447
1448     if (is_wow64)
1449         access |= KEY_WOW64_64KEY;
1450
1451     /* NULL szProductCode */
1452     state = MAGIC_ERROR;
1453     SetLastError(0xdeadbeef);
1454     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1455     error = GetLastError();
1456     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1457     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1458     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1459
1460     /* empty szProductCode */
1461     state = MAGIC_ERROR;
1462     SetLastError(0xdeadbeef);
1463     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1464     error = GetLastError();
1465     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1466     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1467     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1468
1469     /* random szProductCode */
1470     state = MAGIC_ERROR;
1471     SetLastError(0xdeadbeef);
1472     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1473     error = GetLastError();
1474     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1475     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1476     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1477
1478     /* GUID-length szProductCode */
1479     state = MAGIC_ERROR;
1480     SetLastError(0xdeadbeef);
1481     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1482     error = GetLastError();
1483     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1484     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1485     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1486
1487     /* GUID-length with brackets */
1488     state = MAGIC_ERROR;
1489     SetLastError(0xdeadbeef);
1490     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1491     error = GetLastError();
1492     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1493     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1494     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1495
1496     /* actual GUID */
1497     state = MAGIC_ERROR;
1498     SetLastError(0xdeadbeef);
1499     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1500     error = GetLastError();
1501     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1502     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1503     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1504
1505     state = MAGIC_ERROR;
1506     SetLastError(0xdeadbeef);
1507     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1508     error = GetLastError();
1509     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1510     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1511     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1512
1513     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1514     lstrcatA(keypath, prod_squashed);
1515
1516     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1517     if (res == ERROR_ACCESS_DENIED)
1518     {
1519         skip("Not enough rights to perform tests\n");
1520         LocalFree(usersid);
1521         return;
1522     }
1523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1524
1525     state = MAGIC_ERROR;
1526     SetLastError(0xdeadbeef);
1527     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1528     error = GetLastError();
1529     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1530     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1531     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1532
1533     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1534     RegCloseKey(prodkey);
1535
1536     /* create local system product key */
1537     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1538     lstrcatA(keypath, prod_squashed);
1539     lstrcatA(keypath, "\\InstallProperties");
1540
1541     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1543
1544     /* local system product key exists */
1545     state = MAGIC_ERROR;
1546     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1547     error = GetLastError();
1548     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1549     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1550     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1551
1552     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1554
1555     /* LocalPackage value exists */
1556     state = MAGIC_ERROR;
1557     SetLastError(0xdeadbeef);
1558     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1559     error = GetLastError();
1560     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1561     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1562     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1563
1564     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1565     lstrcatA(keypath, comp_squashed);
1566
1567     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1569
1570     /* component key exists */
1571     state = MAGIC_ERROR;
1572     SetLastError(0xdeadbeef);
1573     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1574     error = GetLastError();
1575     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1576     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1577     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1578
1579     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1580     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1581
1582     /* component\product exists */
1583     state = MAGIC_ERROR;
1584     SetLastError(0xdeadbeef);
1585     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1586     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1587     error = GetLastError();
1588     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1589        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1590     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1591
1592     /* NULL component, product exists */
1593     state = MAGIC_ERROR;
1594     SetLastError(0xdeadbeef);
1595     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1596     error = GetLastError();
1597     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1598     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1599     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1600
1601     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1603
1604     /* INSTALLSTATE_LOCAL */
1605     state = MAGIC_ERROR;
1606     SetLastError(0xdeadbeef);
1607     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1608     error = GetLastError();
1609     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1610     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1611     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1612
1613     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1615
1616     /* INSTALLSTATE_SOURCE */
1617     state = MAGIC_ERROR;
1618     SetLastError(0xdeadbeef);
1619     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1620     error = GetLastError();
1621     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1622     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1623     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1624
1625     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1627
1628     /* bad INSTALLSTATE_SOURCE */
1629     state = MAGIC_ERROR;
1630     SetLastError(0xdeadbeef);
1631     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1632     error = GetLastError();
1633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1634     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1635     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1636
1637     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1639
1640     /* INSTALLSTATE_SOURCE */
1641     state = MAGIC_ERROR;
1642     SetLastError(0xdeadbeef);
1643     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1644     error = GetLastError();
1645     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1646     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1647     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1648
1649     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
1650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1651
1652     /* registry component */
1653     state = MAGIC_ERROR;
1654     SetLastError(0xdeadbeef);
1655     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1656     error = GetLastError();
1657     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1658     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1659     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1660
1661     RegDeleteValueA(prodkey, "LocalPackage");
1662     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1663     RegDeleteValueA(compkey, prod_squashed);
1664     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1665     RegCloseKey(prodkey);
1666     RegCloseKey(compkey);
1667
1668     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1669
1670     state = MAGIC_ERROR;
1671     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1672     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1673     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1674
1675     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1676     lstrcatA(keypath, prod_squashed);
1677
1678     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1680
1681     state = MAGIC_ERROR;
1682     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1683     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1684     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1685
1686     RegDeleteKeyA(prodkey, "");
1687     RegCloseKey(prodkey);
1688
1689     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1690     lstrcatA(keypath, usersid);
1691     lstrcatA(keypath, "\\Products\\");
1692     lstrcatA(keypath, prod_squashed);
1693     lstrcatA(keypath, "\\InstallProperties");
1694
1695     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1697
1698     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1700
1701     RegCloseKey(prodkey);
1702
1703     state = MAGIC_ERROR;
1704     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1705     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1706     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1707
1708     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1709     lstrcatA(keypath, usersid);
1710     lstrcatA(keypath, "\\Components\\");
1711     lstrcatA(keypath, comp_squashed);
1712
1713     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1715
1716     /* component key exists */
1717     state = MAGIC_ERROR;
1718     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1719     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1720     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1721
1722     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1723     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1724
1725     /* component\product exists */
1726     state = MAGIC_ERROR;
1727     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1728     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1729     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1730        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1731
1732     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1734
1735     state = MAGIC_ERROR;
1736     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1738     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1739
1740     /* MSIINSTALLCONTEXT_USERMANAGED */
1741
1742     state = MAGIC_ERROR;
1743     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1744     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1745     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1746
1747     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1748     lstrcatA(keypath, prod_squashed);
1749
1750     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1752
1753     state = MAGIC_ERROR;
1754     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1755     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1756     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1757
1758     RegDeleteKeyA(prodkey, "");
1759     RegCloseKey(prodkey);
1760
1761     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1762     lstrcatA(keypath, usersid);
1763     lstrcatA(keypath, "\\Installer\\Products\\");
1764     lstrcatA(keypath, prod_squashed);
1765
1766     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1768
1769     state = MAGIC_ERROR;
1770     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1771     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1772     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1773
1774     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1775     RegCloseKey(prodkey);
1776
1777     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1778     lstrcatA(keypath, usersid);
1779     lstrcatA(keypath, "\\Products\\");
1780     lstrcatA(keypath, prod_squashed);
1781     lstrcatA(keypath, "\\InstallProperties");
1782
1783     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1785
1786     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1788
1789     state = MAGIC_ERROR;
1790     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1791     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1792     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1793
1794     RegDeleteValueA(prodkey, "LocalPackage");
1795     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1796     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1797     RegDeleteValueA(compkey, prod_squashed);
1798     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1799     RegCloseKey(prodkey);
1800     RegCloseKey(compkey);
1801     LocalFree(usersid);
1802 }
1803
1804 static void test_MsiGetComponentPath(void)
1805 {
1806     HKEY compkey, prodkey, installprop;
1807     CHAR prodcode[MAX_PATH];
1808     CHAR prod_squashed[MAX_PATH];
1809     CHAR component[MAX_PATH];
1810     CHAR comp_base85[MAX_PATH];
1811     CHAR comp_squashed[MAX_PATH];
1812     CHAR keypath[MAX_PATH];
1813     CHAR path[MAX_PATH];
1814     INSTALLSTATE state;
1815     LPSTR usersid;
1816     DWORD size, val;
1817     REGSAM access = KEY_ALL_ACCESS;
1818     LONG res;
1819
1820     create_test_guid(prodcode, prod_squashed);
1821     compose_base85_guid(component, comp_base85, comp_squashed);
1822     usersid = get_user_sid();
1823
1824     if (is_wow64)
1825         access |= KEY_WOW64_64KEY;
1826
1827     /* NULL szProduct */
1828     size = MAX_PATH;
1829     state = MsiGetComponentPathA(NULL, component, path, &size);
1830     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1831     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1832
1833     /* NULL szComponent */
1834     size = MAX_PATH;
1835     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1836     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1837     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1838
1839     size = MAX_PATH;
1840     state = MsiLocateComponentA(NULL, path, &size);
1841     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1842     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1843
1844     /* NULL lpPathBuf */
1845     size = MAX_PATH;
1846     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1847     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1848     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1849
1850     size = MAX_PATH;
1851     state = MsiLocateComponentA(component, NULL, &size);
1852     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1853     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1854
1855     /* NULL pcchBuf */
1856     size = MAX_PATH;
1857     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1858     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1859     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1860
1861     size = MAX_PATH;
1862     state = MsiLocateComponentA(component, path, NULL);
1863     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1864     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1865
1866     /* all params valid */
1867     size = MAX_PATH;
1868     state = MsiGetComponentPathA(prodcode, component, path, &size);
1869     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1870     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1871
1872     size = MAX_PATH;
1873     state = MsiLocateComponentA(component, path, &size);
1874     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1875     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1876
1877     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1878     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1879     lstrcatA(keypath, comp_squashed);
1880
1881     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1882     if (res == ERROR_ACCESS_DENIED)
1883     {
1884         skip("Not enough rights to perform tests\n");
1885         LocalFree(usersid);
1886         return;
1887     }
1888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1889
1890     /* local system component key exists */
1891     size = MAX_PATH;
1892     state = MsiGetComponentPathA(prodcode, component, path, &size);
1893     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1894     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1895
1896     size = MAX_PATH;
1897     state = MsiLocateComponentA(component, path, &size);
1898     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1899     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1900
1901     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1903
1904     /* product value exists */
1905     path[0] = 0;
1906     size = MAX_PATH;
1907     state = MsiGetComponentPathA(prodcode, component, path, &size);
1908     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1909     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1910     ok(size == 10, "Expected 10, got %d\n", size);
1911
1912     path[0] = 0;
1913     size = MAX_PATH;
1914     state = MsiLocateComponentA(component, path, &size);
1915     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1916     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1917     ok(size == 10, "Expected 10, got %d\n", size);
1918
1919     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1920     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1921     lstrcatA(keypath, prod_squashed);
1922     lstrcatA(keypath, "\\InstallProperties");
1923
1924     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1926
1927     val = 1;
1928     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1930
1931     /* install properties key exists */
1932     path[0] = 0;
1933     size = MAX_PATH;
1934     state = MsiGetComponentPathA(prodcode, component, path, &size);
1935     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1936     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1937     ok(size == 10, "Expected 10, got %d\n", size);
1938
1939     path[0] = 0;
1940     size = MAX_PATH;
1941     state = MsiLocateComponentA(component, path, &size);
1942     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1943     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1944     ok(size == 10, "Expected 10, got %d\n", size);
1945
1946     create_file("C:\\imapath", "C:\\imapath", 11);
1947
1948     /* file exists */
1949     path[0] = 0;
1950     size = MAX_PATH;
1951     state = MsiGetComponentPathA(prodcode, component, path, &size);
1952     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1953     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1954     ok(size == 10, "Expected 10, got %d\n", size);
1955
1956     path[0] = 0;
1957     size = MAX_PATH;
1958     state = MsiLocateComponentA(component, path, &size);
1959     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1960     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1961     ok(size == 10, "Expected 10, got %d\n", size);
1962
1963     RegDeleteValueA(compkey, prod_squashed);
1964     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1965     RegDeleteValueA(installprop, "WindowsInstaller");
1966     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1967     RegCloseKey(compkey);
1968     RegCloseKey(installprop);
1969     DeleteFileA("C:\\imapath");
1970
1971     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1972     lstrcatA(keypath, "Installer\\UserData\\");
1973     lstrcatA(keypath, usersid);
1974     lstrcatA(keypath, "\\Components\\");
1975     lstrcatA(keypath, comp_squashed);
1976
1977     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1978     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1979
1980     /* user managed component key exists */
1981     size = MAX_PATH;
1982     state = MsiGetComponentPathA(prodcode, component, path, &size);
1983     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1984     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1985
1986     size = MAX_PATH;
1987     state = MsiLocateComponentA(component, path, &size);
1988     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1989     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1990
1991     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1993
1994     /* product value exists */
1995     path[0] = 0;
1996     size = MAX_PATH;
1997     state = MsiGetComponentPathA(prodcode, component, path, &size);
1998     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1999     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2000     ok(size == 10, "Expected 10, got %d\n", size);
2001
2002     path[0] = 0;
2003     size = MAX_PATH;
2004     state = MsiLocateComponentA(component, path, &size);
2005     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2006     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2007     ok(size == 10, "Expected 10, got %d\n", size);
2008
2009     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2010     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2011     lstrcatA(keypath, prod_squashed);
2012     lstrcatA(keypath, "\\InstallProperties");
2013
2014     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2015     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2016
2017     val = 1;
2018     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2020
2021     /* install properties key exists */
2022     path[0] = 0;
2023     size = MAX_PATH;
2024     state = MsiGetComponentPathA(prodcode, component, path, &size);
2025     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2026     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2027     ok(size == 10, "Expected 10, got %d\n", size);
2028
2029     path[0] = 0;
2030     size = MAX_PATH;
2031     state = MsiLocateComponentA(component, path, &size);
2032     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2033     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2034     ok(size == 10, "Expected 10, got %d\n", size);
2035
2036     create_file("C:\\imapath", "C:\\imapath", 11);
2037
2038     /* file exists */
2039     path[0] = 0;
2040     size = MAX_PATH;
2041     state = MsiGetComponentPathA(prodcode, component, path, &size);
2042     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2043     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2044     ok(size == 10, "Expected 10, got %d\n", size);
2045
2046     path[0] = 0;
2047     size = MAX_PATH;
2048     state = MsiLocateComponentA(component, path, &size);
2049     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2050     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2051     ok(size == 10, "Expected 10, got %d\n", size);
2052
2053     RegDeleteValueA(compkey, prod_squashed);
2054     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2055     RegDeleteValueA(installprop, "WindowsInstaller");
2056     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2057     RegCloseKey(compkey);
2058     RegCloseKey(installprop);
2059     DeleteFileA("C:\\imapath");
2060
2061     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2062     lstrcatA(keypath, "Installer\\Managed\\");
2063     lstrcatA(keypath, usersid);
2064     lstrcatA(keypath, "\\Installer\\Products\\");
2065     lstrcatA(keypath, prod_squashed);
2066
2067     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2069
2070     /* user managed product key exists */
2071     size = MAX_PATH;
2072     state = MsiGetComponentPathA(prodcode, component, path, &size);
2073     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2074     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2075
2076     size = MAX_PATH;
2077     state = MsiLocateComponentA(component, path, &size);
2078     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2079     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2080
2081     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2082     lstrcatA(keypath, "Installer\\UserData\\");
2083     lstrcatA(keypath, usersid);
2084     lstrcatA(keypath, "\\Components\\");
2085     lstrcatA(keypath, comp_squashed);
2086
2087     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2088     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2089
2090     /* user managed component key exists */
2091     size = MAX_PATH;
2092     state = MsiGetComponentPathA(prodcode, component, path, &size);
2093     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2094     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2095
2096     size = MAX_PATH;
2097     state = MsiLocateComponentA(component, path, &size);
2098     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2099     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2100
2101     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2103
2104     /* product value exists */
2105     path[0] = 0;
2106     size = MAX_PATH;
2107     state = MsiGetComponentPathA(prodcode, component, path, &size);
2108     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2109     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2110     ok(size == 10, "Expected 10, got %d\n", size);
2111
2112     path[0] = 0;
2113     size = MAX_PATH;
2114     state = MsiLocateComponentA(component, path, &size);
2115     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2116     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2117     ok(size == 10, "Expected 10, got %d\n", size);
2118
2119     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2120     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2121     lstrcatA(keypath, prod_squashed);
2122     lstrcatA(keypath, "\\InstallProperties");
2123
2124     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2126
2127     val = 1;
2128     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2130
2131     /* install properties key exists */
2132     path[0] = 0;
2133     size = MAX_PATH;
2134     state = MsiGetComponentPathA(prodcode, component, path, &size);
2135     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2136     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2137     ok(size == 10, "Expected 10, got %d\n", size);
2138
2139     path[0] = 0;
2140     size = MAX_PATH;
2141     state = MsiLocateComponentA(component, path, &size);
2142     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2143     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2144     ok(size == 10, "Expected 10, got %d\n", size);
2145
2146     create_file("C:\\imapath", "C:\\imapath", 11);
2147
2148     /* file exists */
2149     path[0] = 0;
2150     size = MAX_PATH;
2151     state = MsiGetComponentPathA(prodcode, component, path, &size);
2152     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2153     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2154     ok(size == 10, "Expected 10, got %d\n", size);
2155
2156     path[0] = 0;
2157     size = MAX_PATH;
2158     state = MsiLocateComponentA(component, path, &size);
2159     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2160     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2161     ok(size == 10, "Expected 10, got %d\n", size);
2162
2163     RegDeleteValueA(compkey, prod_squashed);
2164     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2165     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2166     RegDeleteValueA(installprop, "WindowsInstaller");
2167     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2168     RegCloseKey(prodkey);
2169     RegCloseKey(compkey);
2170     RegCloseKey(installprop);
2171     DeleteFileA("C:\\imapath");
2172
2173     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2174     lstrcatA(keypath, prod_squashed);
2175
2176     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2178
2179     /* user unmanaged product key exists */
2180     size = MAX_PATH;
2181     state = MsiGetComponentPathA(prodcode, component, path, &size);
2182     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2183     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2184
2185     size = MAX_PATH;
2186     state = MsiLocateComponentA(component, path, &size);
2187     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2188     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2189
2190     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2191     lstrcatA(keypath, "Installer\\UserData\\");
2192     lstrcatA(keypath, usersid);
2193     lstrcatA(keypath, "\\Components\\");
2194     lstrcatA(keypath, comp_squashed);
2195
2196     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2198
2199     /* user unmanaged component key exists */
2200     size = MAX_PATH;
2201     state = MsiGetComponentPathA(prodcode, component, path, &size);
2202     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2203     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2204
2205     size = MAX_PATH;
2206     state = MsiLocateComponentA(component, path, &size);
2207     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2208     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2209
2210     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2212
2213     /* product value exists */
2214     path[0] = 0;
2215     size = MAX_PATH;
2216     state = MsiGetComponentPathA(prodcode, component, path, &size);
2217     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2218     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2219     ok(size == 10, "Expected 10, got %d\n", size);
2220
2221     path[0] = 0;
2222     size = MAX_PATH;
2223     state = MsiLocateComponentA(component, path, &size);
2224     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2225     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2226     ok(size == 10, "Expected 10, got %d\n", size);
2227
2228     create_file("C:\\imapath", "C:\\imapath", 11);
2229
2230     /* file exists */
2231     path[0] = 0;
2232     size = MAX_PATH;
2233     state = MsiGetComponentPathA(prodcode, component, path, &size);
2234     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2235     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2236     ok(size == 10, "Expected 10, got %d\n", size);
2237
2238     path[0] = 0;
2239     size = MAX_PATH;
2240     state = MsiLocateComponentA(component, path, &size);
2241     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2242     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2243     ok(size == 10, "Expected 10, got %d\n", size);
2244
2245     RegDeleteValueA(compkey, prod_squashed);
2246     RegDeleteKeyA(prodkey, "");
2247     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2248     RegCloseKey(prodkey);
2249     RegCloseKey(compkey);
2250     DeleteFileA("C:\\imapath");
2251
2252     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2253     lstrcatA(keypath, prod_squashed);
2254
2255     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2257
2258     /* local classes product key exists */
2259     size = MAX_PATH;
2260     state = MsiGetComponentPathA(prodcode, component, path, &size);
2261     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2262     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2263
2264     size = MAX_PATH;
2265     state = MsiLocateComponentA(component, path, &size);
2266     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2267     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2268
2269     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2270     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2271     lstrcatA(keypath, comp_squashed);
2272
2273     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2275
2276     /* local user component key exists */
2277     size = MAX_PATH;
2278     state = MsiGetComponentPathA(prodcode, component, path, &size);
2279     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2280     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2281
2282     size = MAX_PATH;
2283     state = MsiLocateComponentA(component, path, &size);
2284     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2285     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2286
2287     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2289
2290     /* product value exists */
2291     path[0] = 0;
2292     size = MAX_PATH;
2293     state = MsiGetComponentPathA(prodcode, component, path, &size);
2294     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2295     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2296     ok(size == 10, "Expected 10, got %d\n", size);
2297
2298     path[0] = 0;
2299     size = MAX_PATH;
2300     state = MsiLocateComponentA(component, path, &size);
2301     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2302     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2303     ok(size == 10, "Expected 10, got %d\n", size);
2304
2305     create_file("C:\\imapath", "C:\\imapath", 11);
2306
2307     /* file exists */
2308     path[0] = 0;
2309     size = MAX_PATH;
2310     state = MsiGetComponentPathA(prodcode, component, path, &size);
2311     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2312     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2313     ok(size == 10, "Expected 10, got %d\n", size);
2314
2315     path[0] = 0;
2316     size = MAX_PATH;
2317     state = MsiLocateComponentA(component, path, &size);
2318     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2319     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2320     ok(size == 10, "Expected 10, got %d\n", size);
2321
2322     RegDeleteValueA(compkey, prod_squashed);
2323     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2324     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2325     RegCloseKey(prodkey);
2326     RegCloseKey(compkey);
2327     DeleteFileA("C:\\imapath");
2328     LocalFree(usersid);
2329 }
2330
2331 static void test_MsiGetProductCode(void)
2332 {
2333     HKEY compkey, prodkey;
2334     CHAR prodcode[MAX_PATH];
2335     CHAR prod_squashed[MAX_PATH];
2336     CHAR prodcode2[MAX_PATH];
2337     CHAR prod2_squashed[MAX_PATH];
2338     CHAR component[MAX_PATH];
2339     CHAR comp_base85[MAX_PATH];
2340     CHAR comp_squashed[MAX_PATH];
2341     CHAR keypath[MAX_PATH];
2342     CHAR product[MAX_PATH];
2343     LPSTR usersid;
2344     LONG res;
2345     UINT r;
2346     REGSAM access = KEY_ALL_ACCESS;
2347
2348     create_test_guid(prodcode, prod_squashed);
2349     create_test_guid(prodcode2, prod2_squashed);
2350     compose_base85_guid(component, comp_base85, comp_squashed);
2351     usersid = get_user_sid();
2352
2353     if (is_wow64)
2354         access |= KEY_WOW64_64KEY;
2355
2356     /* szComponent is NULL */
2357     lstrcpyA(product, "prod");
2358     r = MsiGetProductCodeA(NULL, product);
2359     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2360     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2361
2362     /* szComponent is empty */
2363     lstrcpyA(product, "prod");
2364     r = MsiGetProductCodeA("", product);
2365     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2366     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2367
2368     /* garbage szComponent */
2369     lstrcpyA(product, "prod");
2370     r = MsiGetProductCodeA("garbage", product);
2371     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2372     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2373
2374     /* guid without brackets */
2375     lstrcpyA(product, "prod");
2376     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2377     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2378     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2379
2380     /* guid with brackets */
2381     lstrcpyA(product, "prod");
2382     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2383     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2384     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2385
2386     /* same length as guid, but random */
2387     lstrcpyA(product, "prod");
2388     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2389     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2390     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2391
2392     /* all params correct, szComponent not published */
2393     lstrcpyA(product, "prod");
2394     r = MsiGetProductCodeA(component, product);
2395     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2396     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2397
2398     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2399     lstrcatA(keypath, "Installer\\UserData\\");
2400     lstrcatA(keypath, usersid);
2401     lstrcatA(keypath, "\\Components\\");
2402     lstrcatA(keypath, comp_squashed);
2403
2404     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2405     if (res == ERROR_ACCESS_DENIED)
2406     {
2407         skip("Not enough rights to perform tests\n");
2408         LocalFree(usersid);
2409         return;
2410     }
2411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2412
2413     /* user unmanaged component key exists */
2414     lstrcpyA(product, "prod");
2415     r = MsiGetProductCodeA(component, product);
2416     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2417     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2418
2419     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2421
2422     /* product value exists */
2423     lstrcpyA(product, "prod");
2424     r = MsiGetProductCodeA(component, product);
2425     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2426     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2427
2428     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2430
2431     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2432     lstrcatA(keypath, "Installer\\Managed\\");
2433     lstrcatA(keypath, usersid);
2434     lstrcatA(keypath, "\\Installer\\Products\\");
2435     lstrcatA(keypath, prod_squashed);
2436
2437     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2439
2440     /* user managed product key of first product exists */
2441     lstrcpyA(product, "prod");
2442     r = MsiGetProductCodeA(component, product);
2443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2444     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2445
2446     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2447     RegCloseKey(prodkey);
2448
2449     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2450     lstrcatA(keypath, prod_squashed);
2451
2452     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2454
2455     /* user unmanaged product key exists */
2456     lstrcpyA(product, "prod");
2457     r = MsiGetProductCodeA(component, product);
2458     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2459     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2460
2461     RegDeleteKeyA(prodkey, "");
2462     RegCloseKey(prodkey);
2463
2464     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2465     lstrcatA(keypath, prod_squashed);
2466
2467     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2469
2470     /* local classes product key exists */
2471     lstrcpyA(product, "prod");
2472     r = MsiGetProductCodeA(component, product);
2473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2474     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2475
2476     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2477     RegCloseKey(prodkey);
2478
2479     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2480     lstrcatA(keypath, "Installer\\Managed\\");
2481     lstrcatA(keypath, usersid);
2482     lstrcatA(keypath, "\\Installer\\Products\\");
2483     lstrcatA(keypath, prod2_squashed);
2484
2485     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2487
2488     /* user managed product key of second product exists */
2489     lstrcpyA(product, "prod");
2490     r = MsiGetProductCodeA(component, product);
2491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2492     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2493
2494     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2495     RegCloseKey(prodkey);
2496     RegDeleteValueA(compkey, prod_squashed);
2497     RegDeleteValueA(compkey, prod2_squashed);
2498     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2499     RegCloseKey(compkey);
2500
2501     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2502     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2503     lstrcatA(keypath, comp_squashed);
2504
2505     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2507
2508     /* local user component key exists */
2509     lstrcpyA(product, "prod");
2510     r = MsiGetProductCodeA(component, product);
2511     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2512     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2513
2514     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2516
2517     /* product value exists */
2518     lstrcpyA(product, "prod");
2519     r = MsiGetProductCodeA(component, product);
2520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2521     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2522
2523     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2525
2526     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2527     lstrcatA(keypath, "Installer\\Managed\\");
2528     lstrcatA(keypath, usersid);
2529     lstrcatA(keypath, "\\Installer\\Products\\");
2530     lstrcatA(keypath, prod_squashed);
2531
2532     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2534
2535     /* user managed product key of first product exists */
2536     lstrcpyA(product, "prod");
2537     r = MsiGetProductCodeA(component, product);
2538     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2539     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2540
2541     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2542     RegCloseKey(prodkey);
2543
2544     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2545     lstrcatA(keypath, prod_squashed);
2546
2547     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2549
2550     /* user unmanaged product key exists */
2551     lstrcpyA(product, "prod");
2552     r = MsiGetProductCodeA(component, product);
2553     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2554     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2555
2556     RegDeleteKeyA(prodkey, "");
2557     RegCloseKey(prodkey);
2558
2559     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2560     lstrcatA(keypath, prod_squashed);
2561
2562     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2564
2565     /* local classes product key exists */
2566     lstrcpyA(product, "prod");
2567     r = MsiGetProductCodeA(component, product);
2568     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2569     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2570
2571     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2572     RegCloseKey(prodkey);
2573
2574     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2575     lstrcatA(keypath, "Installer\\Managed\\");
2576     lstrcatA(keypath, usersid);
2577     lstrcatA(keypath, "\\Installer\\Products\\");
2578     lstrcatA(keypath, prod2_squashed);
2579
2580     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2582
2583     /* user managed product key of second product exists */
2584     lstrcpyA(product, "prod");
2585     r = MsiGetProductCodeA(component, product);
2586     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2587     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2588
2589     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2590     RegCloseKey(prodkey);
2591     RegDeleteValueA(compkey, prod_squashed);
2592     RegDeleteValueA(compkey, prod2_squashed);
2593     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2594     RegCloseKey(compkey);
2595     LocalFree(usersid);
2596 }
2597
2598 static void test_MsiEnumClients(void)
2599 {
2600     HKEY compkey;
2601     CHAR prodcode[MAX_PATH];
2602     CHAR prod_squashed[MAX_PATH];
2603     CHAR prodcode2[MAX_PATH];
2604     CHAR prod2_squashed[MAX_PATH];
2605     CHAR component[MAX_PATH];
2606     CHAR comp_base85[MAX_PATH];
2607     CHAR comp_squashed[MAX_PATH];
2608     CHAR product[MAX_PATH];
2609     CHAR keypath[MAX_PATH];
2610     LPSTR usersid;
2611     LONG res;
2612     UINT r;
2613     REGSAM access = KEY_ALL_ACCESS;
2614
2615     create_test_guid(prodcode, prod_squashed);
2616     create_test_guid(prodcode2, prod2_squashed);
2617     compose_base85_guid(component, comp_base85, comp_squashed);
2618     usersid = get_user_sid();
2619
2620     if (is_wow64)
2621         access |= KEY_WOW64_64KEY;
2622
2623     /* NULL szComponent */
2624     product[0] = '\0';
2625     r = MsiEnumClientsA(NULL, 0, product);
2626     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2627     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2628
2629     /* empty szComponent */
2630     product[0] = '\0';
2631     r = MsiEnumClientsA("", 0, product);
2632     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2633     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2634
2635     /* NULL lpProductBuf */
2636     r = MsiEnumClientsA(component, 0, NULL);
2637     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2638
2639     /* all params correct, component missing */
2640     product[0] = '\0';
2641     r = MsiEnumClientsA(component, 0, product);
2642     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2643     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2644
2645     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2646     lstrcatA(keypath, "Installer\\UserData\\");
2647     lstrcatA(keypath, usersid);
2648     lstrcatA(keypath, "\\Components\\");
2649     lstrcatA(keypath, comp_squashed);
2650
2651     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2652     if (res == ERROR_ACCESS_DENIED)
2653     {
2654         skip("Not enough rights to perform tests\n");
2655         LocalFree(usersid);
2656         return;
2657     }
2658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2659
2660     /* user unmanaged component key exists */
2661     product[0] = '\0';
2662     r = MsiEnumClientsA(component, 0, product);
2663     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2664     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2665
2666     /* index > 0, no products exist */
2667     product[0] = '\0';
2668     r = MsiEnumClientsA(component, 1, product);
2669     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2670     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2671
2672     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2674
2675     /* product value exists */
2676     r = MsiEnumClientsA(component, 0, product);
2677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2678     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2679
2680     /* try index 0 again */
2681     product[0] = '\0';
2682     r = MsiEnumClientsA(component, 0, product);
2683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2684     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2685
2686     /* try index 1, second product value does not exist */
2687     product[0] = '\0';
2688     r = MsiEnumClientsA(component, 1, product);
2689     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2690     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2691
2692     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2694
2695     /* try index 1, second product value does exist */
2696     product[0] = '\0';
2697     r = MsiEnumClientsA(component, 1, product);
2698     todo_wine
2699     {
2700         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2701         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2702     }
2703
2704     /* start the enumeration over */
2705     product[0] = '\0';
2706     r = MsiEnumClientsA(component, 0, product);
2707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2708     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2709        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2710
2711     /* correctly query second product */
2712     product[0] = '\0';
2713     r = MsiEnumClientsA(component, 1, product);
2714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2715     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2716        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2717
2718     RegDeleteValueA(compkey, prod_squashed);
2719     RegDeleteValueA(compkey, prod2_squashed);
2720     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2721     RegCloseKey(compkey);
2722
2723     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2724     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2725     lstrcatA(keypath, comp_squashed);
2726
2727     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2729
2730     /* user local component key exists */
2731     product[0] = '\0';
2732     r = MsiEnumClientsA(component, 0, product);
2733     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2734     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2735
2736     /* index > 0, no products exist */
2737     product[0] = '\0';
2738     r = MsiEnumClientsA(component, 1, product);
2739     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2740     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2741
2742     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2744
2745     /* product value exists */
2746     product[0] = '\0';
2747     r = MsiEnumClientsA(component, 0, product);
2748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2749     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2750
2751     /* try index 0 again */
2752     product[0] = '\0';
2753     r = MsiEnumClientsA(component, 0, product);
2754     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2755
2756     /* try index 1, second product value does not exist */
2757     product[0] = '\0';
2758     r = MsiEnumClientsA(component, 1, product);
2759     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2760     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2761
2762     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2764
2765     /* try index 1, second product value does exist */
2766     product[0] = '\0';
2767     r = MsiEnumClientsA(component, 1, product);
2768     todo_wine
2769     {
2770         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2771         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2772     }
2773
2774     /* start the enumeration over */
2775     product[0] = '\0';
2776     r = MsiEnumClientsA(component, 0, product);
2777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2778     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2779        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2780
2781     /* correctly query second product */
2782     product[0] = '\0';
2783     r = MsiEnumClientsA(component, 1, product);
2784     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2785     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2786        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2787
2788     RegDeleteValueA(compkey, prod_squashed);
2789     RegDeleteValueA(compkey, prod2_squashed);
2790     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2791     RegCloseKey(compkey);
2792     LocalFree(usersid);
2793 }
2794
2795 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2796                              LPSTR *langcheck, LPDWORD langchecksz)
2797 {
2798     LPSTR version;
2799     VS_FIXEDFILEINFO *ffi;
2800     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2801     USHORT *lang;
2802
2803     version = HeapAlloc(GetProcessHeap(), 0, size);
2804     GetFileVersionInfoA(path, 0, size, version);
2805
2806     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2807     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2808     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2809             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2810             LOWORD(ffi->dwFileVersionLS));
2811     *verchecksz = lstrlenA(*vercheck);
2812
2813     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2814     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2815     sprintf(*langcheck, "%d", *lang);
2816     *langchecksz = lstrlenA(*langcheck);
2817
2818     HeapFree(GetProcessHeap(), 0, version);
2819 }
2820
2821 static void test_MsiGetFileVersion(void)
2822 {
2823     UINT r;
2824     DWORD versz, langsz;
2825     char version[MAX_PATH];
2826     char lang[MAX_PATH];
2827     char path[MAX_PATH];
2828     LPSTR vercheck, langcheck;
2829     DWORD verchecksz, langchecksz;
2830
2831     /* NULL szFilePath */
2832     versz = MAX_PATH;
2833     langsz = MAX_PATH;
2834     lstrcpyA(version, "version");
2835     lstrcpyA(lang, "lang");
2836     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2837     ok(r == ERROR_INVALID_PARAMETER,
2838        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2839     ok(!lstrcmpA(version, "version"),
2840        "Expected version to be unchanged, got %s\n", version);
2841     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2842     ok(!lstrcmpA(lang, "lang"),
2843        "Expected lang to be unchanged, got %s\n", lang);
2844     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2845
2846     /* empty szFilePath */
2847     versz = MAX_PATH;
2848     langsz = MAX_PATH;
2849     lstrcpyA(version, "version");
2850     lstrcpyA(lang, "lang");
2851     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2852     ok(r == ERROR_FILE_NOT_FOUND,
2853        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2854     ok(!lstrcmpA(version, "version"),
2855        "Expected version to be unchanged, got %s\n", version);
2856     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2857     ok(!lstrcmpA(lang, "lang"),
2858        "Expected lang to be unchanged, got %s\n", lang);
2859     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2860
2861     /* nonexistent szFilePath */
2862     versz = MAX_PATH;
2863     langsz = MAX_PATH;
2864     lstrcpyA(version, "version");
2865     lstrcpyA(lang, "lang");
2866     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2867     ok(r == ERROR_FILE_NOT_FOUND,
2868        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2869     ok(!lstrcmpA(version, "version"),
2870        "Expected version to be unchanged, got %s\n", version);
2871     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2872     ok(!lstrcmpA(lang, "lang"),
2873        "Expected lang to be unchanged, got %s\n", lang);
2874     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2875
2876     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2877     versz = MAX_PATH;
2878     langsz = MAX_PATH;
2879     lstrcpyA(version, "version");
2880     lstrcpyA(lang, "lang");
2881     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2882     ok(r == ERROR_INVALID_PARAMETER,
2883        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2884     ok(!lstrcmpA(version, "version"),
2885        "Expected version to be unchanged, got %s\n", version);
2886     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2887     ok(!lstrcmpA(lang, "lang"),
2888        "Expected lang to be unchanged, got %s\n", lang);
2889     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2890
2891     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2892     versz = MAX_PATH;
2893     langsz = MAX_PATH;
2894     lstrcpyA(version, "version");
2895     lstrcpyA(lang, "lang");
2896     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2897     ok(r == ERROR_INVALID_PARAMETER,
2898        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2899     ok(!lstrcmpA(version, "version"),
2900        "Expected version to be unchanged, got %s\n", version);
2901     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2902     ok(!lstrcmpA(lang, "lang"),
2903        "Expected lang to be unchanged, got %s\n", lang);
2904     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2905
2906     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2907     versz = 0;
2908     langsz = MAX_PATH;
2909     lstrcpyA(version, "version");
2910     lstrcpyA(lang, "lang");
2911     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2912     ok(r == ERROR_FILE_NOT_FOUND,
2913        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2914     ok(!lstrcmpA(version, "version"),
2915        "Expected version to be unchanged, got %s\n", version);
2916     ok(versz == 0, "Expected 0, got %d\n", versz);
2917     ok(!lstrcmpA(lang, "lang"),
2918        "Expected lang to be unchanged, got %s\n", lang);
2919     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2920
2921     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2922     versz = MAX_PATH;
2923     langsz = 0;
2924     lstrcpyA(version, "version");
2925     lstrcpyA(lang, "lang");
2926     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2927     ok(r == ERROR_FILE_NOT_FOUND,
2928        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2929     ok(!lstrcmpA(version, "version"),
2930        "Expected version to be unchanged, got %s\n", version);
2931     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2932     ok(!lstrcmpA(lang, "lang"),
2933        "Expected lang to be unchanged, got %s\n", lang);
2934     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2935
2936     /* nonexistent szFilePath, rest NULL */
2937     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2938     ok(r == ERROR_FILE_NOT_FOUND,
2939        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2940
2941     create_file("ver.txt", "ver.txt", 20);
2942
2943     /* file exists, no version information */
2944     versz = MAX_PATH;
2945     langsz = MAX_PATH;
2946     lstrcpyA(version, "version");
2947     lstrcpyA(lang, "lang");
2948     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2949     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2950     ok(!lstrcmpA(version, "version"),
2951        "Expected version to be unchanged, got %s\n", version);
2952     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2953     ok(!lstrcmpA(lang, "lang"),
2954        "Expected lang to be unchanged, got %s\n", lang);
2955     ok(r == ERROR_FILE_INVALID,
2956        "Expected ERROR_FILE_INVALID, got %d\n", r);
2957
2958     DeleteFileA("ver.txt");
2959
2960     /* relative path, has version information */
2961     versz = MAX_PATH;
2962     langsz = MAX_PATH;
2963     lstrcpyA(version, "version");
2964     lstrcpyA(lang, "lang");
2965     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2966     todo_wine
2967     {
2968         ok(r == ERROR_FILE_NOT_FOUND,
2969            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2970         ok(!lstrcmpA(version, "version"),
2971            "Expected version to be unchanged, got %s\n", version);
2972         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2973         ok(!lstrcmpA(lang, "lang"),
2974            "Expected lang to be unchanged, got %s\n", lang);
2975         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2976     }
2977
2978     GetSystemDirectoryA(path, MAX_PATH);
2979     lstrcatA(path, "\\kernel32.dll");
2980
2981     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2982
2983     /* absolute path, has version information */
2984     versz = MAX_PATH;
2985     langsz = MAX_PATH;
2986     lstrcpyA(version, "version");
2987     lstrcpyA(lang, "lang");
2988     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2989     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2990     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2991     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2992     ok(!lstrcmpA(version, vercheck),
2993         "Expected %s, got %s\n", vercheck, version);
2994
2995     /* only check version */
2996     versz = MAX_PATH;
2997     lstrcpyA(version, "version");
2998     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2999     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3000     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3001     ok(!lstrcmpA(version, vercheck),
3002        "Expected %s, got %s\n", vercheck, version);
3003
3004     /* only check language */
3005     langsz = MAX_PATH;
3006     lstrcpyA(lang, "lang");
3007     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
3008     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3009     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
3010
3011     /* check neither version nor language */
3012     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
3013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3014
3015     /* get pcchVersionBuf */
3016     versz = MAX_PATH;
3017     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
3018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3019     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3020
3021     /* get pcchLangBuf */
3022     langsz = MAX_PATH;
3023     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
3024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3025     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3026
3027     /* pcchVersionBuf not big enough */
3028     versz = 5;
3029     lstrcpyA(version, "version");
3030     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
3031     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3032     ok(!strncmp(version, vercheck, 4),
3033        "Expected first 4 characters of %s, got %s\n", vercheck, version);
3034     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3035
3036     /* pcchLangBuf not big enough */
3037     langsz = 3;
3038     lstrcpyA(lang, "lang");
3039     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
3040     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3041     ok(!strncmp(lang, langcheck, 2),
3042        "Expected first character of %s, got %s\n", langcheck, lang);
3043     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3044
3045     HeapFree(GetProcessHeap(), 0, vercheck);
3046     HeapFree(GetProcessHeap(), 0, langcheck);
3047 }
3048
3049 static void test_MsiGetProductInfo(void)
3050 {
3051     UINT r;
3052     LONG res;
3053     HKEY propkey, source;
3054     HKEY prodkey, localkey;
3055     CHAR prodcode[MAX_PATH];
3056     CHAR prod_squashed[MAX_PATH];
3057     CHAR packcode[MAX_PATH];
3058     CHAR pack_squashed[MAX_PATH];
3059     CHAR buf[MAX_PATH];
3060     CHAR keypath[MAX_PATH];
3061     LPSTR usersid;
3062     DWORD sz, val = 42;
3063     REGSAM access = KEY_ALL_ACCESS;
3064
3065     create_test_guid(prodcode, prod_squashed);
3066     create_test_guid(packcode, pack_squashed);
3067     usersid = get_user_sid();
3068
3069     if (is_wow64)
3070         access |= KEY_WOW64_64KEY;
3071
3072     /* NULL szProduct */
3073     sz = MAX_PATH;
3074     lstrcpyA(buf, "apple");
3075     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
3076     ok(r == ERROR_INVALID_PARAMETER,
3077        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3078     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3079     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3080
3081     /* empty szProduct */
3082     sz = MAX_PATH;
3083     lstrcpyA(buf, "apple");
3084     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
3085     ok(r == ERROR_INVALID_PARAMETER,
3086        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3087     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3088     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3089
3090     /* garbage szProduct */
3091     sz = MAX_PATH;
3092     lstrcpyA(buf, "apple");
3093     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
3094     ok(r == ERROR_INVALID_PARAMETER,
3095        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3096     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3097     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3098
3099     /* guid without brackets */
3100     sz = MAX_PATH;
3101     lstrcpyA(buf, "apple");
3102     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
3103                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3104     ok(r == ERROR_INVALID_PARAMETER,
3105        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3106     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3107     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3108
3109     /* guid with brackets */
3110     sz = MAX_PATH;
3111     lstrcpyA(buf, "apple");
3112     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
3113                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3114     ok(r == ERROR_UNKNOWN_PRODUCT,
3115        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3116     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3117     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3118
3119     /* same length as guid, but random */
3120     sz = MAX_PATH;
3121     lstrcpyA(buf, "apple");
3122     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
3123                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3124     ok(r == ERROR_INVALID_PARAMETER,
3125        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3126     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3127     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3128
3129     /* not installed, NULL szAttribute */
3130     sz = MAX_PATH;
3131     lstrcpyA(buf, "apple");
3132     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
3133     ok(r == ERROR_INVALID_PARAMETER,
3134        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3135     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3136     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3137
3138     /* not installed, NULL lpValueBuf */
3139     sz = MAX_PATH;
3140     lstrcpyA(buf, "apple");
3141     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3142     ok(r == ERROR_UNKNOWN_PRODUCT,
3143        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3144     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3145     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3146
3147     /* not installed, NULL pcchValueBuf */
3148     sz = MAX_PATH;
3149     lstrcpyA(buf, "apple");
3150     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
3151     ok(r == ERROR_INVALID_PARAMETER,
3152        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3153     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3154     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3155
3156     /* created guid cannot possibly be an installed product code */
3157     sz = MAX_PATH;
3158     lstrcpyA(buf, "apple");
3159     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3160     ok(r == ERROR_UNKNOWN_PRODUCT,
3161        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3162     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3163     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3164
3165     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3166     lstrcatA(keypath, usersid);
3167     lstrcatA(keypath, "\\Installer\\Products\\");
3168     lstrcatA(keypath, prod_squashed);
3169
3170     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3171     if (res == ERROR_ACCESS_DENIED)
3172     {
3173         skip("Not enough rights to perform tests\n");
3174         LocalFree(usersid);
3175         return;
3176     }
3177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3178
3179     /* managed product code exists */
3180     sz = MAX_PATH;
3181     lstrcpyA(buf, "apple");
3182     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3183     ok(r == ERROR_UNKNOWN_PROPERTY,
3184        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3185     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3186     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3187
3188     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3189     RegCloseKey(prodkey);
3190
3191     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3192     lstrcatA(keypath, usersid);
3193     lstrcatA(keypath, "\\Products\\");
3194     lstrcatA(keypath, prod_squashed);
3195
3196     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3198
3199     /* local user product code exists */
3200     sz = MAX_PATH;
3201     lstrcpyA(buf, "apple");
3202     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3203     ok(r == ERROR_UNKNOWN_PRODUCT,
3204        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3205     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3206     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3207
3208     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3209     lstrcatA(keypath, usersid);
3210     lstrcatA(keypath, "\\Installer\\Products\\");
3211     lstrcatA(keypath, prod_squashed);
3212
3213     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3214     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3215
3216     /* both local and managed product code exist */
3217     sz = MAX_PATH;
3218     lstrcpyA(buf, "apple");
3219     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3220     ok(r == ERROR_UNKNOWN_PROPERTY,
3221        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3222     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3223     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3224
3225     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3227
3228     /* InstallProperties key exists */
3229     sz = MAX_PATH;
3230     lstrcpyA(buf, "apple");
3231     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3232     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3233     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3234     ok(sz == 0, "Expected 0, got %d\n", sz);
3235
3236     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3238
3239     /* HelpLink value exists */
3240     sz = MAX_PATH;
3241     lstrcpyA(buf, "apple");
3242     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3244     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3245     ok(sz == 4, "Expected 4, got %d\n", sz);
3246
3247     /* pcchBuf is NULL */
3248     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3249     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3250
3251     /* lpValueBuf is NULL */
3252     sz = MAX_PATH;
3253     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3254     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3255     ok(sz == 4, "Expected 4, got %d\n", sz);
3256
3257     /* lpValueBuf is NULL, pcchValueBuf is too small */
3258     sz = 2;
3259     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3261     ok(sz == 4, "Expected 4, got %d\n", sz);
3262
3263     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3264     sz = 2;
3265     lstrcpyA(buf, "apple");
3266     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3267     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3268     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3269     ok(sz == 4, "Expected 4, got %d\n", sz);
3270
3271     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3272     sz = 4;
3273     lstrcpyA(buf, "apple");
3274     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3275     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3276     ok(!lstrcmpA(buf, "apple"),
3277        "Expected buf to remain unchanged, got \"%s\"\n", buf);
3278     ok(sz == 4, "Expected 4, got %d\n", sz);
3279
3280     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3282
3283     /* random property not supported by MSI, value exists */
3284     sz = MAX_PATH;
3285     lstrcpyA(buf, "apple");
3286     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3287     ok(r == ERROR_UNKNOWN_PROPERTY,
3288        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3289     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3290     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3291
3292     RegDeleteValueA(propkey, "IMadeThis");
3293     RegDeleteValueA(propkey, "HelpLink");
3294     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3295     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3296     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3297     RegCloseKey(propkey);
3298     RegCloseKey(localkey);
3299     RegCloseKey(prodkey);
3300
3301     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3302     lstrcatA(keypath, prod_squashed);
3303
3304     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3306
3307     /* user product key exists */
3308     sz = MAX_PATH;
3309     lstrcpyA(buf, "apple");
3310     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3311     ok(r == ERROR_UNKNOWN_PROPERTY,
3312        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3313     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3314     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3315
3316     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3317     lstrcatA(keypath, usersid);
3318     lstrcatA(keypath, "\\Products\\");
3319     lstrcatA(keypath, prod_squashed);
3320
3321     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3322     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3323
3324     /* local user product key exists */
3325     sz = MAX_PATH;
3326     lstrcpyA(buf, "apple");
3327     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3328     ok(r == ERROR_UNKNOWN_PROPERTY,
3329        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3330     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3331     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3332
3333     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3335
3336     /* InstallProperties key exists */
3337     sz = MAX_PATH;
3338     lstrcpyA(buf, "apple");
3339     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3341     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3342     ok(sz == 0, "Expected 0, got %d\n", sz);
3343
3344     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3346
3347     /* HelpLink value exists */
3348     sz = MAX_PATH;
3349     lstrcpyA(buf, "apple");
3350     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3351     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3352     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3353     ok(sz == 4, "Expected 4, got %d\n", sz);
3354
3355     RegDeleteValueA(propkey, "HelpLink");
3356     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3357     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3358     RegDeleteKeyA(prodkey, "");
3359     RegCloseKey(propkey);
3360     RegCloseKey(localkey);
3361     RegCloseKey(prodkey);
3362
3363     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3364     lstrcatA(keypath, prod_squashed);
3365
3366     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3368
3369     /* classes product key exists */
3370     sz = MAX_PATH;
3371     lstrcpyA(buf, "apple");
3372     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3373     ok(r == ERROR_UNKNOWN_PROPERTY,
3374        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3375     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3376     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3377
3378     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3379     lstrcatA(keypath, usersid);
3380     lstrcatA(keypath, "\\Products\\");
3381     lstrcatA(keypath, prod_squashed);
3382
3383     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3384     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3385
3386     /* local user product key exists */
3387     sz = MAX_PATH;
3388     lstrcpyA(buf, "apple");
3389     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3390     ok(r == ERROR_UNKNOWN_PROPERTY,
3391        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3392     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3393     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3394
3395     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3397
3398     /* InstallProperties key exists */
3399     sz = MAX_PATH;
3400     lstrcpyA(buf, "apple");
3401     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3402     ok(r == ERROR_UNKNOWN_PROPERTY,
3403        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3404     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3405     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3406
3407     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3408     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3409     RegCloseKey(propkey);
3410     RegCloseKey(localkey);
3411
3412     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3413     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3414     lstrcatA(keypath, prod_squashed);
3415
3416     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3418
3419     /* Local System product key exists */
3420     sz = MAX_PATH;
3421     lstrcpyA(buf, "apple");
3422     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3423     ok(r == ERROR_UNKNOWN_PROPERTY,
3424         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3425     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3426     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3427
3428     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3430
3431     /* InstallProperties key exists */
3432     sz = MAX_PATH;
3433     lstrcpyA(buf, "apple");
3434     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3435     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3436     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3437     ok(sz == 0, "Expected 0, got %d\n", sz);
3438
3439     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3441
3442     /* HelpLink value exists */
3443     sz = MAX_PATH;
3444     lstrcpyA(buf, "apple");
3445     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3447     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3448     ok(sz == 4, "Expected 4, got %d\n", sz);
3449
3450     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3451                          (const BYTE *)&val, sizeof(DWORD));
3452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3453
3454     /* HelpLink type is REG_DWORD */
3455     sz = MAX_PATH;
3456     lstrcpyA(buf, "apple");
3457     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3458     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3459     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3460     ok(sz == 2, "Expected 2, got %d\n", sz);
3461
3462     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3463     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3464
3465     /* DisplayName value exists */
3466     sz = MAX_PATH;
3467     lstrcpyA(buf, "apple");
3468     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3470     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3471     ok(sz == 4, "Expected 4, got %d\n", sz);
3472
3473     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3474                          (const BYTE *)&val, sizeof(DWORD));
3475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3476
3477     /* DisplayName type is REG_DWORD */
3478     sz = MAX_PATH;
3479     lstrcpyA(buf, "apple");
3480     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3482     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3483     ok(sz == 2, "Expected 2, got %d\n", sz);
3484
3485     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3487
3488     /* DisplayVersion value exists */
3489     sz = MAX_PATH;
3490     lstrcpyA(buf, "apple");
3491     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3493     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3494     ok(sz == 5, "Expected 5, got %d\n", sz);
3495
3496     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3497                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3499
3500     /* DisplayVersion type is REG_DWORD */
3501     sz = MAX_PATH;
3502     lstrcpyA(buf, "apple");
3503     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3504     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3505     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3506     ok(sz == 2, "Expected 2, got %d\n", sz);
3507
3508     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3510
3511     /* HelpTelephone value exists */
3512     sz = MAX_PATH;
3513     lstrcpyA(buf, "apple");
3514     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3516     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3517     ok(sz == 4, "Expected 4, got %d\n", sz);
3518
3519     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3520                          (const BYTE *)&val, sizeof(DWORD));
3521     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3522
3523     /* HelpTelephone type is REG_DWORD */
3524     sz = MAX_PATH;
3525     lstrcpyA(buf, "apple");
3526     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3527     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3528     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3529     ok(sz == 2, "Expected 2, got %d\n", sz);
3530
3531     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3533
3534     /* InstallLocation value exists */
3535     sz = MAX_PATH;
3536     lstrcpyA(buf, "apple");
3537     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3538     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3539     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3540     ok(sz == 3, "Expected 3, got %d\n", sz);
3541
3542     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3543                          (const BYTE *)&val, sizeof(DWORD));
3544     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3545
3546     /* InstallLocation type is REG_DWORD */
3547     sz = MAX_PATH;
3548     lstrcpyA(buf, "apple");
3549     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3551     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3552     ok(sz == 2, "Expected 2, got %d\n", sz);
3553
3554     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3556
3557     /* InstallSource value exists */
3558     sz = MAX_PATH;
3559     lstrcpyA(buf, "apple");
3560     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3562     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3563     ok(sz == 6, "Expected 6, got %d\n", sz);
3564
3565     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3566                          (const BYTE *)&val, sizeof(DWORD));
3567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3568
3569     /* InstallSource type is REG_DWORD */
3570     sz = MAX_PATH;
3571     lstrcpyA(buf, "apple");
3572     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3573     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3574     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3575     ok(sz == 2, "Expected 2, got %d\n", sz);
3576
3577     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3579
3580     /* InstallDate value exists */
3581     sz = MAX_PATH;
3582     lstrcpyA(buf, "apple");
3583     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3585     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3586     ok(sz == 4, "Expected 4, got %d\n", sz);
3587
3588     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3589                          (const BYTE *)&val, sizeof(DWORD));
3590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3591
3592     /* InstallDate type is REG_DWORD */
3593     sz = MAX_PATH;
3594     lstrcpyA(buf, "apple");
3595     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3596     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3597     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3598     ok(sz == 2, "Expected 2, got %d\n", sz);
3599
3600     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3602
3603     /* Publisher value exists */
3604     sz = MAX_PATH;
3605     lstrcpyA(buf, "apple");
3606     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3608     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3609     ok(sz == 3, "Expected 3, got %d\n", sz);
3610
3611     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3612                          (const BYTE *)&val, sizeof(DWORD));
3613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3614
3615     /* Publisher type is REG_DWORD */
3616     sz = MAX_PATH;
3617     lstrcpyA(buf, "apple");
3618     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3620     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3621     ok(sz == 2, "Expected 2, got %d\n", sz);
3622
3623     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3625
3626     /* LocalPackage value exists */
3627     sz = MAX_PATH;
3628     lstrcpyA(buf, "apple");
3629     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3630     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3631     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3632     ok(sz == 4, "Expected 4, got %d\n", sz);
3633
3634     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3635                          (const BYTE *)&val, sizeof(DWORD));
3636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3637
3638     /* LocalPackage type is REG_DWORD */
3639     sz = MAX_PATH;
3640     lstrcpyA(buf, "apple");
3641     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3642     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3643     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3644     ok(sz == 2, "Expected 2, got %d\n", sz);
3645
3646     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3648
3649     /* UrlInfoAbout value exists */
3650     sz = MAX_PATH;
3651     lstrcpyA(buf, "apple");
3652     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3653     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3654     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3655     ok(sz == 5, "Expected 5, got %d\n", sz);
3656
3657     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3658                          (const BYTE *)&val, sizeof(DWORD));
3659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3660
3661     /* UrlInfoAbout type is REG_DWORD */
3662     sz = MAX_PATH;
3663     lstrcpyA(buf, "apple");
3664     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3665     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3666     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3667     ok(sz == 2, "Expected 2, got %d\n", sz);
3668
3669     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3671
3672     /* UrlUpdateInfo value exists */
3673     sz = MAX_PATH;
3674     lstrcpyA(buf, "apple");
3675     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3676     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3677     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3678     ok(sz == 4, "Expected 4, got %d\n", sz);
3679
3680     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3681                          (const BYTE *)&val, sizeof(DWORD));
3682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3683
3684     /* UrlUpdateInfo type is REG_DWORD */
3685     sz = MAX_PATH;
3686     lstrcpyA(buf, "apple");
3687     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3689     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3690     ok(sz == 2, "Expected 2, got %d\n", sz);
3691
3692     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3694
3695     /* VersionMinor value exists */
3696     sz = MAX_PATH;
3697     lstrcpyA(buf, "apple");
3698     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3700     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3701     ok(sz == 1, "Expected 1, got %d\n", sz);
3702
3703     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3704                          (const BYTE *)&val, sizeof(DWORD));
3705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3706
3707     /* VersionMinor type is REG_DWORD */
3708     sz = MAX_PATH;
3709     lstrcpyA(buf, "apple");
3710     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3711     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3712     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3713     ok(sz == 2, "Expected 2, got %d\n", sz);
3714
3715     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3717
3718     /* VersionMajor value exists */
3719     sz = MAX_PATH;
3720     lstrcpyA(buf, "apple");
3721     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3722     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3723     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3724     ok(sz == 1, "Expected 1, got %d\n", sz);
3725
3726     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3727                          (const BYTE *)&val, sizeof(DWORD));
3728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3729
3730     /* VersionMajor type is REG_DWORD */
3731     sz = MAX_PATH;
3732     lstrcpyA(buf, "apple");
3733     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3735     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3736     ok(sz == 2, "Expected 2, got %d\n", sz);
3737
3738     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3740
3741     /* ProductID value exists */
3742     sz = MAX_PATH;
3743     lstrcpyA(buf, "apple");
3744     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3746     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3747     ok(sz == 2, "Expected 2, got %d\n", sz);
3748
3749     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3750                          (const BYTE *)&val, sizeof(DWORD));
3751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3752
3753     /* ProductID type is REG_DWORD */
3754     sz = MAX_PATH;
3755     lstrcpyA(buf, "apple");
3756     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3757     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3758     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3759     ok(sz == 2, "Expected 2, got %d\n", sz);
3760
3761     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3763
3764     /* RegCompany value exists */
3765     sz = MAX_PATH;
3766     lstrcpyA(buf, "apple");
3767     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3769     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3770     ok(sz == 4, "Expected 4, got %d\n", sz);
3771
3772     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3773                          (const BYTE *)&val, sizeof(DWORD));
3774     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3775
3776     /* RegCompany type is REG_DWORD */
3777     sz = MAX_PATH;
3778     lstrcpyA(buf, "apple");
3779     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3780     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3781     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3782     ok(sz == 2, "Expected 2, got %d\n", sz);
3783
3784     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3786
3787     /* RegOwner value exists */
3788     sz = MAX_PATH;
3789     lstrcpyA(buf, "apple");
3790     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3791     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3792     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3793     ok(sz == 3, "Expected 3, got %d\n", sz);
3794
3795     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3796                          (const BYTE *)&val, sizeof(DWORD));
3797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3798
3799     /* RegOwner type is REG_DWORD */
3800     sz = MAX_PATH;
3801     lstrcpyA(buf, "apple");
3802     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3803     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3804     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3805     ok(sz == 2, "Expected 2, got %d\n", sz);
3806
3807     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3808     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3809
3810     /* InstanceType value exists */
3811     sz = MAX_PATH;
3812     lstrcpyA(buf, "apple");
3813     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3815     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3816     ok(sz == 0, "Expected 0, got %d\n", sz);
3817
3818     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3819                          (const BYTE *)&val, sizeof(DWORD));
3820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3821
3822     /* InstanceType type is REG_DWORD */
3823     sz = MAX_PATH;
3824     lstrcpyA(buf, "apple");
3825     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3827     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3828     ok(sz == 0, "Expected 0, got %d\n", sz);
3829
3830     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3832
3833     /* InstanceType value exists */
3834     sz = MAX_PATH;
3835     lstrcpyA(buf, "apple");
3836     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3837     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3838     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3839     ok(sz == 4, "Expected 4, got %d\n", sz);
3840
3841     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3842                          (const BYTE *)&val, sizeof(DWORD));
3843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3844
3845     /* InstanceType type is REG_DWORD */
3846     sz = MAX_PATH;
3847     lstrcpyA(buf, "apple");
3848     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3849     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3850     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3851     ok(sz == 2, "Expected 2, got %d\n", sz);
3852
3853     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3854     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3855
3856     /* Transforms value exists */
3857     sz = MAX_PATH;
3858     lstrcpyA(buf, "apple");
3859     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3860     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3861     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3862     ok(sz == 0, "Expected 0, got %d\n", sz);
3863
3864     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3865                          (const BYTE *)&val, sizeof(DWORD));
3866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3867
3868     /* Transforms type is REG_DWORD */
3869     sz = MAX_PATH;
3870     lstrcpyA(buf, "apple");
3871     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3872     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3873     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3874     ok(sz == 0, "Expected 0, got %d\n", sz);
3875
3876     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3878
3879     /* Transforms value exists */
3880     sz = MAX_PATH;
3881     lstrcpyA(buf, "apple");
3882     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3883     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3884     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3885     ok(sz == 6, "Expected 6, got %d\n", sz);
3886
3887     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3888                          (const BYTE *)&val, sizeof(DWORD));
3889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3890
3891     /* Transforms type is REG_DWORD */
3892     sz = MAX_PATH;
3893     lstrcpyA(buf, "apple");
3894     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3895     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3896     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3897     ok(sz == 2, "Expected 2, got %d\n", sz);
3898
3899     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3901
3902     /* Language value exists */
3903     sz = MAX_PATH;
3904     lstrcpyA(buf, "apple");
3905     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3906     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3907     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3908     ok(sz == 0, "Expected 0, got %d\n", sz);
3909
3910     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3911                          (const BYTE *)&val, sizeof(DWORD));
3912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3913
3914     /* Language type is REG_DWORD */
3915     sz = MAX_PATH;
3916     lstrcpyA(buf, "apple");
3917     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3919     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3920     ok(sz == 0, "Expected 0, got %d\n", sz);
3921
3922     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3924
3925     /* Language value exists */
3926     sz = MAX_PATH;
3927     lstrcpyA(buf, "apple");
3928     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3929     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3930     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3931     ok(sz == 4, "Expected 4, got %d\n", sz);
3932
3933     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3934                          (const BYTE *)&val, sizeof(DWORD));
3935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3936
3937     /* Language type is REG_DWORD */
3938     sz = MAX_PATH;
3939     lstrcpyA(buf, "apple");
3940     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3942     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3943     ok(sz == 2, "Expected 2, got %d\n", sz);
3944
3945     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3947
3948     /* ProductName value exists */
3949     sz = MAX_PATH;
3950     lstrcpyA(buf, "apple");
3951     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3953     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3954     ok(sz == 0, "Expected 0, got %d\n", sz);
3955
3956     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3957                          (const BYTE *)&val, sizeof(DWORD));
3958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3959
3960     /* ProductName type is REG_DWORD */
3961     sz = MAX_PATH;
3962     lstrcpyA(buf, "apple");
3963     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3965     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3966     ok(sz == 0, "Expected 0, got %d\n", sz);
3967
3968     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3970
3971     /* ProductName value exists */
3972     sz = MAX_PATH;
3973     lstrcpyA(buf, "apple");
3974     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3975     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3976     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3977     ok(sz == 4, "Expected 4, got %d\n", sz);
3978
3979     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3980                          (const BYTE *)&val, sizeof(DWORD));
3981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3982
3983     /* ProductName type is REG_DWORD */
3984     sz = MAX_PATH;
3985     lstrcpyA(buf, "apple");
3986     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3988     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3989     ok(sz == 2, "Expected 2, got %d\n", sz);
3990
3991     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3993
3994     /* Assignment value exists */
3995     sz = MAX_PATH;
3996     lstrcpyA(buf, "apple");
3997     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3999     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4000     ok(sz == 0, "Expected 0, got %d\n", sz);
4001
4002     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
4003                          (const BYTE *)&val, sizeof(DWORD));
4004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4005
4006     /* Assignment type is REG_DWORD */
4007     sz = MAX_PATH;
4008     lstrcpyA(buf, "apple");
4009     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4010     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4011     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4012     ok(sz == 0, "Expected 0, got %d\n", sz);
4013
4014     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
4015     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4016
4017     /* Assignment value exists */
4018     sz = MAX_PATH;
4019     lstrcpyA(buf, "apple");
4020     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4022     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
4023     ok(sz == 2, "Expected 2, got %d\n", sz);
4024
4025     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
4026                          (const BYTE *)&val, sizeof(DWORD));
4027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4028
4029     /* Assignment type is REG_DWORD */
4030     sz = MAX_PATH;
4031     lstrcpyA(buf, "apple");
4032     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4034     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4035     ok(sz == 2, "Expected 2, got %d\n", sz);
4036
4037     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4039
4040     /* PackageCode value exists */
4041     sz = MAX_PATH;
4042     lstrcpyA(buf, "apple");
4043     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4044     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4045     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4046     ok(sz == 0, "Expected 0, got %d\n", sz);
4047
4048     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
4049                          (const BYTE *)&val, sizeof(DWORD));
4050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4051
4052     /* PackageCode type is REG_DWORD */
4053     sz = MAX_PATH;
4054     lstrcpyA(buf, "apple");
4055     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4056     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4057     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4058     ok(sz == 0, "Expected 0, got %d\n", sz);
4059
4060     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4062
4063     /* PackageCode value exists */
4064     sz = MAX_PATH;
4065     lstrcpyA(buf, "apple");
4066     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4067     ok(r == ERROR_BAD_CONFIGURATION,
4068        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4069     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
4070     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4071
4072     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
4073                          (const BYTE *)&val, sizeof(DWORD));
4074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4075
4076     /* PackageCode type is REG_DWORD */
4077     sz = MAX_PATH;
4078     lstrcpyA(buf, "apple");
4079     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4080     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4081     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4082     ok(sz == 2, "Expected 2, got %d\n", sz);
4083
4084     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
4085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4086
4087     /* PackageCode value exists */
4088     sz = MAX_PATH;
4089     lstrcpyA(buf, "apple");
4090     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4091     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4092     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
4093     ok(sz == 38, "Expected 38, got %d\n", sz);
4094
4095     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4096     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4097
4098     /* Version value exists */
4099     sz = MAX_PATH;
4100     lstrcpyA(buf, "apple");
4101     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4102     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4103     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4104     ok(sz == 0, "Expected 0, got %d\n", sz);
4105
4106     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
4107                          (const BYTE *)&val, sizeof(DWORD));
4108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4109
4110     /* Version type is REG_DWORD */
4111     sz = MAX_PATH;
4112     lstrcpyA(buf, "apple");
4113     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4116     ok(sz == 0, "Expected 0, got %d\n", sz);
4117
4118     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4120
4121     /* Version value exists */
4122     sz = MAX_PATH;
4123     lstrcpyA(buf, "apple");
4124     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4126     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4127     ok(sz == 3, "Expected 3, got %d\n", sz);
4128
4129     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
4130                          (const BYTE *)&val, sizeof(DWORD));
4131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4132
4133     /* Version type is REG_DWORD */
4134     sz = MAX_PATH;
4135     lstrcpyA(buf, "apple");
4136     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4138     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4139     ok(sz == 2, "Expected 2, got %d\n", sz);
4140
4141     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4143
4144     /* ProductIcon value exists */
4145     sz = MAX_PATH;
4146     lstrcpyA(buf, "apple");
4147     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4148     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4149     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4150     ok(sz == 0, "Expected 0, got %d\n", sz);
4151
4152     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
4153                          (const BYTE *)&val, sizeof(DWORD));
4154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4155
4156     /* ProductIcon type is REG_DWORD */
4157     sz = MAX_PATH;
4158     lstrcpyA(buf, "apple");
4159     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4160     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4161     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4162     ok(sz == 0, "Expected 0, got %d\n", sz);
4163
4164     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4166
4167     /* ProductIcon value exists */
4168     sz = MAX_PATH;
4169     lstrcpyA(buf, "apple");
4170     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4171     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4172     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
4173     ok(sz == 3, "Expected 3, got %d\n", sz);
4174
4175     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
4176                          (const BYTE *)&val, sizeof(DWORD));
4177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4178
4179     /* ProductIcon type is REG_DWORD */
4180     sz = MAX_PATH;
4181     lstrcpyA(buf, "apple");
4182     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4183     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4184     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4185     ok(sz == 2, "Expected 2, got %d\n", sz);
4186
4187     /* SourceList key does not exist */
4188     sz = MAX_PATH;
4189     lstrcpyA(buf, "apple");
4190     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4191     ok(r == ERROR_UNKNOWN_PRODUCT,
4192        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4193     ok(!lstrcmpA(buf, "apple"),
4194        "Expected buf to be unchanged, got \"%s\"\n", buf);
4195     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
4196
4197     res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
4198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4199
4200     /* SourceList key exists, but PackageName val does not exist */
4201     sz = MAX_PATH;
4202     lstrcpyA(buf, "apple");
4203     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4205     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4206     ok(sz == 0, "Expected 0, got %d\n", sz);
4207
4208     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
4209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4210
4211     /* PackageName val exists */
4212     sz = MAX_PATH;
4213     lstrcpyA(buf, "apple");
4214     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4216     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4217     ok(sz == 8, "Expected 8, got %d\n", sz);
4218
4219     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4220                          (const BYTE *)&val, sizeof(DWORD));
4221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4222
4223     /* PackageName type is REG_DWORD */
4224     sz = MAX_PATH;
4225     lstrcpyA(buf, "apple");
4226     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4228     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4229     ok(sz == 2, "Expected 2, got %d\n", sz);
4230
4231     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4233
4234     /* Authorized value exists */
4235     sz = MAX_PATH;
4236     lstrcpyA(buf, "apple");
4237     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4238     if (r != ERROR_UNKNOWN_PROPERTY)
4239     {
4240         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4241         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4242         ok(sz == 0, "Expected 0, got %d\n", sz);
4243     }
4244
4245     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4246                          (const BYTE *)&val, sizeof(DWORD));
4247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4248
4249     /* AuthorizedLUAApp type is REG_DWORD */
4250     sz = MAX_PATH;
4251     lstrcpyA(buf, "apple");
4252     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4253     if (r != ERROR_UNKNOWN_PROPERTY)
4254     {
4255         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4256         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4257         ok(sz == 0, "Expected 0, got %d\n", sz);
4258     }
4259
4260     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4262
4263     /* Authorized value exists */
4264     sz = MAX_PATH;
4265     lstrcpyA(buf, "apple");
4266     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4267     if (r != ERROR_UNKNOWN_PROPERTY)
4268     {
4269         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4270         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4271         ok(sz == 4, "Expected 4, got %d\n", sz);
4272     }
4273
4274     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4275                          (const BYTE *)&val, sizeof(DWORD));
4276     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4277
4278     /* AuthorizedLUAApp type is REG_DWORD */
4279     sz = MAX_PATH;
4280     lstrcpyA(buf, "apple");
4281     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4282     if (r != ERROR_UNKNOWN_PROPERTY)
4283     {
4284         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4285         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4286         ok(sz == 2, "Expected 2, got %d\n", sz);
4287     }
4288
4289     RegDeleteValueA(propkey, "HelpLink");
4290     RegDeleteValueA(propkey, "DisplayName");
4291     RegDeleteValueA(propkey, "DisplayVersion");
4292     RegDeleteValueA(propkey, "HelpTelephone");
4293     RegDeleteValueA(propkey, "InstallLocation");
4294     RegDeleteValueA(propkey, "InstallSource");
4295     RegDeleteValueA(propkey, "InstallDate");
4296     RegDeleteValueA(propkey, "Publisher");
4297     RegDeleteValueA(propkey, "LocalPackage");
4298     RegDeleteValueA(propkey, "UrlInfoAbout");
4299     RegDeleteValueA(propkey, "UrlUpdateInfo");
4300     RegDeleteValueA(propkey, "VersionMinor");
4301     RegDeleteValueA(propkey, "VersionMajor");
4302     RegDeleteValueA(propkey, "ProductID");
4303     RegDeleteValueA(propkey, "RegCompany");
4304     RegDeleteValueA(propkey, "RegOwner");
4305     RegDeleteValueA(propkey, "InstanceType");
4306     RegDeleteValueA(propkey, "Transforms");
4307     RegDeleteValueA(propkey, "Language");
4308     RegDeleteValueA(propkey, "ProductName");
4309     RegDeleteValueA(propkey, "Assignment");
4310     RegDeleteValueA(propkey, "PackageCode");
4311     RegDeleteValueA(propkey, "Version");
4312     RegDeleteValueA(propkey, "ProductIcon");
4313     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4314     delete_key(propkey, "", access & KEY_WOW64_64KEY);
4315     delete_key(localkey, "", access & KEY_WOW64_64KEY);
4316     RegDeleteValueA(prodkey, "InstanceType");
4317     RegDeleteValueA(prodkey, "Transforms");
4318     RegDeleteValueA(prodkey, "Language");
4319     RegDeleteValueA(prodkey, "ProductName");
4320     RegDeleteValueA(prodkey, "Assignment");
4321     RegDeleteValueA(prodkey, "PackageCode");
4322     RegDeleteValueA(prodkey, "Version");
4323     RegDeleteValueA(prodkey, "ProductIcon");
4324     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4325     RegDeleteValueA(source, "PackageName");
4326     delete_key(source, "", access & KEY_WOW64_64KEY);
4327     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4328     RegCloseKey(propkey);
4329     RegCloseKey(localkey);
4330     RegCloseKey(source);
4331     RegCloseKey(prodkey);
4332     LocalFree(usersid);
4333 }
4334
4335 static void test_MsiGetProductInfoEx(void)
4336 {
4337     UINT r;
4338     LONG res;
4339     HKEY propkey, userkey;
4340     HKEY prodkey, localkey;
4341     CHAR prodcode[MAX_PATH];
4342     CHAR prod_squashed[MAX_PATH];
4343     CHAR packcode[MAX_PATH];
4344     CHAR pack_squashed[MAX_PATH];
4345     CHAR buf[MAX_PATH];
4346     CHAR keypath[MAX_PATH];
4347     LPSTR usersid;
4348     DWORD sz;
4349     REGSAM access = KEY_ALL_ACCESS;
4350
4351     if (!pMsiGetProductInfoExA)
4352     {
4353         win_skip("MsiGetProductInfoExA is not available\n");
4354         return;
4355     }
4356
4357     create_test_guid(prodcode, prod_squashed);
4358     create_test_guid(packcode, pack_squashed);
4359     usersid = get_user_sid();
4360
4361     if (is_wow64)
4362         access |= KEY_WOW64_64KEY;
4363
4364     /* NULL szProductCode */
4365     sz = MAX_PATH;
4366     lstrcpyA(buf, "apple");
4367     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4368                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4369     ok(r == ERROR_INVALID_PARAMETER,
4370        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4371     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4372     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4373
4374     /* empty szProductCode */
4375     sz = MAX_PATH;
4376     lstrcpyA(buf, "apple");
4377     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4378                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4379     ok(r == ERROR_INVALID_PARAMETER,
4380        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4381     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4382     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4383
4384     /* garbage szProductCode */
4385     sz = MAX_PATH;
4386     lstrcpyA(buf, "apple");
4387     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4388                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4389     ok(r == ERROR_INVALID_PARAMETER,
4390        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4391     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4392     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4393
4394     /* guid without brackets */
4395     sz = MAX_PATH;
4396     lstrcpyA(buf, "apple");
4397     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4398                               MSIINSTALLCONTEXT_USERUNMANAGED,
4399                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4400     ok(r == ERROR_INVALID_PARAMETER,
4401        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4402     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4403     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4404
4405     /* guid with brackets */
4406     sz = MAX_PATH;
4407     lstrcpyA(buf, "apple");
4408     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4409                               MSIINSTALLCONTEXT_USERUNMANAGED,
4410                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4411     ok(r == ERROR_UNKNOWN_PRODUCT,
4412        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4413     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4414     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4415
4416     /* szValue is non-NULL while pcchValue is NULL */
4417     lstrcpyA(buf, "apple");
4418     r = pMsiGetProductInfoExA(prodcode, usersid,
4419                               MSIINSTALLCONTEXT_USERUNMANAGED,
4420                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4421     ok(r == ERROR_INVALID_PARAMETER,
4422        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4423     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4424
4425     /* dwContext is out of range */
4426     sz = MAX_PATH;
4427     lstrcpyA(buf, "apple");
4428     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4429                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4430     ok(r == ERROR_INVALID_PARAMETER,
4431        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4432     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4433     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4434
4435     /* szProperty is NULL */
4436     sz = MAX_PATH;
4437     lstrcpyA(buf, "apple");
4438     r = pMsiGetProductInfoExA(prodcode, usersid,
4439                               MSIINSTALLCONTEXT_USERUNMANAGED,
4440                               NULL, buf, &sz);
4441     ok(r == ERROR_INVALID_PARAMETER,
4442        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4443     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4444     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4445
4446     /* szProperty is empty */
4447     sz = MAX_PATH;
4448     lstrcpyA(buf, "apple");
4449     r = pMsiGetProductInfoExA(prodcode, usersid,
4450                               MSIINSTALLCONTEXT_USERUNMANAGED,
4451                               "", buf, &sz);
4452     ok(r == ERROR_INVALID_PARAMETER,
4453        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4454     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4455     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4456
4457     /* szProperty is not a valid property */
4458     sz = MAX_PATH;
4459     lstrcpyA(buf, "apple");
4460     r = pMsiGetProductInfoExA(prodcode, usersid,
4461                               MSIINSTALLCONTEXT_USERUNMANAGED,
4462                               "notvalid", buf, &sz);
4463     ok(r == ERROR_UNKNOWN_PRODUCT,
4464        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4465     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4466     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4467
4468     /* same length as guid, but random */
4469     sz = MAX_PATH;
4470     lstrcpyA(buf, "apple");
4471     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4472                               MSIINSTALLCONTEXT_USERUNMANAGED,
4473                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4474     ok(r == ERROR_INVALID_PARAMETER,
4475        "Expected ERROR_INVALID_PARAMETER, 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     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4480
4481     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4482     lstrcatA(keypath, usersid);
4483     lstrcatA(keypath, "\\Products\\");
4484     lstrcatA(keypath, prod_squashed);
4485
4486     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4487     if (res == ERROR_ACCESS_DENIED)
4488     {
4489         skip("Not enough rights to perform tests\n");
4490         LocalFree(usersid);
4491         return;
4492     }
4493     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4494
4495     /* local user product key exists */
4496     sz = MAX_PATH;
4497     lstrcpyA(buf, "apple");
4498     r = pMsiGetProductInfoExA(prodcode, usersid,
4499                               MSIINSTALLCONTEXT_USERUNMANAGED,
4500                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4501     ok(r == ERROR_UNKNOWN_PRODUCT,
4502        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4503     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4504     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4505
4506     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4508
4509     /* InstallProperties key exists */
4510     sz = MAX_PATH;
4511     lstrcpyA(buf, "apple");
4512     r = pMsiGetProductInfoExA(prodcode, usersid,
4513                               MSIINSTALLCONTEXT_USERUNMANAGED,
4514                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4515     ok(r == ERROR_UNKNOWN_PRODUCT,
4516        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4517     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4518     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4519
4520     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4521     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4522
4523     /* LocalPackage value exists */
4524     sz = MAX_PATH;
4525     lstrcpyA(buf, "apple");
4526     r = pMsiGetProductInfoExA(prodcode, usersid,
4527                               MSIINSTALLCONTEXT_USERUNMANAGED,
4528                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4530     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4531     ok(sz == 1, "Expected 1, got %d\n", sz);
4532
4533     RegDeleteValueA(propkey, "LocalPackage");
4534
4535     /* LocalPackage value must exist */
4536     sz = MAX_PATH;
4537     lstrcpyA(buf, "apple");
4538     r = pMsiGetProductInfoExA(prodcode, usersid,
4539                               MSIINSTALLCONTEXT_USERUNMANAGED,
4540                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4541     ok(r == ERROR_UNKNOWN_PRODUCT,
4542        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4543     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4544     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4545
4546     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4548
4549     /* LocalPackage exists, but HelpLink does not exist */
4550     sz = MAX_PATH;
4551     lstrcpyA(buf, "apple");
4552     r = pMsiGetProductInfoExA(prodcode, usersid,
4553                               MSIINSTALLCONTEXT_USERUNMANAGED,
4554                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4556     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4557     ok(sz == 0, "Expected 0, got %d\n", sz);
4558
4559     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4561
4562     /* HelpLink value exists */
4563     sz = MAX_PATH;
4564     lstrcpyA(buf, "apple");
4565     r = pMsiGetProductInfoExA(prodcode, usersid,
4566                               MSIINSTALLCONTEXT_USERUNMANAGED,
4567                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4568     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4569     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4570     ok(sz == 4, "Expected 4, got %d\n", sz);
4571
4572     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4574
4575     /* HelpTelephone value exists */
4576     sz = MAX_PATH;
4577     lstrcpyA(buf, "apple");
4578     r = pMsiGetProductInfoExA(prodcode, usersid,
4579                               MSIINSTALLCONTEXT_USERUNMANAGED,
4580                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4582     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4583     ok(sz == 5, "Expected 5, got %d\n", sz);
4584
4585     /* szValue and pcchValue are NULL */
4586     r = pMsiGetProductInfoExA(prodcode, usersid,
4587                               MSIINSTALLCONTEXT_USERUNMANAGED,
4588                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4589     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4590
4591     /* pcchValue is exactly 5 */
4592     sz = 5;
4593     lstrcpyA(buf, "apple");
4594     r = pMsiGetProductInfoExA(prodcode, usersid,
4595                               MSIINSTALLCONTEXT_USERUNMANAGED,
4596                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4597     ok(r == ERROR_MORE_DATA,
4598        "Expected ERROR_MORE_DATA, got %d\n", r);
4599     ok(sz == 10, "Expected 10, got %d\n", sz);
4600
4601     /* szValue is NULL, pcchValue is exactly 5 */
4602     sz = 5;
4603     r = pMsiGetProductInfoExA(prodcode, usersid,
4604                               MSIINSTALLCONTEXT_USERUNMANAGED,
4605                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4606     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4607     ok(sz == 10, "Expected 10, got %d\n", sz);
4608
4609     /* szValue is NULL, pcchValue is MAX_PATH */
4610     sz = MAX_PATH;
4611     r = pMsiGetProductInfoExA(prodcode, usersid,
4612                               MSIINSTALLCONTEXT_USERUNMANAGED,
4613                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4614     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4615     ok(sz == 10, "Expected 10, got %d\n", sz);
4616
4617     /* pcchValue is exactly 0 */
4618     sz = 0;
4619     lstrcpyA(buf, "apple");
4620     r = pMsiGetProductInfoExA(prodcode, usersid,
4621                               MSIINSTALLCONTEXT_USERUNMANAGED,
4622                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4623     ok(r == ERROR_MORE_DATA,
4624        "Expected ERROR_MORE_DATA, got %d\n", r);
4625     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4626     ok(sz == 10, "Expected 10, got %d\n", sz);
4627
4628     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4630
4631     /* szProperty is not a valid property */
4632     sz = MAX_PATH;
4633     lstrcpyA(buf, "apple");
4634     r = pMsiGetProductInfoExA(prodcode, usersid,
4635                               MSIINSTALLCONTEXT_USERUNMANAGED,
4636                               "notvalid", buf, &sz);
4637     ok(r == ERROR_UNKNOWN_PROPERTY,
4638        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4639     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4640     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4641
4642     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4644
4645     /* InstallDate value exists */
4646     sz = MAX_PATH;
4647     lstrcpyA(buf, "apple");
4648     r = pMsiGetProductInfoExA(prodcode, usersid,
4649                               MSIINSTALLCONTEXT_USERUNMANAGED,
4650                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4651     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4652     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4653     ok(sz == 4, "Expected 4, got %d\n", sz);
4654
4655     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4657
4658     /* DisplayName value exists */
4659     sz = MAX_PATH;
4660     lstrcpyA(buf, "apple");
4661     r = pMsiGetProductInfoExA(prodcode, usersid,
4662                               MSIINSTALLCONTEXT_USERUNMANAGED,
4663                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4665     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4666     ok(sz == 4, "Expected 4, got %d\n", sz);
4667
4668     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4670
4671     /* InstallLocation value exists */
4672     sz = MAX_PATH;
4673     lstrcpyA(buf, "apple");
4674     r = pMsiGetProductInfoExA(prodcode, usersid,
4675                               MSIINSTALLCONTEXT_USERUNMANAGED,
4676                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4678     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4679     ok(sz == 3, "Expected 3, got %d\n", sz);
4680
4681     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4683
4684     /* InstallSource value exists */
4685     sz = MAX_PATH;
4686     lstrcpyA(buf, "apple");
4687     r = pMsiGetProductInfoExA(prodcode, usersid,
4688                               MSIINSTALLCONTEXT_USERUNMANAGED,
4689                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4691     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4692     ok(sz == 6, "Expected 6, got %d\n", sz);
4693
4694     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4696
4697     /* LocalPackage value exists */
4698     sz = MAX_PATH;
4699     lstrcpyA(buf, "apple");
4700     r = pMsiGetProductInfoExA(prodcode, usersid,
4701                               MSIINSTALLCONTEXT_USERUNMANAGED,
4702                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4704     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4705     ok(sz == 5, "Expected 5, got %d\n", sz);
4706
4707     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4709
4710     /* Publisher value exists */
4711     sz = MAX_PATH;
4712     lstrcpyA(buf, "apple");
4713     r = pMsiGetProductInfoExA(prodcode, usersid,
4714                               MSIINSTALLCONTEXT_USERUNMANAGED,
4715                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4717     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4718     ok(sz == 3, "Expected 3, got %d\n", sz);
4719
4720     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4721     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4722
4723     /* URLInfoAbout value exists */
4724     sz = MAX_PATH;
4725     lstrcpyA(buf, "apple");
4726     r = pMsiGetProductInfoExA(prodcode, usersid,
4727                               MSIINSTALLCONTEXT_USERUNMANAGED,
4728                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4730     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4731     ok(sz == 5, "Expected 5, got %d\n", sz);
4732
4733     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4735
4736     /* URLUpdateInfo value exists */
4737     sz = MAX_PATH;
4738     lstrcpyA(buf, "apple");
4739     r = pMsiGetProductInfoExA(prodcode, usersid,
4740                               MSIINSTALLCONTEXT_USERUNMANAGED,
4741                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4742     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4744     ok(sz == 6, "Expected 6, got %d\n", sz);
4745
4746     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4748
4749     /* VersionMinor value exists */
4750     sz = MAX_PATH;
4751     lstrcpyA(buf, "apple");
4752     r = pMsiGetProductInfoExA(prodcode, usersid,
4753                               MSIINSTALLCONTEXT_USERUNMANAGED,
4754                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4756     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4757     ok(sz == 1, "Expected 1, got %d\n", sz);
4758
4759     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4761
4762     /* VersionMajor value exists */
4763     sz = MAX_PATH;
4764     lstrcpyA(buf, "apple");
4765     r = pMsiGetProductInfoExA(prodcode, usersid,
4766                               MSIINSTALLCONTEXT_USERUNMANAGED,
4767                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4769     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4770     ok(sz == 1, "Expected 1, got %d\n", sz);
4771
4772     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4774
4775     /* DisplayVersion value exists */
4776     sz = MAX_PATH;
4777     lstrcpyA(buf, "apple");
4778     r = pMsiGetProductInfoExA(prodcode, usersid,
4779                               MSIINSTALLCONTEXT_USERUNMANAGED,
4780                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4782     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4783     ok(sz == 5, "Expected 5, got %d\n", sz);
4784
4785     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4787
4788     /* ProductID value exists */
4789     sz = MAX_PATH;
4790     lstrcpyA(buf, "apple");
4791     r = pMsiGetProductInfoExA(prodcode, usersid,
4792                               MSIINSTALLCONTEXT_USERUNMANAGED,
4793                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4795     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4796     ok(sz == 2, "Expected 2, got %d\n", sz);
4797
4798     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4800
4801     /* RegCompany value exists */
4802     sz = MAX_PATH;
4803     lstrcpyA(buf, "apple");
4804     r = pMsiGetProductInfoExA(prodcode, usersid,
4805                               MSIINSTALLCONTEXT_USERUNMANAGED,
4806                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4808     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4809     ok(sz == 4, "Expected 4, got %d\n", sz);
4810
4811     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4812     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4813
4814     /* RegOwner value exists */
4815     sz = MAX_PATH;
4816     lstrcpyA(buf, "apple");
4817     r = pMsiGetProductInfoExA(prodcode, usersid,
4818                               MSIINSTALLCONTEXT_USERUNMANAGED,
4819                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4821     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4822     ok(sz == 5, "Expected 5, got %d\n", sz);
4823
4824     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4826
4827     /* Transforms value exists */
4828     sz = MAX_PATH;
4829     lstrcpyA(buf, "apple");
4830     r = pMsiGetProductInfoExA(prodcode, usersid,
4831                               MSIINSTALLCONTEXT_USERUNMANAGED,
4832                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4833     ok(r == ERROR_UNKNOWN_PRODUCT,
4834        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4835     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4836     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4837
4838     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4840
4841     /* Language value exists */
4842     sz = MAX_PATH;
4843     lstrcpyA(buf, "apple");
4844     r = pMsiGetProductInfoExA(prodcode, usersid,
4845                               MSIINSTALLCONTEXT_USERUNMANAGED,
4846                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4847     ok(r == ERROR_UNKNOWN_PRODUCT,
4848        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4849     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4850     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4851
4852     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4854
4855     /* ProductName value exists */
4856     sz = MAX_PATH;
4857     lstrcpyA(buf, "apple");
4858     r = pMsiGetProductInfoExA(prodcode, usersid,
4859                               MSIINSTALLCONTEXT_USERUNMANAGED,
4860                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4861     ok(r == ERROR_UNKNOWN_PRODUCT,
4862        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4863     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4864     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4865
4866     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4868
4869     /* FIXME */
4870
4871     /* AssignmentType value exists */
4872     sz = MAX_PATH;
4873     lstrcpyA(buf, "apple");
4874     r = pMsiGetProductInfoExA(prodcode, usersid,
4875                               MSIINSTALLCONTEXT_USERUNMANAGED,
4876                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4877     ok(r == ERROR_UNKNOWN_PRODUCT,
4878        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4879     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4880     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4881
4882     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4884
4885     /* PackageCode value exists */
4886     sz = MAX_PATH;
4887     lstrcpyA(buf, "apple");
4888     r = pMsiGetProductInfoExA(prodcode, usersid,
4889                               MSIINSTALLCONTEXT_USERUNMANAGED,
4890                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4891     ok(r == ERROR_UNKNOWN_PRODUCT,
4892        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4893     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4894     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4895
4896     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4897     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4898
4899     /* Version value exists */
4900     sz = MAX_PATH;
4901     lstrcpyA(buf, "apple");
4902     r = pMsiGetProductInfoExA(prodcode, usersid,
4903                               MSIINSTALLCONTEXT_USERUNMANAGED,
4904                               INSTALLPROPERTY_VERSION, buf, &sz);
4905     ok(r == ERROR_UNKNOWN_PRODUCT,
4906        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4907     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4908     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4909
4910     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4911     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4912
4913     /* ProductIcon value exists */
4914     sz = MAX_PATH;
4915     lstrcpyA(buf, "apple");
4916     r = pMsiGetProductInfoExA(prodcode, usersid,
4917                               MSIINSTALLCONTEXT_USERUNMANAGED,
4918                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4919     ok(r == ERROR_UNKNOWN_PRODUCT,
4920        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4921     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4922     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4923
4924     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4926
4927     /* PackageName value exists */
4928     sz = MAX_PATH;
4929     lstrcpyA(buf, "apple");
4930     r = pMsiGetProductInfoExA(prodcode, usersid,
4931                               MSIINSTALLCONTEXT_USERUNMANAGED,
4932                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4933     ok(r == ERROR_UNKNOWN_PRODUCT,
4934        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4935     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4936     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4937
4938     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4939     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4940
4941     /* AuthorizedLUAApp value exists */
4942     sz = MAX_PATH;
4943     lstrcpyA(buf, "apple");
4944     r = pMsiGetProductInfoExA(prodcode, usersid,
4945                               MSIINSTALLCONTEXT_USERUNMANAGED,
4946                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4947     ok(r == ERROR_UNKNOWN_PRODUCT,
4948        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4949     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4950     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4951
4952     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4953     RegDeleteValueA(propkey, "PackageName");
4954     RegDeleteValueA(propkey, "ProductIcon");
4955     RegDeleteValueA(propkey, "Version");
4956     RegDeleteValueA(propkey, "PackageCode");
4957     RegDeleteValueA(propkey, "AssignmentType");
4958     RegDeleteValueA(propkey, "ProductName");
4959     RegDeleteValueA(propkey, "Language");
4960     RegDeleteValueA(propkey, "Transforms");
4961     RegDeleteValueA(propkey, "RegOwner");
4962     RegDeleteValueA(propkey, "RegCompany");
4963     RegDeleteValueA(propkey, "ProductID");
4964     RegDeleteValueA(propkey, "DisplayVersion");
4965     RegDeleteValueA(propkey, "VersionMajor");
4966     RegDeleteValueA(propkey, "VersionMinor");
4967     RegDeleteValueA(propkey, "URLUpdateInfo");
4968     RegDeleteValueA(propkey, "URLInfoAbout");
4969     RegDeleteValueA(propkey, "Publisher");
4970     RegDeleteValueA(propkey, "LocalPackage");
4971     RegDeleteValueA(propkey, "InstallSource");
4972     RegDeleteValueA(propkey, "InstallLocation");
4973     RegDeleteValueA(propkey, "DisplayName");
4974     RegDeleteValueA(propkey, "InstallDate");
4975     RegDeleteValueA(propkey, "HelpTelephone");
4976     RegDeleteValueA(propkey, "HelpLink");
4977     RegDeleteValueA(propkey, "LocalPackage");
4978     RegDeleteKeyA(propkey, "");
4979     RegCloseKey(propkey);
4980     RegDeleteKeyA(localkey, "");
4981     RegCloseKey(localkey);
4982
4983     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4984     lstrcatA(keypath, usersid);
4985     lstrcatA(keypath, "\\Installer\\Products\\");
4986     lstrcatA(keypath, prod_squashed);
4987
4988     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
4989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4990
4991     /* user product key exists */
4992     sz = MAX_PATH;
4993     lstrcpyA(buf, "apple");
4994     r = pMsiGetProductInfoExA(prodcode, usersid,
4995                               MSIINSTALLCONTEXT_USERUNMANAGED,
4996                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4997     ok(r == ERROR_UNKNOWN_PRODUCT,
4998        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4999     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5000     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5001
5002     RegDeleteKeyA(userkey, "");
5003     RegCloseKey(userkey);
5004
5005     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5006     lstrcatA(keypath, prod_squashed);
5007
5008     res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
5009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5010
5011     sz = MAX_PATH;
5012     lstrcpyA(buf, "apple");
5013     r = pMsiGetProductInfoExA(prodcode, usersid,
5014                               MSIINSTALLCONTEXT_USERUNMANAGED,
5015                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5016     ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
5017     if (r == ERROR_UNKNOWN_PRODUCT)
5018     {
5019         win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
5020         delete_key(prodkey, "", access);
5021         RegCloseKey(prodkey);
5022         return;
5023     }
5024     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5025     ok(sz == 1, "Expected 1, got %d\n", sz);
5026
5027     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5029
5030     /* HelpLink value exists */
5031     sz = MAX_PATH;
5032     lstrcpyA(buf, "apple");
5033     r = pMsiGetProductInfoExA(prodcode, usersid,
5034                               MSIINSTALLCONTEXT_USERUNMANAGED,
5035                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5036     ok(r == ERROR_UNKNOWN_PROPERTY,
5037        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5038     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5039     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5040
5041     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5043
5044     /* HelpTelephone value exists */
5045     sz = MAX_PATH;
5046     lstrcpyA(buf, "apple");
5047     r = pMsiGetProductInfoExA(prodcode, usersid,
5048                               MSIINSTALLCONTEXT_USERUNMANAGED,
5049                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5050     ok(r == ERROR_UNKNOWN_PROPERTY,
5051        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5052     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5053     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5054
5055     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5057
5058     /* InstallDate value exists */
5059     sz = MAX_PATH;
5060     lstrcpyA(buf, "apple");
5061     r = pMsiGetProductInfoExA(prodcode, usersid,
5062                               MSIINSTALLCONTEXT_USERUNMANAGED,
5063                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5064     ok(r == ERROR_UNKNOWN_PROPERTY,
5065        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5066     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5067     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5068
5069     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5071
5072     /* DisplayName value exists */
5073     sz = MAX_PATH;
5074     lstrcpyA(buf, "apple");
5075     r = pMsiGetProductInfoExA(prodcode, usersid,
5076                               MSIINSTALLCONTEXT_USERUNMANAGED,
5077                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5078     ok(r == ERROR_UNKNOWN_PROPERTY,
5079        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5080     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5081     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5082
5083     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5084     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5085
5086     /* InstallLocation value exists */
5087     sz = MAX_PATH;
5088     lstrcpyA(buf, "apple");
5089     r = pMsiGetProductInfoExA(prodcode, usersid,
5090                               MSIINSTALLCONTEXT_USERUNMANAGED,
5091                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5092     ok(r == ERROR_UNKNOWN_PROPERTY,
5093        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5094     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5095     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5096
5097     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5099
5100     /* InstallSource value exists */
5101     sz = MAX_PATH;
5102     lstrcpyA(buf, "apple");
5103     r = pMsiGetProductInfoExA(prodcode, usersid,
5104                               MSIINSTALLCONTEXT_USERUNMANAGED,
5105                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5106     ok(r == ERROR_UNKNOWN_PROPERTY,
5107        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5108     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5109     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5110
5111     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5113
5114     /* LocalPackage value exists */
5115     sz = MAX_PATH;
5116     lstrcpyA(buf, "apple");
5117     r = pMsiGetProductInfoExA(prodcode, usersid,
5118                               MSIINSTALLCONTEXT_USERUNMANAGED,
5119                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5120     ok(r == ERROR_UNKNOWN_PROPERTY,
5121        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5122     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5123     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5124
5125     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5127
5128     /* Publisher value exists */
5129     sz = MAX_PATH;
5130     lstrcpyA(buf, "apple");
5131     r = pMsiGetProductInfoExA(prodcode, usersid,
5132                               MSIINSTALLCONTEXT_USERUNMANAGED,
5133                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5134     ok(r == ERROR_UNKNOWN_PROPERTY,
5135        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5136     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5137     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5138
5139     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5140     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5141
5142     /* URLInfoAbout value exists */
5143     sz = MAX_PATH;
5144     lstrcpyA(buf, "apple");
5145     r = pMsiGetProductInfoExA(prodcode, usersid,
5146                               MSIINSTALLCONTEXT_USERUNMANAGED,
5147                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5148     ok(r == ERROR_UNKNOWN_PROPERTY,
5149        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5150     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5151     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5152
5153     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5155
5156     /* URLUpdateInfo value exists */
5157     sz = MAX_PATH;
5158     lstrcpyA(buf, "apple");
5159     r = pMsiGetProductInfoExA(prodcode, usersid,
5160                               MSIINSTALLCONTEXT_USERUNMANAGED,
5161                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5162     ok(r == ERROR_UNKNOWN_PROPERTY,
5163        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5164     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5165     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5166
5167     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5168     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5169
5170     /* VersionMinor value exists */
5171     sz = MAX_PATH;
5172     lstrcpyA(buf, "apple");
5173     r = pMsiGetProductInfoExA(prodcode, usersid,
5174                               MSIINSTALLCONTEXT_USERUNMANAGED,
5175                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5176     ok(r == ERROR_UNKNOWN_PROPERTY,
5177        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5178     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5179     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5180
5181     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5183
5184     /* VersionMajor value exists */
5185     sz = MAX_PATH;
5186     lstrcpyA(buf, "apple");
5187     r = pMsiGetProductInfoExA(prodcode, usersid,
5188                               MSIINSTALLCONTEXT_USERUNMANAGED,
5189                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5190     ok(r == ERROR_UNKNOWN_PROPERTY,
5191        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5192     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5193     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5194
5195     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5197
5198     /* DisplayVersion value exists */
5199     sz = MAX_PATH;
5200     lstrcpyA(buf, "apple");
5201     r = pMsiGetProductInfoExA(prodcode, usersid,
5202                               MSIINSTALLCONTEXT_USERUNMANAGED,
5203                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5204     ok(r == ERROR_UNKNOWN_PROPERTY,
5205        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5206     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5207     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5208
5209     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5211
5212     /* ProductID value exists */
5213     sz = MAX_PATH;
5214     lstrcpyA(buf, "apple");
5215     r = pMsiGetProductInfoExA(prodcode, usersid,
5216                               MSIINSTALLCONTEXT_USERUNMANAGED,
5217                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5218     ok(r == ERROR_UNKNOWN_PROPERTY,
5219        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5220     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5221     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5222
5223     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5225
5226     /* RegCompany value exists */
5227     sz = MAX_PATH;
5228     lstrcpyA(buf, "apple");
5229     r = pMsiGetProductInfoExA(prodcode, usersid,
5230                               MSIINSTALLCONTEXT_USERUNMANAGED,
5231                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5232     ok(r == ERROR_UNKNOWN_PROPERTY,
5233        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5234     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5235     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5236
5237     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5239
5240     /* RegOwner value exists */
5241     sz = MAX_PATH;
5242     lstrcpyA(buf, "apple");
5243     r = pMsiGetProductInfoExA(prodcode, usersid,
5244                               MSIINSTALLCONTEXT_USERUNMANAGED,
5245                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5246     ok(r == ERROR_UNKNOWN_PROPERTY,
5247        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5248     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5249     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5250
5251     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5253
5254     /* Transforms value exists */
5255     sz = MAX_PATH;
5256     lstrcpyA(buf, "apple");
5257     r = pMsiGetProductInfoExA(prodcode, usersid,
5258                               MSIINSTALLCONTEXT_USERUNMANAGED,
5259                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5261     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5262     ok(sz == 5, "Expected 5, got %d\n", sz);
5263
5264     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5266
5267     /* Language value exists */
5268     sz = MAX_PATH;
5269     lstrcpyA(buf, "apple");
5270     r = pMsiGetProductInfoExA(prodcode, usersid,
5271                               MSIINSTALLCONTEXT_USERUNMANAGED,
5272                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5274     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5275     ok(sz == 4, "Expected 4, got %d\n", sz);
5276
5277     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5279
5280     /* ProductName value exists */
5281     sz = MAX_PATH;
5282     lstrcpyA(buf, "apple");
5283     r = pMsiGetProductInfoExA(prodcode, usersid,
5284                               MSIINSTALLCONTEXT_USERUNMANAGED,
5285                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5287     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5288     ok(sz == 4, "Expected 4, got %d\n", sz);
5289
5290     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5292
5293     /* FIXME */
5294
5295     /* AssignmentType value exists */
5296     sz = MAX_PATH;
5297     lstrcpyA(buf, "apple");
5298     r = pMsiGetProductInfoExA(prodcode, usersid,
5299                               MSIINSTALLCONTEXT_USERUNMANAGED,
5300                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5301     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5302     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5303     ok(sz == 0, "Expected 0, got %d\n", sz);
5304
5305     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5307
5308     /* FIXME */
5309
5310     /* PackageCode value exists */
5311     sz = MAX_PATH;
5312     lstrcpyA(buf, "apple");
5313     r = pMsiGetProductInfoExA(prodcode, usersid,
5314                               MSIINSTALLCONTEXT_USERUNMANAGED,
5315                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5316     todo_wine
5317     {
5318         ok(r == ERROR_BAD_CONFIGURATION,
5319            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5320         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5321         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5322     }
5323
5324     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5326
5327     /* Version value exists */
5328     sz = MAX_PATH;
5329     lstrcpyA(buf, "apple");
5330     r = pMsiGetProductInfoExA(prodcode, usersid,
5331                               MSIINSTALLCONTEXT_USERUNMANAGED,
5332                               INSTALLPROPERTY_VERSION, buf, &sz);
5333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5334     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5335     ok(sz == 3, "Expected 3, got %d\n", sz);
5336
5337     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5339
5340     /* ProductIcon value exists */
5341     sz = MAX_PATH;
5342     lstrcpyA(buf, "apple");
5343     r = pMsiGetProductInfoExA(prodcode, usersid,
5344                               MSIINSTALLCONTEXT_USERUNMANAGED,
5345                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5347     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5348     ok(sz == 4, "Expected 4, got %d\n", sz);
5349
5350     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5352
5353     /* PackageName value exists */
5354     sz = MAX_PATH;
5355     lstrcpyA(buf, "apple");
5356     r = pMsiGetProductInfoExA(prodcode, usersid,
5357                               MSIINSTALLCONTEXT_USERUNMANAGED,
5358                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5359     todo_wine
5360     {
5361         ok(r == ERROR_UNKNOWN_PRODUCT,
5362            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5363         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5364         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5365     }
5366
5367     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5369
5370     /* AuthorizedLUAApp value exists */
5371     sz = MAX_PATH;
5372     lstrcpyA(buf, "apple");
5373     r = pMsiGetProductInfoExA(prodcode, usersid,
5374                               MSIINSTALLCONTEXT_USERUNMANAGED,
5375                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5377     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5378     ok(sz == 4, "Expected 4, got %d\n", sz);
5379
5380     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5381     RegDeleteValueA(prodkey, "PackageName");
5382     RegDeleteValueA(prodkey, "ProductIcon");
5383     RegDeleteValueA(prodkey, "Version");
5384     RegDeleteValueA(prodkey, "PackageCode");
5385     RegDeleteValueA(prodkey, "AssignmentType");
5386     RegDeleteValueA(prodkey, "ProductName");
5387     RegDeleteValueA(prodkey, "Language");
5388     RegDeleteValueA(prodkey, "Transforms");
5389     RegDeleteValueA(prodkey, "RegOwner");
5390     RegDeleteValueA(prodkey, "RegCompany");
5391     RegDeleteValueA(prodkey, "ProductID");
5392     RegDeleteValueA(prodkey, "DisplayVersion");
5393     RegDeleteValueA(prodkey, "VersionMajor");
5394     RegDeleteValueA(prodkey, "VersionMinor");
5395     RegDeleteValueA(prodkey, "URLUpdateInfo");
5396     RegDeleteValueA(prodkey, "URLInfoAbout");
5397     RegDeleteValueA(prodkey, "Publisher");
5398     RegDeleteValueA(prodkey, "LocalPackage");
5399     RegDeleteValueA(prodkey, "InstallSource");
5400     RegDeleteValueA(prodkey, "InstallLocation");
5401     RegDeleteValueA(prodkey, "DisplayName");
5402     RegDeleteValueA(prodkey, "InstallDate");
5403     RegDeleteValueA(prodkey, "HelpTelephone");
5404     RegDeleteValueA(prodkey, "HelpLink");
5405     RegDeleteValueA(prodkey, "LocalPackage");
5406     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5407     RegCloseKey(prodkey);
5408
5409     /* MSIINSTALLCONTEXT_USERMANAGED */
5410
5411     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5412     lstrcatA(keypath, usersid);
5413     lstrcatA(keypath, "\\Products\\");
5414     lstrcatA(keypath, prod_squashed);
5415
5416     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5418
5419     /* local user product key exists */
5420     sz = MAX_PATH;
5421     lstrcpyA(buf, "apple");
5422     r = pMsiGetProductInfoExA(prodcode, usersid,
5423                               MSIINSTALLCONTEXT_USERMANAGED,
5424                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5425     ok(r == ERROR_UNKNOWN_PRODUCT,
5426        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5427     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5428     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5429
5430     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5432
5433     /* InstallProperties key exists */
5434     sz = MAX_PATH;
5435     lstrcpyA(buf, "apple");
5436     r = pMsiGetProductInfoExA(prodcode, usersid,
5437                               MSIINSTALLCONTEXT_USERMANAGED,
5438                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5439     ok(r == ERROR_UNKNOWN_PRODUCT,
5440        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5441     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5442     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5443
5444     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5446
5447     /* ManagedLocalPackage value exists */
5448     sz = MAX_PATH;
5449     lstrcpyA(buf, "apple");
5450     r = pMsiGetProductInfoExA(prodcode, usersid,
5451                               MSIINSTALLCONTEXT_USERMANAGED,
5452                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5453     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5454     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5455     ok(sz == 1, "Expected 1, got %d\n", sz);
5456
5457     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5459
5460     /* HelpLink value exists */
5461     sz = MAX_PATH;
5462     lstrcpyA(buf, "apple");
5463     r = pMsiGetProductInfoExA(prodcode, usersid,
5464                               MSIINSTALLCONTEXT_USERMANAGED,
5465                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5466     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5467     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5468     ok(sz == 4, "Expected 4, got %d\n", sz);
5469
5470     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5472
5473     /* HelpTelephone value exists */
5474     sz = MAX_PATH;
5475     lstrcpyA(buf, "apple");
5476     r = pMsiGetProductInfoExA(prodcode, usersid,
5477                               MSIINSTALLCONTEXT_USERMANAGED,
5478                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5480     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5481     ok(sz == 5, "Expected 5, got %d\n", sz);
5482
5483     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5485
5486     /* InstallDate value exists */
5487     sz = MAX_PATH;
5488     lstrcpyA(buf, "apple");
5489     r = pMsiGetProductInfoExA(prodcode, usersid,
5490                               MSIINSTALLCONTEXT_USERMANAGED,
5491                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5493     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5494     ok(sz == 4, "Expected 4, got %d\n", sz);
5495
5496     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5497     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5498
5499     /* DisplayName value exists */
5500     sz = MAX_PATH;
5501     lstrcpyA(buf, "apple");
5502     r = pMsiGetProductInfoExA(prodcode, usersid,
5503                               MSIINSTALLCONTEXT_USERMANAGED,
5504                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5506     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5507     ok(sz == 4, "Expected 4, got %d\n", sz);
5508
5509     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5511
5512     /* InstallLocation value exists */
5513     sz = MAX_PATH;
5514     lstrcpyA(buf, "apple");
5515     r = pMsiGetProductInfoExA(prodcode, usersid,
5516                               MSIINSTALLCONTEXT_USERMANAGED,
5517                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5518     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5519     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5520     ok(sz == 3, "Expected 3, got %d\n", sz);
5521
5522     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5524
5525     /* InstallSource value exists */
5526     sz = MAX_PATH;
5527     lstrcpyA(buf, "apple");
5528     r = pMsiGetProductInfoExA(prodcode, usersid,
5529                               MSIINSTALLCONTEXT_USERMANAGED,
5530                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5531     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5532     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5533     ok(sz == 6, "Expected 6, got %d\n", sz);
5534
5535     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5536     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5537
5538     /* LocalPackage value exists */
5539     sz = MAX_PATH;
5540     lstrcpyA(buf, "apple");
5541     r = pMsiGetProductInfoExA(prodcode, usersid,
5542                               MSIINSTALLCONTEXT_USERMANAGED,
5543                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5545     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5546     ok(sz == 5, "Expected 5, got %d\n", sz);
5547
5548     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5550
5551     /* Publisher value exists */
5552     sz = MAX_PATH;
5553     lstrcpyA(buf, "apple");
5554     r = pMsiGetProductInfoExA(prodcode, usersid,
5555                               MSIINSTALLCONTEXT_USERMANAGED,
5556                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5557     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5558     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5559     ok(sz == 3, "Expected 3, got %d\n", sz);
5560
5561     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5563
5564     /* URLInfoAbout value exists */
5565     sz = MAX_PATH;
5566     lstrcpyA(buf, "apple");
5567     r = pMsiGetProductInfoExA(prodcode, usersid,
5568                               MSIINSTALLCONTEXT_USERMANAGED,
5569                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5570     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5571     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5572     ok(sz == 5, "Expected 5, got %d\n", sz);
5573
5574     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5576
5577     /* URLUpdateInfo value exists */
5578     sz = MAX_PATH;
5579     lstrcpyA(buf, "apple");
5580     r = pMsiGetProductInfoExA(prodcode, usersid,
5581                               MSIINSTALLCONTEXT_USERMANAGED,
5582                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5583     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5584     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5585     ok(sz == 6, "Expected 6, got %d\n", sz);
5586
5587     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5589
5590     /* VersionMinor value exists */
5591     sz = MAX_PATH;
5592     lstrcpyA(buf, "apple");
5593     r = pMsiGetProductInfoExA(prodcode, usersid,
5594                               MSIINSTALLCONTEXT_USERMANAGED,
5595                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5596     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5597     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5598     ok(sz == 1, "Expected 1, got %d\n", sz);
5599
5600     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5602
5603     /* VersionMajor value exists */
5604     sz = MAX_PATH;
5605     lstrcpyA(buf, "apple");
5606     r = pMsiGetProductInfoExA(prodcode, usersid,
5607                               MSIINSTALLCONTEXT_USERMANAGED,
5608                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5609     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5610     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5611     ok(sz == 1, "Expected 1, got %d\n", sz);
5612
5613     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5615
5616     /* DisplayVersion value exists */
5617     sz = MAX_PATH;
5618     lstrcpyA(buf, "apple");
5619     r = pMsiGetProductInfoExA(prodcode, usersid,
5620                               MSIINSTALLCONTEXT_USERMANAGED,
5621                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5622     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5623     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5624     ok(sz == 5, "Expected 5, got %d\n", sz);
5625
5626     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5628
5629     /* ProductID value exists */
5630     sz = MAX_PATH;
5631     lstrcpyA(buf, "apple");
5632     r = pMsiGetProductInfoExA(prodcode, usersid,
5633                               MSIINSTALLCONTEXT_USERMANAGED,
5634                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5636     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5637     ok(sz == 2, "Expected 2, got %d\n", sz);
5638
5639     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5641
5642     /* RegCompany value exists */
5643     sz = MAX_PATH;
5644     lstrcpyA(buf, "apple");
5645     r = pMsiGetProductInfoExA(prodcode, usersid,
5646                               MSIINSTALLCONTEXT_USERMANAGED,
5647                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5649     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5650     ok(sz == 4, "Expected 4, got %d\n", sz);
5651
5652     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5654
5655     /* RegOwner value exists */
5656     sz = MAX_PATH;
5657     lstrcpyA(buf, "apple");
5658     r = pMsiGetProductInfoExA(prodcode, usersid,
5659                               MSIINSTALLCONTEXT_USERMANAGED,
5660                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5662     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5663     ok(sz == 5, "Expected 5, got %d\n", sz);
5664
5665     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5667
5668     /* Transforms value exists */
5669     sz = MAX_PATH;
5670     lstrcpyA(buf, "apple");
5671     r = pMsiGetProductInfoExA(prodcode, usersid,
5672                               MSIINSTALLCONTEXT_USERMANAGED,
5673                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5674     ok(r == ERROR_UNKNOWN_PRODUCT,
5675        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5676     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5677     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5678
5679     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5681
5682     /* Language value exists */
5683     sz = MAX_PATH;
5684     lstrcpyA(buf, "apple");
5685     r = pMsiGetProductInfoExA(prodcode, usersid,
5686                               MSIINSTALLCONTEXT_USERMANAGED,
5687                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5688     ok(r == ERROR_UNKNOWN_PRODUCT,
5689        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5690     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5691     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5692
5693     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5695
5696     /* ProductName value exists */
5697     sz = MAX_PATH;
5698     lstrcpyA(buf, "apple");
5699     r = pMsiGetProductInfoExA(prodcode, usersid,
5700                               MSIINSTALLCONTEXT_USERMANAGED,
5701                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5702     ok(r == ERROR_UNKNOWN_PRODUCT,
5703        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5704     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5705     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5706
5707     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5709
5710     /* FIXME */
5711
5712     /* AssignmentType value exists */
5713     sz = MAX_PATH;
5714     lstrcpyA(buf, "apple");
5715     r = pMsiGetProductInfoExA(prodcode, usersid,
5716                               MSIINSTALLCONTEXT_USERMANAGED,
5717                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5718     ok(r == ERROR_UNKNOWN_PRODUCT,
5719        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5720     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5721     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5722
5723     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5725
5726     /* PackageCode value exists */
5727     sz = MAX_PATH;
5728     lstrcpyA(buf, "apple");
5729     r = pMsiGetProductInfoExA(prodcode, usersid,
5730                               MSIINSTALLCONTEXT_USERMANAGED,
5731                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5732     ok(r == ERROR_UNKNOWN_PRODUCT,
5733        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5734     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5735     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5736
5737     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5739
5740     /* Version value exists */
5741     sz = MAX_PATH;
5742     lstrcpyA(buf, "apple");
5743     r = pMsiGetProductInfoExA(prodcode, usersid,
5744                               MSIINSTALLCONTEXT_USERMANAGED,
5745                               INSTALLPROPERTY_VERSION, buf, &sz);
5746     ok(r == ERROR_UNKNOWN_PRODUCT,
5747        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5748     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5749     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5750
5751     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5753
5754     /* ProductIcon value exists */
5755     sz = MAX_PATH;
5756     lstrcpyA(buf, "apple");
5757     r = pMsiGetProductInfoExA(prodcode, usersid,
5758                               MSIINSTALLCONTEXT_USERMANAGED,
5759                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5760     ok(r == ERROR_UNKNOWN_PRODUCT,
5761        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5762     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5763     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5764
5765     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5767
5768     /* PackageName value exists */
5769     sz = MAX_PATH;
5770     lstrcpyA(buf, "apple");
5771     r = pMsiGetProductInfoExA(prodcode, usersid,
5772                               MSIINSTALLCONTEXT_USERMANAGED,
5773                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5774     ok(r == ERROR_UNKNOWN_PRODUCT,
5775        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5776     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5777     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5778
5779     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5780     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5781
5782     /* AuthorizedLUAApp value exists */
5783     sz = MAX_PATH;
5784     lstrcpyA(buf, "apple");
5785     r = pMsiGetProductInfoExA(prodcode, usersid,
5786                               MSIINSTALLCONTEXT_USERMANAGED,
5787                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5788     ok(r == ERROR_UNKNOWN_PRODUCT,
5789        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5790     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5791     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5792
5793     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5794     RegDeleteValueA(propkey, "PackageName");
5795     RegDeleteValueA(propkey, "ProductIcon");
5796     RegDeleteValueA(propkey, "Version");
5797     RegDeleteValueA(propkey, "PackageCode");
5798     RegDeleteValueA(propkey, "AssignmentType");
5799     RegDeleteValueA(propkey, "ProductName");
5800     RegDeleteValueA(propkey, "Language");
5801     RegDeleteValueA(propkey, "Transforms");
5802     RegDeleteValueA(propkey, "RegOwner");
5803     RegDeleteValueA(propkey, "RegCompany");
5804     RegDeleteValueA(propkey, "ProductID");
5805     RegDeleteValueA(propkey, "DisplayVersion");
5806     RegDeleteValueA(propkey, "VersionMajor");
5807     RegDeleteValueA(propkey, "VersionMinor");
5808     RegDeleteValueA(propkey, "URLUpdateInfo");
5809     RegDeleteValueA(propkey, "URLInfoAbout");
5810     RegDeleteValueA(propkey, "Publisher");
5811     RegDeleteValueA(propkey, "LocalPackage");
5812     RegDeleteValueA(propkey, "InstallSource");
5813     RegDeleteValueA(propkey, "InstallLocation");
5814     RegDeleteValueA(propkey, "DisplayName");
5815     RegDeleteValueA(propkey, "InstallDate");
5816     RegDeleteValueA(propkey, "HelpTelephone");
5817     RegDeleteValueA(propkey, "HelpLink");
5818     RegDeleteValueA(propkey, "ManagedLocalPackage");
5819     delete_key(propkey, "", access & KEY_WOW64_64KEY);
5820     RegCloseKey(propkey);
5821     delete_key(localkey, "", access & KEY_WOW64_64KEY);
5822     RegCloseKey(localkey);
5823
5824     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5825     lstrcatA(keypath, usersid);
5826     lstrcatA(keypath, "\\Installer\\Products\\");
5827     lstrcatA(keypath, prod_squashed);
5828
5829     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5830     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5831
5832     /* user product key exists */
5833     sz = MAX_PATH;
5834     lstrcpyA(buf, "apple");
5835     r = pMsiGetProductInfoExA(prodcode, usersid,
5836                               MSIINSTALLCONTEXT_USERMANAGED,
5837                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5838     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5839     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5840     ok(sz == 1, "Expected 1, got %d\n", sz);
5841
5842     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5843     RegCloseKey(userkey);
5844
5845     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5846     lstrcatA(keypath, prod_squashed);
5847
5848     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5850
5851     /* current user product key exists */
5852     sz = MAX_PATH;
5853     lstrcpyA(buf, "apple");
5854     r = pMsiGetProductInfoExA(prodcode, usersid,
5855                               MSIINSTALLCONTEXT_USERMANAGED,
5856                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5857     ok(r == ERROR_UNKNOWN_PRODUCT,
5858        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5859     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5860     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5861
5862     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5864
5865     /* HelpLink value exists, user product key does not exist */
5866     sz = MAX_PATH;
5867     lstrcpyA(buf, "apple");
5868     r = pMsiGetProductInfoExA(prodcode, usersid,
5869                               MSIINSTALLCONTEXT_USERMANAGED,
5870                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5871     ok(r == ERROR_UNKNOWN_PRODUCT,
5872        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5873     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5874     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5875
5876     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5877     lstrcatA(keypath, usersid);
5878     lstrcatA(keypath, "\\Installer\\Products\\");
5879     lstrcatA(keypath, prod_squashed);
5880
5881     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5883
5884     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5886
5887     /* HelpLink value exists, user product key does exist */
5888     sz = MAX_PATH;
5889     lstrcpyA(buf, "apple");
5890     r = pMsiGetProductInfoExA(prodcode, usersid,
5891                               MSIINSTALLCONTEXT_USERMANAGED,
5892                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5893     ok(r == ERROR_UNKNOWN_PROPERTY,
5894        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5895     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5896     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5897
5898     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5900
5901     /* HelpTelephone value exists */
5902     sz = MAX_PATH;
5903     lstrcpyA(buf, "apple");
5904     r = pMsiGetProductInfoExA(prodcode, usersid,
5905                               MSIINSTALLCONTEXT_USERMANAGED,
5906                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5907     ok(r == ERROR_UNKNOWN_PROPERTY,
5908        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5909     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5910     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5911
5912     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5914
5915     /* InstallDate value exists */
5916     sz = MAX_PATH;
5917     lstrcpyA(buf, "apple");
5918     r = pMsiGetProductInfoExA(prodcode, usersid,
5919                               MSIINSTALLCONTEXT_USERMANAGED,
5920                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5921     ok(r == ERROR_UNKNOWN_PROPERTY,
5922        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5923     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5924     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5925
5926     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5928
5929     /* DisplayName value exists */
5930     sz = MAX_PATH;
5931     lstrcpyA(buf, "apple");
5932     r = pMsiGetProductInfoExA(prodcode, usersid,
5933                               MSIINSTALLCONTEXT_USERMANAGED,
5934                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5935     ok(r == ERROR_UNKNOWN_PROPERTY,
5936        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5937     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5938     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5939
5940     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5941     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5942
5943     /* InstallLocation value exists */
5944     sz = MAX_PATH;
5945     lstrcpyA(buf, "apple");
5946     r = pMsiGetProductInfoExA(prodcode, usersid,
5947                               MSIINSTALLCONTEXT_USERMANAGED,
5948                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5949     ok(r == ERROR_UNKNOWN_PROPERTY,
5950        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5951     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5952     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5953
5954     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5956
5957     /* InstallSource value exists */
5958     sz = MAX_PATH;
5959     lstrcpyA(buf, "apple");
5960     r = pMsiGetProductInfoExA(prodcode, usersid,
5961                               MSIINSTALLCONTEXT_USERMANAGED,
5962                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5963     ok(r == ERROR_UNKNOWN_PROPERTY,
5964        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5965     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5966     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5967
5968     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5970
5971     /* LocalPackage value exists */
5972     sz = MAX_PATH;
5973     lstrcpyA(buf, "apple");
5974     r = pMsiGetProductInfoExA(prodcode, usersid,
5975                               MSIINSTALLCONTEXT_USERMANAGED,
5976                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5977     ok(r == ERROR_UNKNOWN_PROPERTY,
5978        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5979     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5980     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5981
5982     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5984
5985     /* Publisher value exists */
5986     sz = MAX_PATH;
5987     lstrcpyA(buf, "apple");
5988     r = pMsiGetProductInfoExA(prodcode, usersid,
5989                               MSIINSTALLCONTEXT_USERMANAGED,
5990                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5991     ok(r == ERROR_UNKNOWN_PROPERTY,
5992        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5993     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5994     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5995
5996     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5998
5999     /* URLInfoAbout value exists */
6000     sz = MAX_PATH;
6001     lstrcpyA(buf, "apple");
6002     r = pMsiGetProductInfoExA(prodcode, usersid,
6003                               MSIINSTALLCONTEXT_USERMANAGED,
6004                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6005     ok(r == ERROR_UNKNOWN_PROPERTY,
6006        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6007     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6008     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6009
6010     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6012
6013     /* URLUpdateInfo value exists */
6014     sz = MAX_PATH;
6015     lstrcpyA(buf, "apple");
6016     r = pMsiGetProductInfoExA(prodcode, usersid,
6017                               MSIINSTALLCONTEXT_USERMANAGED,
6018                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6019     ok(r == ERROR_UNKNOWN_PROPERTY,
6020        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6021     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6022     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6023
6024     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6026
6027     /* VersionMinor value exists */
6028     sz = MAX_PATH;
6029     lstrcpyA(buf, "apple");
6030     r = pMsiGetProductInfoExA(prodcode, usersid,
6031                               MSIINSTALLCONTEXT_USERMANAGED,
6032                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6033     ok(r == ERROR_UNKNOWN_PROPERTY,
6034        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6035     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6036     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6037
6038     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6040
6041     /* VersionMajor value exists */
6042     sz = MAX_PATH;
6043     lstrcpyA(buf, "apple");
6044     r = pMsiGetProductInfoExA(prodcode, usersid,
6045                               MSIINSTALLCONTEXT_USERMANAGED,
6046                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6047     ok(r == ERROR_UNKNOWN_PROPERTY,
6048        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6049     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6050     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6051
6052     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6054
6055     /* DisplayVersion value exists */
6056     sz = MAX_PATH;
6057     lstrcpyA(buf, "apple");
6058     r = pMsiGetProductInfoExA(prodcode, usersid,
6059                               MSIINSTALLCONTEXT_USERMANAGED,
6060                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6061     ok(r == ERROR_UNKNOWN_PROPERTY,
6062        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6063     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6064     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6065
6066     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6068
6069     /* ProductID value exists */
6070     sz = MAX_PATH;
6071     lstrcpyA(buf, "apple");
6072     r = pMsiGetProductInfoExA(prodcode, usersid,
6073                               MSIINSTALLCONTEXT_USERMANAGED,
6074                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6075     ok(r == ERROR_UNKNOWN_PROPERTY,
6076        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6077     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6078     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6079
6080     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6082
6083     /* RegCompany value exists */
6084     sz = MAX_PATH;
6085     lstrcpyA(buf, "apple");
6086     r = pMsiGetProductInfoExA(prodcode, usersid,
6087                               MSIINSTALLCONTEXT_USERMANAGED,
6088                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6089     ok(r == ERROR_UNKNOWN_PROPERTY,
6090        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6091     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6092     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6093
6094     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6095     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6096
6097     /* RegOwner value exists */
6098     sz = MAX_PATH;
6099     lstrcpyA(buf, "apple");
6100     r = pMsiGetProductInfoExA(prodcode, usersid,
6101                               MSIINSTALLCONTEXT_USERMANAGED,
6102                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6103     ok(r == ERROR_UNKNOWN_PROPERTY,
6104        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6105     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6106     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6107
6108     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6110
6111     /* Transforms value exists */
6112     sz = MAX_PATH;
6113     lstrcpyA(buf, "apple");
6114     r = pMsiGetProductInfoExA(prodcode, usersid,
6115                               MSIINSTALLCONTEXT_USERMANAGED,
6116                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6118     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6119     ok(sz == 5, "Expected 5, got %d\n", sz);
6120
6121     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6123
6124     /* Language value exists */
6125     sz = MAX_PATH;
6126     lstrcpyA(buf, "apple");
6127     r = pMsiGetProductInfoExA(prodcode, usersid,
6128                               MSIINSTALLCONTEXT_USERMANAGED,
6129                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6131     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6132     ok(sz == 4, "Expected 4, got %d\n", sz);
6133
6134     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6136
6137     /* ProductName value exists */
6138     sz = MAX_PATH;
6139     lstrcpyA(buf, "apple");
6140     r = pMsiGetProductInfoExA(prodcode, usersid,
6141                               MSIINSTALLCONTEXT_USERMANAGED,
6142                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6143     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6144     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6145     ok(sz == 4, "Expected 4, got %d\n", sz);
6146
6147     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6149
6150     /* FIXME */
6151
6152     /* AssignmentType value exists */
6153     sz = MAX_PATH;
6154     lstrcpyA(buf, "apple");
6155     r = pMsiGetProductInfoExA(prodcode, usersid,
6156                               MSIINSTALLCONTEXT_USERMANAGED,
6157                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6159     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6160     ok(sz == 0, "Expected 0, got %d\n", sz);
6161
6162     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6164
6165     /* FIXME */
6166
6167     /* PackageCode value exists */
6168     sz = MAX_PATH;
6169     lstrcpyA(buf, "apple");
6170     r = pMsiGetProductInfoExA(prodcode, usersid,
6171                               MSIINSTALLCONTEXT_USERMANAGED,
6172                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6173     todo_wine
6174     {
6175         ok(r == ERROR_BAD_CONFIGURATION,
6176            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6177         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6178         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6179     }
6180
6181     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6183
6184     /* Version value exists */
6185     sz = MAX_PATH;
6186     lstrcpyA(buf, "apple");
6187     r = pMsiGetProductInfoExA(prodcode, usersid,
6188                               MSIINSTALLCONTEXT_USERMANAGED,
6189                               INSTALLPROPERTY_VERSION, buf, &sz);
6190     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6191     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6192     ok(sz == 3, "Expected 3, got %d\n", sz);
6193
6194     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6196
6197     /* ProductIcon value exists */
6198     sz = MAX_PATH;
6199     lstrcpyA(buf, "apple");
6200     r = pMsiGetProductInfoExA(prodcode, usersid,
6201                               MSIINSTALLCONTEXT_USERMANAGED,
6202                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6204     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6205     ok(sz == 4, "Expected 4, got %d\n", sz);
6206
6207     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6209
6210     /* PackageName value exists */
6211     sz = MAX_PATH;
6212     lstrcpyA(buf, "apple");
6213     r = pMsiGetProductInfoExA(prodcode, usersid,
6214                               MSIINSTALLCONTEXT_USERMANAGED,
6215                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6216     todo_wine
6217     {
6218         ok(r == ERROR_UNKNOWN_PRODUCT,
6219            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6220         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6221         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6222     }
6223
6224     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6226
6227     /* AuthorizedLUAApp value exists */
6228     sz = MAX_PATH;
6229     lstrcpyA(buf, "apple");
6230     r = pMsiGetProductInfoExA(prodcode, usersid,
6231                               MSIINSTALLCONTEXT_USERMANAGED,
6232                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6234     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6235     ok(sz == 4, "Expected 4, got %d\n", sz);
6236
6237     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6238     RegDeleteValueA(userkey, "PackageName");
6239     RegDeleteValueA(userkey, "ProductIcon");
6240     RegDeleteValueA(userkey, "Version");
6241     RegDeleteValueA(userkey, "PackageCode");
6242     RegDeleteValueA(userkey, "AssignmentType");
6243     RegDeleteValueA(userkey, "ProductName");
6244     RegDeleteValueA(userkey, "Language");
6245     RegDeleteValueA(userkey, "Transforms");
6246     RegDeleteValueA(userkey, "RegOwner");
6247     RegDeleteValueA(userkey, "RegCompany");
6248     RegDeleteValueA(userkey, "ProductID");
6249     RegDeleteValueA(userkey, "DisplayVersion");
6250     RegDeleteValueA(userkey, "VersionMajor");
6251     RegDeleteValueA(userkey, "VersionMinor");
6252     RegDeleteValueA(userkey, "URLUpdateInfo");
6253     RegDeleteValueA(userkey, "URLInfoAbout");
6254     RegDeleteValueA(userkey, "Publisher");
6255     RegDeleteValueA(userkey, "LocalPackage");
6256     RegDeleteValueA(userkey, "InstallSource");
6257     RegDeleteValueA(userkey, "InstallLocation");
6258     RegDeleteValueA(userkey, "DisplayName");
6259     RegDeleteValueA(userkey, "InstallDate");
6260     RegDeleteValueA(userkey, "HelpTelephone");
6261     RegDeleteValueA(userkey, "HelpLink");
6262     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6263     RegCloseKey(userkey);
6264     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6265     RegCloseKey(prodkey);
6266
6267     /* MSIINSTALLCONTEXT_MACHINE */
6268
6269     /* szUserSid is non-NULL */
6270     sz = MAX_PATH;
6271     lstrcpyA(buf, "apple");
6272     r = pMsiGetProductInfoExA(prodcode, usersid,
6273                               MSIINSTALLCONTEXT_MACHINE,
6274                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6275     ok(r == ERROR_INVALID_PARAMETER,
6276        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6277     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6278     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6279
6280     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6281     lstrcatA(keypath, prod_squashed);
6282
6283     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6285
6286     /* local system product key exists */
6287     sz = MAX_PATH;
6288     lstrcpyA(buf, "apple");
6289     r = pMsiGetProductInfoExA(prodcode, NULL,
6290                               MSIINSTALLCONTEXT_MACHINE,
6291                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6292     ok(r == ERROR_UNKNOWN_PRODUCT,
6293        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6294     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6295     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6296
6297     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6299
6300     /* InstallProperties key exists */
6301     sz = MAX_PATH;
6302     lstrcpyA(buf, "apple");
6303     r = pMsiGetProductInfoExA(prodcode, NULL,
6304                               MSIINSTALLCONTEXT_MACHINE,
6305                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6306     ok(r == ERROR_UNKNOWN_PRODUCT,
6307        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6308     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6309     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6310
6311     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6312     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6313
6314     /* LocalPackage value exists */
6315     sz = MAX_PATH;
6316     lstrcpyA(buf, "apple");
6317     r = pMsiGetProductInfoExA(prodcode, NULL,
6318                               MSIINSTALLCONTEXT_MACHINE,
6319                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6321     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6322     ok(sz == 1, "Expected 1, got %d\n", sz);
6323
6324     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6326
6327     /* HelpLink value exists */
6328     sz = MAX_PATH;
6329     lstrcpyA(buf, "apple");
6330     r = pMsiGetProductInfoExA(prodcode, NULL,
6331                               MSIINSTALLCONTEXT_MACHINE,
6332                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6334     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6335     ok(sz == 4, "Expected 4, got %d\n", sz);
6336
6337     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6339
6340     /* HelpTelephone value exists */
6341     sz = MAX_PATH;
6342     lstrcpyA(buf, "apple");
6343     r = pMsiGetProductInfoExA(prodcode, NULL,
6344                               MSIINSTALLCONTEXT_MACHINE,
6345                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6347     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6348     ok(sz == 5, "Expected 5, got %d\n", sz);
6349
6350     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6352
6353     /* InstallDate value exists */
6354     sz = MAX_PATH;
6355     lstrcpyA(buf, "apple");
6356     r = pMsiGetProductInfoExA(prodcode, NULL,
6357                               MSIINSTALLCONTEXT_MACHINE,
6358                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6360     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6361     ok(sz == 4, "Expected 4, got %d\n", sz);
6362
6363     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6365
6366     /* DisplayName value exists */
6367     sz = MAX_PATH;
6368     lstrcpyA(buf, "apple");
6369     r = pMsiGetProductInfoExA(prodcode, NULL,
6370                               MSIINSTALLCONTEXT_MACHINE,
6371                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6373     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6374     ok(sz == 4, "Expected 4, got %d\n", sz);
6375
6376     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6378
6379     /* InstallLocation value exists */
6380     sz = MAX_PATH;
6381     lstrcpyA(buf, "apple");
6382     r = pMsiGetProductInfoExA(prodcode, NULL,
6383                               MSIINSTALLCONTEXT_MACHINE,
6384                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6385     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6386     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6387     ok(sz == 3, "Expected 3, got %d\n", sz);
6388
6389     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6390     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6391
6392     /* InstallSource value exists */
6393     sz = MAX_PATH;
6394     lstrcpyA(buf, "apple");
6395     r = pMsiGetProductInfoExA(prodcode, NULL,
6396                               MSIINSTALLCONTEXT_MACHINE,
6397                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6398     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6399     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6400     ok(sz == 6, "Expected 6, got %d\n", sz);
6401
6402     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6404
6405     /* LocalPackage value exists */
6406     sz = MAX_PATH;
6407     lstrcpyA(buf, "apple");
6408     r = pMsiGetProductInfoExA(prodcode, NULL,
6409                               MSIINSTALLCONTEXT_MACHINE,
6410                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6412     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6413     ok(sz == 5, "Expected 5, got %d\n", sz);
6414
6415     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6417
6418     /* Publisher value exists */
6419     sz = MAX_PATH;
6420     lstrcpyA(buf, "apple");
6421     r = pMsiGetProductInfoExA(prodcode, NULL,
6422                               MSIINSTALLCONTEXT_MACHINE,
6423                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6425     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6426     ok(sz == 3, "Expected 3, got %d\n", sz);
6427
6428     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6430
6431     /* URLInfoAbout value exists */
6432     sz = MAX_PATH;
6433     lstrcpyA(buf, "apple");
6434     r = pMsiGetProductInfoExA(prodcode, NULL,
6435                               MSIINSTALLCONTEXT_MACHINE,
6436                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6438     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6439     ok(sz == 5, "Expected 5, got %d\n", sz);
6440
6441     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6443
6444     /* URLUpdateInfo value exists */
6445     sz = MAX_PATH;
6446     lstrcpyA(buf, "apple");
6447     r = pMsiGetProductInfoExA(prodcode, NULL,
6448                               MSIINSTALLCONTEXT_MACHINE,
6449                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6451     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6452     ok(sz == 6, "Expected 6, got %d\n", sz);
6453
6454     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6456
6457     /* VersionMinor value exists */
6458     sz = MAX_PATH;
6459     lstrcpyA(buf, "apple");
6460     r = pMsiGetProductInfoExA(prodcode, NULL,
6461                               MSIINSTALLCONTEXT_MACHINE,
6462                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6464     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6465     ok(sz == 1, "Expected 1, got %d\n", sz);
6466
6467     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6469
6470     /* VersionMajor value exists */
6471     sz = MAX_PATH;
6472     lstrcpyA(buf, "apple");
6473     r = pMsiGetProductInfoExA(prodcode, NULL,
6474                               MSIINSTALLCONTEXT_MACHINE,
6475                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6477     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6478     ok(sz == 1, "Expected 1, got %d\n", sz);
6479
6480     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6481     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6482
6483     /* DisplayVersion value exists */
6484     sz = MAX_PATH;
6485     lstrcpyA(buf, "apple");
6486     r = pMsiGetProductInfoExA(prodcode, NULL,
6487                               MSIINSTALLCONTEXT_MACHINE,
6488                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6489     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6490     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6491     ok(sz == 5, "Expected 5, got %d\n", sz);
6492
6493     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6495
6496     /* ProductID value exists */
6497     sz = MAX_PATH;
6498     lstrcpyA(buf, "apple");
6499     r = pMsiGetProductInfoExA(prodcode, NULL,
6500                               MSIINSTALLCONTEXT_MACHINE,
6501                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6502     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6503     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6504     ok(sz == 2, "Expected 2, got %d\n", sz);
6505
6506     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6508
6509     /* RegCompany value exists */
6510     sz = MAX_PATH;
6511     lstrcpyA(buf, "apple");
6512     r = pMsiGetProductInfoExA(prodcode, NULL,
6513                               MSIINSTALLCONTEXT_MACHINE,
6514                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6516     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6517     ok(sz == 4, "Expected 4, got %d\n", sz);
6518
6519     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6521
6522     /* RegOwner value exists */
6523     sz = MAX_PATH;
6524     lstrcpyA(buf, "apple");
6525     r = pMsiGetProductInfoExA(prodcode, NULL,
6526                               MSIINSTALLCONTEXT_MACHINE,
6527                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6529     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6530     ok(sz == 5, "Expected 5, got %d\n", sz);
6531
6532     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6534
6535     /* Transforms value exists */
6536     sz = MAX_PATH;
6537     lstrcpyA(buf, "apple");
6538     r = pMsiGetProductInfoExA(prodcode, NULL,
6539                               MSIINSTALLCONTEXT_MACHINE,
6540                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6541     ok(r == ERROR_UNKNOWN_PRODUCT,
6542        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6543     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6544     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6545
6546     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6548
6549     /* Language value exists */
6550     sz = MAX_PATH;
6551     lstrcpyA(buf, "apple");
6552     r = pMsiGetProductInfoExA(prodcode, NULL,
6553                               MSIINSTALLCONTEXT_MACHINE,
6554                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6555     ok(r == ERROR_UNKNOWN_PRODUCT,
6556        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6557     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6558     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6559
6560     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6562
6563     /* ProductName value exists */
6564     sz = MAX_PATH;
6565     lstrcpyA(buf, "apple");
6566     r = pMsiGetProductInfoExA(prodcode, NULL,
6567                               MSIINSTALLCONTEXT_MACHINE,
6568                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6569     ok(r == ERROR_UNKNOWN_PRODUCT,
6570        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6571     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6572     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6573
6574     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6576
6577     /* FIXME */
6578
6579     /* AssignmentType value exists */
6580     sz = MAX_PATH;
6581     lstrcpyA(buf, "apple");
6582     r = pMsiGetProductInfoExA(prodcode, NULL,
6583                               MSIINSTALLCONTEXT_MACHINE,
6584                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6585     ok(r == ERROR_UNKNOWN_PRODUCT,
6586        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6587     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6588     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6589
6590     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6592
6593     /* PackageCode value exists */
6594     sz = MAX_PATH;
6595     lstrcpyA(buf, "apple");
6596     r = pMsiGetProductInfoExA(prodcode, NULL,
6597                               MSIINSTALLCONTEXT_MACHINE,
6598                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6599     ok(r == ERROR_UNKNOWN_PRODUCT,
6600        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6601     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6602     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6603
6604     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6605     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6606
6607     /* Version value exists */
6608     sz = MAX_PATH;
6609     lstrcpyA(buf, "apple");
6610     r = pMsiGetProductInfoExA(prodcode, NULL,
6611                               MSIINSTALLCONTEXT_MACHINE,
6612                               INSTALLPROPERTY_VERSION, buf, &sz);
6613     ok(r == ERROR_UNKNOWN_PRODUCT,
6614        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6615     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6616     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6617
6618     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6620
6621     /* ProductIcon value exists */
6622     sz = MAX_PATH;
6623     lstrcpyA(buf, "apple");
6624     r = pMsiGetProductInfoExA(prodcode, NULL,
6625                               MSIINSTALLCONTEXT_MACHINE,
6626                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6627     ok(r == ERROR_UNKNOWN_PRODUCT,
6628        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6629     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6630     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6631
6632     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6633     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6634
6635     /* PackageName value exists */
6636     sz = MAX_PATH;
6637     lstrcpyA(buf, "apple");
6638     r = pMsiGetProductInfoExA(prodcode, NULL,
6639                               MSIINSTALLCONTEXT_MACHINE,
6640                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6641     ok(r == ERROR_UNKNOWN_PRODUCT,
6642        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6643     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6644     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6645
6646     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6648
6649     /* AuthorizedLUAApp value exists */
6650     sz = MAX_PATH;
6651     lstrcpyA(buf, "apple");
6652     r = pMsiGetProductInfoExA(prodcode, NULL,
6653                               MSIINSTALLCONTEXT_MACHINE,
6654                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6655     ok(r == ERROR_UNKNOWN_PRODUCT,
6656        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6657     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6658     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6659
6660     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6661     RegDeleteValueA(propkey, "PackageName");
6662     RegDeleteValueA(propkey, "ProductIcon");
6663     RegDeleteValueA(propkey, "Version");
6664     RegDeleteValueA(propkey, "PackageCode");
6665     RegDeleteValueA(propkey, "AssignmentType");
6666     RegDeleteValueA(propkey, "ProductName");
6667     RegDeleteValueA(propkey, "Language");
6668     RegDeleteValueA(propkey, "Transforms");
6669     RegDeleteValueA(propkey, "RegOwner");
6670     RegDeleteValueA(propkey, "RegCompany");
6671     RegDeleteValueA(propkey, "ProductID");
6672     RegDeleteValueA(propkey, "DisplayVersion");
6673     RegDeleteValueA(propkey, "VersionMajor");
6674     RegDeleteValueA(propkey, "VersionMinor");
6675     RegDeleteValueA(propkey, "URLUpdateInfo");
6676     RegDeleteValueA(propkey, "URLInfoAbout");
6677     RegDeleteValueA(propkey, "Publisher");
6678     RegDeleteValueA(propkey, "LocalPackage");
6679     RegDeleteValueA(propkey, "InstallSource");
6680     RegDeleteValueA(propkey, "InstallLocation");
6681     RegDeleteValueA(propkey, "DisplayName");
6682     RegDeleteValueA(propkey, "InstallDate");
6683     RegDeleteValueA(propkey, "HelpTelephone");
6684     RegDeleteValueA(propkey, "HelpLink");
6685     RegDeleteValueA(propkey, "LocalPackage");
6686     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6687     RegCloseKey(propkey);
6688     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6689     RegCloseKey(localkey);
6690
6691     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6692     lstrcatA(keypath, prod_squashed);
6693
6694     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6696
6697     /* local classes product key exists */
6698     sz = MAX_PATH;
6699     lstrcpyA(buf, "apple");
6700     r = pMsiGetProductInfoExA(prodcode, NULL,
6701                               MSIINSTALLCONTEXT_MACHINE,
6702                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6704     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6705     ok(sz == 1, "Expected 1, got %d\n", sz);
6706
6707     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6709
6710     /* HelpLink value exists */
6711     sz = MAX_PATH;
6712     lstrcpyA(buf, "apple");
6713     r = pMsiGetProductInfoExA(prodcode, NULL,
6714                               MSIINSTALLCONTEXT_MACHINE,
6715                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6716     ok(r == ERROR_UNKNOWN_PROPERTY,
6717        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6718     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6719     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6720
6721     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6723
6724     /* HelpTelephone value exists */
6725     sz = MAX_PATH;
6726     lstrcpyA(buf, "apple");
6727     r = pMsiGetProductInfoExA(prodcode, NULL,
6728                               MSIINSTALLCONTEXT_MACHINE,
6729                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6730     ok(r == ERROR_UNKNOWN_PROPERTY,
6731        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6732     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6733     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6734
6735     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6737
6738     /* InstallDate value exists */
6739     sz = MAX_PATH;
6740     lstrcpyA(buf, "apple");
6741     r = pMsiGetProductInfoExA(prodcode, NULL,
6742                               MSIINSTALLCONTEXT_MACHINE,
6743                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6744     ok(r == ERROR_UNKNOWN_PROPERTY,
6745        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6746     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6747     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6748
6749     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6751
6752     /* DisplayName value exists */
6753     sz = MAX_PATH;
6754     lstrcpyA(buf, "apple");
6755     r = pMsiGetProductInfoExA(prodcode, NULL,
6756                               MSIINSTALLCONTEXT_MACHINE,
6757                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6758     ok(r == ERROR_UNKNOWN_PROPERTY,
6759        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6760     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6761     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6762
6763     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6765
6766     /* InstallLocation value exists */
6767     sz = MAX_PATH;
6768     lstrcpyA(buf, "apple");
6769     r = pMsiGetProductInfoExA(prodcode, NULL,
6770                               MSIINSTALLCONTEXT_MACHINE,
6771                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6772     ok(r == ERROR_UNKNOWN_PROPERTY,
6773        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6774     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6775     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6776
6777     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6779
6780     /* InstallSource value exists */
6781     sz = MAX_PATH;
6782     lstrcpyA(buf, "apple");
6783     r = pMsiGetProductInfoExA(prodcode, NULL,
6784                               MSIINSTALLCONTEXT_MACHINE,
6785                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6786     ok(r == ERROR_UNKNOWN_PROPERTY,
6787        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6788     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6789     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6790
6791     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6793
6794     /* LocalPackage value exists */
6795     sz = MAX_PATH;
6796     lstrcpyA(buf, "apple");
6797     r = pMsiGetProductInfoExA(prodcode, NULL,
6798                               MSIINSTALLCONTEXT_MACHINE,
6799                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6800     ok(r == ERROR_UNKNOWN_PROPERTY,
6801        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6802     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6803     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6804
6805     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6807
6808     /* Publisher value exists */
6809     sz = MAX_PATH;
6810     lstrcpyA(buf, "apple");
6811     r = pMsiGetProductInfoExA(prodcode, NULL,
6812                               MSIINSTALLCONTEXT_MACHINE,
6813                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6814     ok(r == ERROR_UNKNOWN_PROPERTY,
6815        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6816     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6817     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6818
6819     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6821
6822     /* URLInfoAbout value exists */
6823     sz = MAX_PATH;
6824     lstrcpyA(buf, "apple");
6825     r = pMsiGetProductInfoExA(prodcode, NULL,
6826                               MSIINSTALLCONTEXT_MACHINE,
6827                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6828     ok(r == ERROR_UNKNOWN_PROPERTY,
6829        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6830     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6831     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6832
6833     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6835
6836     /* URLUpdateInfo value exists */
6837     sz = MAX_PATH;
6838     lstrcpyA(buf, "apple");
6839     r = pMsiGetProductInfoExA(prodcode, NULL,
6840                               MSIINSTALLCONTEXT_MACHINE,
6841                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6842     ok(r == ERROR_UNKNOWN_PROPERTY,
6843        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6844     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6845     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6846
6847     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6849
6850     /* VersionMinor value exists */
6851     sz = MAX_PATH;
6852     lstrcpyA(buf, "apple");
6853     r = pMsiGetProductInfoExA(prodcode, NULL,
6854                               MSIINSTALLCONTEXT_MACHINE,
6855                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6856     ok(r == ERROR_UNKNOWN_PROPERTY,
6857        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6858     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6859     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6860
6861     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6863
6864     /* VersionMajor value exists */
6865     sz = MAX_PATH;
6866     lstrcpyA(buf, "apple");
6867     r = pMsiGetProductInfoExA(prodcode, NULL,
6868                               MSIINSTALLCONTEXT_MACHINE,
6869                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6870     ok(r == ERROR_UNKNOWN_PROPERTY,
6871        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6872     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6873     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6874
6875     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6877
6878     /* DisplayVersion value exists */
6879     sz = MAX_PATH;
6880     lstrcpyA(buf, "apple");
6881     r = pMsiGetProductInfoExA(prodcode, NULL,
6882                               MSIINSTALLCONTEXT_MACHINE,
6883                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6884     ok(r == ERROR_UNKNOWN_PROPERTY,
6885        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6886     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6887     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6888
6889     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6891
6892     /* ProductID value exists */
6893     sz = MAX_PATH;
6894     lstrcpyA(buf, "apple");
6895     r = pMsiGetProductInfoExA(prodcode, NULL,
6896                               MSIINSTALLCONTEXT_MACHINE,
6897                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6898     ok(r == ERROR_UNKNOWN_PROPERTY,
6899        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6900     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6901     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6902
6903     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6905
6906     /* RegCompany value exists */
6907     sz = MAX_PATH;
6908     lstrcpyA(buf, "apple");
6909     r = pMsiGetProductInfoExA(prodcode, NULL,
6910                               MSIINSTALLCONTEXT_MACHINE,
6911                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6912     ok(r == ERROR_UNKNOWN_PROPERTY,
6913        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6914     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6915     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6916
6917     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6919
6920     /* RegOwner value exists */
6921     sz = MAX_PATH;
6922     lstrcpyA(buf, "apple");
6923     r = pMsiGetProductInfoExA(prodcode, NULL,
6924                               MSIINSTALLCONTEXT_MACHINE,
6925                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6926     ok(r == ERROR_UNKNOWN_PROPERTY,
6927        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6928     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6929     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6930
6931     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6933
6934     /* Transforms value exists */
6935     sz = MAX_PATH;
6936     lstrcpyA(buf, "apple");
6937     r = pMsiGetProductInfoExA(prodcode, NULL,
6938                               MSIINSTALLCONTEXT_MACHINE,
6939                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6940     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6941     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6942     ok(sz == 5, "Expected 5, got %d\n", sz);
6943
6944     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6946
6947     /* Language value exists */
6948     sz = MAX_PATH;
6949     lstrcpyA(buf, "apple");
6950     r = pMsiGetProductInfoExA(prodcode, NULL,
6951                               MSIINSTALLCONTEXT_MACHINE,
6952                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6953     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6954     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6955     ok(sz == 4, "Expected 4, got %d\n", sz);
6956
6957     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6959
6960     /* ProductName value exists */
6961     sz = MAX_PATH;
6962     lstrcpyA(buf, "apple");
6963     r = pMsiGetProductInfoExA(prodcode, NULL,
6964                               MSIINSTALLCONTEXT_MACHINE,
6965                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6967     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6968     ok(sz == 4, "Expected 4, got %d\n", sz);
6969
6970     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6972
6973     /* FIXME */
6974
6975     /* AssignmentType value exists */
6976     sz = MAX_PATH;
6977     lstrcpyA(buf, "apple");
6978     r = pMsiGetProductInfoExA(prodcode, NULL,
6979                               MSIINSTALLCONTEXT_MACHINE,
6980                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6982     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6983     ok(sz == 0, "Expected 0, got %d\n", sz);
6984
6985     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6987
6988     /* FIXME */
6989
6990     /* PackageCode value exists */
6991     sz = MAX_PATH;
6992     lstrcpyA(buf, "apple");
6993     r = pMsiGetProductInfoExA(prodcode, NULL,
6994                               MSIINSTALLCONTEXT_MACHINE,
6995                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6996     todo_wine
6997     {
6998         ok(r == ERROR_BAD_CONFIGURATION,
6999            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7000         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7001         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7002     }
7003
7004     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7006
7007     /* Version value exists */
7008     sz = MAX_PATH;
7009     lstrcpyA(buf, "apple");
7010     r = pMsiGetProductInfoExA(prodcode, NULL,
7011                               MSIINSTALLCONTEXT_MACHINE,
7012                               INSTALLPROPERTY_VERSION, buf, &sz);
7013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7014     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7015     ok(sz == 3, "Expected 3, got %d\n", sz);
7016
7017     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7019
7020     /* ProductIcon value exists */
7021     sz = MAX_PATH;
7022     lstrcpyA(buf, "apple");
7023     r = pMsiGetProductInfoExA(prodcode, NULL,
7024                               MSIINSTALLCONTEXT_MACHINE,
7025                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7027     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7028     ok(sz == 4, "Expected 4, got %d\n", sz);
7029
7030     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7032
7033     /* PackageName value exists */
7034     sz = MAX_PATH;
7035     lstrcpyA(buf, "apple");
7036     r = pMsiGetProductInfoExA(prodcode, NULL,
7037                               MSIINSTALLCONTEXT_MACHINE,
7038                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7039     todo_wine
7040     {
7041         ok(r == ERROR_UNKNOWN_PRODUCT,
7042            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7043         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7044         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7045     }
7046
7047     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7049
7050     /* AuthorizedLUAApp value exists */
7051     sz = MAX_PATH;
7052     lstrcpyA(buf, "apple");
7053     r = pMsiGetProductInfoExA(prodcode, NULL,
7054                               MSIINSTALLCONTEXT_MACHINE,
7055                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7056     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7057     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7058     ok(sz == 4, "Expected 4, got %d\n", sz);
7059
7060     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7061     RegDeleteValueA(prodkey, "PackageName");
7062     RegDeleteValueA(prodkey, "ProductIcon");
7063     RegDeleteValueA(prodkey, "Version");
7064     RegDeleteValueA(prodkey, "PackageCode");
7065     RegDeleteValueA(prodkey, "AssignmentType");
7066     RegDeleteValueA(prodkey, "ProductName");
7067     RegDeleteValueA(prodkey, "Language");
7068     RegDeleteValueA(prodkey, "Transforms");
7069     RegDeleteValueA(prodkey, "RegOwner");
7070     RegDeleteValueA(prodkey, "RegCompany");
7071     RegDeleteValueA(prodkey, "ProductID");
7072     RegDeleteValueA(prodkey, "DisplayVersion");
7073     RegDeleteValueA(prodkey, "VersionMajor");
7074     RegDeleteValueA(prodkey, "VersionMinor");
7075     RegDeleteValueA(prodkey, "URLUpdateInfo");
7076     RegDeleteValueA(prodkey, "URLInfoAbout");
7077     RegDeleteValueA(prodkey, "Publisher");
7078     RegDeleteValueA(prodkey, "LocalPackage");
7079     RegDeleteValueA(prodkey, "InstallSource");
7080     RegDeleteValueA(prodkey, "InstallLocation");
7081     RegDeleteValueA(prodkey, "DisplayName");
7082     RegDeleteValueA(prodkey, "InstallDate");
7083     RegDeleteValueA(prodkey, "HelpTelephone");
7084     RegDeleteValueA(prodkey, "HelpLink");
7085     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7086     RegCloseKey(prodkey);
7087     LocalFree(usersid);
7088 }
7089
7090 #define INIT_USERINFO() \
7091     lstrcpyA(user, "apple"); \
7092     lstrcpyA(org, "orange"); \
7093     lstrcpyA(serial, "banana"); \
7094     usersz = orgsz = serialsz = MAX_PATH;
7095
7096 static void test_MsiGetUserInfo(void)
7097 {
7098     USERINFOSTATE state;
7099     CHAR user[MAX_PATH];
7100     CHAR org[MAX_PATH];
7101     CHAR serial[MAX_PATH];
7102     DWORD usersz, orgsz, serialsz;
7103     CHAR keypath[MAX_PATH * 2];
7104     CHAR prodcode[MAX_PATH];
7105     CHAR prod_squashed[MAX_PATH];
7106     HKEY prodkey, userprod, props;
7107     LPSTR usersid;
7108     LONG res;
7109     REGSAM access = KEY_ALL_ACCESS;
7110
7111     create_test_guid(prodcode, prod_squashed);
7112     usersid = get_user_sid();
7113
7114     if (is_wow64)
7115         access |= KEY_WOW64_64KEY;
7116
7117     /* NULL szProduct */
7118     INIT_USERINFO();
7119     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
7120     ok(state == USERINFOSTATE_INVALIDARG,
7121        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7122     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7123     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7124     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7125     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7126     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7127     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7128
7129     /* empty szProductCode */
7130     INIT_USERINFO();
7131     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
7132     ok(state == USERINFOSTATE_INVALIDARG,
7133        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7134     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7135     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7136     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7137     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7138     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7139     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7140
7141     /* garbage szProductCode */
7142     INIT_USERINFO();
7143     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
7144     ok(state == USERINFOSTATE_INVALIDARG,
7145        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7146     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7147     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7148     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7149     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7150     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7151     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7152
7153     /* guid without brackets */
7154     INIT_USERINFO();
7155     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7156                             user, &usersz, org, &orgsz, serial, &serialsz);
7157     ok(state == USERINFOSTATE_INVALIDARG,
7158        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7159     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7160     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7161     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7162     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7163     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7164     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7165
7166     /* guid with brackets */
7167     INIT_USERINFO();
7168     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7169                             user, &usersz, org, &orgsz, serial, &serialsz);
7170     ok(state == USERINFOSTATE_UNKNOWN,
7171        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7172     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7173     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7174     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7175     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7176     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7177     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7178
7179     /* NULL lpUserNameBuf */
7180     INIT_USERINFO();
7181     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7182     ok(state == USERINFOSTATE_UNKNOWN,
7183        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7184     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7185     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7186     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7187     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7188     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7189
7190     /* NULL pcchUserNameBuf */
7191     INIT_USERINFO();
7192     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
7193     ok(state == USERINFOSTATE_INVALIDARG,
7194        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7195     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7196     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7197     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7198     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7199     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7200
7201     /* both lpUserNameBuf and pcchUserNameBuf NULL */
7202     INIT_USERINFO();
7203     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7204     ok(state == USERINFOSTATE_UNKNOWN,
7205        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7206     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7207     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7208     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7209     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7210
7211     /* NULL lpOrgNameBuf */
7212     INIT_USERINFO();
7213     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
7214     ok(state == USERINFOSTATE_UNKNOWN,
7215        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7216     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7217     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7218     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7219     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7220     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7221
7222     /* NULL pcchOrgNameBuf */
7223     INIT_USERINFO();
7224     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7225     ok(state == USERINFOSTATE_INVALIDARG,
7226        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7227     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7228     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7229     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7230     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7231     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7232
7233     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7234     INIT_USERINFO();
7235     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7236     ok(state == USERINFOSTATE_UNKNOWN,
7237        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7238     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7239     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7240     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7241     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7242
7243     /* NULL lpSerialBuf */
7244     INIT_USERINFO();
7245     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7246     ok(state == USERINFOSTATE_UNKNOWN,
7247        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7248     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7249     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7250     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7251     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7252     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7253
7254     /* NULL pcchSerialBuf */
7255     INIT_USERINFO();
7256     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7257     ok(state == USERINFOSTATE_INVALIDARG,
7258        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7259     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7260     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7261     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7262     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7263     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7264
7265     /* both lpSerialBuf and pcchSerialBuf NULL */
7266     INIT_USERINFO();
7267     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7268     ok(state == USERINFOSTATE_UNKNOWN,
7269        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7270     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7271     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7272     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7273     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7274
7275     /* MSIINSTALLCONTEXT_USERMANAGED */
7276
7277     /* create local system product key */
7278     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7279     lstrcatA(keypath, usersid);
7280     lstrcatA(keypath, "\\Installer\\Products\\");
7281     lstrcatA(keypath, prod_squashed);
7282
7283     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7284     if (res == ERROR_ACCESS_DENIED)
7285     {
7286         skip("Not enough rights to perform tests\n");
7287         LocalFree(usersid);
7288         return;
7289     }
7290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7291
7292     /* managed product key exists */
7293     INIT_USERINFO();
7294     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7295     ok(state == USERINFOSTATE_ABSENT,
7296        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7297     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7298     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7299     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7300     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7301     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7302     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7303
7304     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7305     lstrcatA(keypath, "Installer\\UserData\\");
7306     lstrcatA(keypath, usersid);
7307     lstrcatA(keypath, "\\Products\\");
7308     lstrcatA(keypath, prod_squashed);
7309
7310     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7311     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7312
7313     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7315
7316     /* InstallProperties key exists */
7317     INIT_USERINFO();
7318     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7319     ok(state == USERINFOSTATE_ABSENT,
7320        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7321     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7322     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7323     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7324     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7325     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7326     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7327
7328     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7329     INIT_USERINFO();
7330     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7331     ok(state == USERINFOSTATE_ABSENT,
7332        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7333     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7334     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7335     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7336     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7337
7338     /* RegOwner, RegCompany don't exist, out params are NULL */
7339     INIT_USERINFO();
7340     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7341     ok(state == USERINFOSTATE_ABSENT,
7342        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7343     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7344     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7345
7346     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7348
7349     /* RegOwner value exists */
7350     INIT_USERINFO();
7351     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7352     ok(state == USERINFOSTATE_ABSENT,
7353        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7354     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7355     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7356     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7357     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7358     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7359     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7360
7361     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7363
7364     /* RegCompany value exists */
7365     INIT_USERINFO();
7366     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7367     ok(state == USERINFOSTATE_ABSENT,
7368        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7369     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7370     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7371     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7372     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7373     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7374     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7375
7376     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7378
7379     /* ProductID value exists */
7380     INIT_USERINFO();
7381     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7382     ok(state == USERINFOSTATE_PRESENT,
7383        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7384     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7385     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7386     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7387     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7388     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7389     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7390
7391     /* pcchUserNameBuf is too small */
7392     INIT_USERINFO();
7393     usersz = 0;
7394     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7395     ok(state == USERINFOSTATE_MOREDATA,
7396        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7397     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7398     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7399     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7400     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7401     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7402     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7403
7404     /* pcchUserNameBuf has no room for NULL terminator */
7405     INIT_USERINFO();
7406     usersz = 5;
7407     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7408     ok(state == USERINFOSTATE_MOREDATA,
7409        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7410     todo_wine
7411     {
7412         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7413     }
7414     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7415     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7416     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7417     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7418     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7419
7420     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7421     INIT_USERINFO();
7422     usersz = 0;
7423     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7424     ok(state == USERINFOSTATE_PRESENT,
7425        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7426     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7427     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7428     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7429     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7430     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7431     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7432
7433     RegDeleteValueA(props, "ProductID");
7434     RegDeleteValueA(props, "RegCompany");
7435     RegDeleteValueA(props, "RegOwner");
7436     delete_key(props, "", access & KEY_WOW64_64KEY);
7437     RegCloseKey(props);
7438     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7439     RegCloseKey(userprod);
7440     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7441     RegCloseKey(prodkey);
7442
7443     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7444
7445     /* create local system product key */
7446     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7447     lstrcatA(keypath, prod_squashed);
7448
7449     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7451
7452     /* product key exists */
7453     INIT_USERINFO();
7454     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7455     ok(state == USERINFOSTATE_ABSENT,
7456        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7457     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7458     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7459     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7460     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7461     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7462     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7463
7464     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7465     lstrcatA(keypath, "Installer\\UserData\\");
7466     lstrcatA(keypath, usersid);
7467     lstrcatA(keypath, "\\Products\\");
7468     lstrcatA(keypath, prod_squashed);
7469
7470     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7472
7473     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7474     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7475
7476     /* InstallProperties key exists */
7477     INIT_USERINFO();
7478     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7479     ok(state == USERINFOSTATE_ABSENT,
7480        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7481     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7482     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7483     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7484     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7485     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7486     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7487
7488     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7489     INIT_USERINFO();
7490     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7491     ok(state == USERINFOSTATE_ABSENT,
7492        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7493     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7494     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7495     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7496     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7497
7498     /* RegOwner, RegCompany don't exist, out params are NULL */
7499     INIT_USERINFO();
7500     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7501     ok(state == USERINFOSTATE_ABSENT,
7502        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7503     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7504     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7505
7506     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7508
7509     /* RegOwner value exists */
7510     INIT_USERINFO();
7511     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7512     ok(state == USERINFOSTATE_ABSENT,
7513        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7514     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7515     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7516     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7517     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7518     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7519     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7520
7521     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7523
7524     /* RegCompany value exists */
7525     INIT_USERINFO();
7526     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7527     ok(state == USERINFOSTATE_ABSENT,
7528        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7529     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7530     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7531     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7532     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7533     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7534     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7535
7536     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7538
7539     /* ProductID value exists */
7540     INIT_USERINFO();
7541     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7542     ok(state == USERINFOSTATE_PRESENT,
7543        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7544     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7545     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7546     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7547     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7548     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7549     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7550
7551     RegDeleteValueA(props, "ProductID");
7552     RegDeleteValueA(props, "RegCompany");
7553     RegDeleteValueA(props, "RegOwner");
7554     delete_key(props, "", access & KEY_WOW64_64KEY);
7555     RegCloseKey(props);
7556     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7557     RegCloseKey(userprod);
7558     RegDeleteKeyA(prodkey, "");
7559     RegCloseKey(prodkey);
7560
7561     /* MSIINSTALLCONTEXT_MACHINE */
7562
7563     /* create local system product key */
7564     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7565     lstrcatA(keypath, prod_squashed);
7566
7567     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7569
7570     /* product key exists */
7571     INIT_USERINFO();
7572     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7573     ok(state == USERINFOSTATE_ABSENT,
7574        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7575     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7576     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7577     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7578     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7579     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7580     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7581
7582     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7583     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7584     lstrcatA(keypath, "\\Products\\");
7585     lstrcatA(keypath, prod_squashed);
7586
7587     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7589
7590     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7592
7593     /* InstallProperties key exists */
7594     INIT_USERINFO();
7595     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7596     ok(state == USERINFOSTATE_ABSENT,
7597        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7598     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7599     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7600     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7601     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7602     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7603     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7604
7605     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7606     INIT_USERINFO();
7607     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7608     ok(state == USERINFOSTATE_ABSENT,
7609        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7610     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7611     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7612     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7613     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7614
7615     /* RegOwner, RegCompany don't exist, out params are NULL */
7616     INIT_USERINFO();
7617     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7618     ok(state == USERINFOSTATE_ABSENT,
7619        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7620     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7621     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7622
7623     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7625
7626     /* RegOwner value exists */
7627     INIT_USERINFO();
7628     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7629     ok(state == USERINFOSTATE_ABSENT,
7630        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7631     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7632     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7633     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7634     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7635     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7636     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7637
7638     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7640
7641     /* RegCompany value exists */
7642     INIT_USERINFO();
7643     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7644     ok(state == USERINFOSTATE_ABSENT,
7645        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7646     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7647     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7648     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7649     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7650     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7651     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7652
7653     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7655
7656     /* ProductID value exists */
7657     INIT_USERINFO();
7658     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7659     ok(state == USERINFOSTATE_PRESENT,
7660        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7661     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7662     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7663     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7664     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7665     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7666     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7667
7668     RegDeleteValueA(props, "ProductID");
7669     RegDeleteValueA(props, "RegCompany");
7670     RegDeleteValueA(props, "RegOwner");
7671     delete_key(props, "", access & KEY_WOW64_64KEY);
7672     RegCloseKey(props);
7673     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7674     RegCloseKey(userprod);
7675     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7676     RegCloseKey(prodkey);
7677     LocalFree(usersid);
7678 }
7679
7680 static void test_MsiOpenProduct(void)
7681 {
7682     MSIHANDLE hprod, hdb;
7683     CHAR val[MAX_PATH];
7684     CHAR path[MAX_PATH];
7685     CHAR keypath[MAX_PATH*2];
7686     CHAR prodcode[MAX_PATH];
7687     CHAR prod_squashed[MAX_PATH];
7688     HKEY prodkey, userkey, props;
7689     LPSTR usersid;
7690     DWORD size;
7691     LONG res;
7692     UINT r;
7693     REGSAM access = KEY_ALL_ACCESS;
7694
7695     GetCurrentDirectoryA(MAX_PATH, path);
7696     lstrcatA(path, "\\");
7697
7698     create_test_guid(prodcode, prod_squashed);
7699     usersid = get_user_sid();
7700
7701     if (is_wow64)
7702         access |= KEY_WOW64_64KEY;
7703
7704     hdb = create_package_db(prodcode);
7705     MsiCloseHandle(hdb);
7706
7707     /* NULL szProduct */
7708     hprod = 0xdeadbeef;
7709     r = MsiOpenProductA(NULL, &hprod);
7710     ok(r == ERROR_INVALID_PARAMETER,
7711        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7712     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7713
7714     /* empty szProduct */
7715     hprod = 0xdeadbeef;
7716     r = MsiOpenProductA("", &hprod);
7717     ok(r == ERROR_INVALID_PARAMETER,
7718        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7719     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7720
7721     /* garbage szProduct */
7722     hprod = 0xdeadbeef;
7723     r = MsiOpenProductA("garbage", &hprod);
7724     ok(r == ERROR_INVALID_PARAMETER,
7725        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7726     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7727
7728     /* guid without brackets */
7729     hprod = 0xdeadbeef;
7730     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7731     ok(r == ERROR_INVALID_PARAMETER,
7732        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7733     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7734
7735     /* guid with brackets */
7736     hprod = 0xdeadbeef;
7737     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7738     ok(r == ERROR_UNKNOWN_PRODUCT,
7739        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7740     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7741
7742     /* same length as guid, but random */
7743     hprod = 0xdeadbeef;
7744     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7745     ok(r == ERROR_INVALID_PARAMETER,
7746        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7747     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7748
7749     /* hProduct is NULL */
7750     hprod = 0xdeadbeef;
7751     r = MsiOpenProductA(prodcode, NULL);
7752     ok(r == ERROR_INVALID_PARAMETER,
7753        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7754     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7755
7756     /* MSIINSTALLCONTEXT_USERMANAGED */
7757
7758     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7759     lstrcatA(keypath, "Installer\\Managed\\");
7760     lstrcatA(keypath, usersid);
7761     lstrcatA(keypath, "\\Installer\\Products\\");
7762     lstrcatA(keypath, prod_squashed);
7763
7764     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7765     if (res == ERROR_ACCESS_DENIED)
7766     {
7767         skip("Not enough rights to perform tests\n");
7768         LocalFree(usersid);
7769         return;
7770     }
7771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7772
7773     /* managed product key exists */
7774     hprod = 0xdeadbeef;
7775     r = MsiOpenProductA(prodcode, &hprod);
7776     ok(r == ERROR_UNKNOWN_PRODUCT,
7777        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7778     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7779
7780     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7781     lstrcatA(keypath, "Installer\\UserData\\");
7782     lstrcatA(keypath, usersid);
7783     lstrcatA(keypath, "\\Products\\");
7784     lstrcatA(keypath, prod_squashed);
7785
7786     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7788
7789     /* user product key exists */
7790     hprod = 0xdeadbeef;
7791     r = MsiOpenProductA(prodcode, &hprod);
7792     ok(r == ERROR_UNKNOWN_PRODUCT,
7793        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7794     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7795
7796     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7798
7799     /* InstallProperties key exists */
7800     hprod = 0xdeadbeef;
7801     r = MsiOpenProductA(prodcode, &hprod);
7802     ok(r == ERROR_UNKNOWN_PRODUCT,
7803        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7804     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7805
7806     lstrcpyA(val, path);
7807     lstrcatA(val, "\\winetest.msi");
7808     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7809                          (const BYTE *)val, lstrlenA(val) + 1);
7810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7811
7812     /* ManagedLocalPackage value exists */
7813     hprod = 0xdeadbeef;
7814     r = MsiOpenProductA(prodcode, &hprod);
7815     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7816     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7817
7818     size = MAX_PATH;
7819     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7821     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7822     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7823
7824     MsiCloseHandle(hprod);
7825
7826     RegDeleteValueA(props, "ManagedLocalPackage");
7827     delete_key(props, "", access & KEY_WOW64_64KEY);
7828     RegCloseKey(props);
7829     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7830     RegCloseKey(userkey);
7831     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7832     RegCloseKey(prodkey);
7833
7834     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7835
7836     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7837     lstrcatA(keypath, prod_squashed);
7838
7839     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7841
7842     /* unmanaged product key exists */
7843     hprod = 0xdeadbeef;
7844     r = MsiOpenProductA(prodcode, &hprod);
7845     ok(r == ERROR_UNKNOWN_PRODUCT,
7846        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7847     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7848
7849     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7850     lstrcatA(keypath, "Installer\\UserData\\");
7851     lstrcatA(keypath, usersid);
7852     lstrcatA(keypath, "\\Products\\");
7853     lstrcatA(keypath, prod_squashed);
7854
7855     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7856     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7857
7858     /* user product key exists */
7859     hprod = 0xdeadbeef;
7860     r = MsiOpenProductA(prodcode, &hprod);
7861     ok(r == ERROR_UNKNOWN_PRODUCT,
7862        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7863     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7864
7865     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7867
7868     /* InstallProperties key exists */
7869     hprod = 0xdeadbeef;
7870     r = MsiOpenProductA(prodcode, &hprod);
7871     ok(r == ERROR_UNKNOWN_PRODUCT,
7872        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7873     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7874
7875     lstrcpyA(val, path);
7876     lstrcatA(val, "\\winetest.msi");
7877     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7878                          (const BYTE *)val, lstrlenA(val) + 1);
7879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7880
7881     /* LocalPackage value exists */
7882     hprod = 0xdeadbeef;
7883     r = MsiOpenProductA(prodcode, &hprod);
7884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7885     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7886
7887     size = MAX_PATH;
7888     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7889     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7890     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7891     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7892
7893     MsiCloseHandle(hprod);
7894
7895     RegDeleteValueA(props, "LocalPackage");
7896     delete_key(props, "", access & KEY_WOW64_64KEY);
7897     RegCloseKey(props);
7898     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7899     RegCloseKey(userkey);
7900     RegDeleteKeyA(prodkey, "");
7901     RegCloseKey(prodkey);
7902
7903     /* MSIINSTALLCONTEXT_MACHINE */
7904
7905     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7906     lstrcatA(keypath, prod_squashed);
7907
7908     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7909     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7910
7911     /* managed product key exists */
7912     hprod = 0xdeadbeef;
7913     r = MsiOpenProductA(prodcode, &hprod);
7914     ok(r == ERROR_UNKNOWN_PRODUCT,
7915        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7916     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7917
7918     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7919     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7920     lstrcatA(keypath, prod_squashed);
7921
7922     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7924
7925     /* user product key exists */
7926     hprod = 0xdeadbeef;
7927     r = MsiOpenProductA(prodcode, &hprod);
7928     ok(r == ERROR_UNKNOWN_PRODUCT,
7929        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7930     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7931
7932     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7934
7935     /* InstallProperties key exists */
7936     hprod = 0xdeadbeef;
7937     r = MsiOpenProductA(prodcode, &hprod);
7938     ok(r == ERROR_UNKNOWN_PRODUCT,
7939        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7940     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7941
7942     lstrcpyA(val, path);
7943     lstrcatA(val, "\\winetest.msi");
7944     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7945                          (const BYTE *)val, lstrlenA(val) + 1);
7946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7947
7948     /* LocalPackage value exists */
7949     hprod = 0xdeadbeef;
7950     r = MsiOpenProductA(prodcode, &hprod);
7951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7952     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7953
7954     size = MAX_PATH;
7955     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7957     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7958     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7959
7960     MsiCloseHandle(hprod);
7961
7962     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7963                          (const BYTE *)"winetest.msi", 13);
7964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7965
7966     /* LocalPackage has just the package name */
7967     hprod = 0xdeadbeef;
7968     r = MsiOpenProductA(prodcode, &hprod);
7969     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7970     {
7971         skip("Not enough rights to perform tests\n");
7972         goto error;
7973     }
7974     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7975        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7976     if (r == ERROR_SUCCESS)
7977         MsiCloseHandle(hprod);
7978     else
7979         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7980
7981     lstrcpyA(val, path);
7982     lstrcatA(val, "\\winetest.msi");
7983     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7984                          (const BYTE *)val, lstrlenA(val) + 1);
7985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7986
7987     DeleteFileA(msifile);
7988
7989     /* local package does not exist */
7990     hprod = 0xdeadbeef;
7991     r = MsiOpenProductA(prodcode, &hprod);
7992     ok(r == ERROR_UNKNOWN_PRODUCT,
7993        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7994     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7995
7996 error:
7997     RegDeleteValueA(props, "LocalPackage");
7998     delete_key(props, "", access & KEY_WOW64_64KEY);
7999     RegCloseKey(props);
8000     delete_key(userkey, "", access & KEY_WOW64_64KEY);
8001     RegCloseKey(userkey);
8002     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8003     RegCloseKey(prodkey);
8004
8005     DeleteFileA(msifile);
8006     LocalFree(usersid);
8007 }
8008
8009 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
8010 {
8011     MSIINSTALLCONTEXT context;
8012     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8013     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8014     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8015     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8016     HKEY prodkey, patches, udprod, udpatch, hpatch;
8017     DWORD size, data;
8018     LONG res;
8019     UINT r;
8020     REGSAM access = KEY_ALL_ACCESS;
8021
8022     create_test_guid(prodcode, prod_squashed);
8023     create_test_guid(patch, patch_squashed);
8024
8025     if (is_wow64)
8026         access |= KEY_WOW64_64KEY;
8027
8028     /* MSIPATCHSTATE_APPLIED */
8029
8030     lstrcpyA(patchcode, "apple");
8031     lstrcpyA(targetprod, "banana");
8032     context = 0xdeadbeef;
8033     lstrcpyA(targetsid, "kiwi");
8034     size = MAX_PATH;
8035     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8036                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8037                            &context, targetsid, &size);
8038     if (r == ERROR_ACCESS_DENIED)
8039     {
8040         skip("Not enough rights to perform tests\n");
8041         return;
8042     }
8043     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8044     ok(!lstrcmpA(patchcode, "apple"),
8045        "Expected patchcode to be unchanged, got %s\n", patchcode);
8046     ok(!lstrcmpA(targetprod, "banana"),
8047        "Expected targetprod to be unchanged, got %s\n", targetprod);
8048     ok(context == 0xdeadbeef,
8049        "Expected context to be unchanged, got %d\n", context);
8050     ok(!lstrcmpA(targetsid, "kiwi"),
8051        "Expected targetsid to be unchanged, got %s\n", targetsid);
8052     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8053
8054     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8055     lstrcatA(keypath, expectedsid);
8056     lstrcatA(keypath, "\\Installer\\Products\\");
8057     lstrcatA(keypath, prod_squashed);
8058
8059     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8060     if (res == ERROR_ACCESS_DENIED)
8061     {
8062         skip("Not enough rights to perform tests\n");
8063         return;
8064     }
8065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8066
8067     /* managed product key exists */
8068     lstrcpyA(patchcode, "apple");
8069     lstrcpyA(targetprod, "banana");
8070     context = 0xdeadbeef;
8071     lstrcpyA(targetsid, "kiwi");
8072     size = MAX_PATH;
8073     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8074                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8075                            &context, targetsid, &size);
8076     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8077     ok(!lstrcmpA(patchcode, "apple"),
8078        "Expected patchcode to be unchanged, got %s\n", patchcode);
8079     ok(!lstrcmpA(targetprod, "banana"),
8080        "Expected targetprod to be unchanged, got %s\n", targetprod);
8081     ok(context == 0xdeadbeef,
8082        "Expected context to be unchanged, got %d\n", context);
8083     ok(!lstrcmpA(targetsid, "kiwi"),
8084        "Expected targetsid to be unchanged, got %s\n", targetsid);
8085     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8086
8087     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8088     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8089
8090     /* patches key exists */
8091     lstrcpyA(patchcode, "apple");
8092     lstrcpyA(targetprod, "banana");
8093     context = 0xdeadbeef;
8094     lstrcpyA(targetsid, "kiwi");
8095     size = MAX_PATH;
8096     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8097                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8098                            &context, targetsid, &size);
8099     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8100     ok(!lstrcmpA(patchcode, "apple"),
8101        "Expected patchcode to be unchanged, got %s\n", patchcode);
8102     ok(!lstrcmpA(targetprod, "banana"),
8103        "Expected targetprod to be unchanged, got %s\n", targetprod);
8104     ok(context == 0xdeadbeef,
8105        "Expected context to be unchanged, got %d\n", context);
8106     ok(!lstrcmpA(targetsid, "kiwi"),
8107        "Expected targetsid to be unchanged, got %s\n", targetsid);
8108     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8109
8110     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8111                          (const BYTE *)patch_squashed,
8112                          lstrlenA(patch_squashed) + 1);
8113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8114
8115     /* Patches value exists, is not REG_MULTI_SZ */
8116     lstrcpyA(patchcode, "apple");
8117     lstrcpyA(targetprod, "banana");
8118     context = 0xdeadbeef;
8119     lstrcpyA(targetsid, "kiwi");
8120     size = MAX_PATH;
8121     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8122                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8123                            &context, targetsid, &size);
8124     ok(r == ERROR_BAD_CONFIGURATION,
8125        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8126     ok(!lstrcmpA(patchcode, "apple"),
8127        "Expected patchcode to be unchanged, got %s\n", patchcode);
8128     ok(!lstrcmpA(targetprod, "banana"),
8129        "Expected targetprod to be unchanged, got %s\n", targetprod);
8130     ok(context == 0xdeadbeef,
8131        "Expected context to be unchanged, got %d\n", context);
8132     ok(!lstrcmpA(targetsid, "kiwi"),
8133        "Expected targetsid to be unchanged, got %s\n", targetsid);
8134     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8135
8136     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8137                          (const BYTE *)"a\0b\0c\0\0", 7);
8138     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8139
8140     /* Patches value exists, is not a squashed guid */
8141     lstrcpyA(patchcode, "apple");
8142     lstrcpyA(targetprod, "banana");
8143     context = 0xdeadbeef;
8144     lstrcpyA(targetsid, "kiwi");
8145     size = MAX_PATH;
8146     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8147                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8148                            &context, targetsid, &size);
8149     ok(r == ERROR_BAD_CONFIGURATION,
8150        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8151     ok(!lstrcmpA(patchcode, "apple"),
8152        "Expected patchcode to be unchanged, got %s\n", patchcode);
8153     ok(!lstrcmpA(targetprod, "banana"),
8154        "Expected targetprod to be unchanged, got %s\n", targetprod);
8155     ok(context == 0xdeadbeef,
8156        "Expected context to be unchanged, got %d\n", context);
8157     ok(!lstrcmpA(targetsid, "kiwi"),
8158        "Expected targetsid to be unchanged, got %s\n", targetsid);
8159     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8160
8161     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8162     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8163                          (const BYTE *)patch_squashed,
8164                          lstrlenA(patch_squashed) + 2);
8165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8166
8167     /* Patches value exists */
8168     lstrcpyA(patchcode, "apple");
8169     lstrcpyA(targetprod, "banana");
8170     context = 0xdeadbeef;
8171     lstrcpyA(targetsid, "kiwi");
8172     size = MAX_PATH;
8173     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8174                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8175                            &context, targetsid, &size);
8176     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8177     ok(!lstrcmpA(patchcode, "apple"),
8178        "Expected patchcode to be unchanged, got %s\n", patchcode);
8179     ok(!lstrcmpA(targetprod, "banana"),
8180        "Expected targetprod to be unchanged, got %s\n", targetprod);
8181     ok(context == 0xdeadbeef,
8182        "Expected context to be unchanged, got %d\n", context);
8183     ok(!lstrcmpA(targetsid, "kiwi"),
8184        "Expected targetsid to be unchanged, got %s\n", targetsid);
8185     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8186
8187     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8188                          (const BYTE *)"whatever", 9);
8189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8190
8191     /* patch squashed value exists */
8192     lstrcpyA(patchcode, "apple");
8193     lstrcpyA(targetprod, "banana");
8194     context = 0xdeadbeef;
8195     lstrcpyA(targetsid, "kiwi");
8196     size = MAX_PATH;
8197     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8198                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8199                            &context, targetsid, &size);
8200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8201     ok(!lstrcmpA(patchcode, patch),
8202        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8203     ok(!lstrcmpA(targetprod, prodcode),
8204        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8205     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8206        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8207     ok(!lstrcmpA(targetsid, expectedsid),
8208        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8209     ok(size == lstrlenA(expectedsid),
8210        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8211
8212     /* increase the index */
8213     lstrcpyA(patchcode, "apple");
8214     lstrcpyA(targetprod, "banana");
8215     context = 0xdeadbeef;
8216     lstrcpyA(targetsid, "kiwi");
8217     size = MAX_PATH;
8218     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8219                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
8220                            &context, targetsid, &size);
8221     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8222     ok(!lstrcmpA(patchcode, "apple"),
8223        "Expected patchcode to be unchanged, got %s\n", patchcode);
8224     ok(!lstrcmpA(targetprod, "banana"),
8225        "Expected targetprod to be unchanged, got %s\n", targetprod);
8226     ok(context == 0xdeadbeef,
8227        "Expected context to be unchanged, got %d\n", context);
8228     ok(!lstrcmpA(targetsid, "kiwi"),
8229        "Expected targetsid to be unchanged, got %s\n", targetsid);
8230     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8231
8232     /* increase again */
8233     lstrcpyA(patchcode, "apple");
8234     lstrcpyA(targetprod, "banana");
8235     context = 0xdeadbeef;
8236     lstrcpyA(targetsid, "kiwi");
8237     size = MAX_PATH;
8238     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8239                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8240                            &context, targetsid, &size);
8241     ok(r == ERROR_INVALID_PARAMETER,
8242        "Expected ERROR_INVALID_PARAMETER, 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     /* szPatchCode is NULL */
8254     lstrcpyA(targetprod, "banana");
8255     context = 0xdeadbeef;
8256     lstrcpyA(targetsid, "kiwi");
8257     size = MAX_PATH;
8258     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8259                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8260                            &context, targetsid, &size);
8261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8262     ok(!lstrcmpA(targetprod, prodcode),
8263        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8264     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8265        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8266     ok(!lstrcmpA(targetsid, expectedsid),
8267        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8268     ok(size == lstrlenA(expectedsid),
8269        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8270
8271     /* szTargetProductCode is NULL */
8272     lstrcpyA(patchcode, "apple");
8273     context = 0xdeadbeef;
8274     lstrcpyA(targetsid, "kiwi");
8275     size = MAX_PATH;
8276     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8277                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8278                            &context, targetsid, &size);
8279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8280     ok(!lstrcmpA(patchcode, patch),
8281        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8282     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8283        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8284     ok(!lstrcmpA(targetsid, expectedsid),
8285        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8286     ok(size == lstrlenA(expectedsid),
8287        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8288
8289     /* pdwTargetProductContext is NULL */
8290     lstrcpyA(patchcode, "apple");
8291     lstrcpyA(targetprod, "banana");
8292     lstrcpyA(targetsid, "kiwi");
8293     size = MAX_PATH;
8294     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8295                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8296                            NULL, targetsid, &size);
8297     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8298     ok(!lstrcmpA(patchcode, patch),
8299        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8300     ok(!lstrcmpA(targetprod, prodcode),
8301        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8302     ok(!lstrcmpA(targetsid, expectedsid),
8303        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8304     ok(size == lstrlenA(expectedsid),
8305        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8306
8307     /* szTargetUserSid is NULL */
8308     lstrcpyA(patchcode, "apple");
8309     lstrcpyA(targetprod, "banana");
8310     context = 0xdeadbeef;
8311     size = MAX_PATH;
8312     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8313                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8314                            &context, NULL, &size);
8315     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8316     ok(!lstrcmpA(patchcode, patch),
8317        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8318     ok(!lstrcmpA(targetprod, prodcode),
8319        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8320     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8321        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8322     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8323        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8324
8325     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8326     lstrcpyA(patchcode, "apple");
8327     lstrcpyA(targetprod, "banana");
8328     context = 0xdeadbeef;
8329     lstrcpyA(targetsid, "kiwi");
8330     size = lstrlenA(expectedsid);
8331     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8332                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8333                            &context, targetsid, &size);
8334     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8335     ok(!lstrcmpA(patchcode, patch),
8336        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8337     ok(!lstrcmpA(targetprod, prodcode),
8338        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8339     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8340        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8341     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8342        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8343     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8344        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8345
8346     /* pcchTargetUserSid has enough room for NULL terminator */
8347     lstrcpyA(patchcode, "apple");
8348     lstrcpyA(targetprod, "banana");
8349     context = 0xdeadbeef;
8350     lstrcpyA(targetsid, "kiwi");
8351     size = lstrlenA(expectedsid) + 1;
8352     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8353                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8354                            &context, targetsid, &size);
8355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8356     ok(!lstrcmpA(patchcode, patch),
8357        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8358     ok(!lstrcmpA(targetprod, prodcode),
8359        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8360     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8361        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8362     ok(!lstrcmpA(targetsid, expectedsid),
8363        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8364     ok(size == lstrlenA(expectedsid),
8365        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8366
8367     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8368     lstrcpyA(patchcode, "apple");
8369     lstrcpyA(targetprod, "banana");
8370     context = 0xdeadbeef;
8371     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8372                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8373                            &context, NULL, NULL);
8374     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8375     ok(!lstrcmpA(patchcode, patch),
8376        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8377     ok(!lstrcmpA(targetprod, prodcode),
8378        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8379     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8380        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8381
8382     /* MSIPATCHSTATE_SUPERSEDED */
8383
8384     lstrcpyA(patchcode, "apple");
8385     lstrcpyA(targetprod, "banana");
8386     context = 0xdeadbeef;
8387     lstrcpyA(targetsid, "kiwi");
8388     size = MAX_PATH;
8389     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8390                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8391                            &context, targetsid, &size);
8392     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8393     ok(!lstrcmpA(patchcode, "apple"),
8394        "Expected patchcode to be unchanged, got %s\n", patchcode);
8395     ok(!lstrcmpA(targetprod, "banana"),
8396        "Expected targetprod to be unchanged, got %s\n", targetprod);
8397     ok(context == 0xdeadbeef,
8398        "Expected context to be unchanged, got %d\n", context);
8399     ok(!lstrcmpA(targetsid, "kiwi"),
8400        "Expected targetsid to be unchanged, got %s\n", targetsid);
8401     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8402
8403     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8404     lstrcatA(keypath, expectedsid);
8405     lstrcatA(keypath, "\\Products\\");
8406     lstrcatA(keypath, prod_squashed);
8407
8408     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8410
8411     /* UserData product key exists */
8412     lstrcpyA(patchcode, "apple");
8413     lstrcpyA(targetprod, "banana");
8414     context = 0xdeadbeef;
8415     lstrcpyA(targetsid, "kiwi");
8416     size = MAX_PATH;
8417     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8418                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8419                            &context, targetsid, &size);
8420     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8421     ok(!lstrcmpA(patchcode, "apple"),
8422        "Expected patchcode to be unchanged, got %s\n", patchcode);
8423     ok(!lstrcmpA(targetprod, "banana"),
8424        "Expected targetprod to be unchanged, got %s\n", targetprod);
8425     ok(context == 0xdeadbeef,
8426        "Expected context to be unchanged, got %d\n", context);
8427     ok(!lstrcmpA(targetsid, "kiwi"),
8428        "Expected targetsid to be unchanged, got %s\n", targetsid);
8429     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8430
8431     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8432     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8433
8434     /* UserData patches key exists */
8435     lstrcpyA(patchcode, "apple");
8436     lstrcpyA(targetprod, "banana");
8437     context = 0xdeadbeef;
8438     lstrcpyA(targetsid, "kiwi");
8439     size = MAX_PATH;
8440     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8441                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8442                            &context, targetsid, &size);
8443     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8444     ok(!lstrcmpA(patchcode, "apple"),
8445        "Expected patchcode to be unchanged, got %s\n", patchcode);
8446     ok(!lstrcmpA(targetprod, "banana"),
8447        "Expected targetprod to be unchanged, got %s\n", targetprod);
8448     ok(context == 0xdeadbeef,
8449        "Expected context to be unchanged, got %d\n", context);
8450     ok(!lstrcmpA(targetsid, "kiwi"),
8451        "Expected targetsid to be unchanged, got %s\n", targetsid);
8452     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8453
8454     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8456
8457     /* specific UserData patch key exists */
8458     lstrcpyA(patchcode, "apple");
8459     lstrcpyA(targetprod, "banana");
8460     context = 0xdeadbeef;
8461     lstrcpyA(targetsid, "kiwi");
8462     size = MAX_PATH;
8463     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8464                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8465                            &context, targetsid, &size);
8466     ok(r == ERROR_BAD_CONFIGURATION,
8467        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8468     ok(!lstrcmpA(patchcode, "apple"),
8469        "Expected patchcode to be unchanged, got %s\n", patchcode);
8470     ok(!lstrcmpA(targetprod, "banana"),
8471        "Expected targetprod to be unchanged, got %s\n", targetprod);
8472     ok(context == 0xdeadbeef,
8473        "Expected context to be unchanged, got %d\n", context);
8474     ok(!lstrcmpA(targetsid, "kiwi"),
8475        "Expected targetsid to be unchanged, got %s\n", targetsid);
8476     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8477
8478     data = MSIPATCHSTATE_SUPERSEDED;
8479     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8480                          (const BYTE *)&data, sizeof(DWORD));
8481     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8482
8483     /* State value 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_USERMANAGED,
8490                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8491                            &context, targetsid, &size);
8492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8493     ok(!lstrcmpA(patchcode, patch),
8494        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8495     ok(!lstrcmpA(targetprod, prodcode),
8496        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8497     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8498        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8499     ok(!lstrcmpA(targetsid, expectedsid),
8500        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8501     ok(size == lstrlenA(expectedsid),
8502        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8503
8504     /* MSIPATCHSTATE_OBSOLETED */
8505
8506     lstrcpyA(patchcode, "apple");
8507     lstrcpyA(targetprod, "banana");
8508     context = 0xdeadbeef;
8509     lstrcpyA(targetsid, "kiwi");
8510     size = MAX_PATH;
8511     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8512                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8513                            &context, targetsid, &size);
8514     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8515     ok(!lstrcmpA(patchcode, "apple"),
8516        "Expected patchcode to be unchanged, got %s\n", patchcode);
8517     ok(!lstrcmpA(targetprod, "banana"),
8518        "Expected targetprod to be unchanged, got %s\n", targetprod);
8519     ok(context == 0xdeadbeef,
8520        "Expected context to be unchanged, got %d\n", context);
8521     ok(!lstrcmpA(targetsid, "kiwi"),
8522        "Expected targetsid to be unchanged, got %s\n", targetsid);
8523     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8524
8525     data = MSIPATCHSTATE_OBSOLETED;
8526     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8527                          (const BYTE *)&data, sizeof(DWORD));
8528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8529
8530     /* State value is obsoleted */
8531     lstrcpyA(patchcode, "apple");
8532     lstrcpyA(targetprod, "banana");
8533     context = 0xdeadbeef;
8534     lstrcpyA(targetsid, "kiwi");
8535     size = MAX_PATH;
8536     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8537                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8538                            &context, targetsid, &size);
8539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8540     ok(!lstrcmpA(patchcode, patch),
8541        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8542     ok(!lstrcmpA(targetprod, prodcode),
8543        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8544     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8545        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8546     ok(!lstrcmpA(targetsid, expectedsid),
8547        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8548     ok(size == lstrlenA(expectedsid),
8549        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8550
8551     /* MSIPATCHSTATE_REGISTERED */
8552     /* FIXME */
8553
8554     /* MSIPATCHSTATE_ALL */
8555
8556     /* 1st */
8557     lstrcpyA(patchcode, "apple");
8558     lstrcpyA(targetprod, "banana");
8559     context = 0xdeadbeef;
8560     lstrcpyA(targetsid, "kiwi");
8561     size = MAX_PATH;
8562     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8563                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8564                            &context, targetsid, &size);
8565     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8566     ok(!lstrcmpA(patchcode, patch),
8567        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8568     ok(!lstrcmpA(targetprod, prodcode),
8569        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8570     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8571        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8572     ok(!lstrcmpA(targetsid, expectedsid),
8573        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8574     ok(size == lstrlenA(expectedsid),
8575        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8576
8577     /* same patch in multiple places, only one is enumerated */
8578     lstrcpyA(patchcode, "apple");
8579     lstrcpyA(targetprod, "banana");
8580     context = 0xdeadbeef;
8581     lstrcpyA(targetsid, "kiwi");
8582     size = MAX_PATH;
8583     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8584                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8585                            &context, targetsid, &size);
8586     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8587     ok(!lstrcmpA(patchcode, "apple"),
8588        "Expected patchcode to be unchanged, got %s\n", patchcode);
8589     ok(!lstrcmpA(targetprod, "banana"),
8590        "Expected targetprod to be unchanged, got %s\n", targetprod);
8591     ok(context == 0xdeadbeef,
8592        "Expected context to be unchanged, got %d\n", context);
8593     ok(!lstrcmpA(targetsid, "kiwi"),
8594        "Expected targetsid to be unchanged, got %s\n", targetsid);
8595     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8596
8597     RegDeleteValueA(hpatch, "State");
8598     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8599     RegCloseKey(hpatch);
8600     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8601     RegCloseKey(udpatch);
8602     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8603     RegCloseKey(udprod);
8604     RegDeleteValueA(patches, "Patches");
8605     delete_key(patches, "", access & KEY_WOW64_64KEY);
8606     RegCloseKey(patches);
8607     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8608     RegCloseKey(prodkey);
8609 }
8610
8611 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8612 {
8613     MSIINSTALLCONTEXT context;
8614     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8615     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8616     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8617     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8618     HKEY prodkey, patches, udprod, udpatch;
8619     HKEY userkey, hpatch;
8620     DWORD size, data;
8621     LONG res;
8622     UINT r;
8623     REGSAM access = KEY_ALL_ACCESS;
8624
8625     create_test_guid(prodcode, prod_squashed);
8626     create_test_guid(patch, patch_squashed);
8627
8628     if (is_wow64)
8629         access |= KEY_WOW64_64KEY;
8630
8631     /* MSIPATCHSTATE_APPLIED */
8632
8633     lstrcpyA(patchcode, "apple");
8634     lstrcpyA(targetprod, "banana");
8635     context = 0xdeadbeef;
8636     lstrcpyA(targetsid, "kiwi");
8637     size = MAX_PATH;
8638     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8639                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8640                            &context, targetsid, &size);
8641     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8642     ok(!lstrcmpA(patchcode, "apple"),
8643        "Expected patchcode to be unchanged, got %s\n", patchcode);
8644     ok(!lstrcmpA(targetprod, "banana"),
8645        "Expected targetprod to be unchanged, got %s\n", targetprod);
8646     ok(context == 0xdeadbeef,
8647        "Expected context to be unchanged, got %d\n", context);
8648     ok(!lstrcmpA(targetsid, "kiwi"),
8649        "Expected targetsid to be unchanged, got %s\n", targetsid);
8650     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8651
8652     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8653     lstrcatA(keypath, prod_squashed);
8654
8655     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8657
8658     /* current user product key exists */
8659     lstrcpyA(patchcode, "apple");
8660     lstrcpyA(targetprod, "banana");
8661     context = 0xdeadbeef;
8662     lstrcpyA(targetsid, "kiwi");
8663     size = MAX_PATH;
8664     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8665                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8666                            &context, targetsid, &size);
8667     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8668     ok(!lstrcmpA(patchcode, "apple"),
8669        "Expected patchcode to be unchanged, got %s\n", patchcode);
8670     ok(!lstrcmpA(targetprod, "banana"),
8671        "Expected targetprod to be unchanged, got %s\n", targetprod);
8672     ok(context == 0xdeadbeef,
8673        "Expected context to be unchanged, got %d\n", context);
8674     ok(!lstrcmpA(targetsid, "kiwi"),
8675        "Expected targetsid to be unchanged, got %s\n", targetsid);
8676     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8677
8678     res = RegCreateKeyA(prodkey, "Patches", &patches);
8679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8680
8681     /* Patches key exists */
8682     lstrcpyA(patchcode, "apple");
8683     lstrcpyA(targetprod, "banana");
8684     context = 0xdeadbeef;
8685     lstrcpyA(targetsid, "kiwi");
8686     size = MAX_PATH;
8687     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8688                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8689                            &context, targetsid, &size);
8690     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8691     ok(!lstrcmpA(patchcode, "apple"),
8692        "Expected patchcode to be unchanged, got %s\n", patchcode);
8693     ok(!lstrcmpA(targetprod, "banana"),
8694        "Expected targetprod to be unchanged, got %s\n", targetprod);
8695     ok(context == 0xdeadbeef,
8696        "Expected context to be unchanged, got %d\n", context);
8697     ok(!lstrcmpA(targetsid, "kiwi"),
8698        "Expected targetsid to be unchanged, got %s\n", targetsid);
8699     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8700
8701     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8702                          (const BYTE *)patch_squashed,
8703                          lstrlenA(patch_squashed) + 1);
8704     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8705
8706     /* Patches value exists, is not REG_MULTI_SZ */
8707     lstrcpyA(patchcode, "apple");
8708     lstrcpyA(targetprod, "banana");
8709     context = 0xdeadbeef;
8710     lstrcpyA(targetsid, "kiwi");
8711     size = MAX_PATH;
8712     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8713                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8714                            &context, targetsid, &size);
8715     ok(r == ERROR_BAD_CONFIGURATION,
8716        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8717     ok(!lstrcmpA(patchcode, "apple"),
8718        "Expected patchcode to be unchanged, got %s\n", patchcode);
8719     ok(!lstrcmpA(targetprod, "banana"),
8720        "Expected targetprod to be unchanged, got %s\n", targetprod);
8721     ok(context == 0xdeadbeef,
8722        "Expected context to be unchanged, got %d\n", context);
8723     ok(!lstrcmpA(targetsid, "kiwi"),
8724        "Expected targetsid to be unchanged, got %s\n", targetsid);
8725     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8726
8727     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8728                          (const BYTE *)"a\0b\0c\0\0", 7);
8729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8730
8731     /* Patches value exists, is not a squashed guid */
8732     lstrcpyA(patchcode, "apple");
8733     lstrcpyA(targetprod, "banana");
8734     context = 0xdeadbeef;
8735     lstrcpyA(targetsid, "kiwi");
8736     size = MAX_PATH;
8737     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8738                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8739                            &context, targetsid, &size);
8740     ok(r == ERROR_BAD_CONFIGURATION,
8741        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8742     ok(!lstrcmpA(patchcode, "apple"),
8743        "Expected patchcode to be unchanged, got %s\n", patchcode);
8744     ok(!lstrcmpA(targetprod, "banana"),
8745        "Expected targetprod to be unchanged, got %s\n", targetprod);
8746     ok(context == 0xdeadbeef,
8747        "Expected context to be unchanged, got %d\n", context);
8748     ok(!lstrcmpA(targetsid, "kiwi"),
8749        "Expected targetsid to be unchanged, got %s\n", targetsid);
8750     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8751
8752     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8753     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8754                          (const BYTE *)patch_squashed,
8755                          lstrlenA(patch_squashed) + 2);
8756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8757
8758     /* Patches value exists */
8759     lstrcpyA(patchcode, "apple");
8760     lstrcpyA(targetprod, "banana");
8761     context = 0xdeadbeef;
8762     lstrcpyA(targetsid, "kiwi");
8763     size = MAX_PATH;
8764     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8765                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8766                            &context, targetsid, &size);
8767     ok(r == ERROR_NO_MORE_ITEMS ||
8768        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8769        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8770     ok(!lstrcmpA(patchcode, "apple"),
8771        "Expected patchcode to be unchanged, got %s\n", patchcode);
8772     ok(!lstrcmpA(targetprod, "banana"),
8773        "Expected targetprod to be unchanged, got %s\n", targetprod);
8774     ok(context == 0xdeadbeef,
8775        "Expected context to be unchanged, got %d\n", context);
8776     ok(!lstrcmpA(targetsid, "kiwi"),
8777        "Expected targetsid to be unchanged, got %s\n", targetsid);
8778     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8779
8780     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8781                          (const BYTE *)"whatever", 9);
8782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8783
8784     /* patch code value exists */
8785     lstrcpyA(patchcode, "apple");
8786     lstrcpyA(targetprod, "banana");
8787     context = 0xdeadbeef;
8788     lstrcpyA(targetsid, "kiwi");
8789     size = MAX_PATH;
8790     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8791                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8792                            &context, targetsid, &size);
8793     ok(r == ERROR_NO_MORE_ITEMS ||
8794        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8795        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8796     ok(!lstrcmpA(patchcode, "apple"),
8797        "Expected patchcode to be unchanged, got %s\n", patchcode);
8798     ok(!lstrcmpA(targetprod, "banana"),
8799        "Expected targetprod to be unchanged, got %s\n", targetprod);
8800     ok(context == 0xdeadbeef,
8801        "Expected context to be unchanged, got %d\n", context);
8802     ok(!lstrcmpA(targetsid, "kiwi"),
8803        "Expected targetsid to be unchanged, got %s\n", targetsid);
8804     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8805
8806     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8807     lstrcatA(keypath, expectedsid);
8808     lstrcatA(keypath, "\\Patches\\");
8809     lstrcatA(keypath, patch_squashed);
8810
8811     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8812     if (res == ERROR_ACCESS_DENIED)
8813     {
8814         skip("Not enough rights to perform tests\n");
8815         goto error;
8816     }
8817     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8818
8819     /* userdata patch key exists */
8820     lstrcpyA(patchcode, "apple");
8821     lstrcpyA(targetprod, "banana");
8822     context = 0xdeadbeef;
8823     lstrcpyA(targetsid, "kiwi");
8824     size = MAX_PATH;
8825     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8826                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8827                            &context, targetsid, &size);
8828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8829     ok(!lstrcmpA(patchcode, patch),
8830        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8831     ok(!lstrcmpA(targetprod, prodcode),
8832        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8833     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8834        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8835     ok(!lstrcmpA(targetsid, expectedsid),
8836        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8837     ok(size == lstrlenA(expectedsid),
8838        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8839
8840     /* MSIPATCHSTATE_SUPERSEDED */
8841
8842     lstrcpyA(patchcode, "apple");
8843     lstrcpyA(targetprod, "banana");
8844     context = 0xdeadbeef;
8845     lstrcpyA(targetsid, "kiwi");
8846     size = MAX_PATH;
8847     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8848                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8849                            &context, targetsid, &size);
8850     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8851     ok(!lstrcmpA(patchcode, "apple"),
8852        "Expected patchcode to be unchanged, got %s\n", patchcode);
8853     ok(!lstrcmpA(targetprod, "banana"),
8854        "Expected targetprod to be unchanged, got %s\n", targetprod);
8855     ok(context == 0xdeadbeef,
8856        "Expected context to be unchanged, got %d\n", context);
8857     ok(!lstrcmpA(targetsid, "kiwi"),
8858        "Expected targetsid to be unchanged, got %s\n", targetsid);
8859     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8860
8861     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8862     lstrcatA(keypath, expectedsid);
8863     lstrcatA(keypath, "\\Products\\");
8864     lstrcatA(keypath, prod_squashed);
8865
8866     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8868
8869     /* UserData product key exists */
8870     lstrcpyA(patchcode, "apple");
8871     lstrcpyA(targetprod, "banana");
8872     context = 0xdeadbeef;
8873     lstrcpyA(targetsid, "kiwi");
8874     size = MAX_PATH;
8875     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8876                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8877                            &context, targetsid, &size);
8878     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8879     ok(!lstrcmpA(patchcode, "apple"),
8880        "Expected patchcode to be unchanged, got %s\n", patchcode);
8881     ok(!lstrcmpA(targetprod, "banana"),
8882        "Expected targetprod to be unchanged, got %s\n", targetprod);
8883     ok(context == 0xdeadbeef,
8884        "Expected context to be unchanged, got %d\n", context);
8885     ok(!lstrcmpA(targetsid, "kiwi"),
8886        "Expected targetsid to be unchanged, got %s\n", targetsid);
8887     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8888
8889     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8891
8892     /* UserData patches key exists */
8893     lstrcpyA(patchcode, "apple");
8894     lstrcpyA(targetprod, "banana");
8895     context = 0xdeadbeef;
8896     lstrcpyA(targetsid, "kiwi");
8897     size = MAX_PATH;
8898     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8899                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8900                            &context, targetsid, &size);
8901     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8902     ok(!lstrcmpA(patchcode, "apple"),
8903        "Expected patchcode to be unchanged, got %s\n", patchcode);
8904     ok(!lstrcmpA(targetprod, "banana"),
8905        "Expected targetprod to be unchanged, got %s\n", targetprod);
8906     ok(context == 0xdeadbeef,
8907        "Expected context to be unchanged, got %d\n", context);
8908     ok(!lstrcmpA(targetsid, "kiwi"),
8909        "Expected targetsid to be unchanged, got %s\n", targetsid);
8910     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8911
8912     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8914
8915     /* specific UserData patch key exists */
8916     lstrcpyA(patchcode, "apple");
8917     lstrcpyA(targetprod, "banana");
8918     context = 0xdeadbeef;
8919     lstrcpyA(targetsid, "kiwi");
8920     size = MAX_PATH;
8921     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8922                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8923                            &context, targetsid, &size);
8924     ok(r == ERROR_BAD_CONFIGURATION,
8925        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8926     ok(!lstrcmpA(patchcode, "apple"),
8927        "Expected patchcode to be unchanged, got %s\n", patchcode);
8928     ok(!lstrcmpA(targetprod, "banana"),
8929        "Expected targetprod to be unchanged, got %s\n", targetprod);
8930     ok(context == 0xdeadbeef,
8931        "Expected context to be unchanged, got %d\n", context);
8932     ok(!lstrcmpA(targetsid, "kiwi"),
8933        "Expected targetsid to be unchanged, got %s\n", targetsid);
8934     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8935
8936     data = MSIPATCHSTATE_SUPERSEDED;
8937     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8938                          (const BYTE *)&data, sizeof(DWORD));
8939     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8940
8941     /* State value exists */
8942     lstrcpyA(patchcode, "apple");
8943     lstrcpyA(targetprod, "banana");
8944     context = 0xdeadbeef;
8945     lstrcpyA(targetsid, "kiwi");
8946     size = MAX_PATH;
8947     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8948                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8949                            &context, targetsid, &size);
8950     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8951     ok(!lstrcmpA(patchcode, patch),
8952        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8953     ok(!lstrcmpA(targetprod, prodcode),
8954        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8955     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8956        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8957     ok(!lstrcmpA(targetsid, expectedsid),
8958        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8959     ok(size == lstrlenA(expectedsid),
8960        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8961
8962     /* MSIPATCHSTATE_OBSOLETED */
8963
8964     lstrcpyA(patchcode, "apple");
8965     lstrcpyA(targetprod, "banana");
8966     context = 0xdeadbeef;
8967     lstrcpyA(targetsid, "kiwi");
8968     size = MAX_PATH;
8969     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8970                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8971                            &context, targetsid, &size);
8972     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8973     ok(!lstrcmpA(patchcode, "apple"),
8974        "Expected patchcode to be unchanged, got %s\n", patchcode);
8975     ok(!lstrcmpA(targetprod, "banana"),
8976        "Expected targetprod to be unchanged, got %s\n", targetprod);
8977     ok(context == 0xdeadbeef,
8978        "Expected context to be unchanged, got %d\n", context);
8979     ok(!lstrcmpA(targetsid, "kiwi"),
8980        "Expected targetsid to be unchanged, got %s\n", targetsid);
8981     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8982
8983     data = MSIPATCHSTATE_OBSOLETED;
8984     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8985                          (const BYTE *)&data, sizeof(DWORD));
8986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8987
8988     /* State value is obsoleted */
8989     lstrcpyA(patchcode, "apple");
8990     lstrcpyA(targetprod, "banana");
8991     context = 0xdeadbeef;
8992     lstrcpyA(targetsid, "kiwi");
8993     size = MAX_PATH;
8994     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8995                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8996                            &context, targetsid, &size);
8997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8998     ok(!lstrcmpA(patchcode, patch),
8999        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9000     ok(!lstrcmpA(targetprod, prodcode),
9001        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9002     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9003        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9004     ok(!lstrcmpA(targetsid, expectedsid),
9005        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9006     ok(size == lstrlenA(expectedsid),
9007        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9008
9009     /* MSIPATCHSTATE_REGISTERED */
9010     /* FIXME */
9011
9012     /* MSIPATCHSTATE_ALL */
9013
9014     /* 1st */
9015     lstrcpyA(patchcode, "apple");
9016     lstrcpyA(targetprod, "banana");
9017     context = 0xdeadbeef;
9018     lstrcpyA(targetsid, "kiwi");
9019     size = MAX_PATH;
9020     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9021                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9022                            &context, targetsid, &size);
9023     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9024     ok(!lstrcmpA(patchcode, patch),
9025        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9026     ok(!lstrcmpA(targetprod, prodcode),
9027        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9028     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9029        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9030     ok(!lstrcmpA(targetsid, expectedsid),
9031        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9032     ok(size == lstrlenA(expectedsid),
9033        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9034
9035     /* same patch in multiple places, only one is enumerated */
9036     lstrcpyA(patchcode, "apple");
9037     lstrcpyA(targetprod, "banana");
9038     context = 0xdeadbeef;
9039     lstrcpyA(targetsid, "kiwi");
9040     size = MAX_PATH;
9041     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9042                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9043                            &context, targetsid, &size);
9044     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9045     ok(!lstrcmpA(patchcode, "apple"),
9046        "Expected patchcode to be unchanged, got %s\n", patchcode);
9047     ok(!lstrcmpA(targetprod, "banana"),
9048        "Expected targetprod to be unchanged, got %s\n", targetprod);
9049     ok(context == 0xdeadbeef,
9050        "Expected context to be unchanged, got %d\n", context);
9051     ok(!lstrcmpA(targetsid, "kiwi"),
9052        "Expected targetsid to be unchanged, got %s\n", targetsid);
9053     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9054
9055     RegDeleteValueA(hpatch, "State");
9056     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9057     RegCloseKey(hpatch);
9058     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9059     RegCloseKey(udpatch);
9060     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9061     RegCloseKey(udprod);
9062     delete_key(userkey, "", access & KEY_WOW64_64KEY);
9063     RegCloseKey(userkey);
9064     RegDeleteValueA(patches, patch_squashed);
9065     RegDeleteValueA(patches, "Patches");
9066
9067 error:
9068     RegDeleteKeyA(patches, "");
9069     RegCloseKey(patches);
9070     RegDeleteKeyA(prodkey, "");
9071     RegCloseKey(prodkey);
9072 }
9073
9074 static void test_MsiEnumPatchesEx_machine(void)
9075 {
9076     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9077     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9078     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9079     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9080     HKEY prodkey, patches, udprod, udpatch;
9081     HKEY hpatch;
9082     MSIINSTALLCONTEXT context;
9083     DWORD size, data;
9084     LONG res;
9085     UINT r;
9086     REGSAM access = KEY_ALL_ACCESS;
9087
9088     create_test_guid(prodcode, prod_squashed);
9089     create_test_guid(patch, patch_squashed);
9090
9091     if (is_wow64)
9092         access |= KEY_WOW64_64KEY;
9093
9094     /* MSIPATCHSTATE_APPLIED */
9095
9096     lstrcpyA(patchcode, "apple");
9097     lstrcpyA(targetprod, "banana");
9098     context = 0xdeadbeef;
9099     lstrcpyA(targetsid, "kiwi");
9100     size = MAX_PATH;
9101     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9102                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9103                            &context, targetsid, &size);
9104     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9105     ok(!lstrcmpA(patchcode, "apple"),
9106        "Expected patchcode to be unchanged, got %s\n", patchcode);
9107     ok(!lstrcmpA(targetprod, "banana"),
9108        "Expected targetprod to be unchanged, got %s\n", targetprod);
9109     ok(context == 0xdeadbeef,
9110        "Expected context to be unchanged, got %d\n", context);
9111     ok(!lstrcmpA(targetsid, "kiwi"),
9112        "Expected targetsid to be unchanged, got %s\n", targetsid);
9113     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9114
9115     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9116     lstrcatA(keypath, prod_squashed);
9117
9118     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9119     if (res == ERROR_ACCESS_DENIED)
9120     {
9121         skip("Not enough rights to perform tests\n");
9122         return;
9123     }
9124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9125
9126     /* local product key exists */
9127     lstrcpyA(patchcode, "apple");
9128     lstrcpyA(targetprod, "banana");
9129     context = 0xdeadbeef;
9130     lstrcpyA(targetsid, "kiwi");
9131     size = MAX_PATH;
9132     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9133                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9134                            &context, targetsid, &size);
9135     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9136     ok(!lstrcmpA(patchcode, "apple"),
9137        "Expected patchcode to be unchanged, got %s\n", patchcode);
9138     ok(!lstrcmpA(targetprod, "banana"),
9139        "Expected targetprod to be unchanged, got %s\n", targetprod);
9140     ok(context == 0xdeadbeef,
9141        "Expected context to be unchanged, got %d\n", context);
9142     ok(!lstrcmpA(targetsid, "kiwi"),
9143        "Expected targetsid to be unchanged, got %s\n", targetsid);
9144     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9145
9146     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9148
9149     /* Patches key exists */
9150     lstrcpyA(patchcode, "apple");
9151     lstrcpyA(targetprod, "banana");
9152     context = 0xdeadbeef;
9153     lstrcpyA(targetsid, "kiwi");
9154     size = MAX_PATH;
9155     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9156                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9157                            &context, targetsid, &size);
9158     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9159     ok(!lstrcmpA(patchcode, "apple"),
9160        "Expected patchcode to be unchanged, got %s\n", patchcode);
9161     ok(!lstrcmpA(targetprod, "banana"),
9162        "Expected targetprod to be unchanged, got %s\n", targetprod);
9163     ok(context == 0xdeadbeef,
9164        "Expected context to be unchanged, got %d\n", context);
9165     ok(!lstrcmpA(targetsid, "kiwi"),
9166        "Expected targetsid to be unchanged, got %s\n", targetsid);
9167     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9168
9169     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9170                          (const BYTE *)patch_squashed,
9171                          lstrlenA(patch_squashed) + 1);
9172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9173
9174     /* Patches value exists, is not REG_MULTI_SZ */
9175     lstrcpyA(patchcode, "apple");
9176     lstrcpyA(targetprod, "banana");
9177     context = 0xdeadbeef;
9178     lstrcpyA(targetsid, "kiwi");
9179     size = MAX_PATH;
9180     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9181                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9182                            &context, targetsid, &size);
9183     ok(r == ERROR_BAD_CONFIGURATION,
9184        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9185     ok(!lstrcmpA(patchcode, "apple"),
9186        "Expected patchcode to be unchanged, got %s\n", patchcode);
9187     ok(!lstrcmpA(targetprod, "banana"),
9188        "Expected targetprod to be unchanged, got %s\n", targetprod);
9189     ok(context == 0xdeadbeef,
9190        "Expected context to be unchanged, got %d\n", context);
9191     ok(!lstrcmpA(targetsid, "kiwi"),
9192        "Expected targetsid to be unchanged, got %s\n", targetsid);
9193     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9194
9195     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9196                          (const BYTE *)"a\0b\0c\0\0", 7);
9197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9198
9199     /* Patches value exists, is not a squashed guid */
9200     lstrcpyA(patchcode, "apple");
9201     lstrcpyA(targetprod, "banana");
9202     context = 0xdeadbeef;
9203     lstrcpyA(targetsid, "kiwi");
9204     size = MAX_PATH;
9205     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9206                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9207                            &context, targetsid, &size);
9208     ok(r == ERROR_BAD_CONFIGURATION,
9209        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9210     ok(!lstrcmpA(patchcode, "apple"),
9211        "Expected patchcode to be unchanged, got %s\n", patchcode);
9212     ok(!lstrcmpA(targetprod, "banana"),
9213        "Expected targetprod to be unchanged, got %s\n", targetprod);
9214     ok(context == 0xdeadbeef,
9215        "Expected context to be unchanged, got %d\n", context);
9216     ok(!lstrcmpA(targetsid, "kiwi"),
9217        "Expected targetsid to be unchanged, got %s\n", targetsid);
9218     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9219
9220     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9221     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9222                          (const BYTE *)patch_squashed,
9223                          lstrlenA(patch_squashed) + 2);
9224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9225
9226     /* Patches value exists */
9227     lstrcpyA(patchcode, "apple");
9228     lstrcpyA(targetprod, "banana");
9229     context = 0xdeadbeef;
9230     lstrcpyA(targetsid, "kiwi");
9231     size = MAX_PATH;
9232     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9233                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9234                            &context, targetsid, &size);
9235     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9236     ok(!lstrcmpA(patchcode, "apple"),
9237        "Expected patchcode to be unchanged, got %s\n", patchcode);
9238     ok(!lstrcmpA(targetprod, "banana"),
9239        "Expected targetprod to be unchanged, got %s\n", targetprod);
9240     ok(context == 0xdeadbeef,
9241        "Expected context to be unchanged, got %d\n", context);
9242     ok(!lstrcmpA(targetsid, "kiwi"),
9243        "Expected targetsid to be unchanged, got %s\n", targetsid);
9244     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9245
9246     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9247                          (const BYTE *)"whatever", 9);
9248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9249
9250     /* patch code value exists */
9251     lstrcpyA(patchcode, "apple");
9252     lstrcpyA(targetprod, "banana");
9253     context = 0xdeadbeef;
9254     lstrcpyA(targetsid, "kiwi");
9255     size = MAX_PATH;
9256     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9257                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9258                            &context, targetsid, &size);
9259     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9260     ok(!lstrcmpA(patchcode, patch),
9261        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9262     ok(!lstrcmpA(targetprod, prodcode),
9263        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9264     ok(context == MSIINSTALLCONTEXT_MACHINE,
9265        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9266     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9267     ok(size == 0, "Expected 0, got %d\n", size);
9268
9269     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9270     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9271     lstrcatA(keypath, prod_squashed);
9272
9273     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9275
9276     /* local UserData product key exists */
9277     lstrcpyA(patchcode, "apple");
9278     lstrcpyA(targetprod, "banana");
9279     context = 0xdeadbeef;
9280     lstrcpyA(targetsid, "kiwi");
9281     size = MAX_PATH;
9282     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9283                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9284                            &context, targetsid, &size);
9285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9286     ok(!lstrcmpA(patchcode, patch),
9287        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9288     ok(!lstrcmpA(targetprod, prodcode),
9289        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9290     ok(context == MSIINSTALLCONTEXT_MACHINE,
9291        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9292     ok(!lstrcmpA(targetsid, ""),
9293        "Expected \"\", got \"%s\"\n", targetsid);
9294     ok(size == 0, "Expected 0, got %d\n", size);
9295
9296     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9298
9299     /* local UserData Patches key exists */
9300     lstrcpyA(patchcode, "apple");
9301     lstrcpyA(targetprod, "banana");
9302     context = 0xdeadbeef;
9303     lstrcpyA(targetsid, "kiwi");
9304     size = MAX_PATH;
9305     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9306                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9307                            &context, targetsid, &size);
9308     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9309     ok(!lstrcmpA(patchcode, patch),
9310        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9311     ok(!lstrcmpA(targetprod, prodcode),
9312        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9313     ok(context == MSIINSTALLCONTEXT_MACHINE,
9314        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9315     ok(!lstrcmpA(targetsid, ""),
9316        "Expected \"\", got \"%s\"\n", targetsid);
9317     ok(size == 0, "Expected 0, got %d\n", size);
9318
9319     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9320     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9321
9322     /* local UserData Product patch key exists */
9323     lstrcpyA(patchcode, "apple");
9324     lstrcpyA(targetprod, "banana");
9325     context = 0xdeadbeef;
9326     lstrcpyA(targetsid, "kiwi");
9327     size = MAX_PATH;
9328     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9329                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9330                            &context, targetsid, &size);
9331     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9332     ok(!lstrcmpA(patchcode, "apple"),
9333        "Expected patchcode to be unchanged, got %s\n", patchcode);
9334     ok(!lstrcmpA(targetprod, "banana"),
9335        "Expected targetprod to be unchanged, got %s\n", targetprod);
9336     ok(context == 0xdeadbeef,
9337        "Expected context to be unchanged, got %d\n", context);
9338     ok(!lstrcmpA(targetsid, "kiwi"),
9339        "Expected targetsid to be unchanged, got %s\n", targetsid);
9340     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9341
9342     data = MSIPATCHSTATE_APPLIED;
9343     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9344                          (const BYTE *)&data, sizeof(DWORD));
9345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9346
9347     /* State value exists */
9348     lstrcpyA(patchcode, "apple");
9349     lstrcpyA(targetprod, "banana");
9350     context = 0xdeadbeef;
9351     lstrcpyA(targetsid, "kiwi");
9352     size = MAX_PATH;
9353     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9354                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9355                            &context, targetsid, &size);
9356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9357     ok(!lstrcmpA(patchcode, patch),
9358        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9359     ok(!lstrcmpA(targetprod, prodcode),
9360        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9361     ok(context == MSIINSTALLCONTEXT_MACHINE,
9362        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9363     ok(!lstrcmpA(targetsid, ""),
9364        "Expected \"\", got \"%s\"\n", targetsid);
9365     ok(size == 0, "Expected 0, got %d\n", size);
9366
9367     /* MSIPATCHSTATE_SUPERSEDED */
9368
9369     lstrcpyA(patchcode, "apple");
9370     lstrcpyA(targetprod, "banana");
9371     context = 0xdeadbeef;
9372     lstrcpyA(targetsid, "kiwi");
9373     size = MAX_PATH;
9374     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9375                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9376                            &context, targetsid, &size);
9377     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9378     ok(!lstrcmpA(patchcode, "apple"),
9379        "Expected patchcode to be unchanged, got %s\n", patchcode);
9380     ok(!lstrcmpA(targetprod, "banana"),
9381        "Expected targetprod to be unchanged, got %s\n", targetprod);
9382     ok(context == 0xdeadbeef,
9383        "Expected context to be unchanged, got %d\n", context);
9384     ok(!lstrcmpA(targetsid, "kiwi"),
9385        "Expected targetsid to be unchanged, got %s\n", targetsid);
9386     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9387
9388     data = MSIPATCHSTATE_SUPERSEDED;
9389     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9390                          (const BYTE *)&data, sizeof(DWORD));
9391     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9392
9393     /* State value is MSIPATCHSTATE_SUPERSEDED */
9394     lstrcpyA(patchcode, "apple");
9395     lstrcpyA(targetprod, "banana");
9396     context = 0xdeadbeef;
9397     lstrcpyA(targetsid, "kiwi");
9398     size = MAX_PATH;
9399     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9400                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9401                            &context, targetsid, &size);
9402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9403     ok(!lstrcmpA(patchcode, patch),
9404        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9405     ok(!lstrcmpA(targetprod, prodcode),
9406        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9407     ok(context == MSIINSTALLCONTEXT_MACHINE,
9408        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9409     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9410     ok(size == 0, "Expected 0, got %d\n", size);
9411
9412     /* MSIPATCHSTATE_OBSOLETED */
9413
9414     lstrcpyA(patchcode, "apple");
9415     lstrcpyA(targetprod, "banana");
9416     context = 0xdeadbeef;
9417     lstrcpyA(targetsid, "kiwi");
9418     size = MAX_PATH;
9419     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9420                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9421                            &context, targetsid, &size);
9422     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9423     ok(!lstrcmpA(patchcode, "apple"),
9424        "Expected patchcode to be unchanged, got %s\n", patchcode);
9425     ok(!lstrcmpA(targetprod, "banana"),
9426        "Expected targetprod to be unchanged, got %s\n", targetprod);
9427     ok(context == 0xdeadbeef,
9428        "Expected context to be unchanged, got %d\n", context);
9429     ok(!lstrcmpA(targetsid, "kiwi"),
9430        "Expected targetsid to be unchanged, got %s\n", targetsid);
9431     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9432
9433     data = MSIPATCHSTATE_OBSOLETED;
9434     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9435                          (const BYTE *)&data, sizeof(DWORD));
9436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9437
9438     /* State value is obsoleted */
9439     lstrcpyA(patchcode, "apple");
9440     lstrcpyA(targetprod, "banana");
9441     context = 0xdeadbeef;
9442     lstrcpyA(targetsid, "kiwi");
9443     size = MAX_PATH;
9444     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9445                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9446                            &context, targetsid, &size);
9447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9448     ok(!lstrcmpA(patchcode, patch),
9449        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9450     ok(!lstrcmpA(targetprod, prodcode),
9451        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9452     ok(context == MSIINSTALLCONTEXT_MACHINE,
9453        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9454     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9455     ok(size == 0, "Expected 0, got %d\n", size);
9456
9457     /* MSIPATCHSTATE_REGISTERED */
9458     /* FIXME */
9459
9460     /* MSIPATCHSTATE_ALL */
9461
9462     /* 1st */
9463     lstrcpyA(patchcode, "apple");
9464     lstrcpyA(targetprod, "banana");
9465     context = 0xdeadbeef;
9466     lstrcpyA(targetsid, "kiwi");
9467     size = MAX_PATH;
9468     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9469                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9470                            &context, targetsid, &size);
9471     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9472     ok(!lstrcmpA(patchcode, patch),
9473        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9474     ok(!lstrcmpA(targetprod, prodcode),
9475        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9476     ok(context == MSIINSTALLCONTEXT_MACHINE,
9477        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9478     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9479     ok(size == 0, "Expected 0, got %d\n", size);
9480
9481     /* same patch in multiple places, only one is enumerated */
9482     lstrcpyA(patchcode, "apple");
9483     lstrcpyA(targetprod, "banana");
9484     context = 0xdeadbeef;
9485     lstrcpyA(targetsid, "kiwi");
9486     size = MAX_PATH;
9487     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9488                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9489                            &context, targetsid, &size);
9490     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9491     ok(!lstrcmpA(patchcode, "apple"),
9492        "Expected patchcode to be unchanged, got %s\n", patchcode);
9493     ok(!lstrcmpA(targetprod, "banana"),
9494        "Expected targetprod to be unchanged, got %s\n", targetprod);
9495     ok(context == 0xdeadbeef,
9496        "Expected context to be unchanged, got %d\n", context);
9497     ok(!lstrcmpA(targetsid, "kiwi"),
9498        "Expected targetsid to be unchanged, got %s\n", targetsid);
9499     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9500
9501     RegDeleteValueA(patches, patch_squashed);
9502     RegDeleteValueA(patches, "Patches");
9503     delete_key(patches, "", access & KEY_WOW64_64KEY);
9504     RegCloseKey(patches);
9505     RegDeleteValueA(hpatch, "State");
9506     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9507     RegCloseKey(hpatch);
9508     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9509     RegCloseKey(udpatch);
9510     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9511     RegCloseKey(udprod);
9512     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9513     RegCloseKey(prodkey);
9514 }
9515
9516 static void test_MsiEnumPatchesEx(void)
9517 {
9518     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9519     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9520     CHAR patchcode[MAX_PATH];
9521     MSIINSTALLCONTEXT context;
9522     LPSTR usersid;
9523     DWORD size;
9524     UINT r;
9525
9526     if (!pMsiEnumPatchesExA)
9527     {
9528         win_skip("MsiEnumPatchesExA not implemented\n");
9529         return;
9530     }
9531
9532     create_test_guid(prodcode, prod_squashed);
9533     usersid = get_user_sid();
9534
9535     /* empty szProductCode */
9536     lstrcpyA(patchcode, "apple");
9537     lstrcpyA(targetprod, "banana");
9538     context = 0xdeadbeef;
9539     lstrcpyA(targetsid, "kiwi");
9540     size = MAX_PATH;
9541     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9542                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9543                            targetsid, &size);
9544     ok(r == ERROR_INVALID_PARAMETER,
9545        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9546     ok(!lstrcmpA(patchcode, "apple"),
9547        "Expected patchcode to be unchanged, got %s\n", patchcode);
9548     ok(!lstrcmpA(targetprod, "banana"),
9549        "Expected targetprod to be unchanged, got %s\n", targetprod);
9550     ok(context == 0xdeadbeef,
9551        "Expected context to be unchanged, got %d\n", context);
9552     ok(!lstrcmpA(targetsid, "kiwi"),
9553        "Expected targetsid to be unchanged, got %s\n", targetsid);
9554     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9555
9556     /* garbage szProductCode */
9557     lstrcpyA(patchcode, "apple");
9558     lstrcpyA(targetprod, "banana");
9559     context = 0xdeadbeef;
9560     lstrcpyA(targetsid, "kiwi");
9561     size = MAX_PATH;
9562     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9563                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9564                            targetsid, &size);
9565     ok(r == ERROR_INVALID_PARAMETER,
9566        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9567     ok(!lstrcmpA(patchcode, "apple"),
9568        "Expected patchcode to be unchanged, got %s\n", patchcode);
9569     ok(!lstrcmpA(targetprod, "banana"),
9570        "Expected targetprod to be unchanged, got %s\n", targetprod);
9571     ok(context == 0xdeadbeef,
9572        "Expected context to be unchanged, got %d\n", context);
9573     ok(!lstrcmpA(targetsid, "kiwi"),
9574        "Expected targetsid to be unchanged, got %s\n", targetsid);
9575     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9576
9577     /* guid without brackets */
9578     lstrcpyA(patchcode, "apple");
9579     lstrcpyA(targetprod, "banana");
9580     context = 0xdeadbeef;
9581     lstrcpyA(targetsid, "kiwi");
9582     size = MAX_PATH;
9583     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9584                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9585                            0, patchcode, targetprod, &context,
9586                            targetsid, &size);
9587     ok(r == ERROR_INVALID_PARAMETER,
9588        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9589     ok(!lstrcmpA(patchcode, "apple"),
9590        "Expected patchcode to be unchanged, got %s\n", patchcode);
9591     ok(!lstrcmpA(targetprod, "banana"),
9592        "Expected targetprod to be unchanged, got %s\n", targetprod);
9593     ok(context == 0xdeadbeef,
9594        "Expected context to be unchanged, got %d\n", context);
9595     ok(!lstrcmpA(targetsid, "kiwi"),
9596        "Expected targetsid to be unchanged, got %s\n", targetsid);
9597     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9598
9599     /* guid with brackets */
9600     lstrcpyA(patchcode, "apple");
9601     lstrcpyA(targetprod, "banana");
9602     context = 0xdeadbeef;
9603     lstrcpyA(targetsid, "kiwi");
9604     size = MAX_PATH;
9605     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9606                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9607                            0, patchcode, targetprod, &context,
9608                            targetsid, &size);
9609     ok(r == ERROR_NO_MORE_ITEMS,
9610        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9611     ok(!lstrcmpA(patchcode, "apple"),
9612        "Expected patchcode to be unchanged, got %s\n", patchcode);
9613     ok(!lstrcmpA(targetprod, "banana"),
9614        "Expected targetprod to be unchanged, got %s\n", targetprod);
9615     ok(context == 0xdeadbeef,
9616        "Expected context to be unchanged, got %d\n", context);
9617     ok(!lstrcmpA(targetsid, "kiwi"),
9618        "Expected targetsid to be unchanged, got %s\n", targetsid);
9619     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9620
9621     /* szUserSid is S-1-5-18 */
9622     lstrcpyA(patchcode, "apple");
9623     lstrcpyA(targetprod, "banana");
9624     context = 0xdeadbeef;
9625     lstrcpyA(targetsid, "kiwi");
9626     size = MAX_PATH;
9627     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9628                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9629                            0, patchcode, targetprod, &context,
9630                            targetsid, &size);
9631     ok(r == ERROR_INVALID_PARAMETER,
9632        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9633     ok(!lstrcmpA(patchcode, "apple"),
9634        "Expected patchcode to be unchanged, got %s\n", patchcode);
9635     ok(!lstrcmpA(targetprod, "banana"),
9636        "Expected targetprod to be unchanged, got %s\n", targetprod);
9637     ok(context == 0xdeadbeef,
9638        "Expected context to be unchanged, got %d\n", context);
9639     ok(!lstrcmpA(targetsid, "kiwi"),
9640        "Expected targetsid to be unchanged, got %s\n", targetsid);
9641     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9642
9643     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9644     lstrcpyA(patchcode, "apple");
9645     lstrcpyA(targetprod, "banana");
9646     context = 0xdeadbeef;
9647     lstrcpyA(targetsid, "kiwi");
9648     size = MAX_PATH;
9649     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9650                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9651                            &context, targetsid, &size);
9652     ok(r == ERROR_INVALID_PARAMETER,
9653        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9654     ok(!lstrcmpA(patchcode, "apple"),
9655        "Expected patchcode to be unchanged, got %s\n", patchcode);
9656     ok(!lstrcmpA(targetprod, "banana"),
9657        "Expected targetprod to be unchanged, got %s\n", targetprod);
9658     ok(context == 0xdeadbeef,
9659        "Expected context to be unchanged, got %d\n", context);
9660     ok(!lstrcmpA(targetsid, "kiwi"),
9661        "Expected targetsid to be unchanged, got %s\n", targetsid);
9662     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9663
9664     /* dwContext is out of bounds */
9665     lstrcpyA(patchcode, "apple");
9666     lstrcpyA(targetprod, "banana");
9667     context = 0xdeadbeef;
9668     lstrcpyA(targetsid, "kiwi");
9669     size = MAX_PATH;
9670     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9671                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9672                            &context, targetsid, &size);
9673     ok(r == ERROR_INVALID_PARAMETER,
9674        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9675     ok(!lstrcmpA(patchcode, "apple"),
9676        "Expected patchcode to be unchanged, got %s\n", patchcode);
9677     ok(!lstrcmpA(targetprod, "banana"),
9678        "Expected targetprod to be unchanged, got %s\n", targetprod);
9679     ok(context == 0xdeadbeef,
9680        "Expected context to be unchanged, got %d\n", context);
9681     ok(!lstrcmpA(targetsid, "kiwi"),
9682        "Expected targetsid to be unchanged, got %s\n", targetsid);
9683     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9684
9685     /* dwContext is out of bounds */
9686     lstrcpyA(patchcode, "apple");
9687     lstrcpyA(targetprod, "banana");
9688     context = 0xdeadbeef;
9689     lstrcpyA(targetsid, "kiwi");
9690     size = MAX_PATH;
9691     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9692                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9693                            &context, targetsid, &size);
9694     ok(r == ERROR_INVALID_PARAMETER,
9695        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9696     ok(!lstrcmpA(patchcode, "apple"),
9697        "Expected patchcode to be unchanged, got %s\n", patchcode);
9698     ok(!lstrcmpA(targetprod, "banana"),
9699        "Expected targetprod to be unchanged, got %s\n", targetprod);
9700     ok(context == 0xdeadbeef,
9701        "Expected context to be unchanged, got %d\n", context);
9702     ok(!lstrcmpA(targetsid, "kiwi"),
9703        "Expected targetsid to be unchanged, got %s\n", targetsid);
9704     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9705
9706     /* dwFilter is out of bounds */
9707     lstrcpyA(patchcode, "apple");
9708     lstrcpyA(targetprod, "banana");
9709     context = 0xdeadbeef;
9710     lstrcpyA(targetsid, "kiwi");
9711     size = MAX_PATH;
9712     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9713                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9714                            &context, targetsid, &size);
9715     ok(r == ERROR_INVALID_PARAMETER,
9716        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9717     ok(!lstrcmpA(patchcode, "apple"),
9718        "Expected patchcode to be unchanged, got %s\n", patchcode);
9719     ok(!lstrcmpA(targetprod, "banana"),
9720        "Expected targetprod to be unchanged, got %s\n", targetprod);
9721     ok(context == 0xdeadbeef,
9722        "Expected context to be unchanged, got %d\n", context);
9723     ok(!lstrcmpA(targetsid, "kiwi"),
9724        "Expected targetsid to be unchanged, got %s\n", targetsid);
9725     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9726
9727     /* dwFilter is out of bounds */
9728     lstrcpyA(patchcode, "apple");
9729     lstrcpyA(targetprod, "banana");
9730     context = 0xdeadbeef;
9731     lstrcpyA(targetsid, "kiwi");
9732     size = MAX_PATH;
9733     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9734                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9735                            &context, targetsid, &size);
9736     ok(r == ERROR_INVALID_PARAMETER,
9737        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9738     ok(!lstrcmpA(patchcode, "apple"),
9739        "Expected patchcode to be unchanged, got %s\n", patchcode);
9740     ok(!lstrcmpA(targetprod, "banana"),
9741        "Expected targetprod to be unchanged, got %s\n", targetprod);
9742     ok(context == 0xdeadbeef,
9743        "Expected context to be unchanged, got %d\n", context);
9744     ok(!lstrcmpA(targetsid, "kiwi"),
9745        "Expected targetsid to be unchanged, got %s\n", targetsid);
9746     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9747
9748     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9749     lstrcpyA(patchcode, "apple");
9750     lstrcpyA(targetprod, "banana");
9751     context = 0xdeadbeef;
9752     lstrcpyA(targetsid, "kiwi");
9753     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9754                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9755                            &context, targetsid, NULL);
9756     ok(r == ERROR_INVALID_PARAMETER,
9757        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9758     ok(!lstrcmpA(patchcode, "apple"),
9759        "Expected patchcode to be unchanged, got %s\n", patchcode);
9760     ok(!lstrcmpA(targetprod, "banana"),
9761        "Expected targetprod to be unchanged, got %s\n", targetprod);
9762     ok(context == 0xdeadbeef,
9763        "Expected context to be unchanged, got %d\n", context);
9764     ok(!lstrcmpA(targetsid, "kiwi"),
9765        "Expected targetsid to be unchanged, got %s\n", targetsid);
9766
9767     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9768     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9769     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9770     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9771     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9772     /* FIXME: Successfully test userunmanaged with a different user */
9773     test_MsiEnumPatchesEx_machine();
9774     LocalFree(usersid);
9775 }
9776
9777 static void test_MsiEnumPatches(void)
9778 {
9779     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9780     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9781     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9782     CHAR transforms[MAX_PATH];
9783     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9784     HKEY prodkey, patches, udprod;
9785     HKEY userkey, hpatch, udpatch;
9786     DWORD size, data;
9787     LPSTR usersid;
9788     LONG res;
9789     UINT r;
9790     REGSAM access = KEY_ALL_ACCESS;
9791
9792     create_test_guid(prodcode, prod_squashed);
9793     create_test_guid(patchcode, patch_squashed);
9794     usersid = get_user_sid();
9795
9796     if (is_wow64)
9797         access |= KEY_WOW64_64KEY;
9798
9799     /* NULL szProduct */
9800     size = MAX_PATH;
9801     lstrcpyA(patch, "apple");
9802     lstrcpyA(transforms, "banana");
9803     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9804     ok(r == ERROR_INVALID_PARAMETER,
9805        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9806     ok(!lstrcmpA(patch, "apple"),
9807        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9808     ok(!lstrcmpA(transforms, "banana"),
9809        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9810     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9811
9812     /* empty szProduct */
9813     size = MAX_PATH;
9814     lstrcpyA(patch, "apple");
9815     lstrcpyA(transforms, "banana");
9816     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9817     ok(r == ERROR_INVALID_PARAMETER,
9818        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9819     ok(!lstrcmpA(patch, "apple"),
9820        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9821     ok(!lstrcmpA(transforms, "banana"),
9822        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9823     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9824
9825     /* garbage szProduct */
9826     size = MAX_PATH;
9827     lstrcpyA(patch, "apple");
9828     lstrcpyA(transforms, "banana");
9829     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9830     ok(r == ERROR_INVALID_PARAMETER,
9831        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9832     ok(!lstrcmpA(patch, "apple"),
9833        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9834     ok(!lstrcmpA(transforms, "banana"),
9835        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9836     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9837
9838     /* guid without brackets */
9839     size = MAX_PATH;
9840     lstrcpyA(patch, "apple");
9841     lstrcpyA(transforms, "banana");
9842     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9843                         transforms, &size);
9844     ok(r == ERROR_INVALID_PARAMETER,
9845        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9846     ok(!lstrcmpA(patch, "apple"),
9847        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9848     ok(!lstrcmpA(transforms, "banana"),
9849        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9850     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9851
9852     /* guid with brackets */
9853     size = MAX_PATH;
9854     lstrcpyA(patch, "apple");
9855     lstrcpyA(transforms, "banana");
9856     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9857                         transforms, &size);
9858     ok(r == ERROR_UNKNOWN_PRODUCT,
9859        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9860     ok(!lstrcmpA(patch, "apple"),
9861        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9862     ok(!lstrcmpA(transforms, "banana"),
9863        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9864     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9865
9866     /* same length as guid, but random */
9867     size = MAX_PATH;
9868     lstrcpyA(patch, "apple");
9869     lstrcpyA(transforms, "banana");
9870     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9871                         transforms, &size);
9872     ok(r == ERROR_INVALID_PARAMETER,
9873        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9874     ok(!lstrcmpA(patch, "apple"),
9875        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9876     ok(!lstrcmpA(transforms, "banana"),
9877        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9878     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9879
9880     /* MSIINSTALLCONTEXT_USERMANAGED */
9881
9882     size = MAX_PATH;
9883     lstrcpyA(patch, "apple");
9884     lstrcpyA(transforms, "banana");
9885     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9886     ok(r == ERROR_UNKNOWN_PRODUCT,
9887        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9888     ok(!lstrcmpA(patch, "apple"),
9889        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9890     ok(!lstrcmpA(transforms, "banana"),
9891        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9892     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9893
9894     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9895     lstrcatA(keypath, usersid);
9896     lstrcatA(keypath, "\\Installer\\Products\\");
9897     lstrcatA(keypath, prod_squashed);
9898
9899     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9900     if (res == ERROR_ACCESS_DENIED)
9901     {
9902         skip("Not enough rights to perform tests\n");
9903         LocalFree(usersid);
9904         return;
9905     }
9906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9907
9908     /* managed product key exists */
9909     size = MAX_PATH;
9910     lstrcpyA(patch, "apple");
9911     lstrcpyA(transforms, "banana");
9912     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9913     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9914     ok(!lstrcmpA(patch, "apple"),
9915        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9916     ok(!lstrcmpA(transforms, "banana"),
9917        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9918     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9919
9920     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9922
9923     /* patches key exists */
9924     size = MAX_PATH;
9925     lstrcpyA(patch, "apple");
9926     lstrcpyA(transforms, "banana");
9927     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9928     ok(r == ERROR_NO_MORE_ITEMS ||
9929        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9930        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9931     ok(!lstrcmpA(patch, "apple"),
9932        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9933     ok(!lstrcmpA(transforms, "banana"),
9934        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9935     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9936
9937     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9938                          (const BYTE *)patch_squashed,
9939                          lstrlenA(patch_squashed) + 1);
9940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9941
9942     /* Patches value exists, is not REG_MULTI_SZ */
9943     size = MAX_PATH;
9944     lstrcpyA(patch, "apple");
9945     lstrcpyA(transforms, "banana");
9946     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9947     ok(r == ERROR_BAD_CONFIGURATION ||
9948        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9949        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9950     ok(!lstrcmpA(patch, "apple"),
9951        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9952     ok(!lstrcmpA(transforms, "banana"),
9953        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9954     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9955
9956     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9957                          (const BYTE *)"a\0b\0c\0\0", 7);
9958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9959
9960     /* Patches value exists, is not a squashed guid */
9961     size = MAX_PATH;
9962     lstrcpyA(patch, "apple");
9963     lstrcpyA(transforms, "banana");
9964     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9965     ok(r == ERROR_BAD_CONFIGURATION,
9966        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9967     ok(!lstrcmpA(patch, "apple"),
9968        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9969     ok(!lstrcmpA(transforms, "banana"),
9970        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9971     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9972
9973     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9974     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9975                          (const BYTE *)patch_squashed,
9976                          lstrlenA(patch_squashed) + 2);
9977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9978
9979     /* Patches value exists */
9980     size = MAX_PATH;
9981     lstrcpyA(patch, "apple");
9982     lstrcpyA(transforms, "banana");
9983     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9984     ok(r == ERROR_NO_MORE_ITEMS ||
9985        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9986        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9987     ok(!lstrcmpA(patch, "apple") ||
9988        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9989        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9990     ok(!lstrcmpA(transforms, "banana"),
9991        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9992     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9993
9994     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9995                          (const BYTE *)"whatever", 9);
9996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9997
9998     /* patch squashed value exists */
9999     size = MAX_PATH;
10000     lstrcpyA(patch, "apple");
10001     lstrcpyA(transforms, "banana");
10002     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10004     ok(!lstrcmpA(patch, patchcode),
10005        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10006     ok(!lstrcmpA(transforms, "whatever"),
10007        "Expected \"whatever\", got \"%s\"\n", transforms);
10008     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10009
10010     /* lpPatchBuf is NULL */
10011     size = MAX_PATH;
10012     lstrcpyA(transforms, "banana");
10013     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
10014     ok(r == ERROR_INVALID_PARAMETER,
10015        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10016     ok(!lstrcmpA(transforms, "banana"),
10017        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10018     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10019
10020     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
10021     size = MAX_PATH;
10022     lstrcpyA(patch, "apple");
10023     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
10024     ok(r == ERROR_INVALID_PARAMETER,
10025        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10026     ok(!lstrcmpA(patch, "apple"),
10027        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10028     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10029
10030     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
10031     lstrcpyA(patch, "apple");
10032     lstrcpyA(transforms, "banana");
10033     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
10034     ok(r == ERROR_INVALID_PARAMETER,
10035        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10036     ok(!lstrcmpA(patch, "apple"),
10037        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10038     ok(!lstrcmpA(transforms, "banana"),
10039        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10040
10041     /* pcchTransformsBuf is too small */
10042     size = 6;
10043     lstrcpyA(patch, "apple");
10044     lstrcpyA(transforms, "banana");
10045     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10046     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10047     ok(!lstrcmpA(patch, patchcode),
10048        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10049     ok(!lstrcmpA(transforms, "whate") ||
10050        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10051        "Expected \"whate\", got \"%s\"\n", transforms);
10052     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
10053
10054     /* increase the index */
10055     size = MAX_PATH;
10056     lstrcpyA(patch, "apple");
10057     lstrcpyA(transforms, "banana");
10058     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
10059     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10060     ok(!lstrcmpA(patch, "apple"),
10061        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10062     ok(!lstrcmpA(transforms, "banana"),
10063        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10064     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10065
10066     /* increase again */
10067     size = MAX_PATH;
10068     lstrcpyA(patch, "apple");
10069     lstrcpyA(transforms, "banana");
10070     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
10071     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10072     ok(!lstrcmpA(patch, "apple"),
10073        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10074     ok(!lstrcmpA(transforms, "banana"),
10075        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10076     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10077
10078     RegDeleteValueA(patches, "Patches");
10079     delete_key(patches, "", access & KEY_WOW64_64KEY);
10080     RegCloseKey(patches);
10081     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10082     RegCloseKey(prodkey);
10083
10084     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10085
10086     size = MAX_PATH;
10087     lstrcpyA(patch, "apple");
10088     lstrcpyA(transforms, "banana");
10089     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10090     ok(r == ERROR_UNKNOWN_PRODUCT,
10091        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10092     ok(!lstrcmpA(patch, "apple"),
10093        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10094     ok(!lstrcmpA(transforms, "banana"),
10095        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10096     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10097
10098     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10099     lstrcatA(keypath, prod_squashed);
10100
10101     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10103
10104     /* current user product key exists */
10105     size = MAX_PATH;
10106     lstrcpyA(patch, "apple");
10107     lstrcpyA(transforms, "banana");
10108     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10109     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10110     ok(!lstrcmpA(patch, "apple"),
10111        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10112     ok(!lstrcmpA(transforms, "banana"),
10113        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10114     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10115
10116     res = RegCreateKeyA(prodkey, "Patches", &patches);
10117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10118
10119     /* Patches key exists */
10120     size = MAX_PATH;
10121     lstrcpyA(patch, "apple");
10122     lstrcpyA(transforms, "banana");
10123     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10124     ok(r == ERROR_NO_MORE_ITEMS ||
10125        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10126        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10127     ok(!lstrcmpA(patch, "apple"),
10128        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10129     ok(!lstrcmpA(transforms, "banana"),
10130        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10131     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10132
10133     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10134                          (const BYTE *)patch_squashed,
10135                          lstrlenA(patch_squashed) + 1);
10136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10137
10138     /* Patches value exists, is not REG_MULTI_SZ */
10139     size = MAX_PATH;
10140     lstrcpyA(patch, "apple");
10141     lstrcpyA(transforms, "banana");
10142     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10143     ok(r == ERROR_BAD_CONFIGURATION ||
10144        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10145        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10146     ok(!lstrcmpA(patch, "apple"),
10147        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10148     ok(!lstrcmpA(transforms, "banana"),
10149        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10150     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10151
10152     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10153                          (const BYTE *)"a\0b\0c\0\0", 7);
10154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10155
10156     /* Patches value exists, is not a squashed guid */
10157     size = MAX_PATH;
10158     lstrcpyA(patch, "apple");
10159     lstrcpyA(transforms, "banana");
10160     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10161     ok(r == ERROR_BAD_CONFIGURATION,
10162        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10163     ok(!lstrcmpA(patch, "apple"),
10164        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10165     ok(!lstrcmpA(transforms, "banana"),
10166        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10167     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10168
10169     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10170     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10171                          (const BYTE *)patch_squashed,
10172                          lstrlenA(patch_squashed) + 2);
10173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10174
10175     /* Patches value exists */
10176     size = MAX_PATH;
10177     lstrcpyA(patch, "apple");
10178     lstrcpyA(transforms, "banana");
10179     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10180     ok(r == ERROR_NO_MORE_ITEMS ||
10181        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10182        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10183     ok(!lstrcmpA(patch, "apple") ||
10184        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10185        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10186     ok(!lstrcmpA(transforms, "banana"),
10187        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10188     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10189
10190     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10191                          (const BYTE *)"whatever", 9);
10192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10193
10194     /* patch code value exists */
10195     size = MAX_PATH;
10196     lstrcpyA(patch, "apple");
10197     lstrcpyA(transforms, "banana");
10198     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10199     ok(r == ERROR_NO_MORE_ITEMS ||
10200        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10201        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10202     ok(!lstrcmpA(patch, "apple") ||
10203        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10204        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10205     ok(!lstrcmpA(transforms, "banana") ||
10206        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10207        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10208     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10209
10210     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10211     lstrcatA(keypath, usersid);
10212     lstrcatA(keypath, "\\Patches\\");
10213     lstrcatA(keypath, patch_squashed);
10214
10215     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10217
10218     /* userdata patch key exists */
10219     size = MAX_PATH;
10220     lstrcpyA(patch, "apple");
10221     lstrcpyA(transforms, "banana");
10222     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10224     ok(!lstrcmpA(patch, patchcode),
10225        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10226     ok(!lstrcmpA(transforms, "whatever"),
10227        "Expected \"whatever\", got \"%s\"\n", transforms);
10228     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10229
10230     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10231     RegCloseKey(userkey);
10232     RegDeleteValueA(patches, patch_squashed);
10233     RegDeleteValueA(patches, "Patches");
10234     RegDeleteKeyA(patches, "");
10235     RegCloseKey(patches);
10236     RegDeleteKeyA(prodkey, "");
10237     RegCloseKey(prodkey);
10238
10239     /* MSIINSTALLCONTEXT_MACHINE */
10240
10241     size = MAX_PATH;
10242     lstrcpyA(patch, "apple");
10243     lstrcpyA(transforms, "banana");
10244     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10245     ok(r == ERROR_UNKNOWN_PRODUCT,
10246        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10247     ok(!lstrcmpA(patch, "apple"),
10248        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10249     ok(!lstrcmpA(transforms, "banana"),
10250        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10251     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10252
10253     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10254     lstrcatA(keypath, prod_squashed);
10255
10256     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10258
10259     /* local product key exists */
10260     size = MAX_PATH;
10261     lstrcpyA(patch, "apple");
10262     lstrcpyA(transforms, "banana");
10263     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10264     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10265     ok(!lstrcmpA(patch, "apple"),
10266        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10267     ok(!lstrcmpA(transforms, "banana"),
10268        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10269     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10270
10271     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10273
10274     /* Patches key exists */
10275     size = MAX_PATH;
10276     lstrcpyA(patch, "apple");
10277     lstrcpyA(transforms, "banana");
10278     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10279     ok(r == ERROR_NO_MORE_ITEMS ||
10280        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10281        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10282     ok(!lstrcmpA(patch, "apple"),
10283        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10284     ok(!lstrcmpA(transforms, "banana"),
10285        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10286     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10287
10288     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10289                          (const BYTE *)patch_squashed,
10290                          lstrlenA(patch_squashed) + 1);
10291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10292
10293     /* Patches value exists, is not REG_MULTI_SZ */
10294     size = MAX_PATH;
10295     lstrcpyA(patch, "apple");
10296     lstrcpyA(transforms, "banana");
10297     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10298     ok(r == ERROR_BAD_CONFIGURATION ||
10299        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10300        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10301     ok(!lstrcmpA(patch, "apple"),
10302        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10303     ok(!lstrcmpA(transforms, "banana"),
10304        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10305     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10306
10307     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10308                          (const BYTE *)"a\0b\0c\0\0", 7);
10309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10310
10311     /* Patches value exists, is not a squashed guid */
10312     size = MAX_PATH;
10313     lstrcpyA(patch, "apple");
10314     lstrcpyA(transforms, "banana");
10315     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10316     ok(r == ERROR_BAD_CONFIGURATION,
10317        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10318     ok(!lstrcmpA(patch, "apple"),
10319        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10320     ok(!lstrcmpA(transforms, "banana"),
10321        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10322     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10323
10324     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10325     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10326                          (const BYTE *)patch_squashed,
10327                          lstrlenA(patch_squashed) + 2);
10328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10329
10330     /* Patches value exists */
10331     size = MAX_PATH;
10332     lstrcpyA(patch, "apple");
10333     lstrcpyA(transforms, "banana");
10334     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10335     ok(r == ERROR_NO_MORE_ITEMS ||
10336        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10337        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10338     ok(!lstrcmpA(patch, "apple") ||
10339        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10340        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10341     ok(!lstrcmpA(transforms, "banana"),
10342        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10343     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10344
10345     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10346                          (const BYTE *)"whatever", 9);
10347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10348
10349     /* patch code value exists */
10350     size = MAX_PATH;
10351     lstrcpyA(patch, "apple");
10352     lstrcpyA(transforms, "banana");
10353     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10355     ok(!lstrcmpA(patch, patchcode),
10356        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10357     ok(!lstrcmpA(transforms, "whatever"),
10358        "Expected \"whatever\", got \"%s\"\n", transforms);
10359     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10360
10361     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10362     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10363     lstrcatA(keypath, prod_squashed);
10364
10365     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10367
10368     /* local UserData product key exists */
10369     size = MAX_PATH;
10370     lstrcpyA(patch, "apple");
10371     lstrcpyA(transforms, "banana");
10372     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10374     ok(!lstrcmpA(patch, patchcode),
10375        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10376     ok(!lstrcmpA(transforms, "whatever"),
10377        "Expected \"whatever\", got \"%s\"\n", transforms);
10378     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10379
10380     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10382
10383     /* local UserData Patches key exists */
10384     size = MAX_PATH;
10385     lstrcpyA(patch, "apple");
10386     lstrcpyA(transforms, "banana");
10387     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10389     ok(!lstrcmpA(patch, patchcode),
10390        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10391     ok(!lstrcmpA(transforms, "whatever"),
10392        "Expected \"whatever\", got \"%s\"\n", transforms);
10393     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10394
10395     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10397
10398     /* local UserData Product patch key exists */
10399     size = MAX_PATH;
10400     lstrcpyA(patch, "apple");
10401     lstrcpyA(transforms, "banana");
10402     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10403     ok(r == ERROR_NO_MORE_ITEMS ||
10404        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10405        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10406     ok(!lstrcmpA(patch, "apple") ||
10407        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10408        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10409     ok(!lstrcmpA(transforms, "banana") ||
10410        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10411        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10412     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10413
10414     data = MSIPATCHSTATE_APPLIED;
10415     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10416                          (const BYTE *)&data, sizeof(DWORD));
10417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10418
10419     /* State value exists */
10420     size = MAX_PATH;
10421     lstrcpyA(patch, "apple");
10422     lstrcpyA(transforms, "banana");
10423     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10425     ok(!lstrcmpA(patch, patchcode),
10426        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10427     ok(!lstrcmpA(transforms, "whatever"),
10428        "Expected \"whatever\", got \"%s\"\n", transforms);
10429     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10430
10431     /* now duplicate some of the tests for the W version */
10432
10433     /* pcchTransformsBuf is too small */
10434     size = 6;
10435     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10436     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10437     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10438     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10439     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10440     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10441     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10442     ok(!lstrcmpA(patch, patchcode),
10443        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10444     ok(!lstrcmpA(transforms, "whate") ||
10445        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10446        "Expected \"whate\", got \"%s\"\n", transforms);
10447     ok(size == 8, "Expected 8, got %d\n", size);
10448
10449     /* patch code value exists */
10450     size = MAX_PATH;
10451     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10452     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10453     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10455     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10456     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10457     ok(!lstrcmpA(patch, patchcode),
10458        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10459     ok(!lstrcmpA(transforms, "whatever"),
10460        "Expected \"whatever\", got \"%s\"\n", transforms);
10461     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10462
10463     RegDeleteValueA(patches, patch_squashed);
10464     RegDeleteValueA(patches, "Patches");
10465     delete_key(patches, "", access & KEY_WOW64_64KEY);
10466     RegCloseKey(patches);
10467     RegDeleteValueA(hpatch, "State");
10468     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10469     RegCloseKey(hpatch);
10470     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10471     RegCloseKey(udpatch);
10472     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10473     RegCloseKey(udprod);
10474     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10475     RegCloseKey(prodkey);
10476     LocalFree(usersid);
10477 }
10478
10479 static void test_MsiGetPatchInfoEx(void)
10480 {
10481     CHAR keypath[MAX_PATH], val[MAX_PATH];
10482     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10483     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10484     HKEY prodkey, patches, udprod, props;
10485     HKEY hpatch, udpatch, prodpatches;
10486     LPSTR usersid;
10487     DWORD size;
10488     LONG res;
10489     UINT r;
10490     REGSAM access = KEY_ALL_ACCESS;
10491
10492     if (!pMsiGetPatchInfoExA)
10493     {
10494         win_skip("MsiGetPatchInfoEx not implemented\n");
10495         return;
10496     }
10497
10498     create_test_guid(prodcode, prod_squashed);
10499     create_test_guid(patchcode, patch_squashed);
10500     usersid = get_user_sid();
10501
10502     if (is_wow64)
10503         access |= KEY_WOW64_64KEY;
10504
10505     /* NULL szPatchCode */
10506     lstrcpyA(val, "apple");
10507     size = MAX_PATH;
10508     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10509                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10510     ok(r == ERROR_INVALID_PARAMETER,
10511        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10512     ok(!lstrcmpA(val, "apple"),
10513        "Expected val to be unchanged, got \"%s\"\n", val);
10514     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10515
10516     /* empty szPatchCode */
10517     size = MAX_PATH;
10518     lstrcpyA(val, "apple");
10519     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10520                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10521     ok(r == ERROR_INVALID_PARAMETER,
10522        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10523     ok(!lstrcmpA(val, "apple"),
10524        "Expected val to be unchanged, got \"%s\"\n", val);
10525     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10526
10527     /* garbage szPatchCode */
10528     size = MAX_PATH;
10529     lstrcpyA(val, "apple");
10530     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10531                             MSIINSTALLCONTEXT_USERMANAGED,
10532                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10533     ok(r == ERROR_INVALID_PARAMETER,
10534        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10535     ok(!lstrcmpA(val, "apple"),
10536        "Expected val to be unchanged, got \"%s\"\n", val);
10537     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10538
10539     /* guid without brackets */
10540     size = MAX_PATH;
10541     lstrcpyA(val, "apple");
10542     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10543                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10544                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10545     ok(r == ERROR_INVALID_PARAMETER,
10546        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10547     ok(!lstrcmpA(val, "apple"),
10548        "Expected val to be unchanged, got \"%s\"\n", val);
10549     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10550
10551     /* guid with brackets */
10552     size = MAX_PATH;
10553     lstrcpyA(val, "apple");
10554     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10555                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10556                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10557     ok(r == ERROR_UNKNOWN_PRODUCT,
10558        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10559     ok(!lstrcmpA(val, "apple"),
10560        "Expected val to be unchanged, got \"%s\"\n", val);
10561     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10562
10563     /* same length as guid, but random */
10564     size = MAX_PATH;
10565     lstrcpyA(val, "apple");
10566     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10567                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10568                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10569     ok(r == ERROR_INVALID_PARAMETER,
10570        "Expected ERROR_INVALID_PARAMETER, 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     /* NULL szProductCode */
10576     lstrcpyA(val, "apple");
10577     size = MAX_PATH;
10578     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10579                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10580     ok(r == ERROR_INVALID_PARAMETER,
10581        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10582     ok(!lstrcmpA(val, "apple"),
10583        "Expected val to be unchanged, got \"%s\"\n", val);
10584     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10585
10586     /* empty szProductCode */
10587     size = MAX_PATH;
10588     lstrcpyA(val, "apple");
10589     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10590                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10591     ok(r == ERROR_INVALID_PARAMETER,
10592        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10593     ok(!lstrcmpA(val, "apple"),
10594        "Expected val to be unchanged, got \"%s\"\n", val);
10595     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10596
10597     /* garbage szProductCode */
10598     size = MAX_PATH;
10599     lstrcpyA(val, "apple");
10600     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10601                             MSIINSTALLCONTEXT_USERMANAGED,
10602                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10603     ok(r == ERROR_INVALID_PARAMETER,
10604        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10605     ok(!lstrcmpA(val, "apple"),
10606        "Expected val to be unchanged, got \"%s\"\n", val);
10607     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10608
10609     /* guid without brackets */
10610     size = MAX_PATH;
10611     lstrcpyA(val, "apple");
10612     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10613                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10614                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10615     ok(r == ERROR_INVALID_PARAMETER,
10616        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10617     ok(!lstrcmpA(val, "apple"),
10618        "Expected val to be unchanged, got \"%s\"\n", val);
10619     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10620
10621     /* guid with brackets */
10622     size = MAX_PATH;
10623     lstrcpyA(val, "apple");
10624     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10625                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10626                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10627     ok(r == ERROR_UNKNOWN_PRODUCT,
10628        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10629     ok(!lstrcmpA(val, "apple"),
10630        "Expected val to be unchanged, got \"%s\"\n", val);
10631     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10632
10633     /* same length as guid, but random */
10634     size = MAX_PATH;
10635     lstrcpyA(val, "apple");
10636     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10637                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10638                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10639     ok(r == ERROR_INVALID_PARAMETER,
10640        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10641     ok(!lstrcmpA(val, "apple"),
10642        "Expected val to be unchanged, got \"%s\"\n", val);
10643     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10644
10645     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10646     size = MAX_PATH;
10647     lstrcpyA(val, "apple");
10648     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10649                             MSIINSTALLCONTEXT_USERMANAGED,
10650                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10651     ok(r == ERROR_INVALID_PARAMETER,
10652        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10653     ok(!lstrcmpA(val, "apple"),
10654        "Expected val to be unchanged, got \"%s\"\n", val);
10655     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10656
10657     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10658     size = MAX_PATH;
10659     lstrcpyA(val, "apple");
10660     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10661                             MSIINSTALLCONTEXT_USERUNMANAGED,
10662                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10663     ok(r == ERROR_INVALID_PARAMETER,
10664        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10665     ok(!lstrcmpA(val, "apple"),
10666        "Expected val to be unchanged, got \"%s\"\n", val);
10667     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10668
10669     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10670     size = MAX_PATH;
10671     lstrcpyA(val, "apple");
10672     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10673                             MSIINSTALLCONTEXT_MACHINE,
10674                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10675     ok(r == ERROR_INVALID_PARAMETER,
10676        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10677     ok(!lstrcmpA(val, "apple"),
10678        "Expected val to be unchanged, got \"%s\"\n", val);
10679     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10680
10681     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10682     size = MAX_PATH;
10683     lstrcpyA(val, "apple");
10684     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10685                             MSIINSTALLCONTEXT_MACHINE,
10686                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10687     ok(r == ERROR_INVALID_PARAMETER,
10688        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10689     ok(!lstrcmpA(val, "apple"),
10690        "Expected val to be unchanged, got \"%s\"\n", val);
10691     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10692
10693     /* dwContext is out of range */
10694     size = MAX_PATH;
10695     lstrcpyA(val, "apple");
10696     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10697                             MSIINSTALLCONTEXT_NONE,
10698                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10699     ok(r == ERROR_INVALID_PARAMETER,
10700        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10701     ok(!lstrcmpA(val, "apple"),
10702        "Expected val to be unchanged, got \"%s\"\n", val);
10703     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10704
10705     /* dwContext is out of range */
10706     size = MAX_PATH;
10707     lstrcpyA(val, "apple");
10708     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10709                             MSIINSTALLCONTEXT_ALL,
10710                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10711     ok(r == ERROR_INVALID_PARAMETER,
10712        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10713     ok(!lstrcmpA(val, "apple"),
10714        "Expected val to be unchanged, got \"%s\"\n", val);
10715     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10716
10717     /* dwContext is invalid */
10718     size = MAX_PATH;
10719     lstrcpyA(val, "apple");
10720     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10721                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10722     ok(r == ERROR_INVALID_PARAMETER,
10723        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10724     ok(!lstrcmpA(val, "apple"),
10725        "Expected val to be unchanged, got \"%s\"\n", val);
10726     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10727
10728     /* MSIINSTALLCONTEXT_USERMANAGED */
10729
10730     size = MAX_PATH;
10731     lstrcpyA(val, "apple");
10732     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10733                             MSIINSTALLCONTEXT_USERMANAGED,
10734                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10735     ok(r == ERROR_UNKNOWN_PRODUCT,
10736        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10737     ok(!lstrcmpA(val, "apple"),
10738        "Expected val to be unchanged, got \"%s\"\n", val);
10739     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10740
10741     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10742     lstrcatA(keypath, usersid);
10743     lstrcatA(keypath, "\\Products\\");
10744     lstrcatA(keypath, prod_squashed);
10745
10746     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10747     if (res == ERROR_ACCESS_DENIED)
10748     {
10749         skip("Not enough rights to perform tests\n");
10750         LocalFree(usersid);
10751         return;
10752     }
10753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10754
10755     /* local UserData product key exists */
10756     size = MAX_PATH;
10757     lstrcpyA(val, "apple");
10758     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10759                             MSIINSTALLCONTEXT_USERMANAGED,
10760                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10761     ok(r == ERROR_UNKNOWN_PRODUCT,
10762        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10763     ok(!lstrcmpA(val, "apple"),
10764        "Expected val to be unchanged, got \"%s\"\n", val);
10765     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10766
10767     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10769
10770     /* InstallProperties key exists */
10771     size = MAX_PATH;
10772     lstrcpyA(val, "apple");
10773     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10774                             MSIINSTALLCONTEXT_USERMANAGED,
10775                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10776     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10777     ok(!lstrcmpA(val, "apple"),
10778        "Expected val to be unchanged, got \"%s\"\n", val);
10779     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10780
10781     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10783
10784     /* Patches key exists */
10785     size = MAX_PATH;
10786     lstrcpyA(val, "apple");
10787     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10788                             MSIINSTALLCONTEXT_USERMANAGED,
10789                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10790     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10791     ok(!lstrcmpA(val, "apple"),
10792        "Expected val to be unchanged, got \"%s\"\n", val);
10793     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10794
10795     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10797
10798     /* Patches key exists */
10799     size = MAX_PATH;
10800     lstrcpyA(val, "apple");
10801     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10802                             MSIINSTALLCONTEXT_USERMANAGED,
10803                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10804     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10805     ok(!lstrcmpA(val, "apple"),
10806        "Expected val to be unchanged, got \"%s\"\n", val);
10807     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10808
10809     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10810     lstrcatA(keypath, usersid);
10811     lstrcatA(keypath, "\\Installer\\Products\\");
10812     lstrcatA(keypath, prod_squashed);
10813
10814     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10815     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10816
10817     /* managed product key exists */
10818     size = MAX_PATH;
10819     lstrcpyA(val, "apple");
10820     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10821                             MSIINSTALLCONTEXT_USERMANAGED,
10822                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10823     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10824     ok(!lstrcmpA(val, "apple"),
10825        "Expected val to be unchanged, got \"%s\"\n", val);
10826     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10827
10828     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10830
10831     /* Patches key exists */
10832     size = MAX_PATH;
10833     lstrcpyA(val, "apple");
10834     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10835                             MSIINSTALLCONTEXT_USERMANAGED,
10836                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10837     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10838     ok(!lstrcmpA(val, "apple"),
10839        "Expected val to be unchanged, got \"%s\"\n", val);
10840     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10841
10842     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10843                          (const BYTE *)"transforms", 11);
10844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10845
10846     /* specific patch value exists */
10847     size = MAX_PATH;
10848     lstrcpyA(val, "apple");
10849     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10850                             MSIINSTALLCONTEXT_USERMANAGED,
10851                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10852     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10853     ok(!lstrcmpA(val, "apple"),
10854        "Expected val to be unchanged, got \"%s\"\n", val);
10855     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10856
10857     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10858     lstrcatA(keypath, usersid);
10859     lstrcatA(keypath, "\\Patches\\");
10860     lstrcatA(keypath, patch_squashed);
10861
10862     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10864
10865     /* UserData Patches key exists */
10866     size = MAX_PATH;
10867     lstrcpyA(val, "apple");
10868     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10869                             MSIINSTALLCONTEXT_USERMANAGED,
10870                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10871     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10872     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10873     ok(size == 0, "Expected 0, got %d\n", size);
10874
10875     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10876                          (const BYTE *)"pack", 5);
10877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10878
10879     /* ManagedLocalPatch value exists */
10880     size = MAX_PATH;
10881     lstrcpyA(val, "apple");
10882     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10883                             MSIINSTALLCONTEXT_USERMANAGED,
10884                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10886     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10887     ok(size == 4, "Expected 4, got %d\n", size);
10888
10889     size = MAX_PATH;
10890     lstrcpyA(val, "apple");
10891     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10892                             MSIINSTALLCONTEXT_USERMANAGED,
10893                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10895     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10896     ok(size == 10, "Expected 10, got %d\n", size);
10897
10898     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10899                          (const BYTE *)"mydate", 7);
10900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10901
10902     /* Installed value exists */
10903     size = MAX_PATH;
10904     lstrcpyA(val, "apple");
10905     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10906                             MSIINSTALLCONTEXT_USERMANAGED,
10907                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10908     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10909     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10910     ok(size == 6, "Expected 6, got %d\n", size);
10911
10912     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10913                          (const BYTE *)"yes", 4);
10914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10915
10916     /* Uninstallable value exists */
10917     size = MAX_PATH;
10918     lstrcpyA(val, "apple");
10919     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10920                             MSIINSTALLCONTEXT_USERMANAGED,
10921                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10922     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10923     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10924     ok(size == 3, "Expected 3, got %d\n", size);
10925
10926     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10927                          (const BYTE *)"good", 5);
10928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10929
10930     /* State value exists */
10931     size = MAX_PATH;
10932     lstrcpyA(val, "apple");
10933     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10934                             MSIINSTALLCONTEXT_USERMANAGED,
10935                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10937     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10938     ok(size == 4, "Expected 4, got %d\n", size);
10939
10940     size = 1;
10941     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10942                          (const BYTE *)&size, sizeof(DWORD));
10943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10944
10945     /* State value exists */
10946     size = MAX_PATH;
10947     lstrcpyA(val, "apple");
10948     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10949                             MSIINSTALLCONTEXT_USERMANAGED,
10950                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10952     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10953     ok(size == 1, "Expected 1, got %d\n", size);
10954
10955     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10956                          (const BYTE *)"display", 8);
10957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10958
10959     /* DisplayName value exists */
10960     size = MAX_PATH;
10961     lstrcpyA(val, "apple");
10962     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10963                             MSIINSTALLCONTEXT_USERMANAGED,
10964                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10965     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10966     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10967     ok(size == 7, "Expected 7, got %d\n", size);
10968
10969     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10970                          (const BYTE *)"moreinfo", 9);
10971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10972
10973     /* MoreInfoURL value exists */
10974     size = MAX_PATH;
10975     lstrcpyA(val, "apple");
10976     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10977                             MSIINSTALLCONTEXT_USERMANAGED,
10978                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10980     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10981     ok(size == 8, "Expected 8, got %d\n", size);
10982
10983     /* szProperty is invalid */
10984     size = MAX_PATH;
10985     lstrcpyA(val, "apple");
10986     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10987                             MSIINSTALLCONTEXT_USERMANAGED,
10988                             "IDontExist", val, &size);
10989     ok(r == ERROR_UNKNOWN_PROPERTY,
10990        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10991     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10992     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10993
10994     /* lpValue is NULL, while pcchValue is non-NULL */
10995     size = MAX_PATH;
10996     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10997                             MSIINSTALLCONTEXT_USERMANAGED,
10998                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10999     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11000     ok(size == 16, "Expected 16, got %d\n", size);
11001
11002     /* pcchValue is NULL, while lpValue is non-NULL */
11003     lstrcpyA(val, "apple");
11004     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11005                             MSIINSTALLCONTEXT_USERMANAGED,
11006                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
11007     ok(r == ERROR_INVALID_PARAMETER,
11008        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11009     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11010
11011     /* both lpValue and pcchValue are NULL */
11012     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11013                             MSIINSTALLCONTEXT_USERMANAGED,
11014                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
11015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11016
11017     /* pcchValue doesn't have enough room for NULL terminator */
11018     size = 8;
11019     lstrcpyA(val, "apple");
11020     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11021                             MSIINSTALLCONTEXT_USERMANAGED,
11022                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11023     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11024     ok(!lstrcmpA(val, "moreinf"),
11025        "Expected \"moreinf\", got \"%s\"\n", val);
11026     ok(size == 16, "Expected 16, got %d\n", size);
11027
11028     /* pcchValue has exactly enough room for NULL terminator */
11029     size = 9;
11030     lstrcpyA(val, "apple");
11031     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11032                             MSIINSTALLCONTEXT_USERMANAGED,
11033                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11035     ok(!lstrcmpA(val, "moreinfo"),
11036        "Expected \"moreinfo\", got \"%s\"\n", val);
11037     ok(size == 8, "Expected 8, got %d\n", size);
11038
11039     /* pcchValue is too small, lpValue is NULL */
11040     size = 0;
11041     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11042                             MSIINSTALLCONTEXT_USERMANAGED,
11043                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
11044     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11045     ok(size == 16, "Expected 16, got %d\n", size);
11046
11047     RegDeleteValueA(prodpatches, patch_squashed);
11048     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11049     RegCloseKey(prodpatches);
11050     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11051     RegCloseKey(prodkey);
11052
11053     /* UserData is sufficient for all properties
11054      * except INSTALLPROPERTY_TRANSFORMS
11055      */
11056     size = MAX_PATH;
11057     lstrcpyA(val, "apple");
11058     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11059                             MSIINSTALLCONTEXT_USERMANAGED,
11060                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11062     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11063     ok(size == 4, "Expected 4, got %d\n", size);
11064
11065     /* UserData is sufficient for all properties
11066      * except INSTALLPROPERTY_TRANSFORMS
11067      */
11068     size = MAX_PATH;
11069     lstrcpyA(val, "apple");
11070     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11071                             MSIINSTALLCONTEXT_USERMANAGED,
11072                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11073     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11074     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11075     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11076
11077     RegDeleteValueA(hpatch, "MoreInfoURL");
11078     RegDeleteValueA(hpatch, "Display");
11079     RegDeleteValueA(hpatch, "State");
11080     RegDeleteValueA(hpatch, "Uninstallable");
11081     RegDeleteValueA(hpatch, "Installed");
11082     RegDeleteValueA(udpatch, "ManagedLocalPackage");
11083     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11084     RegCloseKey(udpatch);
11085     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11086     RegCloseKey(hpatch);
11087     delete_key(patches, "", access & KEY_WOW64_64KEY);
11088     RegCloseKey(patches);
11089     delete_key(props, "", access & KEY_WOW64_64KEY);
11090     RegCloseKey(props);
11091     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11092     RegCloseKey(udprod);
11093
11094     /* MSIINSTALLCONTEXT_USERUNMANAGED */
11095
11096     size = MAX_PATH;
11097     lstrcpyA(val, "apple");
11098     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11099                             MSIINSTALLCONTEXT_USERUNMANAGED,
11100                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11101     ok(r == ERROR_UNKNOWN_PRODUCT,
11102        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11103     ok(!lstrcmpA(val, "apple"),
11104        "Expected val to be unchanged, got \"%s\"\n", val);
11105     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11106
11107     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11108     lstrcatA(keypath, usersid);
11109     lstrcatA(keypath, "\\Products\\");
11110     lstrcatA(keypath, prod_squashed);
11111
11112     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11114
11115     /* local UserData product key exists */
11116     size = MAX_PATH;
11117     lstrcpyA(val, "apple");
11118     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11119                             MSIINSTALLCONTEXT_USERUNMANAGED,
11120                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11121     ok(r == ERROR_UNKNOWN_PRODUCT,
11122        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11123     ok(!lstrcmpA(val, "apple"),
11124        "Expected val to be unchanged, got \"%s\"\n", val);
11125     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11126
11127     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11129
11130     /* InstallProperties key exists */
11131     size = MAX_PATH;
11132     lstrcpyA(val, "apple");
11133     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11134                             MSIINSTALLCONTEXT_USERUNMANAGED,
11135                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11136     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11137     ok(!lstrcmpA(val, "apple"),
11138        "Expected val to be unchanged, got \"%s\"\n", val);
11139     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11140
11141     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11143
11144     /* Patches key exists */
11145     size = MAX_PATH;
11146     lstrcpyA(val, "apple");
11147     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11148                             MSIINSTALLCONTEXT_USERUNMANAGED,
11149                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11150     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11151     ok(!lstrcmpA(val, "apple"),
11152        "Expected val to be unchanged, got \"%s\"\n", val);
11153     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11154
11155     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11157
11158     /* Patches key exists */
11159     size = MAX_PATH;
11160     lstrcpyA(val, "apple");
11161     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11162                             MSIINSTALLCONTEXT_USERUNMANAGED,
11163                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11164     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11165     ok(!lstrcmpA(val, "apple"),
11166        "Expected val to be unchanged, got \"%s\"\n", val);
11167     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11168
11169     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11170     lstrcatA(keypath, prod_squashed);
11171
11172     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11174
11175     /* current user product key exists */
11176     size = MAX_PATH;
11177     lstrcpyA(val, "apple");
11178     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11179                             MSIINSTALLCONTEXT_USERUNMANAGED,
11180                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11181     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11182     ok(!lstrcmpA(val, "apple"),
11183        "Expected val to be unchanged, got \"%s\"\n", val);
11184     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11185
11186     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
11187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11188
11189     /* Patches key exists */
11190     size = MAX_PATH;
11191     lstrcpyA(val, "apple");
11192     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11193                             MSIINSTALLCONTEXT_USERUNMANAGED,
11194                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11195     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11196     ok(!lstrcmpA(val, "apple"),
11197        "Expected val to be unchanged, got \"%s\"\n", val);
11198     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11199
11200     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11201                          (const BYTE *)"transforms", 11);
11202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11203
11204     /* specific patch value exists */
11205     size = MAX_PATH;
11206     lstrcpyA(val, "apple");
11207     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11208                             MSIINSTALLCONTEXT_USERUNMANAGED,
11209                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11210     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11211     ok(!lstrcmpA(val, "apple"),
11212        "Expected val to be unchanged, got \"%s\"\n", val);
11213     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11214
11215     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11216     lstrcatA(keypath, usersid);
11217     lstrcatA(keypath, "\\Patches\\");
11218     lstrcatA(keypath, patch_squashed);
11219
11220     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11222
11223     /* UserData Patches key exists */
11224     size = MAX_PATH;
11225     lstrcpyA(val, "apple");
11226     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11227                             MSIINSTALLCONTEXT_USERUNMANAGED,
11228                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11230     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11231     ok(size == 0, "Expected 0, got %d\n", size);
11232
11233     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11234                          (const BYTE *)"pack", 5);
11235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11236
11237     /* LocalPatch value exists */
11238     size = MAX_PATH;
11239     lstrcpyA(val, "apple");
11240     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11241                             MSIINSTALLCONTEXT_USERUNMANAGED,
11242                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11244     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11245     ok(size == 4, "Expected 4, got %d\n", size);
11246
11247     size = MAX_PATH;
11248     lstrcpyA(val, "apple");
11249     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11250                             MSIINSTALLCONTEXT_USERUNMANAGED,
11251                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11253     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11254     ok(size == 10, "Expected 10, got %d\n", size);
11255
11256     RegDeleteValueA(prodpatches, patch_squashed);
11257     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11258     RegCloseKey(prodpatches);
11259     RegDeleteKeyA(prodkey, "");
11260     RegCloseKey(prodkey);
11261
11262     /* UserData is sufficient for all properties
11263      * except INSTALLPROPERTY_TRANSFORMS
11264      */
11265     size = MAX_PATH;
11266     lstrcpyA(val, "apple");
11267     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11268                             MSIINSTALLCONTEXT_USERUNMANAGED,
11269                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11271     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11272     ok(size == 4, "Expected 4, got %d\n", size);
11273
11274     /* UserData is sufficient for all properties
11275      * except INSTALLPROPERTY_TRANSFORMS
11276      */
11277     size = MAX_PATH;
11278     lstrcpyA(val, "apple");
11279     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11280                             MSIINSTALLCONTEXT_USERUNMANAGED,
11281                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11282     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11283     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11284     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11285
11286     RegDeleteValueA(udpatch, "LocalPackage");
11287     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11288     RegCloseKey(udpatch);
11289     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11290     RegCloseKey(hpatch);
11291     delete_key(patches, "", access & KEY_WOW64_64KEY);
11292     RegCloseKey(patches);
11293     delete_key(props, "", access & KEY_WOW64_64KEY);
11294     RegCloseKey(props);
11295     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11296     RegCloseKey(udprod);
11297
11298     /* MSIINSTALLCONTEXT_MACHINE */
11299
11300     size = MAX_PATH;
11301     lstrcpyA(val, "apple");
11302     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11303                             MSIINSTALLCONTEXT_MACHINE,
11304                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11305     ok(r == ERROR_UNKNOWN_PRODUCT,
11306        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11307     ok(!lstrcmpA(val, "apple"),
11308        "Expected val to be unchanged, got \"%s\"\n", val);
11309     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11310
11311     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11312     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11313     lstrcatA(keypath, prod_squashed);
11314
11315     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11317
11318     /* local UserData product key exists */
11319     size = MAX_PATH;
11320     lstrcpyA(val, "apple");
11321     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11322                             MSIINSTALLCONTEXT_MACHINE,
11323                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11324     ok(r == ERROR_UNKNOWN_PRODUCT,
11325        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11326     ok(!lstrcmpA(val, "apple"),
11327        "Expected val to be unchanged, got \"%s\"\n", val);
11328     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11329
11330     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11332
11333     /* InstallProperties key exists */
11334     size = MAX_PATH;
11335     lstrcpyA(val, "apple");
11336     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11337                             MSIINSTALLCONTEXT_MACHINE,
11338                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11339     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11340     ok(!lstrcmpA(val, "apple"),
11341        "Expected val to be unchanged, got \"%s\"\n", val);
11342     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11343
11344     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11346
11347     /* Patches key exists */
11348     size = MAX_PATH;
11349     lstrcpyA(val, "apple");
11350     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11351                             MSIINSTALLCONTEXT_MACHINE,
11352                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11353     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11354     ok(!lstrcmpA(val, "apple"),
11355        "Expected val to be unchanged, got \"%s\"\n", val);
11356     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11357
11358     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11359     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11360
11361     /* Patches key exists */
11362     size = MAX_PATH;
11363     lstrcpyA(val, "apple");
11364     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11365                             MSIINSTALLCONTEXT_MACHINE,
11366                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11367     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11368     ok(!lstrcmpA(val, "apple"),
11369        "Expected val to be unchanged, got \"%s\"\n", val);
11370     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11371
11372     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11373     lstrcatA(keypath, prod_squashed);
11374
11375     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11377
11378     /* local product key exists */
11379     size = MAX_PATH;
11380     lstrcpyA(val, "apple");
11381     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11382                             MSIINSTALLCONTEXT_MACHINE,
11383                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11384     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11385     ok(!lstrcmpA(val, "apple"),
11386        "Expected val to be unchanged, got \"%s\"\n", val);
11387     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11388
11389     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11390     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11391
11392     /* Patches key exists */
11393     size = MAX_PATH;
11394     lstrcpyA(val, "apple");
11395     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11396                             MSIINSTALLCONTEXT_MACHINE,
11397                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11398     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11399     ok(!lstrcmpA(val, "apple"),
11400        "Expected val to be unchanged, got \"%s\"\n", val);
11401     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11402
11403     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11404                          (const BYTE *)"transforms", 11);
11405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11406
11407     /* specific patch value exists */
11408     size = MAX_PATH;
11409     lstrcpyA(val, "apple");
11410     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11411                             MSIINSTALLCONTEXT_MACHINE,
11412                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11413     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11414     ok(!lstrcmpA(val, "apple"),
11415        "Expected val to be unchanged, got \"%s\"\n", val);
11416     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11417
11418     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11419     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11420     lstrcatA(keypath, patch_squashed);
11421
11422     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11424
11425     /* UserData Patches key exists */
11426     size = MAX_PATH;
11427     lstrcpyA(val, "apple");
11428     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11429                             MSIINSTALLCONTEXT_MACHINE,
11430                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11431     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11432     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11433     ok(size == 0, "Expected 0, got %d\n", size);
11434
11435     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11436                          (const BYTE *)"pack", 5);
11437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11438
11439     /* LocalPatch value exists */
11440     size = MAX_PATH;
11441     lstrcpyA(val, "apple");
11442     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11443                             MSIINSTALLCONTEXT_MACHINE,
11444                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11446     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11447     ok(size == 4, "Expected 4, got %d\n", size);
11448
11449     size = MAX_PATH;
11450     lstrcpyA(val, "apple");
11451     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11452                             MSIINSTALLCONTEXT_MACHINE,
11453                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11455     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11456     ok(size == 10, "Expected 10, got %d\n", size);
11457
11458     RegDeleteValueA(prodpatches, patch_squashed);
11459     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11460     RegCloseKey(prodpatches);
11461     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11462     RegCloseKey(prodkey);
11463
11464     /* UserData is sufficient for all properties
11465      * except INSTALLPROPERTY_TRANSFORMS
11466      */
11467     size = MAX_PATH;
11468     lstrcpyA(val, "apple");
11469     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11470                             MSIINSTALLCONTEXT_MACHINE,
11471                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11473     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11474     ok(size == 4, "Expected 4, got %d\n", size);
11475
11476     /* UserData is sufficient for all properties
11477      * except INSTALLPROPERTY_TRANSFORMS
11478      */
11479     size = MAX_PATH;
11480     lstrcpyA(val, "apple");
11481     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11482                             MSIINSTALLCONTEXT_MACHINE,
11483                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11484     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11485     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11486     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11487
11488     RegDeleteValueA(udpatch, "LocalPackage");
11489     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11490     RegCloseKey(udpatch);
11491     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11492     RegCloseKey(hpatch);
11493     delete_key(patches, "", access & KEY_WOW64_64KEY);
11494     RegCloseKey(patches);
11495     delete_key(props, "", access & KEY_WOW64_64KEY);
11496     RegCloseKey(props);
11497     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11498     RegCloseKey(udprod);
11499     LocalFree(usersid);
11500 }
11501
11502 static void test_MsiGetPatchInfo(void)
11503 {
11504     UINT r;
11505     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11506     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11507     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11508     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11509     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11510     DWORD size;
11511     LONG res;
11512     REGSAM access = KEY_ALL_ACCESS;
11513
11514     create_test_guid(patch_code, patch_squashed);
11515     create_test_guid(prod_code, prod_squashed);
11516     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11517
11518     if (is_wow64)
11519         access |= KEY_WOW64_64KEY;
11520
11521     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11522     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11523
11524     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11525     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11526
11527     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11528     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11529
11530     size = 0;
11531     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11532     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11533
11534     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11535     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11536
11537     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11538     lstrcatA(keypath, prod_squashed);
11539
11540     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11541     if (res == ERROR_ACCESS_DENIED)
11542     {
11543         skip("Not enough rights to perform tests\n");
11544         return;
11545     }
11546     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11547
11548     /* product key exists */
11549     size = MAX_PATH;
11550     lstrcpyA(val, "apple");
11551     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11552     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11553     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11554     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11555
11556     res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11557     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11558
11559     /* patches key exists */
11560     size = MAX_PATH;
11561     lstrcpyA(val, "apple");
11562     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11563     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11564     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11565     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11566
11567     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11568     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11569
11570     /* patch key exists */
11571     size = MAX_PATH;
11572     lstrcpyA(val, "apple");
11573     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11574     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11575     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11576     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11577
11578     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11579     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11580     lstrcatA(keypath, prod_squashed);
11581
11582     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11583     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11584
11585     /* UserData product key exists */
11586     size = MAX_PATH;
11587     lstrcpyA(val, "apple");
11588     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11589     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11590     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11591     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11592
11593     res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11594     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11595
11596     /* InstallProperties key exists */
11597     size = MAX_PATH;
11598     lstrcpyA(val, "apple");
11599     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11600     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11601     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11602     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11603
11604     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11605     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11606
11607     /* UserData Patches key exists */
11608     size = MAX_PATH;
11609     lstrcpyA(val, "apple");
11610     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11611     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11612     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11613     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11614
11615     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11616     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11617
11618     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11620
11621     /* UserData product patch key exists */
11622     size = MAX_PATH;
11623     lstrcpyA(val, "apple");
11624     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11625     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11626     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11627     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11628
11629     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11630     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11631     lstrcatA(keypath, patch_squashed);
11632
11633     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11634     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11635
11636     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11637     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11638
11639     /* UserData Patch key exists */
11640     size = 0;
11641     lstrcpyA(val, "apple");
11642     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11643     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11644     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11645     ok(size == 11, "expected 11 got %u\n", size);
11646
11647     size = MAX_PATH;
11648     lstrcpyA(val, "apple");
11649     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11650     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11651     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11652     ok(size == 11, "expected 11 got %u\n", size);
11653
11654     size = 0;
11655     valW[0] = 0;
11656     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11657     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11658     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11659     ok(size == 11, "expected 11 got %u\n", size);
11660
11661     size = MAX_PATH;
11662     valW[0] = 0;
11663     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11664     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11665     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11666     ok(size == 11, "expected 11 got %u\n", size);
11667
11668     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11669     RegCloseKey(hkey_udproductpatch);
11670     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11671     RegCloseKey(hkey_udproductpatches);
11672     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11673     RegCloseKey(hkey_udpatch);
11674     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11675     RegCloseKey(hkey_patches);
11676     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11677     RegCloseKey(hkey_product);
11678     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11679     RegCloseKey(hkey_patch);
11680     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11681     RegCloseKey(hkey_udpatches);
11682     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11683     RegCloseKey(hkey_udprops);
11684     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11685     RegCloseKey(hkey_udproduct);
11686 }
11687
11688 static void test_MsiEnumProducts(void)
11689 {
11690     UINT r;
11691     int found1, found2, found3;
11692     DWORD index;
11693     char product1[39], product2[39], product3[39], guid[39];
11694     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11695     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11696     char *usersid;
11697     HKEY key1, key2, key3;
11698     REGSAM access = KEY_ALL_ACCESS;
11699
11700     create_test_guid(product1, product_squashed1);
11701     create_test_guid(product2, product_squashed2);
11702     create_test_guid(product3, product_squashed3);
11703     usersid = get_user_sid();
11704
11705     if (is_wow64)
11706         access |= KEY_WOW64_64KEY;
11707
11708     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11709     strcat(keypath1, product_squashed1);
11710
11711     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11712     if (r == ERROR_ACCESS_DENIED)
11713     {
11714         skip("Not enough rights to perform tests\n");
11715         LocalFree(usersid);
11716         return;
11717     }
11718     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11719
11720     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11721     strcat(keypath2, usersid);
11722     strcat(keypath2, "\\Installer\\Products\\");
11723     strcat(keypath2, product_squashed2);
11724
11725     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11726     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11727
11728     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11729     strcat(keypath3, product_squashed3);
11730
11731     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11733
11734     index = 0;
11735     r = MsiEnumProductsA(index, guid);
11736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11737
11738     r = MsiEnumProductsA(index, NULL);
11739     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11740
11741     index = 2;
11742     r = MsiEnumProductsA(index, guid);
11743     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11744
11745     index = 0;
11746     r = MsiEnumProductsA(index, guid);
11747     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11748
11749     found1 = found2 = found3 = 0;
11750     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11751     {
11752         if (!strcmp(product1, guid)) found1 = 1;
11753         if (!strcmp(product2, guid)) found2 = 1;
11754         if (!strcmp(product3, guid)) found3 = 1;
11755         index++;
11756     }
11757     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11758     ok(found1, "product1 not found\n");
11759     ok(found2, "product2 not found\n");
11760     ok(found3, "product3 not found\n");
11761
11762     delete_key(key1, "", access & KEY_WOW64_64KEY);
11763     delete_key(key2, "", access & KEY_WOW64_64KEY);
11764     RegDeleteKeyA(key3, "");
11765     RegCloseKey(key1);
11766     RegCloseKey(key2);
11767     RegCloseKey(key3);
11768     LocalFree(usersid);
11769 }
11770
11771 static void test_MsiGetFileSignatureInformation(void)
11772 {
11773     HRESULT hr;
11774     const CERT_CONTEXT *cert;
11775     DWORD len;
11776
11777     hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
11778     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11779
11780     hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
11781     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11782
11783     hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
11784     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11785
11786     hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
11787     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11788
11789     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
11790     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11791
11792     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
11793     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11794
11795     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
11796     todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
11797
11798     create_file( "signature.bin", "signature", sizeof("signature") );
11799
11800     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
11801     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11802
11803     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
11804     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11805
11806     cert = (const CERT_CONTEXT *)0xdeadbeef;
11807     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
11808     todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
11809     ok(cert == NULL, "got %p\n", cert);
11810
11811     DeleteFileA( "signature.bin" );
11812 }
11813
11814 static void test_MsiEnumProductsEx(void)
11815 {
11816     UINT r;
11817     DWORD len, index;
11818     MSIINSTALLCONTEXT context;
11819     char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
11820     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11821     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11822     HKEY key1 = NULL, key2 = NULL, key3 = NULL;
11823     REGSAM access = KEY_ALL_ACCESS;
11824     char *usersid = get_user_sid();
11825
11826     if (!pMsiEnumProductsExA)
11827     {
11828         win_skip("MsiEnumProductsExA not implemented\n");
11829         return;
11830     }
11831
11832     create_test_guid( product0, NULL );
11833     create_test_guid( product1, product_squashed1 );
11834     create_test_guid( product2, product_squashed2 );
11835     create_test_guid( product3, product_squashed3 );
11836
11837     if (is_wow64) access |= KEY_WOW64_64KEY;
11838
11839     strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
11840     strcat( keypath1, product_squashed1 );
11841
11842     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
11843     if (r == ERROR_ACCESS_DENIED)
11844     {
11845         skip( "insufficient rights\n" );
11846         goto done;
11847     }
11848     ok( r == ERROR_SUCCESS, "got %u\n", r );
11849
11850     strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
11851     strcat( keypath2, usersid );
11852     strcat( keypath2, "\\Installer\\Products\\" );
11853     strcat( keypath2, product_squashed2 );
11854
11855     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
11856     ok( r == ERROR_SUCCESS, "got %u\n", r );
11857
11858     strcpy( keypath3, usersid );
11859     strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
11860     strcat( keypath3, product_squashed3 );
11861
11862     r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
11863     ok( r == ERROR_SUCCESS, "got %u\n", r );
11864
11865     r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
11866     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
11867
11868     len = sizeof(sid);
11869     r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
11870     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
11871     ok( len == sizeof(sid), "got %u\n", len );
11872
11873     r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
11874     ok( r == ERROR_SUCCESS, "got %u\n", r );
11875
11876     sid[0] = 0;
11877     len = sizeof(sid);
11878     r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
11879     ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
11880     ok( len == sizeof(sid), "got %u\n", len );
11881     ok( !sid[0], "got %s\n", sid );
11882
11883     sid[0] = 0;
11884     len = sizeof(sid);
11885     r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
11886     ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
11887     ok( len == sizeof(sid), "got %u\n", len );
11888     ok( !sid[0], "got %s\n", sid );
11889
11890     sid[0] = 0;
11891     len = 0;
11892     r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
11893     ok( r == ERROR_MORE_DATA, "got %u\n", r );
11894     ok( len, "length unchanged\n" );
11895     ok( !sid[0], "got %s\n", sid );
11896
11897     guid[0] = 0;
11898     context = 0xdeadbeef;
11899     sid[0] = 0;
11900     len = sizeof(sid);
11901     r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
11902     ok( r == ERROR_SUCCESS, "got %u\n", r );
11903     ok( guid[0], "empty guid\n" );
11904     ok( context != 0xdeadbeef, "context unchanged\n" );
11905     ok( !len, "got %u\n", len );
11906     ok( !sid[0], "got %s\n", sid );
11907
11908     guid[0] = 0;
11909     context = 0xdeadbeef;
11910     sid[0] = 0;
11911     len = sizeof(sid);
11912     r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
11913     ok( r == ERROR_SUCCESS, "got %u\n", r );
11914     ok( guid[0], "empty guid\n" );
11915     ok( context != 0xdeadbeef, "context unchanged\n" );
11916     ok( !len, "got %u\n", len );
11917     ok( !sid[0], "got %s\n", sid );
11918
11919     guid[0] = 0;
11920     context = 0xdeadbeef;
11921     sid[0] = 0;
11922     len = sizeof(sid);
11923     r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
11924     if (r == ERROR_ACCESS_DENIED)
11925     {
11926         skip( "insufficient rights\n" );
11927         goto done;
11928     }
11929     ok( r == ERROR_SUCCESS, "got %u\n", r );
11930     ok( guid[0], "empty guid\n" );
11931     ok( context != 0xdeadbeef, "context unchanged\n" );
11932     ok( !len, "got %u\n", len );
11933     ok( !sid[0], "got %s\n", sid );
11934
11935     index = 0;
11936     guid[0] = 0;
11937     context = 0xdeadbeef;
11938     sid[0] = 0;
11939     len = sizeof(sid);
11940     while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
11941     {
11942         if (!strcmp( product1, guid ))
11943         {
11944             ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
11945             ok( !sid[0], "got \"%s\"\n", sid );
11946             ok( !len, "unexpected length %u\n", len );
11947         }
11948         if (!strcmp( product2, guid ))
11949         {
11950             ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
11951             ok( sid[0], "empty sid\n" );
11952             ok( len == strlen(sid), "unexpected length %u\n", len );
11953         }
11954         if (!strcmp( product3, guid ))
11955         {
11956             ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
11957             ok( sid[0], "empty sid\n" );
11958             ok( len == strlen(sid), "unexpected length %u\n", len );
11959         }
11960         index++;
11961         guid[0] = 0;
11962         context = 0xdeadbeef;
11963         sid[0] = 0;
11964         len = sizeof(sid);
11965     }
11966
11967 done:
11968     delete_key( key1, "", access );
11969     delete_key( key2, "", access );
11970     delete_key( key3, "", access );
11971     RegCloseKey( key1 );
11972     RegCloseKey( key2 );
11973     RegCloseKey( key3 );
11974     LocalFree( usersid );
11975 }
11976
11977 static void test_MsiEnumComponents(void)
11978 {
11979     UINT r;
11980     int found1, found2;
11981     DWORD index;
11982     char comp1[39], comp2[39], guid[39];
11983     char comp_squashed1[33], comp_squashed2[33];
11984     char keypath1[MAX_PATH], keypath2[MAX_PATH];
11985     REGSAM access = KEY_ALL_ACCESS;
11986     char *usersid = get_user_sid();
11987     HKEY key1 = NULL, key2 = NULL;
11988
11989     create_test_guid( comp1, comp_squashed1 );
11990     create_test_guid( comp2, comp_squashed2 );
11991
11992     if (is_wow64) access |= KEY_WOW64_64KEY;
11993
11994     strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
11995     strcat( keypath1, "S-1-5-18\\Components\\" );
11996     strcat( keypath1, comp_squashed1 );
11997
11998     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
11999     if (r == ERROR_ACCESS_DENIED)
12000     {
12001         skip( "insufficient rights\n" );
12002         goto done;
12003     }
12004     ok( r == ERROR_SUCCESS, "got %u\n", r );
12005
12006     strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12007     strcat( keypath2, usersid );
12008     strcat( keypath2, "\\Components\\" );
12009     strcat( keypath2, comp_squashed2 );
12010
12011     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12012     if (r == ERROR_ACCESS_DENIED)
12013     {
12014         skip( "insufficient rights\n" );
12015         goto done;
12016     }
12017
12018     r = MsiEnumComponentsA( 0, NULL );
12019     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12020
12021     index = 0;
12022     guid[0] = 0;
12023     found1 = found2 = 0;
12024     while (!MsiEnumComponentsA( index, guid ))
12025     {
12026         if (!strcmp( guid, comp1 )) found1 = 1;
12027         if (!strcmp( guid, comp2 )) found2 = 1;
12028         ok( guid[0], "empty guid\n" );
12029         guid[0] = 0;
12030         index++;
12031     }
12032     ok( found1, "comp1 not found\n" );
12033     ok( found2, "comp2 not found\n" );
12034
12035 done:
12036     delete_key( key1, "", access );
12037     delete_key( key2, "", access );
12038     RegCloseKey( key1 );
12039     RegCloseKey( key2 );
12040     LocalFree( usersid );
12041 }
12042
12043 static void test_MsiEnumComponentsEx(void)
12044 {
12045     UINT r;
12046     int found1, found2;
12047     DWORD len, index;
12048     MSIINSTALLCONTEXT context;
12049     char comp1[39], comp2[39], guid[39], sid[128];
12050     char comp_squashed1[33], comp_squashed2[33];
12051     char keypath1[MAX_PATH], keypath2[MAX_PATH];
12052     HKEY key1 = NULL, key2 = NULL;
12053     REGSAM access = KEY_ALL_ACCESS;
12054     char *usersid = get_user_sid();
12055
12056     if (!pMsiEnumComponentsExA)
12057     {
12058         win_skip( "MsiEnumComponentsExA not implemented\n" );
12059         return;
12060     }
12061     create_test_guid( comp1, comp_squashed1 );
12062     create_test_guid( comp2, comp_squashed2 );
12063
12064     if (is_wow64) access |= KEY_WOW64_64KEY;
12065
12066     strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12067     strcat( keypath1, "S-1-5-18\\Components\\" );
12068     strcat( keypath1, comp_squashed1 );
12069
12070     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12071     if (r == ERROR_ACCESS_DENIED)
12072     {
12073         skip( "insufficient rights\n" );
12074         goto done;
12075     }
12076     ok( r == ERROR_SUCCESS, "got %u\n", r );
12077
12078     strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12079     strcat( keypath2, usersid );
12080     strcat( keypath2, "\\Components\\" );
12081     strcat( keypath2, comp_squashed2 );
12082
12083     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12084     if (r == ERROR_ACCESS_DENIED)
12085     {
12086         skip( "insufficient rights\n" );
12087         goto done;
12088     }
12089     ok( r == ERROR_SUCCESS, "got %u\n", r );
12090     r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
12091                         sizeof("c:\\doesnotexist"));
12092     ok( r == ERROR_SUCCESS, "got %u\n", r );
12093
12094     index = 0;
12095     guid[0] = 0;
12096     context = 0xdeadbeef;
12097     sid[0] = 0;
12098     len = sizeof(sid);
12099     found1 = found2 = 0;
12100     while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
12101     {
12102         if (!strcmp( comp1, guid ))
12103         {
12104             ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
12105             ok( !sid[0], "got \"%s\"\n", sid );
12106             ok( !len, "unexpected length %u\n", len );
12107             found1 = 1;
12108         }
12109         if (!strcmp( comp2, guid ))
12110         {
12111             ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
12112             ok( sid[0], "empty sid\n" );
12113             ok( len == strlen(sid), "unexpected length %u\n", len );
12114             found2 = 1;
12115         }
12116         index++;
12117         guid[0] = 0;
12118         context = 0xdeadbeef;
12119         sid[0] = 0;
12120         len = sizeof(sid);
12121     }
12122     ok( found1, "comp1 not found\n" );
12123     ok( found2, "comp2 not found\n" );
12124
12125     r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
12126     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12127
12128     r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
12129     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12130
12131 done:
12132     RegDeleteValueA( key2, comp_squashed2 );
12133     delete_key( key1, "", access );
12134     delete_key( key2, "", access );
12135     RegCloseKey( key1 );
12136     RegCloseKey( key2 );
12137     LocalFree( usersid );
12138 }
12139
12140 START_TEST(msi)
12141 {
12142     init_functionpointers();
12143
12144     if (pIsWow64Process)
12145         pIsWow64Process(GetCurrentProcess(), &is_wow64);
12146
12147     test_usefeature();
12148     test_null();
12149     test_getcomponentpath();
12150     test_MsiGetFileHash();
12151
12152     if (!pConvertSidToStringSidA)
12153         win_skip("ConvertSidToStringSidA not implemented\n");
12154     else
12155     {
12156         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
12157         test_MsiQueryProductState();
12158         test_MsiQueryFeatureState();
12159         test_MsiQueryComponentState();
12160         test_MsiGetComponentPath();
12161         test_MsiGetProductCode();
12162         test_MsiEnumClients();
12163         test_MsiGetProductInfo();
12164         test_MsiGetProductInfoEx();
12165         test_MsiGetUserInfo();
12166         test_MsiOpenProduct();
12167         test_MsiEnumPatchesEx();
12168         test_MsiEnumPatches();
12169         test_MsiGetPatchInfoEx();
12170         test_MsiGetPatchInfo();
12171         test_MsiEnumProducts();
12172         test_MsiEnumProductsEx();
12173         test_MsiEnumComponents();
12174         test_MsiEnumComponentsEx();
12175     }
12176     test_MsiGetFileVersion();
12177     test_MsiGetFileSignatureInformation();
12178 }