msi/tests: Allocate the user token dynamically and unify implementations.
[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
59 static void init_functionpointers(void)
60 {
61     HMODULE hmsi = GetModuleHandleA("msi.dll");
62     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
63     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
64
65 #define GET_PROC(dll, func) \
66     p ## func = (void *)GetProcAddress(dll, #func); \
67     if(!p ## func) \
68       trace("GetProcAddress(%s) failed\n", #func);
69
70     GET_PROC(hmsi, MsiGetComponentPathA)
71     GET_PROC(hmsi, MsiGetFileHashA)
72     GET_PROC(hmsi, MsiGetProductInfoExA)
73     GET_PROC(hmsi, MsiOpenPackageExA)
74     GET_PROC(hmsi, MsiOpenPackageExW)
75     GET_PROC(hmsi, MsiEnumPatchesExA)
76     GET_PROC(hmsi, MsiQueryComponentStateA)
77     GET_PROC(hmsi, MsiUseFeatureExA)
78     GET_PROC(hmsi, MsiGetPatchInfoExA)
79
80     GET_PROC(hadvapi32, ConvertSidToStringSidA)
81     GET_PROC(hadvapi32, RegDeleteKeyExA)
82     GET_PROC(hkernel32, IsWow64Process)
83
84 #undef GET_PROC
85 }
86
87 static UINT run_query(MSIHANDLE hdb, const char *query)
88 {
89     MSIHANDLE hview = 0;
90     UINT r;
91
92     r = MsiDatabaseOpenView(hdb, query, &hview);
93     if (r != ERROR_SUCCESS)
94         return r;
95
96     r = MsiViewExecute(hview, 0);
97     if (r == ERROR_SUCCESS)
98         r = MsiViewClose(hview);
99     MsiCloseHandle(hview);
100     return r;
101 }
102
103 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
104 {
105     UINT res;
106     MSIHANDLE suminfo;
107
108     /* build summary info */
109     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
110     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
111
112     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
113                                     "Installation Database");
114     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
115
116     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
117                                     "Installation Database");
118     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
119
120     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
121                                     "Wine Hackers");
122     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
123
124     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
125                                     ";1033");
126     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
127
128     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
129                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
130     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
131
132     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
133     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
134
135     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
136     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
137
138     res = MsiSummaryInfoPersist(suminfo);
139     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
140
141     res = MsiCloseHandle(suminfo);
142     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
143
144     return res;
145 }
146
147 static MSIHANDLE create_package_db(LPSTR prodcode)
148 {
149     MSIHANDLE hdb = 0;
150     CHAR query[MAX_PATH];
151     UINT res;
152
153     DeleteFile(msifile);
154
155     /* create an empty database */
156     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
157     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
158     if (res != ERROR_SUCCESS)
159         return hdb;
160
161     res = MsiDatabaseCommit(hdb);
162     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
163
164     set_summary_info(hdb, prodcode);
165
166     res = run_query(hdb,
167             "CREATE TABLE `Directory` ( "
168             "`Directory` CHAR(255) NOT NULL, "
169             "`Directory_Parent` CHAR(255), "
170             "`DefaultDir` CHAR(255) NOT NULL "
171             "PRIMARY KEY `Directory`)");
172     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
173
174     res = run_query(hdb,
175             "CREATE TABLE `Property` ( "
176             "`Property` CHAR(72) NOT NULL, "
177             "`Value` CHAR(255) "
178             "PRIMARY KEY `Property`)");
179     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
180
181     sprintf(query, "INSERT INTO `Property` "
182             "(`Property`, `Value`) "
183             "VALUES( 'ProductCode', '%s' )", prodcode);
184     res = run_query(hdb, query);
185     ok(res == ERROR_SUCCESS , "Failed\n");
186
187     res = MsiDatabaseCommit(hdb);
188     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
189
190     return hdb;
191 }
192
193 static void test_usefeature(void)
194 {
195     INSTALLSTATE r;
196
197     if (!pMsiUseFeatureExA)
198     {
199         win_skip("MsiUseFeatureExA not implemented\n");
200         return;
201     }
202
203     r = MsiQueryFeatureState(NULL,NULL);
204     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
205
206     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
207     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
208
209     r = pMsiUseFeatureExA(NULL,NULL,0,0);
210     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
211
212     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
213     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
214
215     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
216                          NULL, -2, 0 );
217     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
218
219     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
220                          "WORDVIEWFiles", -2, 0 );
221     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
222
223     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
224                          "WORDVIEWFiles", -2, 0 );
225     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
226
227     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
228                          "WORDVIEWFiles", -2, 1 );
229     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
230 }
231
232 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
233 {
234     if (pRegDeleteKeyExA)
235         return pRegDeleteKeyExA( key, subkey, access, 0 );
236     return RegDeleteKeyA( key, subkey );
237 }
238
239 static void test_null(void)
240 {
241     MSIHANDLE hpkg;
242     UINT r;
243     HKEY hkey;
244     DWORD dwType, cbData;
245     LPBYTE lpData = NULL;
246     INSTALLSTATE state;
247     REGSAM access = KEY_ALL_ACCESS;
248
249     if (is_wow64)
250         access |= KEY_WOW64_64KEY;
251
252     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
253     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
254
255     state = MsiQueryProductStateW(NULL);
256     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
257
258     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
259     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
260
261     r = MsiConfigureFeatureW(NULL, NULL, 0);
262     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
263
264     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
265     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
266
267     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
268     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
269
270     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
271     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
272
273     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
274      * necessary registry values */
275
276     /* empty product string */
277     r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
278     if (r == ERROR_ACCESS_DENIED)
279     {
280         skip("Not enough rights to perform tests\n");
281         return;
282     }
283     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
284
285     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
286     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
287     if ( r == ERROR_SUCCESS )
288     {
289         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
290         if (!lpData)
291             skip("Out of memory\n");
292         else
293         {
294             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
295             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
296         }
297     }
298
299     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
300     if (r == ERROR_ACCESS_DENIED)
301     {
302         skip("Not enough rights to perform tests\n");
303         HeapFree(GetProcessHeap(), 0, lpData);
304         RegCloseKey(hkey);
305         return;
306     }
307     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
308
309     r = MsiGetProductInfoA("", "", NULL, NULL);
310     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
311
312     if (lpData)
313     {
314         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
315         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
316
317         HeapFree(GetProcessHeap(), 0, lpData);
318     }
319     else
320     {
321         r = RegDeleteValueA(hkey, NULL);
322         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
323     }
324
325     r = RegCloseKey(hkey);
326     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
327
328     /* empty attribute */
329     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
330                         0, NULL, 0, access, NULL, &hkey, NULL);
331     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
332
333     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
334     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
335
336     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
337     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
338
339     r = RegCloseKey(hkey);
340     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
341
342     r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
343                    access & KEY_WOW64_64KEY);
344     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
345 }
346
347 static void test_getcomponentpath(void)
348 {
349     INSTALLSTATE r;
350     char buffer[0x100];
351     DWORD sz;
352
353     if(!pMsiGetComponentPathA)
354         return;
355
356     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
357     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
358
359     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
360     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
361
362     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
363     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
364
365     sz = sizeof buffer;
366     buffer[0]=0;
367     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
368     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
369
370     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
371         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
372     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
373
374     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
375         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
376     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
377
378     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
379         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
380     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
381
382     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
383                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
384     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
385 }
386
387 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
388 {
389     HANDLE file;
390     DWORD written;
391
392     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
393     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
394     WriteFile(file, data, strlen(data), &written, NULL);
395
396     if (size)
397     {
398         SetFilePointer(file, size, NULL, FILE_BEGIN);
399         SetEndOfFile(file);
400     }
401
402     CloseHandle(file);
403 }
404
405 #define HASHSIZE sizeof(MSIFILEHASHINFO)
406
407 static const struct
408 {
409     LPCSTR data;
410     DWORD size;
411     MSIFILEHASHINFO hash;
412 } hash_data[] =
413 {
414     { "abc", 0,
415       { HASHSIZE,
416         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
417       },
418     },
419
420     { "C:\\Program Files\\msitest\\caesar\n", 0,
421       { HASHSIZE,
422         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
423       },
424     },
425
426     { "C:\\Program Files\\msitest\\caesar\n", 500,
427       { HASHSIZE,
428         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
429       },
430     },
431 };
432
433 static void test_MsiGetFileHash(void)
434 {
435     const char name[] = "msitest.bin";
436     UINT r;
437     MSIFILEHASHINFO hash;
438     DWORD i;
439
440     if (!pMsiGetFileHashA)
441     {
442         win_skip("MsiGetFileHash not implemented\n");
443         return;
444     }
445
446     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
447
448     /* szFilePath is NULL */
449     r = pMsiGetFileHashA(NULL, 0, &hash);
450     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
451
452     /* szFilePath is empty */
453     r = pMsiGetFileHashA("", 0, &hash);
454     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
455        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
456
457     /* szFilePath is nonexistent */
458     r = pMsiGetFileHashA(name, 0, &hash);
459     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
460
461     /* dwOptions is non-zero */
462     r = pMsiGetFileHashA(name, 1, &hash);
463     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
464
465     /* pHash.dwFileHashInfoSize is not correct */
466     hash.dwFileHashInfoSize = 0;
467     r = pMsiGetFileHashA(name, 0, &hash);
468     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
469
470     /* pHash is NULL */
471     r = pMsiGetFileHashA(name, 0, NULL);
472     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
473
474     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
475     {
476         int ret;
477
478         create_file(name, hash_data[i].data, hash_data[i].size);
479
480         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
481         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
482
483         r = pMsiGetFileHashA(name, 0, &hash);
484         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
485
486         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
487         ok(!ret, "Hash incorrect\n");
488
489         DeleteFile(name);
490     }
491 }
492
493 /* copied from dlls/msi/registry.c */
494 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
495 {
496     DWORD i,n=1;
497     GUID guid;
498
499     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
500         return FALSE;
501
502     for(i=0; i<8; i++)
503         out[7-i] = in[n++];
504     n++;
505     for(i=0; i<4; i++)
506         out[11-i] = in[n++];
507     n++;
508     for(i=0; i<4; i++)
509         out[15-i] = in[n++];
510     n++;
511     for(i=0; i<2; i++)
512     {
513         out[17+i*2] = in[n++];
514         out[16+i*2] = in[n++];
515     }
516     n++;
517     for( ; i<8; i++)
518     {
519         out[17+i*2] = in[n++];
520         out[16+i*2] = in[n++];
521     }
522     out[32]=0;
523     return TRUE;
524 }
525
526 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
527 {
528     WCHAR guidW[MAX_PATH];
529     WCHAR squashedW[MAX_PATH];
530     GUID guid;
531     HRESULT hr;
532     int size;
533
534     hr = CoCreateGuid(&guid);
535     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
536
537     size = StringFromGUID2(&guid, guidW, MAX_PATH);
538     ok(size == 39, "Expected 39, got %d\n", hr);
539
540     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
541     squash_guid(guidW, squashedW);
542     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
543 }
544
545 static char *get_user_sid(void)
546 {
547     HANDLE token;
548     DWORD size = 0;
549     TOKEN_USER *user;
550     char *usersid = NULL;
551
552     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
553     GetTokenInformation(token, TokenUser, NULL, size, &size);
554
555     user = HeapAlloc(GetProcessHeap(), 0, size);
556     GetTokenInformation(token, TokenUser, user, size, &size);
557     pConvertSidToStringSidA(user->User.Sid, &usersid);
558     HeapFree(GetProcessHeap(), 0, user);
559
560     CloseHandle(token);
561     return usersid;
562 }
563
564 static void test_MsiQueryProductState(void)
565 {
566     CHAR prodcode[MAX_PATH];
567     CHAR prod_squashed[MAX_PATH];
568     CHAR keypath[MAX_PATH*2];
569     LPSTR usersid;
570     INSTALLSTATE state;
571     LONG res;
572     HKEY userkey, localkey, props;
573     HKEY prodkey;
574     DWORD data, error;
575     REGSAM access = KEY_ALL_ACCESS;
576
577     create_test_guid(prodcode, prod_squashed);
578     usersid = get_user_sid();
579
580     if (is_wow64)
581         access |= KEY_WOW64_64KEY;
582
583     /* NULL prodcode */
584     SetLastError(0xdeadbeef);
585     state = MsiQueryProductStateA(NULL);
586     error = GetLastError();
587     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
588     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
589
590     /* empty prodcode */
591     SetLastError(0xdeadbeef);
592     state = MsiQueryProductStateA("");
593     error = GetLastError();
594     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
595     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
596
597     /* garbage prodcode */
598     SetLastError(0xdeadbeef);
599     state = MsiQueryProductStateA("garbage");
600     error = GetLastError();
601     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
602     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
603
604     /* guid without brackets */
605     SetLastError(0xdeadbeef);
606     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
607     error = GetLastError();
608     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
609     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
610
611     /* guid with brackets */
612     SetLastError(0xdeadbeef);
613     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
614     error = GetLastError();
615     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
616     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
617        "expected ERROR_SUCCESS, got %u\n", error);
618
619     /* same length as guid, but random */
620     SetLastError(0xdeadbeef);
621     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
622     error = GetLastError();
623     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
624     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
625
626     /* MSIINSTALLCONTEXT_USERUNMANAGED */
627
628     SetLastError(0xdeadbeef);
629     state = MsiQueryProductStateA(prodcode);
630     error = GetLastError();
631     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
632     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
633        "expected ERROR_SUCCESS, got %u\n", error);
634
635     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
636     lstrcatA(keypath, prod_squashed);
637
638     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
640
641     /* user product key exists */
642     SetLastError(0xdeadbeef);
643     state = MsiQueryProductStateA(prodcode);
644     error = GetLastError();
645     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
646     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
647        "expected ERROR_SUCCESS, got %u\n", error);
648
649     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
650     lstrcatA(keypath, prodcode);
651
652     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
653     if (res == ERROR_ACCESS_DENIED)
654     {
655         skip("Not enough rights to perform tests\n");
656         RegDeleteKeyA(userkey, "");
657         LocalFree(usersid);
658         return;
659     }
660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
661
662     /* local uninstall key exists */
663     SetLastError(0xdeadbeef);
664     state = MsiQueryProductStateA(prodcode);
665     error = GetLastError();
666     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
667     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
668        "expected ERROR_SUCCESS, got %u\n", error);
669
670     data = 1;
671     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
673
674     /* WindowsInstaller value exists */
675     SetLastError(0xdeadbeef);
676     state = MsiQueryProductStateA(prodcode);
677     error = GetLastError();
678     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
679     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
680        "expected ERROR_SUCCESS, got %u\n", error);
681
682     RegDeleteValueA(localkey, "WindowsInstaller");
683     delete_key(localkey, "", access & KEY_WOW64_64KEY);
684
685     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
686     lstrcatA(keypath, usersid);
687     lstrcatA(keypath, "\\Products\\");
688     lstrcatA(keypath, prod_squashed);
689
690     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
692
693     /* local product key exists */
694     SetLastError(0xdeadbeef);
695     state = MsiQueryProductStateA(prodcode);
696     error = GetLastError();
697     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
698     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
699        "expected ERROR_SUCCESS, got %u\n", error);
700
701     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
703
704     /* install properties key exists */
705     SetLastError(0xdeadbeef);
706     state = MsiQueryProductStateA(prodcode);
707     error = GetLastError();
708     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
709     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
710        "expected ERROR_SUCCESS, got %u\n", error);
711
712     data = 1;
713     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
715
716     /* WindowsInstaller value exists */
717     SetLastError(0xdeadbeef);
718     state = MsiQueryProductStateA(prodcode);
719     error = GetLastError();
720     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
721     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
722        "expected ERROR_SUCCESS, got %u\n", error);
723
724     data = 2;
725     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
727
728     /* WindowsInstaller value is not 1 */
729     SetLastError(0xdeadbeef);
730     state = MsiQueryProductStateA(prodcode);
731     error = GetLastError();
732     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
733     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
734        "expected ERROR_SUCCESS, got %u\n", error);
735
736     RegDeleteKeyA(userkey, "");
737
738     /* user product key does not exist */
739     SetLastError(0xdeadbeef);
740     state = MsiQueryProductStateA(prodcode);
741     error = GetLastError();
742     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
743     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
744        "expected ERROR_SUCCESS, got %u\n", error);
745
746     RegDeleteValueA(props, "WindowsInstaller");
747     delete_key(props, "", access & KEY_WOW64_64KEY);
748     RegCloseKey(props);
749     delete_key(localkey, "", access & KEY_WOW64_64KEY);
750     RegCloseKey(localkey);
751     RegDeleteKeyA(userkey, "");
752     RegCloseKey(userkey);
753
754     /* MSIINSTALLCONTEXT_USERMANAGED */
755
756     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
757     lstrcatA(keypath, usersid);
758     lstrcatA(keypath, "\\Installer\\Products\\");
759     lstrcatA(keypath, prod_squashed);
760
761     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
763
764     state = MsiQueryProductStateA(prodcode);
765     ok(state == INSTALLSTATE_ADVERTISED,
766        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
767
768     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
769     lstrcatA(keypath, usersid);
770     lstrcatA(keypath, "\\Products\\");
771     lstrcatA(keypath, prod_squashed);
772
773     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
774     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
775
776     state = MsiQueryProductStateA(prodcode);
777     ok(state == INSTALLSTATE_ADVERTISED,
778        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
779
780     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
782
783     state = MsiQueryProductStateA(prodcode);
784     ok(state == INSTALLSTATE_ADVERTISED,
785        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
786
787     data = 1;
788     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
789     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
790
791     /* WindowsInstaller value exists */
792     state = MsiQueryProductStateA(prodcode);
793     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
794
795     RegDeleteValueA(props, "WindowsInstaller");
796     delete_key(props, "", access & KEY_WOW64_64KEY);
797     RegCloseKey(props);
798     delete_key(localkey, "", access & KEY_WOW64_64KEY);
799     RegCloseKey(localkey);
800     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
801     RegCloseKey(prodkey);
802
803     /* MSIINSTALLCONTEXT_MACHINE */
804
805     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
806     lstrcatA(keypath, prod_squashed);
807
808     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
809     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
810
811     state = MsiQueryProductStateA(prodcode);
812     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
813
814     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
815     lstrcatA(keypath, "S-1-5-18\\Products\\");
816     lstrcatA(keypath, prod_squashed);
817
818     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
819     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
820
821     state = MsiQueryProductStateA(prodcode);
822     ok(state == INSTALLSTATE_ADVERTISED,
823        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
824
825     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
826     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
827
828     state = MsiQueryProductStateA(prodcode);
829     ok(state == INSTALLSTATE_ADVERTISED,
830        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
831
832     data = 1;
833     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
835
836     /* WindowsInstaller value exists */
837     state = MsiQueryProductStateA(prodcode);
838     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
839
840     RegDeleteValueA(props, "WindowsInstaller");
841     delete_key(props, "", access & KEY_WOW64_64KEY);
842     RegCloseKey(props);
843     delete_key(localkey, "", access & KEY_WOW64_64KEY);
844     RegCloseKey(localkey);
845     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
846     RegCloseKey(prodkey);
847
848     LocalFree(usersid);
849 }
850
851 static const char table_enc85[] =
852 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
853 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
854 "yz{}~";
855
856 /*
857  *  Encodes a base85 guid given a GUID pointer
858  *  Caller should provide a 21 character buffer for the encoded string.
859  */
860 static void encode_base85_guid( GUID *guid, LPWSTR str )
861 {
862     unsigned int x, *p, i;
863
864     p = (unsigned int*) guid;
865     for( i=0; i<4; i++ )
866     {
867         x = p[i];
868         *str++ = table_enc85[x%85];
869         x = x/85;
870         *str++ = table_enc85[x%85];
871         x = x/85;
872         *str++ = table_enc85[x%85];
873         x = x/85;
874         *str++ = table_enc85[x%85];
875         x = x/85;
876         *str++ = table_enc85[x%85];
877     }
878     *str = 0;
879 }
880
881 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
882 {
883     WCHAR guidW[MAX_PATH];
884     WCHAR base85W[MAX_PATH];
885     WCHAR squashedW[MAX_PATH];
886     GUID guid;
887     HRESULT hr;
888     int size;
889
890     hr = CoCreateGuid(&guid);
891     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
892
893     size = StringFromGUID2(&guid, guidW, MAX_PATH);
894     ok(size == 39, "Expected 39, got %d\n", hr);
895
896     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
897     encode_base85_guid(&guid, base85W);
898     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
899     squash_guid(guidW, squashedW);
900     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
901 }
902
903 static void test_MsiQueryFeatureState(void)
904 {
905     HKEY userkey, localkey, compkey, compkey2;
906     CHAR prodcode[MAX_PATH];
907     CHAR prod_squashed[MAX_PATH];
908     CHAR component[MAX_PATH];
909     CHAR comp_base85[MAX_PATH];
910     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
911     CHAR keypath[MAX_PATH*2];
912     INSTALLSTATE state;
913     LPSTR usersid;
914     LONG res;
915     REGSAM access = KEY_ALL_ACCESS;
916     DWORD error;
917
918     create_test_guid(prodcode, prod_squashed);
919     compose_base85_guid(component, comp_base85, comp_squashed);
920     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
921     usersid = get_user_sid();
922
923     if (is_wow64)
924         access |= KEY_WOW64_64KEY;
925
926     /* NULL prodcode */
927     SetLastError(0xdeadbeef);
928     state = MsiQueryFeatureStateA(NULL, "feature");
929     error = GetLastError();
930     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
931     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
932
933     /* empty prodcode */
934     SetLastError(0xdeadbeef);
935     state = MsiQueryFeatureStateA("", "feature");
936     error = GetLastError();
937     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
938     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
939
940     /* garbage prodcode */
941     SetLastError(0xdeadbeef);
942     state = MsiQueryFeatureStateA("garbage", "feature");
943     error = GetLastError();
944     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
945     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
946
947     /* guid without brackets */
948     SetLastError(0xdeadbeef);
949     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
950     error = GetLastError();
951     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
952     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
953
954     /* guid with brackets */
955     SetLastError(0xdeadbeef);
956     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
957     error = GetLastError();
958     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
959     ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
960        "expected ERROR_SUCCESS, got %u\n", error);
961
962     /* same length as guid, but random */
963     SetLastError(0xdeadbeef);
964     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "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     /* NULL szFeature */
970     SetLastError(0xdeadbeef);
971     state = MsiQueryFeatureStateA(prodcode, NULL);
972     error = GetLastError();
973     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
974     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
975
976     /* empty szFeature */
977     SetLastError(0xdeadbeef);
978     state = MsiQueryFeatureStateA(prodcode, "");
979     error = GetLastError();
980     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
981     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
982        "expected ERROR_SUCCESS, got %u\n", error);
983
984     /* feature key does not exist yet */
985     SetLastError(0xdeadbeef);
986     state = MsiQueryFeatureStateA(prodcode, "feature");
987     error = GetLastError();
988     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
989     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
990        "expected ERROR_SUCCESS, got %u\n", error);
991
992     /* MSIINSTALLCONTEXT_USERUNMANAGED */
993
994     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
995     lstrcatA(keypath, prod_squashed);
996
997     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
999
1000     /* feature key exists */
1001     SetLastError(0xdeadbeef);
1002     state = MsiQueryFeatureStateA(prodcode, "feature");
1003     error = GetLastError();
1004     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1005     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1006        "expected ERROR_SUCCESS, got %u\n", error);
1007
1008     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1010
1011     /* feature value exists */
1012     SetLastError(0xdeadbeef);
1013     state = MsiQueryFeatureStateA(prodcode, "feature");
1014     error = GetLastError();
1015     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1016     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1017        "expected ERROR_SUCCESS, got %u\n", error);
1018
1019     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1020     lstrcatA(keypath, usersid);
1021     lstrcatA(keypath, "\\Products\\");
1022     lstrcatA(keypath, prod_squashed);
1023     lstrcatA(keypath, "\\Features");
1024
1025     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1026     if (res == ERROR_ACCESS_DENIED)
1027     {
1028         skip("Not enough rights to perform tests\n");
1029         RegDeleteKeyA(userkey, "");
1030         RegCloseKey(userkey);
1031         LocalFree(usersid);
1032         return;
1033     }
1034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1035
1036     /* userdata features key exists */
1037     SetLastError(0xdeadbeef);
1038     state = MsiQueryFeatureStateA(prodcode, "feature");
1039     error = GetLastError();
1040     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1041     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1042        "expected ERROR_SUCCESS, got %u\n", error);
1043
1044     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1046
1047     SetLastError(0xdeadbeef);
1048     state = MsiQueryFeatureStateA(prodcode, "feature");
1049     error = GetLastError();
1050     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1051     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1052        "expected ERROR_SUCCESS, got %u\n", error);
1053
1054     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1056
1057     SetLastError(0xdeadbeef);
1058     state = MsiQueryFeatureStateA(prodcode, "feature");
1059     error = GetLastError();
1060     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1061     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1062        "expected ERROR_SUCCESS, got %u\n", error);
1063
1064     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1066
1067     SetLastError(0xdeadbeef);
1068     state = MsiQueryFeatureStateA(prodcode, "feature");
1069     error = GetLastError();
1070     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1071     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1072        "expected ERROR_SUCCESS, got %u\n", error);
1073
1074     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1076
1077     SetLastError(0xdeadbeef);
1078     state = MsiQueryFeatureStateA(prodcode, "feature");
1079     error = GetLastError();
1080     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1081     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1082        "expected ERROR_SUCCESS, got %u\n", error);
1083
1084     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1085     lstrcatA(keypath, usersid);
1086     lstrcatA(keypath, "\\Components\\");
1087     lstrcatA(keypath, comp_squashed);
1088
1089     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1091
1092     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1093     lstrcatA(keypath, usersid);
1094     lstrcatA(keypath, "\\Components\\");
1095     lstrcatA(keypath, comp_squashed2);
1096
1097     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1099
1100     SetLastError(0xdeadbeef);
1101     state = MsiQueryFeatureStateA(prodcode, "feature");
1102     error = GetLastError();
1103     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1104     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1105        "expected ERROR_SUCCESS, got %u\n", error);
1106
1107     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1109
1110     SetLastError(0xdeadbeef);
1111     state = MsiQueryFeatureStateA(prodcode, "feature");
1112     error = GetLastError();
1113     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1114     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1115        "expected ERROR_SUCCESS, got %u\n", error);
1116
1117     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1119
1120     SetLastError(0xdeadbeef);
1121     state = MsiQueryFeatureStateA(prodcode, "feature");
1122     error = GetLastError();
1123     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1124     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1125        "expected ERROR_SUCCESS, got %u\n", error);
1126
1127     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1129
1130     /* INSTALLSTATE_LOCAL */
1131     SetLastError(0xdeadbeef);
1132     state = MsiQueryFeatureStateA(prodcode, "feature");
1133     error = GetLastError();
1134     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1135     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1136        "expected ERROR_SUCCESS, got %u\n", error);
1137
1138     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1140
1141     /* INSTALLSTATE_SOURCE */
1142     SetLastError(0xdeadbeef);
1143     state = MsiQueryFeatureStateA(prodcode, "feature");
1144     error = GetLastError();
1145     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1146     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1147        "expected ERROR_SUCCESS, got %u\n", error);
1148
1149     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1151
1152     /* bad INSTALLSTATE_SOURCE */
1153     SetLastError(0xdeadbeef);
1154     state = MsiQueryFeatureStateA(prodcode, "feature");
1155     error = GetLastError();
1156     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1157     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1158        "expected ERROR_SUCCESS, got %u\n", error);
1159
1160     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1161     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1162
1163     /* INSTALLSTATE_SOURCE */
1164     SetLastError(0xdeadbeef);
1165     state = MsiQueryFeatureStateA(prodcode, "feature");
1166     error = GetLastError();
1167     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1168     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1169        "expected ERROR_SUCCESS, got %u\n", error);
1170
1171     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1173
1174     /* bad INSTALLSTATE_SOURCE */
1175     SetLastError(0xdeadbeef);
1176     state = MsiQueryFeatureStateA(prodcode, "feature");
1177     error = GetLastError();
1178     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1179     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1180        "expected ERROR_SUCCESS, got %u\n", error);
1181
1182     RegDeleteValueA(compkey, prod_squashed);
1183     RegDeleteValueA(compkey2, prod_squashed);
1184     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1185     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1186     RegDeleteValueA(localkey, "feature");
1187     RegDeleteValueA(userkey, "feature");
1188     RegDeleteKeyA(userkey, "");
1189     RegCloseKey(compkey);
1190     RegCloseKey(compkey2);
1191     RegCloseKey(localkey);
1192     RegCloseKey(userkey);
1193
1194     /* MSIINSTALLCONTEXT_USERMANAGED */
1195
1196     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1197     lstrcatA(keypath, usersid);
1198     lstrcatA(keypath, "\\Installer\\Features\\");
1199     lstrcatA(keypath, prod_squashed);
1200
1201     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1203
1204     /* feature key exists */
1205     state = MsiQueryFeatureStateA(prodcode, "feature");
1206     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1207
1208     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1210
1211     /* feature value exists */
1212     state = MsiQueryFeatureStateA(prodcode, "feature");
1213     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1214
1215     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1216     lstrcatA(keypath, usersid);
1217     lstrcatA(keypath, "\\Products\\");
1218     lstrcatA(keypath, prod_squashed);
1219     lstrcatA(keypath, "\\Features");
1220
1221     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1223
1224     /* userdata features key exists */
1225     state = MsiQueryFeatureStateA(prodcode, "feature");
1226     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1227
1228     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1229     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1230
1231     state = MsiQueryFeatureStateA(prodcode, "feature");
1232     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1233
1234     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1236
1237     state = MsiQueryFeatureStateA(prodcode, "feature");
1238     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1239
1240     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1242
1243     state = MsiQueryFeatureStateA(prodcode, "feature");
1244     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1245
1246     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1248
1249     state = MsiQueryFeatureStateA(prodcode, "feature");
1250     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1251
1252     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1253     lstrcatA(keypath, usersid);
1254     lstrcatA(keypath, "\\Components\\");
1255     lstrcatA(keypath, comp_squashed);
1256
1257     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1259
1260     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1261     lstrcatA(keypath, usersid);
1262     lstrcatA(keypath, "\\Components\\");
1263     lstrcatA(keypath, comp_squashed2);
1264
1265     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1267
1268     state = MsiQueryFeatureStateA(prodcode, "feature");
1269     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1270
1271     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1273
1274     state = MsiQueryFeatureStateA(prodcode, "feature");
1275     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1276
1277     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1279
1280     state = MsiQueryFeatureStateA(prodcode, "feature");
1281     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1282
1283     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1285
1286     state = MsiQueryFeatureStateA(prodcode, "feature");
1287     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1288
1289     RegDeleteValueA(compkey, prod_squashed);
1290     RegDeleteValueA(compkey2, prod_squashed);
1291     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1292     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1293     RegDeleteValueA(localkey, "feature");
1294     RegDeleteValueA(userkey, "feature");
1295     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1296     RegCloseKey(compkey);
1297     RegCloseKey(compkey2);
1298     RegCloseKey(localkey);
1299     RegCloseKey(userkey);
1300
1301     /* MSIINSTALLCONTEXT_MACHINE */
1302
1303     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1304     lstrcatA(keypath, prod_squashed);
1305
1306     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1308
1309     /* feature key exists */
1310     state = MsiQueryFeatureStateA(prodcode, "feature");
1311     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1312
1313     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1315
1316     /* feature value exists */
1317     state = MsiQueryFeatureStateA(prodcode, "feature");
1318     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1319
1320     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1321     lstrcatA(keypath, "S-1-5-18\\Products\\");
1322     lstrcatA(keypath, prod_squashed);
1323     lstrcatA(keypath, "\\Features");
1324
1325     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1326     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1327
1328     /* userdata features key exists */
1329     state = MsiQueryFeatureStateA(prodcode, "feature");
1330     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1331
1332     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1333     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1334
1335     state = MsiQueryFeatureStateA(prodcode, "feature");
1336     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1337
1338     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1340
1341     state = MsiQueryFeatureStateA(prodcode, "feature");
1342     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1343
1344     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1346
1347     state = MsiQueryFeatureStateA(prodcode, "feature");
1348     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1349
1350     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1352
1353     state = MsiQueryFeatureStateA(prodcode, "feature");
1354     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1355
1356     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1357     lstrcatA(keypath, "S-1-5-18\\Components\\");
1358     lstrcatA(keypath, comp_squashed);
1359
1360     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1362
1363     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1364     lstrcatA(keypath, "S-1-5-18\\Components\\");
1365     lstrcatA(keypath, comp_squashed2);
1366
1367     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1369
1370     state = MsiQueryFeatureStateA(prodcode, "feature");
1371     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1372
1373     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1375
1376     state = MsiQueryFeatureStateA(prodcode, "feature");
1377     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1378
1379     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1381
1382     state = MsiQueryFeatureStateA(prodcode, "feature");
1383     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1384
1385     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1387
1388     state = MsiQueryFeatureStateA(prodcode, "feature");
1389     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1390
1391     RegDeleteValueA(compkey, prod_squashed);
1392     RegDeleteValueA(compkey2, prod_squashed);
1393     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1394     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1395     RegDeleteValueA(localkey, "feature");
1396     RegDeleteValueA(userkey, "feature");
1397     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1398     RegCloseKey(compkey);
1399     RegCloseKey(compkey2);
1400     RegCloseKey(localkey);
1401     RegCloseKey(userkey);
1402     LocalFree(usersid);
1403 }
1404
1405 static void test_MsiQueryComponentState(void)
1406 {
1407     HKEY compkey, prodkey;
1408     CHAR prodcode[MAX_PATH];
1409     CHAR prod_squashed[MAX_PATH];
1410     CHAR component[MAX_PATH];
1411     CHAR comp_base85[MAX_PATH];
1412     CHAR comp_squashed[MAX_PATH];
1413     CHAR keypath[MAX_PATH];
1414     INSTALLSTATE state;
1415     LPSTR usersid;
1416     LONG res;
1417     UINT r;
1418     REGSAM access = KEY_ALL_ACCESS;
1419     DWORD error;
1420
1421     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1422
1423     if (!pMsiQueryComponentStateA)
1424     {
1425         win_skip("MsiQueryComponentStateA not implemented\n");
1426         return;
1427     }
1428
1429     create_test_guid(prodcode, prod_squashed);
1430     compose_base85_guid(component, comp_base85, comp_squashed);
1431     usersid = get_user_sid();
1432
1433     if (is_wow64)
1434         access |= KEY_WOW64_64KEY;
1435
1436     /* NULL szProductCode */
1437     state = MAGIC_ERROR;
1438     SetLastError(0xdeadbeef);
1439     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1440     error = GetLastError();
1441     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1442     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1443     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1444
1445     /* empty szProductCode */
1446     state = MAGIC_ERROR;
1447     SetLastError(0xdeadbeef);
1448     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1449     error = GetLastError();
1450     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1451     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1452     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1453
1454     /* random szProductCode */
1455     state = MAGIC_ERROR;
1456     SetLastError(0xdeadbeef);
1457     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1458     error = GetLastError();
1459     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1460     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1461     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1462
1463     /* GUID-length szProductCode */
1464     state = MAGIC_ERROR;
1465     SetLastError(0xdeadbeef);
1466     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1467     error = GetLastError();
1468     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1469     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1470     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1471
1472     /* GUID-length with brackets */
1473     state = MAGIC_ERROR;
1474     SetLastError(0xdeadbeef);
1475     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1476     error = GetLastError();
1477     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1478     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1479     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1480
1481     /* actual GUID */
1482     state = MAGIC_ERROR;
1483     SetLastError(0xdeadbeef);
1484     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1485     error = GetLastError();
1486     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1487     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1488     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1489
1490     state = MAGIC_ERROR;
1491     SetLastError(0xdeadbeef);
1492     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1493     error = GetLastError();
1494     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1495     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1496     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1497
1498     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1499     lstrcatA(keypath, prod_squashed);
1500
1501     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1502     if (res == ERROR_ACCESS_DENIED)
1503     {
1504         skip("Not enough rights to perform tests\n");
1505         LocalFree(usersid);
1506         return;
1507     }
1508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1509
1510     state = MAGIC_ERROR;
1511     SetLastError(0xdeadbeef);
1512     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1513     error = GetLastError();
1514     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1515     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1516     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1517
1518     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1519     RegCloseKey(prodkey);
1520
1521     /* create local system product key */
1522     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1523     lstrcatA(keypath, prod_squashed);
1524     lstrcatA(keypath, "\\InstallProperties");
1525
1526     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1528
1529     /* local system product key exists */
1530     state = MAGIC_ERROR;
1531     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1532     error = GetLastError();
1533     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1534     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1535     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1536
1537     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1539
1540     /* LocalPackage value exists */
1541     state = MAGIC_ERROR;
1542     SetLastError(0xdeadbeef);
1543     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1544     error = GetLastError();
1545     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1546     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1547     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1548
1549     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1550     lstrcatA(keypath, comp_squashed);
1551
1552     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1554
1555     /* component key 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     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1566
1567     /* component\product exists */
1568     state = MAGIC_ERROR;
1569     SetLastError(0xdeadbeef);
1570     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1572     error = GetLastError();
1573     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1574        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1575     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1576
1577     /* NULL component, product exists */
1578     state = MAGIC_ERROR;
1579     SetLastError(0xdeadbeef);
1580     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1581     error = GetLastError();
1582     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1583     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1584     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1585
1586     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1588
1589     /* INSTALLSTATE_LOCAL */
1590     state = MAGIC_ERROR;
1591     SetLastError(0xdeadbeef);
1592     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1593     error = GetLastError();
1594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1595     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1596     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1597
1598     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1600
1601     /* INSTALLSTATE_SOURCE */
1602     state = MAGIC_ERROR;
1603     SetLastError(0xdeadbeef);
1604     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1605     error = GetLastError();
1606     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1607     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1608     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1609
1610     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1612
1613     /* bad INSTALLSTATE_SOURCE */
1614     state = MAGIC_ERROR;
1615     SetLastError(0xdeadbeef);
1616     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1617     error = GetLastError();
1618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1619     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1620     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1621
1622     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1624
1625     /* INSTALLSTATE_SOURCE */
1626     state = MAGIC_ERROR;
1627     SetLastError(0xdeadbeef);
1628     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1629     error = GetLastError();
1630     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1631     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1632     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1633
1634     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1635     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1636
1637     /* bad INSTALLSTATE_SOURCE */
1638     state = MAGIC_ERROR;
1639     SetLastError(0xdeadbeef);
1640     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1641     error = GetLastError();
1642     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1643     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1644     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1645
1646     RegDeleteValueA(prodkey, "LocalPackage");
1647     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1648     RegDeleteValueA(compkey, prod_squashed);
1649     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1650     RegCloseKey(prodkey);
1651     RegCloseKey(compkey);
1652
1653     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1654
1655     state = MAGIC_ERROR;
1656     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1657     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1658     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1659
1660     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1661     lstrcatA(keypath, prod_squashed);
1662
1663     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1665
1666     state = MAGIC_ERROR;
1667     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1668     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1669     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1670
1671     RegDeleteKeyA(prodkey, "");
1672     RegCloseKey(prodkey);
1673
1674     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1675     lstrcatA(keypath, usersid);
1676     lstrcatA(keypath, "\\Products\\");
1677     lstrcatA(keypath, prod_squashed);
1678     lstrcatA(keypath, "\\InstallProperties");
1679
1680     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1681     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1682
1683     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1685
1686     RegCloseKey(prodkey);
1687
1688     state = MAGIC_ERROR;
1689     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1690     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1691     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1692
1693     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1694     lstrcatA(keypath, usersid);
1695     lstrcatA(keypath, "\\Components\\");
1696     lstrcatA(keypath, comp_squashed);
1697
1698     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1700
1701     /* component key exists */
1702     state = MAGIC_ERROR;
1703     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1704     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1705     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1706
1707     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1709
1710     /* component\product exists */
1711     state = MAGIC_ERROR;
1712     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1714     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1715        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1716
1717     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1719
1720     state = MAGIC_ERROR;
1721     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1722     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1723     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1724
1725     /* MSIINSTALLCONTEXT_USERMANAGED */
1726
1727     state = MAGIC_ERROR;
1728     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1729     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1730     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1731
1732     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1733     lstrcatA(keypath, prod_squashed);
1734
1735     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1737
1738     state = MAGIC_ERROR;
1739     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1740     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1741     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1742
1743     RegDeleteKeyA(prodkey, "");
1744     RegCloseKey(prodkey);
1745
1746     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1747     lstrcatA(keypath, usersid);
1748     lstrcatA(keypath, "\\Installer\\Products\\");
1749     lstrcatA(keypath, prod_squashed);
1750
1751     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1753
1754     state = MAGIC_ERROR;
1755     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1756     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1757     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1758
1759     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1760     RegCloseKey(prodkey);
1761
1762     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1763     lstrcatA(keypath, usersid);
1764     lstrcatA(keypath, "\\Products\\");
1765     lstrcatA(keypath, prod_squashed);
1766     lstrcatA(keypath, "\\InstallProperties");
1767
1768     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1770
1771     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1773
1774     state = MAGIC_ERROR;
1775     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1777     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1778
1779     RegDeleteValueA(prodkey, "LocalPackage");
1780     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1781     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1782     RegDeleteValueA(compkey, prod_squashed);
1783     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1784     RegCloseKey(prodkey);
1785     RegCloseKey(compkey);
1786     LocalFree(usersid);
1787 }
1788
1789 static void test_MsiGetComponentPath(void)
1790 {
1791     HKEY compkey, prodkey, installprop;
1792     CHAR prodcode[MAX_PATH];
1793     CHAR prod_squashed[MAX_PATH];
1794     CHAR component[MAX_PATH];
1795     CHAR comp_base85[MAX_PATH];
1796     CHAR comp_squashed[MAX_PATH];
1797     CHAR keypath[MAX_PATH];
1798     CHAR path[MAX_PATH];
1799     INSTALLSTATE state;
1800     LPSTR usersid;
1801     DWORD size, val;
1802     REGSAM access = KEY_ALL_ACCESS;
1803     LONG res;
1804
1805     create_test_guid(prodcode, prod_squashed);
1806     compose_base85_guid(component, comp_base85, comp_squashed);
1807     usersid = get_user_sid();
1808
1809     if (is_wow64)
1810         access |= KEY_WOW64_64KEY;
1811
1812     /* NULL szProduct */
1813     size = MAX_PATH;
1814     state = MsiGetComponentPathA(NULL, component, path, &size);
1815     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1816     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1817
1818     /* NULL szComponent */
1819     size = MAX_PATH;
1820     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1821     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1822     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1823
1824     size = MAX_PATH;
1825     state = MsiLocateComponentA(NULL, path, &size);
1826     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1827     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1828
1829     /* NULL lpPathBuf */
1830     size = MAX_PATH;
1831     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1832     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1833     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1834
1835     size = MAX_PATH;
1836     state = MsiLocateComponentA(component, NULL, &size);
1837     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1838     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1839
1840     /* NULL pcchBuf */
1841     size = MAX_PATH;
1842     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1843     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1844     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1845
1846     size = MAX_PATH;
1847     state = MsiLocateComponentA(component, path, NULL);
1848     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1849     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1850
1851     /* all params valid */
1852     size = MAX_PATH;
1853     state = MsiGetComponentPathA(prodcode, component, path, &size);
1854     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1855     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1856
1857     size = MAX_PATH;
1858     state = MsiLocateComponentA(component, path, &size);
1859     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1860     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1861
1862     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1863     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1864     lstrcatA(keypath, comp_squashed);
1865
1866     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1867     if (res == ERROR_ACCESS_DENIED)
1868     {
1869         skip("Not enough rights to perform tests\n");
1870         LocalFree(usersid);
1871         return;
1872     }
1873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1874
1875     /* local system component key exists */
1876     size = MAX_PATH;
1877     state = MsiGetComponentPathA(prodcode, component, path, &size);
1878     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1879     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1880
1881     size = MAX_PATH;
1882     state = MsiLocateComponentA(component, path, &size);
1883     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1884     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1885
1886     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1888
1889     /* product value exists */
1890     path[0] = 0;
1891     size = MAX_PATH;
1892     state = MsiGetComponentPathA(prodcode, component, path, &size);
1893     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1894     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1895     ok(size == 10, "Expected 10, got %d\n", size);
1896
1897     path[0] = 0;
1898     size = MAX_PATH;
1899     state = MsiLocateComponentA(component, path, &size);
1900     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1901     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1902     ok(size == 10, "Expected 10, got %d\n", size);
1903
1904     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1905     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1906     lstrcatA(keypath, prod_squashed);
1907     lstrcatA(keypath, "\\InstallProperties");
1908
1909     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1911
1912     val = 1;
1913     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1915
1916     /* install properties key exists */
1917     path[0] = 0;
1918     size = MAX_PATH;
1919     state = MsiGetComponentPathA(prodcode, component, path, &size);
1920     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1921     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1922     ok(size == 10, "Expected 10, got %d\n", size);
1923
1924     path[0] = 0;
1925     size = MAX_PATH;
1926     state = MsiLocateComponentA(component, path, &size);
1927     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1928     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1929     ok(size == 10, "Expected 10, got %d\n", size);
1930
1931     create_file("C:\\imapath", "C:\\imapath", 11);
1932
1933     /* file exists */
1934     path[0] = 0;
1935     size = MAX_PATH;
1936     state = MsiGetComponentPathA(prodcode, component, path, &size);
1937     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1938     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1939     ok(size == 10, "Expected 10, got %d\n", size);
1940
1941     path[0] = 0;
1942     size = MAX_PATH;
1943     state = MsiLocateComponentA(component, path, &size);
1944     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1945     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1946     ok(size == 10, "Expected 10, got %d\n", size);
1947
1948     RegDeleteValueA(compkey, prod_squashed);
1949     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1950     RegDeleteValueA(installprop, "WindowsInstaller");
1951     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1952     RegCloseKey(compkey);
1953     RegCloseKey(installprop);
1954     DeleteFileA("C:\\imapath");
1955
1956     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1957     lstrcatA(keypath, "Installer\\UserData\\");
1958     lstrcatA(keypath, usersid);
1959     lstrcatA(keypath, "\\Components\\");
1960     lstrcatA(keypath, comp_squashed);
1961
1962     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1964
1965     /* user managed component key exists */
1966     size = MAX_PATH;
1967     state = MsiGetComponentPathA(prodcode, component, path, &size);
1968     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1969     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1970
1971     size = MAX_PATH;
1972     state = MsiLocateComponentA(component, path, &size);
1973     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1974     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1975
1976     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1978
1979     /* product value exists */
1980     path[0] = 0;
1981     size = MAX_PATH;
1982     state = MsiGetComponentPathA(prodcode, component, path, &size);
1983     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1984     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1985     ok(size == 10, "Expected 10, got %d\n", size);
1986
1987     path[0] = 0;
1988     size = MAX_PATH;
1989     state = MsiLocateComponentA(component, path, &size);
1990     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1991     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1992     ok(size == 10, "Expected 10, got %d\n", size);
1993
1994     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1995     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1996     lstrcatA(keypath, prod_squashed);
1997     lstrcatA(keypath, "\\InstallProperties");
1998
1999     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2001
2002     val = 1;
2003     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2005
2006     /* install properties key exists */
2007     path[0] = 0;
2008     size = MAX_PATH;
2009     state = MsiGetComponentPathA(prodcode, component, path, &size);
2010     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2011     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2012     ok(size == 10, "Expected 10, got %d\n", size);
2013
2014     path[0] = 0;
2015     size = MAX_PATH;
2016     state = MsiLocateComponentA(component, path, &size);
2017     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2018     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2019     ok(size == 10, "Expected 10, got %d\n", size);
2020
2021     create_file("C:\\imapath", "C:\\imapath", 11);
2022
2023     /* file exists */
2024     path[0] = 0;
2025     size = MAX_PATH;
2026     state = MsiGetComponentPathA(prodcode, component, path, &size);
2027     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2028     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2029     ok(size == 10, "Expected 10, got %d\n", size);
2030
2031     path[0] = 0;
2032     size = MAX_PATH;
2033     state = MsiLocateComponentA(component, path, &size);
2034     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2035     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2036     ok(size == 10, "Expected 10, got %d\n", size);
2037
2038     RegDeleteValueA(compkey, prod_squashed);
2039     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2040     RegDeleteValueA(installprop, "WindowsInstaller");
2041     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2042     RegCloseKey(compkey);
2043     RegCloseKey(installprop);
2044     DeleteFileA("C:\\imapath");
2045
2046     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2047     lstrcatA(keypath, "Installer\\Managed\\");
2048     lstrcatA(keypath, usersid);
2049     lstrcatA(keypath, "\\Installer\\Products\\");
2050     lstrcatA(keypath, prod_squashed);
2051
2052     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2054
2055     /* user managed product key exists */
2056     size = MAX_PATH;
2057     state = MsiGetComponentPathA(prodcode, component, path, &size);
2058     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2059     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2060
2061     size = MAX_PATH;
2062     state = MsiLocateComponentA(component, path, &size);
2063     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2064     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2065
2066     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2067     lstrcatA(keypath, "Installer\\UserData\\");
2068     lstrcatA(keypath, usersid);
2069     lstrcatA(keypath, "\\Components\\");
2070     lstrcatA(keypath, comp_squashed);
2071
2072     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2074
2075     /* user managed component key exists */
2076     size = MAX_PATH;
2077     state = MsiGetComponentPathA(prodcode, 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     size = MAX_PATH;
2082     state = MsiLocateComponentA(component, path, &size);
2083     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2084     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2085
2086     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2088
2089     /* product value exists */
2090     path[0] = 0;
2091     size = MAX_PATH;
2092     state = MsiGetComponentPathA(prodcode, component, path, &size);
2093     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2094     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2095     ok(size == 10, "Expected 10, got %d\n", size);
2096
2097     path[0] = 0;
2098     size = MAX_PATH;
2099     state = MsiLocateComponentA(component, path, &size);
2100     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2101     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2102     ok(size == 10, "Expected 10, got %d\n", size);
2103
2104     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2105     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2106     lstrcatA(keypath, prod_squashed);
2107     lstrcatA(keypath, "\\InstallProperties");
2108
2109     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2111
2112     val = 1;
2113     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2114     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2115
2116     /* install properties key exists */
2117     path[0] = 0;
2118     size = MAX_PATH;
2119     state = MsiGetComponentPathA(prodcode, component, path, &size);
2120     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2121     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2122     ok(size == 10, "Expected 10, got %d\n", size);
2123
2124     path[0] = 0;
2125     size = MAX_PATH;
2126     state = MsiLocateComponentA(component, path, &size);
2127     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2128     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2129     ok(size == 10, "Expected 10, got %d\n", size);
2130
2131     create_file("C:\\imapath", "C:\\imapath", 11);
2132
2133     /* file exists */
2134     path[0] = 0;
2135     size = MAX_PATH;
2136     state = MsiGetComponentPathA(prodcode, component, path, &size);
2137     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2138     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2139     ok(size == 10, "Expected 10, got %d\n", size);
2140
2141     path[0] = 0;
2142     size = MAX_PATH;
2143     state = MsiLocateComponentA(component, path, &size);
2144     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2145     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2146     ok(size == 10, "Expected 10, got %d\n", size);
2147
2148     RegDeleteValueA(compkey, prod_squashed);
2149     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2150     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2151     RegDeleteValueA(installprop, "WindowsInstaller");
2152     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2153     RegCloseKey(prodkey);
2154     RegCloseKey(compkey);
2155     RegCloseKey(installprop);
2156     DeleteFileA("C:\\imapath");
2157
2158     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2159     lstrcatA(keypath, prod_squashed);
2160
2161     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2163
2164     /* user unmanaged product key exists */
2165     size = MAX_PATH;
2166     state = MsiGetComponentPathA(prodcode, component, path, &size);
2167     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2168     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2169
2170     size = MAX_PATH;
2171     state = MsiLocateComponentA(component, path, &size);
2172     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2173     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2174
2175     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2176     lstrcatA(keypath, "Installer\\UserData\\");
2177     lstrcatA(keypath, usersid);
2178     lstrcatA(keypath, "\\Components\\");
2179     lstrcatA(keypath, comp_squashed);
2180
2181     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2183
2184     /* user unmanaged component key exists */
2185     size = MAX_PATH;
2186     state = MsiGetComponentPathA(prodcode, 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     size = MAX_PATH;
2191     state = MsiLocateComponentA(component, path, &size);
2192     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2193     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2194
2195     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2197
2198     /* product value exists */
2199     path[0] = 0;
2200     size = MAX_PATH;
2201     state = MsiGetComponentPathA(prodcode, component, path, &size);
2202     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2203     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2204     ok(size == 10, "Expected 10, got %d\n", size);
2205
2206     path[0] = 0;
2207     size = MAX_PATH;
2208     state = MsiLocateComponentA(component, path, &size);
2209     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2210     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2211     ok(size == 10, "Expected 10, got %d\n", size);
2212
2213     create_file("C:\\imapath", "C:\\imapath", 11);
2214
2215     /* file exists */
2216     path[0] = 0;
2217     size = MAX_PATH;
2218     state = MsiGetComponentPathA(prodcode, component, path, &size);
2219     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2220     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2221     ok(size == 10, "Expected 10, got %d\n", size);
2222
2223     path[0] = 0;
2224     size = MAX_PATH;
2225     state = MsiLocateComponentA(component, path, &size);
2226     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2227     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2228     ok(size == 10, "Expected 10, got %d\n", size);
2229
2230     RegDeleteValueA(compkey, prod_squashed);
2231     RegDeleteKeyA(prodkey, "");
2232     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2233     RegCloseKey(prodkey);
2234     RegCloseKey(compkey);
2235     DeleteFileA("C:\\imapath");
2236
2237     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2238     lstrcatA(keypath, prod_squashed);
2239
2240     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2242
2243     /* local classes product key exists */
2244     size = MAX_PATH;
2245     state = MsiGetComponentPathA(prodcode, component, path, &size);
2246     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2247     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2248
2249     size = MAX_PATH;
2250     state = MsiLocateComponentA(component, path, &size);
2251     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2252     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2253
2254     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2255     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2256     lstrcatA(keypath, comp_squashed);
2257
2258     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2260
2261     /* local user component key exists */
2262     size = MAX_PATH;
2263     state = MsiGetComponentPathA(prodcode, component, path, &size);
2264     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2265     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2266
2267     size = MAX_PATH;
2268     state = MsiLocateComponentA(component, path, &size);
2269     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2270     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2271
2272     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2274
2275     /* product value exists */
2276     path[0] = 0;
2277     size = MAX_PATH;
2278     state = MsiGetComponentPathA(prodcode, component, path, &size);
2279     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2280     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2281     ok(size == 10, "Expected 10, got %d\n", size);
2282
2283     path[0] = 0;
2284     size = MAX_PATH;
2285     state = MsiLocateComponentA(component, path, &size);
2286     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2287     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2288     ok(size == 10, "Expected 10, got %d\n", size);
2289
2290     create_file("C:\\imapath", "C:\\imapath", 11);
2291
2292     /* file exists */
2293     path[0] = 0;
2294     size = MAX_PATH;
2295     state = MsiGetComponentPathA(prodcode, component, path, &size);
2296     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2297     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2298     ok(size == 10, "Expected 10, got %d\n", size);
2299
2300     path[0] = 0;
2301     size = MAX_PATH;
2302     state = MsiLocateComponentA(component, path, &size);
2303     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2304     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2305     ok(size == 10, "Expected 10, got %d\n", size);
2306
2307     RegDeleteValueA(compkey, prod_squashed);
2308     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2309     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2310     RegCloseKey(prodkey);
2311     RegCloseKey(compkey);
2312     DeleteFileA("C:\\imapath");
2313     LocalFree(usersid);
2314 }
2315
2316 static void test_MsiGetProductCode(void)
2317 {
2318     HKEY compkey, prodkey;
2319     CHAR prodcode[MAX_PATH];
2320     CHAR prod_squashed[MAX_PATH];
2321     CHAR prodcode2[MAX_PATH];
2322     CHAR prod2_squashed[MAX_PATH];
2323     CHAR component[MAX_PATH];
2324     CHAR comp_base85[MAX_PATH];
2325     CHAR comp_squashed[MAX_PATH];
2326     CHAR keypath[MAX_PATH];
2327     CHAR product[MAX_PATH];
2328     LPSTR usersid;
2329     LONG res;
2330     UINT r;
2331     REGSAM access = KEY_ALL_ACCESS;
2332
2333     create_test_guid(prodcode, prod_squashed);
2334     create_test_guid(prodcode2, prod2_squashed);
2335     compose_base85_guid(component, comp_base85, comp_squashed);
2336     usersid = get_user_sid();
2337
2338     if (is_wow64)
2339         access |= KEY_WOW64_64KEY;
2340
2341     /* szComponent is NULL */
2342     lstrcpyA(product, "prod");
2343     r = MsiGetProductCodeA(NULL, product);
2344     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2345     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2346
2347     /* szComponent is empty */
2348     lstrcpyA(product, "prod");
2349     r = MsiGetProductCodeA("", product);
2350     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2351     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2352
2353     /* garbage szComponent */
2354     lstrcpyA(product, "prod");
2355     r = MsiGetProductCodeA("garbage", product);
2356     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2357     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2358
2359     /* guid without brackets */
2360     lstrcpyA(product, "prod");
2361     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2362     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2363     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2364
2365     /* guid with brackets */
2366     lstrcpyA(product, "prod");
2367     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2368     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2369     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2370
2371     /* same length as guid, but random */
2372     lstrcpyA(product, "prod");
2373     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2374     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2375     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2376
2377     /* all params correct, szComponent not published */
2378     lstrcpyA(product, "prod");
2379     r = MsiGetProductCodeA(component, product);
2380     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2381     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2382
2383     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2384     lstrcatA(keypath, "Installer\\UserData\\");
2385     lstrcatA(keypath, usersid);
2386     lstrcatA(keypath, "\\Components\\");
2387     lstrcatA(keypath, comp_squashed);
2388
2389     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2390     if (res == ERROR_ACCESS_DENIED)
2391     {
2392         skip("Not enough rights to perform tests\n");
2393         LocalFree(usersid);
2394         return;
2395     }
2396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2397
2398     /* user unmanaged component key exists */
2399     lstrcpyA(product, "prod");
2400     r = MsiGetProductCodeA(component, product);
2401     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2402     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2403
2404     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2406
2407     /* product value exists */
2408     lstrcpyA(product, "prod");
2409     r = MsiGetProductCodeA(component, product);
2410     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2411     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2412
2413     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2415
2416     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2417     lstrcatA(keypath, "Installer\\Managed\\");
2418     lstrcatA(keypath, usersid);
2419     lstrcatA(keypath, "\\Installer\\Products\\");
2420     lstrcatA(keypath, prod_squashed);
2421
2422     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2424
2425     /* user managed product key of first product exists */
2426     lstrcpyA(product, "prod");
2427     r = MsiGetProductCodeA(component, product);
2428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2429     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2430
2431     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2432     RegCloseKey(prodkey);
2433
2434     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2435     lstrcatA(keypath, prod_squashed);
2436
2437     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2439
2440     /* user unmanaged product key 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     RegDeleteKeyA(prodkey, "");
2447     RegCloseKey(prodkey);
2448
2449     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2450     lstrcatA(keypath, prod_squashed);
2451
2452     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2454
2455     /* local classes 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     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2462     RegCloseKey(prodkey);
2463
2464     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2465     lstrcatA(keypath, "Installer\\Managed\\");
2466     lstrcatA(keypath, usersid);
2467     lstrcatA(keypath, "\\Installer\\Products\\");
2468     lstrcatA(keypath, prod2_squashed);
2469
2470     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2472
2473     /* user managed product key of second product exists */
2474     lstrcpyA(product, "prod");
2475     r = MsiGetProductCodeA(component, product);
2476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2477     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2478
2479     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2480     RegCloseKey(prodkey);
2481     RegDeleteValueA(compkey, prod_squashed);
2482     RegDeleteValueA(compkey, prod2_squashed);
2483     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2484     RegCloseKey(compkey);
2485
2486     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2487     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2488     lstrcatA(keypath, comp_squashed);
2489
2490     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2491     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2492
2493     /* local user component key exists */
2494     lstrcpyA(product, "prod");
2495     r = MsiGetProductCodeA(component, product);
2496     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2497     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2498
2499     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2501
2502     /* product value exists */
2503     lstrcpyA(product, "prod");
2504     r = MsiGetProductCodeA(component, product);
2505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2506     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2507
2508     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2510
2511     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2512     lstrcatA(keypath, "Installer\\Managed\\");
2513     lstrcatA(keypath, usersid);
2514     lstrcatA(keypath, "\\Installer\\Products\\");
2515     lstrcatA(keypath, prod_squashed);
2516
2517     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2518     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2519
2520     /* user managed product key of first product exists */
2521     lstrcpyA(product, "prod");
2522     r = MsiGetProductCodeA(component, product);
2523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2524     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2525
2526     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2527     RegCloseKey(prodkey);
2528
2529     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2530     lstrcatA(keypath, prod_squashed);
2531
2532     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2534
2535     /* user unmanaged product key 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     RegDeleteKeyA(prodkey, "");
2542     RegCloseKey(prodkey);
2543
2544     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2545     lstrcatA(keypath, prod_squashed);
2546
2547     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2549
2550     /* local classes 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     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2557     RegCloseKey(prodkey);
2558
2559     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2560     lstrcatA(keypath, "Installer\\Managed\\");
2561     lstrcatA(keypath, usersid);
2562     lstrcatA(keypath, "\\Installer\\Products\\");
2563     lstrcatA(keypath, prod2_squashed);
2564
2565     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2566     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2567
2568     /* user managed product key of second product exists */
2569     lstrcpyA(product, "prod");
2570     r = MsiGetProductCodeA(component, product);
2571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2572     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2573
2574     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2575     RegCloseKey(prodkey);
2576     RegDeleteValueA(compkey, prod_squashed);
2577     RegDeleteValueA(compkey, prod2_squashed);
2578     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2579     RegCloseKey(compkey);
2580     LocalFree(usersid);
2581 }
2582
2583 static void test_MsiEnumClients(void)
2584 {
2585     HKEY compkey;
2586     CHAR prodcode[MAX_PATH];
2587     CHAR prod_squashed[MAX_PATH];
2588     CHAR prodcode2[MAX_PATH];
2589     CHAR prod2_squashed[MAX_PATH];
2590     CHAR component[MAX_PATH];
2591     CHAR comp_base85[MAX_PATH];
2592     CHAR comp_squashed[MAX_PATH];
2593     CHAR product[MAX_PATH];
2594     CHAR keypath[MAX_PATH];
2595     LPSTR usersid;
2596     LONG res;
2597     UINT r;
2598     REGSAM access = KEY_ALL_ACCESS;
2599
2600     create_test_guid(prodcode, prod_squashed);
2601     create_test_guid(prodcode2, prod2_squashed);
2602     compose_base85_guid(component, comp_base85, comp_squashed);
2603     usersid = get_user_sid();
2604
2605     if (is_wow64)
2606         access |= KEY_WOW64_64KEY;
2607
2608     /* NULL szComponent */
2609     product[0] = '\0';
2610     r = MsiEnumClientsA(NULL, 0, product);
2611     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2612     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2613
2614     /* empty szComponent */
2615     product[0] = '\0';
2616     r = MsiEnumClientsA("", 0, product);
2617     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2618     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2619
2620     /* NULL lpProductBuf */
2621     r = MsiEnumClientsA(component, 0, NULL);
2622     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2623
2624     /* all params correct, component missing */
2625     product[0] = '\0';
2626     r = MsiEnumClientsA(component, 0, product);
2627     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2628     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2629
2630     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2631     lstrcatA(keypath, "Installer\\UserData\\");
2632     lstrcatA(keypath, usersid);
2633     lstrcatA(keypath, "\\Components\\");
2634     lstrcatA(keypath, comp_squashed);
2635
2636     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2637     if (res == ERROR_ACCESS_DENIED)
2638     {
2639         skip("Not enough rights to perform tests\n");
2640         LocalFree(usersid);
2641         return;
2642     }
2643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2644
2645     /* user unmanaged component key exists */
2646     product[0] = '\0';
2647     r = MsiEnumClientsA(component, 0, product);
2648     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2649     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2650
2651     /* index > 0, no products exist */
2652     product[0] = '\0';
2653     r = MsiEnumClientsA(component, 1, product);
2654     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2655     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2656
2657     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2659
2660     /* product value exists */
2661     r = MsiEnumClientsA(component, 0, product);
2662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2663     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2664
2665     /* try index 0 again */
2666     product[0] = '\0';
2667     r = MsiEnumClientsA(component, 0, product);
2668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2669     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2670
2671     /* try index 1, second product value does not exist */
2672     product[0] = '\0';
2673     r = MsiEnumClientsA(component, 1, product);
2674     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2675     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2676
2677     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2679
2680     /* try index 1, second product value does exist */
2681     product[0] = '\0';
2682     r = MsiEnumClientsA(component, 1, product);
2683     todo_wine
2684     {
2685         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2686         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2687     }
2688
2689     /* start the enumeration over */
2690     product[0] = '\0';
2691     r = MsiEnumClientsA(component, 0, product);
2692     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2693     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2694        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2695
2696     /* correctly query second product */
2697     product[0] = '\0';
2698     r = MsiEnumClientsA(component, 1, product);
2699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2700     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2701        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2702
2703     RegDeleteValueA(compkey, prod_squashed);
2704     RegDeleteValueA(compkey, prod2_squashed);
2705     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2706     RegCloseKey(compkey);
2707
2708     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2709     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2710     lstrcatA(keypath, comp_squashed);
2711
2712     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2714
2715     /* user local component key exists */
2716     product[0] = '\0';
2717     r = MsiEnumClientsA(component, 0, product);
2718     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2719     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2720
2721     /* index > 0, no products exist */
2722     product[0] = '\0';
2723     r = MsiEnumClientsA(component, 1, product);
2724     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2725     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2726
2727     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2729
2730     /* product value exists */
2731     product[0] = '\0';
2732     r = MsiEnumClientsA(component, 0, product);
2733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2734     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2735
2736     /* try index 0 again */
2737     product[0] = '\0';
2738     r = MsiEnumClientsA(component, 0, product);
2739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2740
2741     /* try index 1, second product value does not exist */
2742     product[0] = '\0';
2743     r = MsiEnumClientsA(component, 1, product);
2744     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2745     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2746
2747     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2748     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2749
2750     /* try index 1, second product value does exist */
2751     product[0] = '\0';
2752     r = MsiEnumClientsA(component, 1, product);
2753     todo_wine
2754     {
2755         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2756         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2757     }
2758
2759     /* start the enumeration over */
2760     product[0] = '\0';
2761     r = MsiEnumClientsA(component, 0, product);
2762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2763     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2764        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2765
2766     /* correctly query second product */
2767     product[0] = '\0';
2768     r = MsiEnumClientsA(component, 1, product);
2769     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2770     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2771        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2772
2773     RegDeleteValueA(compkey, prod_squashed);
2774     RegDeleteValueA(compkey, prod2_squashed);
2775     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2776     RegCloseKey(compkey);
2777     LocalFree(usersid);
2778 }
2779
2780 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2781                              LPSTR *langcheck, LPDWORD langchecksz)
2782 {
2783     LPSTR version;
2784     VS_FIXEDFILEINFO *ffi;
2785     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2786     USHORT *lang;
2787
2788     version = HeapAlloc(GetProcessHeap(), 0, size);
2789     GetFileVersionInfoA(path, 0, size, version);
2790
2791     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2792     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2793     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2794             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2795             LOWORD(ffi->dwFileVersionLS));
2796     *verchecksz = lstrlenA(*vercheck);
2797
2798     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2799     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2800     sprintf(*langcheck, "%d", *lang);
2801     *langchecksz = lstrlenA(*langcheck);
2802
2803     HeapFree(GetProcessHeap(), 0, version);
2804 }
2805
2806 static void test_MsiGetFileVersion(void)
2807 {
2808     UINT r;
2809     DWORD versz, langsz;
2810     char version[MAX_PATH];
2811     char lang[MAX_PATH];
2812     char path[MAX_PATH];
2813     LPSTR vercheck, langcheck;
2814     DWORD verchecksz, langchecksz;
2815
2816     /* NULL szFilePath */
2817     versz = MAX_PATH;
2818     langsz = MAX_PATH;
2819     lstrcpyA(version, "version");
2820     lstrcpyA(lang, "lang");
2821     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2822     ok(r == ERROR_INVALID_PARAMETER,
2823        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2824     ok(!lstrcmpA(version, "version"),
2825        "Expected version to be unchanged, got %s\n", version);
2826     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2827     ok(!lstrcmpA(lang, "lang"),
2828        "Expected lang to be unchanged, got %s\n", lang);
2829     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2830
2831     /* empty szFilePath */
2832     versz = MAX_PATH;
2833     langsz = MAX_PATH;
2834     lstrcpyA(version, "version");
2835     lstrcpyA(lang, "lang");
2836     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2837     ok(r == ERROR_FILE_NOT_FOUND,
2838        "Expected ERROR_FILE_NOT_FOUND, 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     /* nonexistent szFilePath */
2847     versz = MAX_PATH;
2848     langsz = MAX_PATH;
2849     lstrcpyA(version, "version");
2850     lstrcpyA(lang, "lang");
2851     r = MsiGetFileVersionA("nonexistent", 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, valid lpVersionBuf, NULL pcchVersionBuf */
2862     versz = MAX_PATH;
2863     langsz = MAX_PATH;
2864     lstrcpyA(version, "version");
2865     lstrcpyA(lang, "lang");
2866     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2867     ok(r == ERROR_INVALID_PARAMETER,
2868        "Expected ERROR_INVALID_PARAMETER, 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 lpLangBuf, NULL pcchLangBuf */
2877     versz = MAX_PATH;
2878     langsz = MAX_PATH;
2879     lstrcpyA(version, "version");
2880     lstrcpyA(lang, "lang");
2881     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
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 lpVersionBuf, pcchVersionBuf is zero */
2892     versz = 0;
2893     langsz = MAX_PATH;
2894     lstrcpyA(version, "version");
2895     lstrcpyA(lang, "lang");
2896     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2897     ok(r == ERROR_FILE_NOT_FOUND,
2898        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2899     ok(!lstrcmpA(version, "version"),
2900        "Expected version to be unchanged, got %s\n", version);
2901     ok(versz == 0, "Expected 0, got %d\n", 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 lpLangBuf, pcchLangBuf is zero */
2907     versz = MAX_PATH;
2908     langsz = 0;
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 == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2917     ok(!lstrcmpA(lang, "lang"),
2918        "Expected lang to be unchanged, got %s\n", lang);
2919     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2920
2921     /* nonexistent szFilePath, rest NULL */
2922     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2923     ok(r == ERROR_FILE_NOT_FOUND,
2924        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2925
2926     create_file("ver.txt", "ver.txt", 20);
2927
2928     /* file exists, no version information */
2929     versz = MAX_PATH;
2930     langsz = MAX_PATH;
2931     lstrcpyA(version, "version");
2932     lstrcpyA(lang, "lang");
2933     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2934     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2935     ok(!lstrcmpA(version, "version"),
2936        "Expected version to be unchanged, got %s\n", version);
2937     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2938     ok(!lstrcmpA(lang, "lang"),
2939        "Expected lang to be unchanged, got %s\n", lang);
2940     ok(r == ERROR_FILE_INVALID,
2941        "Expected ERROR_FILE_INVALID, got %d\n", r);
2942
2943     DeleteFileA("ver.txt");
2944
2945     /* relative path, has version information */
2946     versz = MAX_PATH;
2947     langsz = MAX_PATH;
2948     lstrcpyA(version, "version");
2949     lstrcpyA(lang, "lang");
2950     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2951     todo_wine
2952     {
2953         ok(r == ERROR_FILE_NOT_FOUND,
2954            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2955         ok(!lstrcmpA(version, "version"),
2956            "Expected version to be unchanged, got %s\n", version);
2957         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2958         ok(!lstrcmpA(lang, "lang"),
2959            "Expected lang to be unchanged, got %s\n", lang);
2960         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2961     }
2962
2963     GetSystemDirectoryA(path, MAX_PATH);
2964     lstrcatA(path, "\\kernel32.dll");
2965
2966     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2967
2968     /* absolute path, has version information */
2969     versz = MAX_PATH;
2970     langsz = MAX_PATH;
2971     lstrcpyA(version, "version");
2972     lstrcpyA(lang, "lang");
2973     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2975     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2976     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2977     ok(!lstrcmpA(version, vercheck),
2978         "Expected %s, got %s\n", vercheck, version);
2979
2980     /* only check version */
2981     versz = MAX_PATH;
2982     lstrcpyA(version, "version");
2983     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2984     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2985     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2986     ok(!lstrcmpA(version, vercheck),
2987        "Expected %s, got %s\n", vercheck, version);
2988
2989     /* only check language */
2990     langsz = MAX_PATH;
2991     lstrcpyA(lang, "lang");
2992     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2994     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2995
2996     /* check neither version nor language */
2997     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2999
3000     /* get pcchVersionBuf */
3001     versz = MAX_PATH;
3002     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
3003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3004     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3005
3006     /* get pcchLangBuf */
3007     langsz = MAX_PATH;
3008     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
3009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3010     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3011
3012     /* pcchVersionBuf not big enough */
3013     versz = 5;
3014     lstrcpyA(version, "version");
3015     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
3016     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3017     ok(!strncmp(version, vercheck, 4),
3018        "Expected first 4 characters of %s, got %s\n", vercheck, version);
3019     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3020
3021     /* pcchLangBuf not big enough */
3022     langsz = 3;
3023     lstrcpyA(lang, "lang");
3024     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
3025     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3026     ok(!strncmp(lang, langcheck, 2),
3027        "Expected first character of %s, got %s\n", langcheck, lang);
3028     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3029
3030     HeapFree(GetProcessHeap(), 0, vercheck);
3031     HeapFree(GetProcessHeap(), 0, langcheck);
3032 }
3033
3034 static void test_MsiGetProductInfo(void)
3035 {
3036     UINT r;
3037     LONG res;
3038     HKEY propkey, source;
3039     HKEY prodkey, localkey;
3040     CHAR prodcode[MAX_PATH];
3041     CHAR prod_squashed[MAX_PATH];
3042     CHAR packcode[MAX_PATH];
3043     CHAR pack_squashed[MAX_PATH];
3044     CHAR buf[MAX_PATH];
3045     CHAR keypath[MAX_PATH];
3046     LPSTR usersid;
3047     DWORD sz, val = 42;
3048     REGSAM access = KEY_ALL_ACCESS;
3049
3050     create_test_guid(prodcode, prod_squashed);
3051     create_test_guid(packcode, pack_squashed);
3052     usersid = get_user_sid();
3053
3054     if (is_wow64)
3055         access |= KEY_WOW64_64KEY;
3056
3057     /* NULL szProduct */
3058     sz = MAX_PATH;
3059     lstrcpyA(buf, "apple");
3060     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
3061     ok(r == ERROR_INVALID_PARAMETER,
3062        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3063     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3064     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3065
3066     /* empty szProduct */
3067     sz = MAX_PATH;
3068     lstrcpyA(buf, "apple");
3069     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
3070     ok(r == ERROR_INVALID_PARAMETER,
3071        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3072     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3073     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3074
3075     /* garbage szProduct */
3076     sz = MAX_PATH;
3077     lstrcpyA(buf, "apple");
3078     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
3079     ok(r == ERROR_INVALID_PARAMETER,
3080        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3081     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3082     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3083
3084     /* guid without brackets */
3085     sz = MAX_PATH;
3086     lstrcpyA(buf, "apple");
3087     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
3088                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3089     ok(r == ERROR_INVALID_PARAMETER,
3090        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3091     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3092     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3093
3094     /* guid with brackets */
3095     sz = MAX_PATH;
3096     lstrcpyA(buf, "apple");
3097     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
3098                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3099     ok(r == ERROR_UNKNOWN_PRODUCT,
3100        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3101     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3102     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3103
3104     /* same length as guid, but random */
3105     sz = MAX_PATH;
3106     lstrcpyA(buf, "apple");
3107     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
3108                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3109     ok(r == ERROR_INVALID_PARAMETER,
3110        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3111     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3112     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3113
3114     /* not installed, NULL szAttribute */
3115     sz = MAX_PATH;
3116     lstrcpyA(buf, "apple");
3117     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
3118     ok(r == ERROR_INVALID_PARAMETER,
3119        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3120     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3121     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3122
3123     /* not installed, NULL lpValueBuf */
3124     sz = MAX_PATH;
3125     lstrcpyA(buf, "apple");
3126     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3127     ok(r == ERROR_UNKNOWN_PRODUCT,
3128        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3129     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3130     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3131
3132     /* not installed, NULL pcchValueBuf */
3133     sz = MAX_PATH;
3134     lstrcpyA(buf, "apple");
3135     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
3136     ok(r == ERROR_INVALID_PARAMETER,
3137        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3138     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3139     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3140
3141     /* created guid cannot possibly be an installed product code */
3142     sz = MAX_PATH;
3143     lstrcpyA(buf, "apple");
3144     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3145     ok(r == ERROR_UNKNOWN_PRODUCT,
3146        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3147     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3148     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3149
3150     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3151     lstrcatA(keypath, usersid);
3152     lstrcatA(keypath, "\\Installer\\Products\\");
3153     lstrcatA(keypath, prod_squashed);
3154
3155     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3156     if (res == ERROR_ACCESS_DENIED)
3157     {
3158         skip("Not enough rights to perform tests\n");
3159         LocalFree(usersid);
3160         return;
3161     }
3162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3163
3164     /* managed product code exists */
3165     sz = MAX_PATH;
3166     lstrcpyA(buf, "apple");
3167     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3168     ok(r == ERROR_UNKNOWN_PROPERTY,
3169        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3170     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3171     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3172
3173     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3174     RegCloseKey(prodkey);
3175
3176     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3177     lstrcatA(keypath, usersid);
3178     lstrcatA(keypath, "\\Products\\");
3179     lstrcatA(keypath, prod_squashed);
3180
3181     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3183
3184     /* local user product code exists */
3185     sz = MAX_PATH;
3186     lstrcpyA(buf, "apple");
3187     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3188     ok(r == ERROR_UNKNOWN_PRODUCT,
3189        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3190     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3191     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3192
3193     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3194     lstrcatA(keypath, usersid);
3195     lstrcatA(keypath, "\\Installer\\Products\\");
3196     lstrcatA(keypath, prod_squashed);
3197
3198     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3200
3201     /* both local and managed product code exist */
3202     sz = MAX_PATH;
3203     lstrcpyA(buf, "apple");
3204     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3205     ok(r == ERROR_UNKNOWN_PROPERTY,
3206        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3207     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3208     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3209
3210     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3212
3213     /* InstallProperties key exists */
3214     sz = MAX_PATH;
3215     lstrcpyA(buf, "apple");
3216     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3217     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3218     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3219     ok(sz == 0, "Expected 0, got %d\n", sz);
3220
3221     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3223
3224     /* HelpLink value exists */
3225     sz = MAX_PATH;
3226     lstrcpyA(buf, "apple");
3227     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3229     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3230     ok(sz == 4, "Expected 4, got %d\n", sz);
3231
3232     /* pcchBuf is NULL */
3233     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3235
3236     /* lpValueBuf is NULL */
3237     sz = MAX_PATH;
3238     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3240     ok(sz == 4, "Expected 4, got %d\n", sz);
3241
3242     /* lpValueBuf is NULL, pcchValueBuf is too small */
3243     sz = 2;
3244     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3246     ok(sz == 4, "Expected 4, got %d\n", sz);
3247
3248     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3249     sz = 2;
3250     lstrcpyA(buf, "apple");
3251     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3252     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3253     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3254     ok(sz == 4, "Expected 4, got %d\n", sz);
3255
3256     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3257     sz = 4;
3258     lstrcpyA(buf, "apple");
3259     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3260     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3261     ok(!lstrcmpA(buf, "apple"),
3262        "Expected buf to remain unchanged, got \"%s\"\n", buf);
3263     ok(sz == 4, "Expected 4, got %d\n", sz);
3264
3265     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3267
3268     /* random property not supported by MSI, value exists */
3269     sz = MAX_PATH;
3270     lstrcpyA(buf, "apple");
3271     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3272     ok(r == ERROR_UNKNOWN_PROPERTY,
3273        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3274     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3275     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3276
3277     RegDeleteValueA(propkey, "IMadeThis");
3278     RegDeleteValueA(propkey, "HelpLink");
3279     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3280     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3281     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3282     RegCloseKey(propkey);
3283     RegCloseKey(localkey);
3284     RegCloseKey(prodkey);
3285
3286     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3287     lstrcatA(keypath, prod_squashed);
3288
3289     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3291
3292     /* user product key exists */
3293     sz = MAX_PATH;
3294     lstrcpyA(buf, "apple");
3295     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3296     ok(r == ERROR_UNKNOWN_PROPERTY,
3297        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3298     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3299     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3300
3301     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3302     lstrcatA(keypath, usersid);
3303     lstrcatA(keypath, "\\Products\\");
3304     lstrcatA(keypath, prod_squashed);
3305
3306     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3308
3309     /* local user product key exists */
3310     sz = MAX_PATH;
3311     lstrcpyA(buf, "apple");
3312     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3313     ok(r == ERROR_UNKNOWN_PROPERTY,
3314        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3315     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3316     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3317
3318     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* InstallProperties key exists */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3327     ok(sz == 0, "Expected 0, got %d\n", sz);
3328
3329     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3331
3332     /* HelpLink value exists */
3333     sz = MAX_PATH;
3334     lstrcpyA(buf, "apple");
3335     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3337     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3338     ok(sz == 4, "Expected 4, got %d\n", sz);
3339
3340     RegDeleteValueA(propkey, "HelpLink");
3341     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3342     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3343     RegDeleteKeyA(prodkey, "");
3344     RegCloseKey(propkey);
3345     RegCloseKey(localkey);
3346     RegCloseKey(prodkey);
3347
3348     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3349     lstrcatA(keypath, prod_squashed);
3350
3351     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3353
3354     /* classes product key exists */
3355     sz = MAX_PATH;
3356     lstrcpyA(buf, "apple");
3357     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3358     ok(r == ERROR_UNKNOWN_PROPERTY,
3359        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3360     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3361     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3362
3363     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3364     lstrcatA(keypath, usersid);
3365     lstrcatA(keypath, "\\Products\\");
3366     lstrcatA(keypath, prod_squashed);
3367
3368     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3369     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3370
3371     /* local user product key exists */
3372     sz = MAX_PATH;
3373     lstrcpyA(buf, "apple");
3374     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3375     ok(r == ERROR_UNKNOWN_PROPERTY,
3376        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3377     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3378     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3379
3380     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3382
3383     /* InstallProperties key exists */
3384     sz = MAX_PATH;
3385     lstrcpyA(buf, "apple");
3386     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3387     ok(r == ERROR_UNKNOWN_PROPERTY,
3388        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3389     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3390     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3391
3392     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3393     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3394     RegCloseKey(propkey);
3395     RegCloseKey(localkey);
3396
3397     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3398     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3399     lstrcatA(keypath, prod_squashed);
3400
3401     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3403
3404     /* Local System product key exists */
3405     sz = MAX_PATH;
3406     lstrcpyA(buf, "apple");
3407     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3408     ok(r == ERROR_UNKNOWN_PROPERTY,
3409         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3410     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3411     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3412
3413     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3415
3416     /* InstallProperties key exists */
3417     sz = MAX_PATH;
3418     lstrcpyA(buf, "apple");
3419     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3420     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3421     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3422     ok(sz == 0, "Expected 0, got %d\n", sz);
3423
3424     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3426
3427     /* HelpLink value exists */
3428     sz = MAX_PATH;
3429     lstrcpyA(buf, "apple");
3430     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3431     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3432     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3433     ok(sz == 4, "Expected 4, got %d\n", sz);
3434
3435     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3436                          (const BYTE *)&val, sizeof(DWORD));
3437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3438
3439     /* HelpLink type is REG_DWORD */
3440     sz = MAX_PATH;
3441     lstrcpyA(buf, "apple");
3442     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3444     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3445     ok(sz == 2, "Expected 2, got %d\n", sz);
3446
3447     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3449
3450     /* DisplayName value exists */
3451     sz = MAX_PATH;
3452     lstrcpyA(buf, "apple");
3453     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3455     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3456     ok(sz == 4, "Expected 4, got %d\n", sz);
3457
3458     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3459                          (const BYTE *)&val, sizeof(DWORD));
3460     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3461
3462     /* DisplayName type is REG_DWORD */
3463     sz = MAX_PATH;
3464     lstrcpyA(buf, "apple");
3465     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3466     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3467     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3468     ok(sz == 2, "Expected 2, got %d\n", sz);
3469
3470     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3472
3473     /* DisplayVersion value exists */
3474     sz = MAX_PATH;
3475     lstrcpyA(buf, "apple");
3476     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3477     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3478     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3479     ok(sz == 5, "Expected 5, got %d\n", sz);
3480
3481     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3482                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3484
3485     /* DisplayVersion type is REG_DWORD */
3486     sz = MAX_PATH;
3487     lstrcpyA(buf, "apple");
3488     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3489     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3490     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3491     ok(sz == 2, "Expected 2, got %d\n", sz);
3492
3493     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3495
3496     /* HelpTelephone value exists */
3497     sz = MAX_PATH;
3498     lstrcpyA(buf, "apple");
3499     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3501     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3502     ok(sz == 4, "Expected 4, got %d\n", sz);
3503
3504     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3505                          (const BYTE *)&val, sizeof(DWORD));
3506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3507
3508     /* HelpTelephone type is REG_DWORD */
3509     sz = MAX_PATH;
3510     lstrcpyA(buf, "apple");
3511     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3512     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3513     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3514     ok(sz == 2, "Expected 2, got %d\n", sz);
3515
3516     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3518
3519     /* InstallLocation value exists */
3520     sz = MAX_PATH;
3521     lstrcpyA(buf, "apple");
3522     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3524     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3525     ok(sz == 3, "Expected 3, got %d\n", sz);
3526
3527     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3528                          (const BYTE *)&val, sizeof(DWORD));
3529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3530
3531     /* InstallLocation type is REG_DWORD */
3532     sz = MAX_PATH;
3533     lstrcpyA(buf, "apple");
3534     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3535     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3536     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3537     ok(sz == 2, "Expected 2, got %d\n", sz);
3538
3539     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3541
3542     /* InstallSource value exists */
3543     sz = MAX_PATH;
3544     lstrcpyA(buf, "apple");
3545     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3546     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3547     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3548     ok(sz == 6, "Expected 6, got %d\n", sz);
3549
3550     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3551                          (const BYTE *)&val, sizeof(DWORD));
3552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3553
3554     /* InstallSource type is REG_DWORD */
3555     sz = MAX_PATH;
3556     lstrcpyA(buf, "apple");
3557     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3558     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3559     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3560     ok(sz == 2, "Expected 2, got %d\n", sz);
3561
3562     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3564
3565     /* InstallDate value exists */
3566     sz = MAX_PATH;
3567     lstrcpyA(buf, "apple");
3568     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3569     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3570     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3571     ok(sz == 4, "Expected 4, got %d\n", sz);
3572
3573     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3574                          (const BYTE *)&val, sizeof(DWORD));
3575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3576
3577     /* InstallDate type is REG_DWORD */
3578     sz = MAX_PATH;
3579     lstrcpyA(buf, "apple");
3580     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3582     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3583     ok(sz == 2, "Expected 2, got %d\n", sz);
3584
3585     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3587
3588     /* Publisher value exists */
3589     sz = MAX_PATH;
3590     lstrcpyA(buf, "apple");
3591     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3592     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3593     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3594     ok(sz == 3, "Expected 3, got %d\n", sz);
3595
3596     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3597                          (const BYTE *)&val, sizeof(DWORD));
3598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3599
3600     /* Publisher type is REG_DWORD */
3601     sz = MAX_PATH;
3602     lstrcpyA(buf, "apple");
3603     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3604     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3605     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3606     ok(sz == 2, "Expected 2, got %d\n", sz);
3607
3608     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3609     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3610
3611     /* LocalPackage value exists */
3612     sz = MAX_PATH;
3613     lstrcpyA(buf, "apple");
3614     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3615     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3616     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3617     ok(sz == 4, "Expected 4, got %d\n", sz);
3618
3619     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3620                          (const BYTE *)&val, sizeof(DWORD));
3621     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3622
3623     /* LocalPackage type is REG_DWORD */
3624     sz = MAX_PATH;
3625     lstrcpyA(buf, "apple");
3626     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3627     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3628     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3629     ok(sz == 2, "Expected 2, got %d\n", sz);
3630
3631     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3632     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3633
3634     /* UrlInfoAbout value exists */
3635     sz = MAX_PATH;
3636     lstrcpyA(buf, "apple");
3637     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3638     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3639     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3640     ok(sz == 5, "Expected 5, got %d\n", sz);
3641
3642     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3643                          (const BYTE *)&val, sizeof(DWORD));
3644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3645
3646     /* UrlInfoAbout type is REG_DWORD */
3647     sz = MAX_PATH;
3648     lstrcpyA(buf, "apple");
3649     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3650     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3651     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3652     ok(sz == 2, "Expected 2, got %d\n", sz);
3653
3654     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3656
3657     /* UrlUpdateInfo value exists */
3658     sz = MAX_PATH;
3659     lstrcpyA(buf, "apple");
3660     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3662     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3663     ok(sz == 4, "Expected 4, got %d\n", sz);
3664
3665     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3666                          (const BYTE *)&val, sizeof(DWORD));
3667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3668
3669     /* UrlUpdateInfo type is REG_DWORD */
3670     sz = MAX_PATH;
3671     lstrcpyA(buf, "apple");
3672     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3673     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3674     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3675     ok(sz == 2, "Expected 2, got %d\n", sz);
3676
3677     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3679
3680     /* VersionMinor value exists */
3681     sz = MAX_PATH;
3682     lstrcpyA(buf, "apple");
3683     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3684     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3685     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3686     ok(sz == 1, "Expected 1, got %d\n", sz);
3687
3688     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3689                          (const BYTE *)&val, sizeof(DWORD));
3690     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3691
3692     /* VersionMinor type is REG_DWORD */
3693     sz = MAX_PATH;
3694     lstrcpyA(buf, "apple");
3695     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3696     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3697     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3698     ok(sz == 2, "Expected 2, got %d\n", sz);
3699
3700     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3702
3703     /* VersionMajor value exists */
3704     sz = MAX_PATH;
3705     lstrcpyA(buf, "apple");
3706     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3708     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3709     ok(sz == 1, "Expected 1, got %d\n", sz);
3710
3711     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3712                          (const BYTE *)&val, sizeof(DWORD));
3713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3714
3715     /* VersionMajor type is REG_DWORD */
3716     sz = MAX_PATH;
3717     lstrcpyA(buf, "apple");
3718     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3719     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3720     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3721     ok(sz == 2, "Expected 2, got %d\n", sz);
3722
3723     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3725
3726     /* ProductID value exists */
3727     sz = MAX_PATH;
3728     lstrcpyA(buf, "apple");
3729     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3730     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3731     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3732     ok(sz == 2, "Expected 2, got %d\n", sz);
3733
3734     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3735                          (const BYTE *)&val, sizeof(DWORD));
3736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3737
3738     /* ProductID type is REG_DWORD */
3739     sz = MAX_PATH;
3740     lstrcpyA(buf, "apple");
3741     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3742     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3743     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3744     ok(sz == 2, "Expected 2, got %d\n", sz);
3745
3746     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3748
3749     /* RegCompany value exists */
3750     sz = MAX_PATH;
3751     lstrcpyA(buf, "apple");
3752     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3754     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3755     ok(sz == 4, "Expected 4, got %d\n", sz);
3756
3757     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3758                          (const BYTE *)&val, sizeof(DWORD));
3759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3760
3761     /* RegCompany type is REG_DWORD */
3762     sz = MAX_PATH;
3763     lstrcpyA(buf, "apple");
3764     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3765     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3766     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3767     ok(sz == 2, "Expected 2, got %d\n", sz);
3768
3769     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3771
3772     /* RegOwner value exists */
3773     sz = MAX_PATH;
3774     lstrcpyA(buf, "apple");
3775     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3777     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3778     ok(sz == 3, "Expected 3, got %d\n", sz);
3779
3780     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3781                          (const BYTE *)&val, sizeof(DWORD));
3782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3783
3784     /* RegOwner type is REG_DWORD */
3785     sz = MAX_PATH;
3786     lstrcpyA(buf, "apple");
3787     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3788     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3789     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3790     ok(sz == 2, "Expected 2, got %d\n", sz);
3791
3792     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3794
3795     /* InstanceType value exists */
3796     sz = MAX_PATH;
3797     lstrcpyA(buf, "apple");
3798     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3799     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3800     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3801     ok(sz == 0, "Expected 0, got %d\n", sz);
3802
3803     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3804                          (const BYTE *)&val, sizeof(DWORD));
3805     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3806
3807     /* InstanceType type is REG_DWORD */
3808     sz = MAX_PATH;
3809     lstrcpyA(buf, "apple");
3810     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3812     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3813     ok(sz == 0, "Expected 0, got %d\n", sz);
3814
3815     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3816     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3817
3818     /* InstanceType value exists */
3819     sz = MAX_PATH;
3820     lstrcpyA(buf, "apple");
3821     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3822     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3823     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3824     ok(sz == 4, "Expected 4, got %d\n", sz);
3825
3826     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3827                          (const BYTE *)&val, sizeof(DWORD));
3828     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3829
3830     /* InstanceType type is REG_DWORD */
3831     sz = MAX_PATH;
3832     lstrcpyA(buf, "apple");
3833     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3835     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3836     ok(sz == 2, "Expected 2, got %d\n", sz);
3837
3838     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3840
3841     /* Transforms value exists */
3842     sz = MAX_PATH;
3843     lstrcpyA(buf, "apple");
3844     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3845     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3846     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3847     ok(sz == 0, "Expected 0, got %d\n", sz);
3848
3849     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3850                          (const BYTE *)&val, sizeof(DWORD));
3851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3852
3853     /* Transforms type is REG_DWORD */
3854     sz = MAX_PATH;
3855     lstrcpyA(buf, "apple");
3856     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3858     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3859     ok(sz == 0, "Expected 0, got %d\n", sz);
3860
3861     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3863
3864     /* Transforms value exists */
3865     sz = MAX_PATH;
3866     lstrcpyA(buf, "apple");
3867     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3868     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3869     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3870     ok(sz == 6, "Expected 6, got %d\n", sz);
3871
3872     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3873                          (const BYTE *)&val, sizeof(DWORD));
3874     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3875
3876     /* Transforms type is REG_DWORD */
3877     sz = MAX_PATH;
3878     lstrcpyA(buf, "apple");
3879     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3881     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3882     ok(sz == 2, "Expected 2, got %d\n", sz);
3883
3884     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3886
3887     /* Language value exists */
3888     sz = MAX_PATH;
3889     lstrcpyA(buf, "apple");
3890     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3892     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3893     ok(sz == 0, "Expected 0, got %d\n", sz);
3894
3895     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3896                          (const BYTE *)&val, sizeof(DWORD));
3897     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3898
3899     /* Language type is REG_DWORD */
3900     sz = MAX_PATH;
3901     lstrcpyA(buf, "apple");
3902     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3903     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3904     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3905     ok(sz == 0, "Expected 0, got %d\n", sz);
3906
3907     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3909
3910     /* Language value exists */
3911     sz = MAX_PATH;
3912     lstrcpyA(buf, "apple");
3913     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3914     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3915     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3916     ok(sz == 4, "Expected 4, got %d\n", sz);
3917
3918     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3919                          (const BYTE *)&val, sizeof(DWORD));
3920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3921
3922     /* Language type is REG_DWORD */
3923     sz = MAX_PATH;
3924     lstrcpyA(buf, "apple");
3925     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3927     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3928     ok(sz == 2, "Expected 2, got %d\n", sz);
3929
3930     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3932
3933     /* ProductName value exists */
3934     sz = MAX_PATH;
3935     lstrcpyA(buf, "apple");
3936     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3938     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3939     ok(sz == 0, "Expected 0, got %d\n", sz);
3940
3941     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3942                          (const BYTE *)&val, sizeof(DWORD));
3943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3944
3945     /* ProductName type is REG_DWORD */
3946     sz = MAX_PATH;
3947     lstrcpyA(buf, "apple");
3948     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3950     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3951     ok(sz == 0, "Expected 0, got %d\n", sz);
3952
3953     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3955
3956     /* ProductName value exists */
3957     sz = MAX_PATH;
3958     lstrcpyA(buf, "apple");
3959     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3960     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3961     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3962     ok(sz == 4, "Expected 4, got %d\n", sz);
3963
3964     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3965                          (const BYTE *)&val, sizeof(DWORD));
3966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3967
3968     /* ProductName type is REG_DWORD */
3969     sz = MAX_PATH;
3970     lstrcpyA(buf, "apple");
3971     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3972     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3973     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3974     ok(sz == 2, "Expected 2, got %d\n", sz);
3975
3976     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3978
3979     /* Assignment value exists */
3980     sz = MAX_PATH;
3981     lstrcpyA(buf, "apple");
3982     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3984     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3985     ok(sz == 0, "Expected 0, got %d\n", sz);
3986
3987     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3988                          (const BYTE *)&val, sizeof(DWORD));
3989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3990
3991     /* Assignment type is REG_DWORD */
3992     sz = MAX_PATH;
3993     lstrcpyA(buf, "apple");
3994     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3995     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3996     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3997     ok(sz == 0, "Expected 0, got %d\n", sz);
3998
3999     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
4000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4001
4002     /* Assignment value exists */
4003     sz = MAX_PATH;
4004     lstrcpyA(buf, "apple");
4005     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4006     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4007     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
4008     ok(sz == 2, "Expected 2, got %d\n", sz);
4009
4010     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
4011                          (const BYTE *)&val, sizeof(DWORD));
4012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4013
4014     /* Assignment type is REG_DWORD */
4015     sz = MAX_PATH;
4016     lstrcpyA(buf, "apple");
4017     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4019     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4020     ok(sz == 2, "Expected 2, got %d\n", sz);
4021
4022     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4023     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4024
4025     /* PackageCode value exists */
4026     sz = MAX_PATH;
4027     lstrcpyA(buf, "apple");
4028     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4030     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4031     ok(sz == 0, "Expected 0, got %d\n", sz);
4032
4033     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
4034                          (const BYTE *)&val, sizeof(DWORD));
4035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4036
4037     /* PackageCode type is REG_DWORD */
4038     sz = MAX_PATH;
4039     lstrcpyA(buf, "apple");
4040     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4042     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4043     ok(sz == 0, "Expected 0, got %d\n", sz);
4044
4045     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4046     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4047
4048     /* PackageCode value exists */
4049     sz = MAX_PATH;
4050     lstrcpyA(buf, "apple");
4051     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4052     ok(r == ERROR_BAD_CONFIGURATION,
4053        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4054     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
4055     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4056
4057     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
4058                          (const BYTE *)&val, sizeof(DWORD));
4059     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4060
4061     /* PackageCode type is REG_DWORD */
4062     sz = MAX_PATH;
4063     lstrcpyA(buf, "apple");
4064     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4066     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4067     ok(sz == 2, "Expected 2, got %d\n", sz);
4068
4069     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
4070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4071
4072     /* PackageCode value exists */
4073     sz = MAX_PATH;
4074     lstrcpyA(buf, "apple");
4075     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4076     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4077     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
4078     ok(sz == 38, "Expected 38, got %d\n", sz);
4079
4080     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4082
4083     /* Version value exists */
4084     sz = MAX_PATH;
4085     lstrcpyA(buf, "apple");
4086     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4087     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4088     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4089     ok(sz == 0, "Expected 0, got %d\n", sz);
4090
4091     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
4092                          (const BYTE *)&val, sizeof(DWORD));
4093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4094
4095     /* Version type is REG_DWORD */
4096     sz = MAX_PATH;
4097     lstrcpyA(buf, "apple");
4098     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4099     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4100     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4101     ok(sz == 0, "Expected 0, got %d\n", sz);
4102
4103     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4105
4106     /* Version value exists */
4107     sz = MAX_PATH;
4108     lstrcpyA(buf, "apple");
4109     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4110     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4111     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4112     ok(sz == 3, "Expected 3, got %d\n", sz);
4113
4114     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
4115                          (const BYTE *)&val, sizeof(DWORD));
4116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4117
4118     /* Version type is REG_DWORD */
4119     sz = MAX_PATH;
4120     lstrcpyA(buf, "apple");
4121     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4122     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4123     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4124     ok(sz == 2, "Expected 2, got %d\n", sz);
4125
4126     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4128
4129     /* ProductIcon value exists */
4130     sz = MAX_PATH;
4131     lstrcpyA(buf, "apple");
4132     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4133     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4134     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4135     ok(sz == 0, "Expected 0, got %d\n", sz);
4136
4137     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
4138                          (const BYTE *)&val, sizeof(DWORD));
4139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4140
4141     /* ProductIcon type is REG_DWORD */
4142     sz = MAX_PATH;
4143     lstrcpyA(buf, "apple");
4144     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4146     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4147     ok(sz == 0, "Expected 0, got %d\n", sz);
4148
4149     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4151
4152     /* ProductIcon value exists */
4153     sz = MAX_PATH;
4154     lstrcpyA(buf, "apple");
4155     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4156     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4157     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
4158     ok(sz == 3, "Expected 3, got %d\n", sz);
4159
4160     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
4161                          (const BYTE *)&val, sizeof(DWORD));
4162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4163
4164     /* ProductIcon type is REG_DWORD */
4165     sz = MAX_PATH;
4166     lstrcpyA(buf, "apple");
4167     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4168     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4169     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4170     ok(sz == 2, "Expected 2, got %d\n", sz);
4171
4172     /* SourceList key does not exist */
4173     sz = MAX_PATH;
4174     lstrcpyA(buf, "apple");
4175     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4176     ok(r == ERROR_UNKNOWN_PRODUCT,
4177        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4178     ok(!lstrcmpA(buf, "apple"),
4179        "Expected buf to be unchanged, got \"%s\"\n", buf);
4180     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
4181
4182     res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
4183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4184
4185     /* SourceList key exists, but PackageName val does not exist */
4186     sz = MAX_PATH;
4187     lstrcpyA(buf, "apple");
4188     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4189     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4190     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4191     ok(sz == 0, "Expected 0, got %d\n", sz);
4192
4193     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
4194     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4195
4196     /* PackageName val exists */
4197     sz = MAX_PATH;
4198     lstrcpyA(buf, "apple");
4199     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4201     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4202     ok(sz == 8, "Expected 8, got %d\n", sz);
4203
4204     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4205                          (const BYTE *)&val, sizeof(DWORD));
4206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4207
4208     /* PackageName type is REG_DWORD */
4209     sz = MAX_PATH;
4210     lstrcpyA(buf, "apple");
4211     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4213     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4214     ok(sz == 2, "Expected 2, got %d\n", sz);
4215
4216     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4218
4219     /* Authorized value exists */
4220     sz = MAX_PATH;
4221     lstrcpyA(buf, "apple");
4222     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4223     if (r != ERROR_UNKNOWN_PROPERTY)
4224     {
4225         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4226         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4227         ok(sz == 0, "Expected 0, got %d\n", sz);
4228     }
4229
4230     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4231                          (const BYTE *)&val, sizeof(DWORD));
4232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4233
4234     /* AuthorizedLUAApp type is REG_DWORD */
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(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4246     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4247
4248     /* Authorized value exists */
4249     sz = MAX_PATH;
4250     lstrcpyA(buf, "apple");
4251     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4252     if (r != ERROR_UNKNOWN_PROPERTY)
4253     {
4254         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4255         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4256         ok(sz == 4, "Expected 4, got %d\n", sz);
4257     }
4258
4259     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4260                          (const BYTE *)&val, sizeof(DWORD));
4261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4262
4263     /* AuthorizedLUAApp type is REG_DWORD */
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, "42"), "Expected \"42\", got \"%s\"\n", buf);
4271         ok(sz == 2, "Expected 2, got %d\n", sz);
4272     }
4273
4274     RegDeleteValueA(propkey, "HelpLink");
4275     RegDeleteValueA(propkey, "DisplayName");
4276     RegDeleteValueA(propkey, "DisplayVersion");
4277     RegDeleteValueA(propkey, "HelpTelephone");
4278     RegDeleteValueA(propkey, "InstallLocation");
4279     RegDeleteValueA(propkey, "InstallSource");
4280     RegDeleteValueA(propkey, "InstallDate");
4281     RegDeleteValueA(propkey, "Publisher");
4282     RegDeleteValueA(propkey, "LocalPackage");
4283     RegDeleteValueA(propkey, "UrlInfoAbout");
4284     RegDeleteValueA(propkey, "UrlUpdateInfo");
4285     RegDeleteValueA(propkey, "VersionMinor");
4286     RegDeleteValueA(propkey, "VersionMajor");
4287     RegDeleteValueA(propkey, "ProductID");
4288     RegDeleteValueA(propkey, "RegCompany");
4289     RegDeleteValueA(propkey, "RegOwner");
4290     RegDeleteValueA(propkey, "InstanceType");
4291     RegDeleteValueA(propkey, "Transforms");
4292     RegDeleteValueA(propkey, "Language");
4293     RegDeleteValueA(propkey, "ProductName");
4294     RegDeleteValueA(propkey, "Assignment");
4295     RegDeleteValueA(propkey, "PackageCode");
4296     RegDeleteValueA(propkey, "Version");
4297     RegDeleteValueA(propkey, "ProductIcon");
4298     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4299     delete_key(propkey, "", access & KEY_WOW64_64KEY);
4300     delete_key(localkey, "", access & KEY_WOW64_64KEY);
4301     RegDeleteValueA(prodkey, "InstanceType");
4302     RegDeleteValueA(prodkey, "Transforms");
4303     RegDeleteValueA(prodkey, "Language");
4304     RegDeleteValueA(prodkey, "ProductName");
4305     RegDeleteValueA(prodkey, "Assignment");
4306     RegDeleteValueA(prodkey, "PackageCode");
4307     RegDeleteValueA(prodkey, "Version");
4308     RegDeleteValueA(prodkey, "ProductIcon");
4309     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4310     RegDeleteValueA(source, "PackageName");
4311     delete_key(source, "", access & KEY_WOW64_64KEY);
4312     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4313     RegCloseKey(propkey);
4314     RegCloseKey(localkey);
4315     RegCloseKey(source);
4316     RegCloseKey(prodkey);
4317     LocalFree(usersid);
4318 }
4319
4320 static void test_MsiGetProductInfoEx(void)
4321 {
4322     UINT r;
4323     LONG res;
4324     HKEY propkey, userkey;
4325     HKEY prodkey, localkey;
4326     CHAR prodcode[MAX_PATH];
4327     CHAR prod_squashed[MAX_PATH];
4328     CHAR packcode[MAX_PATH];
4329     CHAR pack_squashed[MAX_PATH];
4330     CHAR buf[MAX_PATH];
4331     CHAR keypath[MAX_PATH];
4332     LPSTR usersid;
4333     DWORD sz;
4334     REGSAM access = KEY_ALL_ACCESS;
4335
4336     if (!pMsiGetProductInfoExA)
4337     {
4338         win_skip("MsiGetProductInfoExA is not available\n");
4339         return;
4340     }
4341
4342     create_test_guid(prodcode, prod_squashed);
4343     create_test_guid(packcode, pack_squashed);
4344     usersid = get_user_sid();
4345
4346     if (is_wow64)
4347         access |= KEY_WOW64_64KEY;
4348
4349     /* NULL szProductCode */
4350     sz = MAX_PATH;
4351     lstrcpyA(buf, "apple");
4352     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4353                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4354     ok(r == ERROR_INVALID_PARAMETER,
4355        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4358
4359     /* empty szProductCode */
4360     sz = MAX_PATH;
4361     lstrcpyA(buf, "apple");
4362     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4363                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4364     ok(r == ERROR_INVALID_PARAMETER,
4365        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4366     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4367     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4368
4369     /* garbage szProductCode */
4370     sz = MAX_PATH;
4371     lstrcpyA(buf, "apple");
4372     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4373                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4374     ok(r == ERROR_INVALID_PARAMETER,
4375        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4376     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4377     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4378
4379     /* guid without brackets */
4380     sz = MAX_PATH;
4381     lstrcpyA(buf, "apple");
4382     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4383                               MSIINSTALLCONTEXT_USERUNMANAGED,
4384                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4385     ok(r == ERROR_INVALID_PARAMETER,
4386        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4387     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4388     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4389
4390     /* guid with brackets */
4391     sz = MAX_PATH;
4392     lstrcpyA(buf, "apple");
4393     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4394                               MSIINSTALLCONTEXT_USERUNMANAGED,
4395                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4396     ok(r == ERROR_UNKNOWN_PRODUCT,
4397        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4398     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4399     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4400
4401     /* szValue is non-NULL while pcchValue is NULL */
4402     lstrcpyA(buf, "apple");
4403     r = pMsiGetProductInfoExA(prodcode, usersid,
4404                               MSIINSTALLCONTEXT_USERUNMANAGED,
4405                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4406     ok(r == ERROR_INVALID_PARAMETER,
4407        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4408     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4409
4410     /* dwContext is out of range */
4411     sz = MAX_PATH;
4412     lstrcpyA(buf, "apple");
4413     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4414                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4415     ok(r == ERROR_INVALID_PARAMETER,
4416        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4417     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4418     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4419
4420     /* szProperty is NULL */
4421     sz = MAX_PATH;
4422     lstrcpyA(buf, "apple");
4423     r = pMsiGetProductInfoExA(prodcode, usersid,
4424                               MSIINSTALLCONTEXT_USERUNMANAGED,
4425                               NULL, buf, &sz);
4426     ok(r == ERROR_INVALID_PARAMETER,
4427        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4428     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4429     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4430
4431     /* szProperty is empty */
4432     sz = MAX_PATH;
4433     lstrcpyA(buf, "apple");
4434     r = pMsiGetProductInfoExA(prodcode, usersid,
4435                               MSIINSTALLCONTEXT_USERUNMANAGED,
4436                               "", buf, &sz);
4437     ok(r == ERROR_INVALID_PARAMETER,
4438        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4439     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4440     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4441
4442     /* szProperty is not a valid property */
4443     sz = MAX_PATH;
4444     lstrcpyA(buf, "apple");
4445     r = pMsiGetProductInfoExA(prodcode, usersid,
4446                               MSIINSTALLCONTEXT_USERUNMANAGED,
4447                               "notvalid", buf, &sz);
4448     ok(r == ERROR_UNKNOWN_PRODUCT,
4449        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4450     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4451     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4452
4453     /* same length as guid, but random */
4454     sz = MAX_PATH;
4455     lstrcpyA(buf, "apple");
4456     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4457                               MSIINSTALLCONTEXT_USERUNMANAGED,
4458                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4459     ok(r == ERROR_INVALID_PARAMETER,
4460        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4461     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4462     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4463
4464     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4465
4466     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4467     lstrcatA(keypath, usersid);
4468     lstrcatA(keypath, "\\Products\\");
4469     lstrcatA(keypath, prod_squashed);
4470
4471     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4472     if (res == ERROR_ACCESS_DENIED)
4473     {
4474         skip("Not enough rights to perform tests\n");
4475         LocalFree(usersid);
4476         return;
4477     }
4478     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4479
4480     /* local user product key exists */
4481     sz = MAX_PATH;
4482     lstrcpyA(buf, "apple");
4483     r = pMsiGetProductInfoExA(prodcode, usersid,
4484                               MSIINSTALLCONTEXT_USERUNMANAGED,
4485                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4486     ok(r == ERROR_UNKNOWN_PRODUCT,
4487        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4488     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4489     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4490
4491     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4493
4494     /* InstallProperties key exists */
4495     sz = MAX_PATH;
4496     lstrcpyA(buf, "apple");
4497     r = pMsiGetProductInfoExA(prodcode, usersid,
4498                               MSIINSTALLCONTEXT_USERUNMANAGED,
4499                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4500     ok(r == ERROR_UNKNOWN_PRODUCT,
4501        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4502     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4503     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4504
4505     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4507
4508     /* LocalPackage value exists */
4509     sz = MAX_PATH;
4510     lstrcpyA(buf, "apple");
4511     r = pMsiGetProductInfoExA(prodcode, usersid,
4512                               MSIINSTALLCONTEXT_USERUNMANAGED,
4513                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4514     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4515     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4516     ok(sz == 1, "Expected 1, got %d\n", sz);
4517
4518     RegDeleteValueA(propkey, "LocalPackage");
4519
4520     /* LocalPackage value must exist */
4521     sz = MAX_PATH;
4522     lstrcpyA(buf, "apple");
4523     r = pMsiGetProductInfoExA(prodcode, usersid,
4524                               MSIINSTALLCONTEXT_USERUNMANAGED,
4525                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4526     ok(r == ERROR_UNKNOWN_PRODUCT,
4527        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4528     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4529     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4530
4531     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4533
4534     /* LocalPackage exists, but HelpLink does not exist */
4535     sz = MAX_PATH;
4536     lstrcpyA(buf, "apple");
4537     r = pMsiGetProductInfoExA(prodcode, usersid,
4538                               MSIINSTALLCONTEXT_USERUNMANAGED,
4539                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4541     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4542     ok(sz == 0, "Expected 0, got %d\n", sz);
4543
4544     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4546
4547     /* HelpLink value exists */
4548     sz = MAX_PATH;
4549     lstrcpyA(buf, "apple");
4550     r = pMsiGetProductInfoExA(prodcode, usersid,
4551                               MSIINSTALLCONTEXT_USERUNMANAGED,
4552                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4553     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4554     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4555     ok(sz == 4, "Expected 4, got %d\n", sz);
4556
4557     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4558     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4559
4560     /* HelpTelephone value exists */
4561     sz = MAX_PATH;
4562     lstrcpyA(buf, "apple");
4563     r = pMsiGetProductInfoExA(prodcode, usersid,
4564                               MSIINSTALLCONTEXT_USERUNMANAGED,
4565                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4567     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4568     ok(sz == 5, "Expected 5, got %d\n", sz);
4569
4570     /* szValue and pcchValue are NULL */
4571     r = pMsiGetProductInfoExA(prodcode, usersid,
4572                               MSIINSTALLCONTEXT_USERUNMANAGED,
4573                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4574     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4575
4576     /* pcchValue is exactly 5 */
4577     sz = 5;
4578     lstrcpyA(buf, "apple");
4579     r = pMsiGetProductInfoExA(prodcode, usersid,
4580                               MSIINSTALLCONTEXT_USERUNMANAGED,
4581                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4582     ok(r == ERROR_MORE_DATA,
4583        "Expected ERROR_MORE_DATA, got %d\n", r);
4584     ok(sz == 10, "Expected 10, got %d\n", sz);
4585
4586     /* szValue is NULL, pcchValue is exactly 5 */
4587     sz = 5;
4588     r = pMsiGetProductInfoExA(prodcode, usersid,
4589                               MSIINSTALLCONTEXT_USERUNMANAGED,
4590                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4591     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4592     ok(sz == 10, "Expected 10, got %d\n", sz);
4593
4594     /* szValue is NULL, pcchValue is MAX_PATH */
4595     sz = MAX_PATH;
4596     r = pMsiGetProductInfoExA(prodcode, usersid,
4597                               MSIINSTALLCONTEXT_USERUNMANAGED,
4598                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4599     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4600     ok(sz == 10, "Expected 10, got %d\n", sz);
4601
4602     /* pcchValue is exactly 0 */
4603     sz = 0;
4604     lstrcpyA(buf, "apple");
4605     r = pMsiGetProductInfoExA(prodcode, usersid,
4606                               MSIINSTALLCONTEXT_USERUNMANAGED,
4607                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4608     ok(r == ERROR_MORE_DATA,
4609        "Expected ERROR_MORE_DATA, got %d\n", r);
4610     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4611     ok(sz == 10, "Expected 10, got %d\n", sz);
4612
4613     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4615
4616     /* szProperty is not a valid property */
4617     sz = MAX_PATH;
4618     lstrcpyA(buf, "apple");
4619     r = pMsiGetProductInfoExA(prodcode, usersid,
4620                               MSIINSTALLCONTEXT_USERUNMANAGED,
4621                               "notvalid", buf, &sz);
4622     ok(r == ERROR_UNKNOWN_PROPERTY,
4623        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4624     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4625     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4626
4627     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4629
4630     /* InstallDate value exists */
4631     sz = MAX_PATH;
4632     lstrcpyA(buf, "apple");
4633     r = pMsiGetProductInfoExA(prodcode, usersid,
4634                               MSIINSTALLCONTEXT_USERUNMANAGED,
4635                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4637     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4638     ok(sz == 4, "Expected 4, got %d\n", sz);
4639
4640     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4642
4643     /* DisplayName value exists */
4644     sz = MAX_PATH;
4645     lstrcpyA(buf, "apple");
4646     r = pMsiGetProductInfoExA(prodcode, usersid,
4647                               MSIINSTALLCONTEXT_USERUNMANAGED,
4648                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4649     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4650     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4651     ok(sz == 4, "Expected 4, got %d\n", sz);
4652
4653     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4655
4656     /* InstallLocation value exists */
4657     sz = MAX_PATH;
4658     lstrcpyA(buf, "apple");
4659     r = pMsiGetProductInfoExA(prodcode, usersid,
4660                               MSIINSTALLCONTEXT_USERUNMANAGED,
4661                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4663     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4664     ok(sz == 3, "Expected 3, got %d\n", sz);
4665
4666     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4668
4669     /* InstallSource value exists */
4670     sz = MAX_PATH;
4671     lstrcpyA(buf, "apple");
4672     r = pMsiGetProductInfoExA(prodcode, usersid,
4673                               MSIINSTALLCONTEXT_USERUNMANAGED,
4674                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4675     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4676     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4677     ok(sz == 6, "Expected 6, got %d\n", sz);
4678
4679     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4681
4682     /* LocalPackage value exists */
4683     sz = MAX_PATH;
4684     lstrcpyA(buf, "apple");
4685     r = pMsiGetProductInfoExA(prodcode, usersid,
4686                               MSIINSTALLCONTEXT_USERUNMANAGED,
4687                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4689     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4690     ok(sz == 5, "Expected 5, got %d\n", sz);
4691
4692     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4694
4695     /* Publisher value exists */
4696     sz = MAX_PATH;
4697     lstrcpyA(buf, "apple");
4698     r = pMsiGetProductInfoExA(prodcode, usersid,
4699                               MSIINSTALLCONTEXT_USERUNMANAGED,
4700                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4702     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4703     ok(sz == 3, "Expected 3, got %d\n", sz);
4704
4705     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4707
4708     /* URLInfoAbout value exists */
4709     sz = MAX_PATH;
4710     lstrcpyA(buf, "apple");
4711     r = pMsiGetProductInfoExA(prodcode, usersid,
4712                               MSIINSTALLCONTEXT_USERUNMANAGED,
4713                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4715     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4716     ok(sz == 5, "Expected 5, got %d\n", sz);
4717
4718     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4720
4721     /* URLUpdateInfo value exists */
4722     sz = MAX_PATH;
4723     lstrcpyA(buf, "apple");
4724     r = pMsiGetProductInfoExA(prodcode, usersid,
4725                               MSIINSTALLCONTEXT_USERUNMANAGED,
4726                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4727     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4728     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4729     ok(sz == 6, "Expected 6, got %d\n", sz);
4730
4731     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4732     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4733
4734     /* VersionMinor value exists */
4735     sz = MAX_PATH;
4736     lstrcpyA(buf, "apple");
4737     r = pMsiGetProductInfoExA(prodcode, usersid,
4738                               MSIINSTALLCONTEXT_USERUNMANAGED,
4739                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4741     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4742     ok(sz == 1, "Expected 1, got %d\n", sz);
4743
4744     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4746
4747     /* VersionMajor value exists */
4748     sz = MAX_PATH;
4749     lstrcpyA(buf, "apple");
4750     r = pMsiGetProductInfoExA(prodcode, usersid,
4751                               MSIINSTALLCONTEXT_USERUNMANAGED,
4752                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4754     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4755     ok(sz == 1, "Expected 1, got %d\n", sz);
4756
4757     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4759
4760     /* DisplayVersion value exists */
4761     sz = MAX_PATH;
4762     lstrcpyA(buf, "apple");
4763     r = pMsiGetProductInfoExA(prodcode, usersid,
4764                               MSIINSTALLCONTEXT_USERUNMANAGED,
4765                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4766     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4767     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4768     ok(sz == 5, "Expected 5, got %d\n", sz);
4769
4770     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4772
4773     /* ProductID value exists */
4774     sz = MAX_PATH;
4775     lstrcpyA(buf, "apple");
4776     r = pMsiGetProductInfoExA(prodcode, usersid,
4777                               MSIINSTALLCONTEXT_USERUNMANAGED,
4778                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4779     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4780     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4781     ok(sz == 2, "Expected 2, got %d\n", sz);
4782
4783     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4785
4786     /* RegCompany value exists */
4787     sz = MAX_PATH;
4788     lstrcpyA(buf, "apple");
4789     r = pMsiGetProductInfoExA(prodcode, usersid,
4790                               MSIINSTALLCONTEXT_USERUNMANAGED,
4791                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4793     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4794     ok(sz == 4, "Expected 4, got %d\n", sz);
4795
4796     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4798
4799     /* RegOwner value exists */
4800     sz = MAX_PATH;
4801     lstrcpyA(buf, "apple");
4802     r = pMsiGetProductInfoExA(prodcode, usersid,
4803                               MSIINSTALLCONTEXT_USERUNMANAGED,
4804                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4806     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4807     ok(sz == 5, "Expected 5, got %d\n", sz);
4808
4809     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4811
4812     /* Transforms value exists */
4813     sz = MAX_PATH;
4814     lstrcpyA(buf, "apple");
4815     r = pMsiGetProductInfoExA(prodcode, usersid,
4816                               MSIINSTALLCONTEXT_USERUNMANAGED,
4817                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4818     ok(r == ERROR_UNKNOWN_PRODUCT,
4819        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4820     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4821     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4822
4823     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4824     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4825
4826     /* Language value exists */
4827     sz = MAX_PATH;
4828     lstrcpyA(buf, "apple");
4829     r = pMsiGetProductInfoExA(prodcode, usersid,
4830                               MSIINSTALLCONTEXT_USERUNMANAGED,
4831                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4832     ok(r == ERROR_UNKNOWN_PRODUCT,
4833        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4834     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4835     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4836
4837     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4838     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4839
4840     /* ProductName value exists */
4841     sz = MAX_PATH;
4842     lstrcpyA(buf, "apple");
4843     r = pMsiGetProductInfoExA(prodcode, usersid,
4844                               MSIINSTALLCONTEXT_USERUNMANAGED,
4845                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4846     ok(r == ERROR_UNKNOWN_PRODUCT,
4847        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4848     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4849     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4850
4851     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4852     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4853
4854     /* FIXME */
4855
4856     /* AssignmentType value exists */
4857     sz = MAX_PATH;
4858     lstrcpyA(buf, "apple");
4859     r = pMsiGetProductInfoExA(prodcode, usersid,
4860                               MSIINSTALLCONTEXT_USERUNMANAGED,
4861                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4862     ok(r == ERROR_UNKNOWN_PRODUCT,
4863        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4864     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4865     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4866
4867     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4869
4870     /* PackageCode value exists */
4871     sz = MAX_PATH;
4872     lstrcpyA(buf, "apple");
4873     r = pMsiGetProductInfoExA(prodcode, usersid,
4874                               MSIINSTALLCONTEXT_USERUNMANAGED,
4875                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4876     ok(r == ERROR_UNKNOWN_PRODUCT,
4877        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4878     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4879     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4880
4881     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4883
4884     /* Version value exists */
4885     sz = MAX_PATH;
4886     lstrcpyA(buf, "apple");
4887     r = pMsiGetProductInfoExA(prodcode, usersid,
4888                               MSIINSTALLCONTEXT_USERUNMANAGED,
4889                               INSTALLPROPERTY_VERSION, buf, &sz);
4890     ok(r == ERROR_UNKNOWN_PRODUCT,
4891        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4892     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4893     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4894
4895     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4897
4898     /* ProductIcon value exists */
4899     sz = MAX_PATH;
4900     lstrcpyA(buf, "apple");
4901     r = pMsiGetProductInfoExA(prodcode, usersid,
4902                               MSIINSTALLCONTEXT_USERUNMANAGED,
4903                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4904     ok(r == ERROR_UNKNOWN_PRODUCT,
4905        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4906     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4907     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4908
4909     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4911
4912     /* PackageName value exists */
4913     sz = MAX_PATH;
4914     lstrcpyA(buf, "apple");
4915     r = pMsiGetProductInfoExA(prodcode, usersid,
4916                               MSIINSTALLCONTEXT_USERUNMANAGED,
4917                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4918     ok(r == ERROR_UNKNOWN_PRODUCT,
4919        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4920     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4921     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4922
4923     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4925
4926     /* AuthorizedLUAApp value exists */
4927     sz = MAX_PATH;
4928     lstrcpyA(buf, "apple");
4929     r = pMsiGetProductInfoExA(prodcode, usersid,
4930                               MSIINSTALLCONTEXT_USERUNMANAGED,
4931                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4932     ok(r == ERROR_UNKNOWN_PRODUCT,
4933        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4934     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4935     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4936
4937     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4938     RegDeleteValueA(propkey, "PackageName");
4939     RegDeleteValueA(propkey, "ProductIcon");
4940     RegDeleteValueA(propkey, "Version");
4941     RegDeleteValueA(propkey, "PackageCode");
4942     RegDeleteValueA(propkey, "AssignmentType");
4943     RegDeleteValueA(propkey, "ProductName");
4944     RegDeleteValueA(propkey, "Language");
4945     RegDeleteValueA(propkey, "Transforms");
4946     RegDeleteValueA(propkey, "RegOwner");
4947     RegDeleteValueA(propkey, "RegCompany");
4948     RegDeleteValueA(propkey, "ProductID");
4949     RegDeleteValueA(propkey, "DisplayVersion");
4950     RegDeleteValueA(propkey, "VersionMajor");
4951     RegDeleteValueA(propkey, "VersionMinor");
4952     RegDeleteValueA(propkey, "URLUpdateInfo");
4953     RegDeleteValueA(propkey, "URLInfoAbout");
4954     RegDeleteValueA(propkey, "Publisher");
4955     RegDeleteValueA(propkey, "LocalPackage");
4956     RegDeleteValueA(propkey, "InstallSource");
4957     RegDeleteValueA(propkey, "InstallLocation");
4958     RegDeleteValueA(propkey, "DisplayName");
4959     RegDeleteValueA(propkey, "InstallDate");
4960     RegDeleteValueA(propkey, "HelpTelephone");
4961     RegDeleteValueA(propkey, "HelpLink");
4962     RegDeleteValueA(propkey, "LocalPackage");
4963     RegDeleteKeyA(propkey, "");
4964     RegCloseKey(propkey);
4965     RegDeleteKeyA(localkey, "");
4966     RegCloseKey(localkey);
4967
4968     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4969     lstrcatA(keypath, usersid);
4970     lstrcatA(keypath, "\\Installer\\Products\\");
4971     lstrcatA(keypath, prod_squashed);
4972
4973     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
4974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4975
4976     /* user product key exists */
4977     sz = MAX_PATH;
4978     lstrcpyA(buf, "apple");
4979     r = pMsiGetProductInfoExA(prodcode, usersid,
4980                               MSIINSTALLCONTEXT_USERUNMANAGED,
4981                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4982     ok(r == ERROR_UNKNOWN_PRODUCT,
4983        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4984     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4985     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4986
4987     RegDeleteKeyA(userkey, "");
4988     RegCloseKey(userkey);
4989
4990     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4991     lstrcatA(keypath, prod_squashed);
4992
4993     res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4995
4996     sz = MAX_PATH;
4997     lstrcpyA(buf, "apple");
4998     r = pMsiGetProductInfoExA(prodcode, usersid,
4999                               MSIINSTALLCONTEXT_USERUNMANAGED,
5000                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5001     ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
5002     if (r == ERROR_UNKNOWN_PRODUCT)
5003     {
5004         win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
5005         delete_key(prodkey, "", access);
5006         RegCloseKey(prodkey);
5007         return;
5008     }
5009     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5010     ok(sz == 1, "Expected 1, got %d\n", sz);
5011
5012     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5014
5015     /* HelpLink value exists */
5016     sz = MAX_PATH;
5017     lstrcpyA(buf, "apple");
5018     r = pMsiGetProductInfoExA(prodcode, usersid,
5019                               MSIINSTALLCONTEXT_USERUNMANAGED,
5020                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5021     ok(r == ERROR_UNKNOWN_PROPERTY,
5022        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5023     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5024     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5025
5026     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5028
5029     /* HelpTelephone value exists */
5030     sz = MAX_PATH;
5031     lstrcpyA(buf, "apple");
5032     r = pMsiGetProductInfoExA(prodcode, usersid,
5033                               MSIINSTALLCONTEXT_USERUNMANAGED,
5034                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5035     ok(r == ERROR_UNKNOWN_PROPERTY,
5036        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5037     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5038     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5039
5040     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5042
5043     /* InstallDate value exists */
5044     sz = MAX_PATH;
5045     lstrcpyA(buf, "apple");
5046     r = pMsiGetProductInfoExA(prodcode, usersid,
5047                               MSIINSTALLCONTEXT_USERUNMANAGED,
5048                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5049     ok(r == ERROR_UNKNOWN_PROPERTY,
5050        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5051     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5052     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5053
5054     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5056
5057     /* DisplayName value exists */
5058     sz = MAX_PATH;
5059     lstrcpyA(buf, "apple");
5060     r = pMsiGetProductInfoExA(prodcode, usersid,
5061                               MSIINSTALLCONTEXT_USERUNMANAGED,
5062                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5063     ok(r == ERROR_UNKNOWN_PROPERTY,
5064        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5065     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5066     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5067
5068     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5069     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5070
5071     /* InstallLocation value exists */
5072     sz = MAX_PATH;
5073     lstrcpyA(buf, "apple");
5074     r = pMsiGetProductInfoExA(prodcode, usersid,
5075                               MSIINSTALLCONTEXT_USERUNMANAGED,
5076                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5077     ok(r == ERROR_UNKNOWN_PROPERTY,
5078        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5079     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5080     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5081
5082     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5084
5085     /* InstallSource value exists */
5086     sz = MAX_PATH;
5087     lstrcpyA(buf, "apple");
5088     r = pMsiGetProductInfoExA(prodcode, usersid,
5089                               MSIINSTALLCONTEXT_USERUNMANAGED,
5090                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5091     ok(r == ERROR_UNKNOWN_PROPERTY,
5092        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5093     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5094     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5095
5096     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5098
5099     /* LocalPackage value exists */
5100     sz = MAX_PATH;
5101     lstrcpyA(buf, "apple");
5102     r = pMsiGetProductInfoExA(prodcode, usersid,
5103                               MSIINSTALLCONTEXT_USERUNMANAGED,
5104                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5105     ok(r == ERROR_UNKNOWN_PROPERTY,
5106        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5107     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5108     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5109
5110     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5112
5113     /* Publisher value exists */
5114     sz = MAX_PATH;
5115     lstrcpyA(buf, "apple");
5116     r = pMsiGetProductInfoExA(prodcode, usersid,
5117                               MSIINSTALLCONTEXT_USERUNMANAGED,
5118                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5119     ok(r == ERROR_UNKNOWN_PROPERTY,
5120        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5121     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5122     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5123
5124     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5126
5127     /* URLInfoAbout value exists */
5128     sz = MAX_PATH;
5129     lstrcpyA(buf, "apple");
5130     r = pMsiGetProductInfoExA(prodcode, usersid,
5131                               MSIINSTALLCONTEXT_USERUNMANAGED,
5132                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5133     ok(r == ERROR_UNKNOWN_PROPERTY,
5134        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5135     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5136     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5137
5138     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5140
5141     /* URLUpdateInfo value exists */
5142     sz = MAX_PATH;
5143     lstrcpyA(buf, "apple");
5144     r = pMsiGetProductInfoExA(prodcode, usersid,
5145                               MSIINSTALLCONTEXT_USERUNMANAGED,
5146                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5147     ok(r == ERROR_UNKNOWN_PROPERTY,
5148        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5149     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5150     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5151
5152     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5153     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5154
5155     /* VersionMinor value exists */
5156     sz = MAX_PATH;
5157     lstrcpyA(buf, "apple");
5158     r = pMsiGetProductInfoExA(prodcode, usersid,
5159                               MSIINSTALLCONTEXT_USERUNMANAGED,
5160                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5161     ok(r == ERROR_UNKNOWN_PROPERTY,
5162        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5163     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5164     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5165
5166     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5168
5169     /* VersionMajor value exists */
5170     sz = MAX_PATH;
5171     lstrcpyA(buf, "apple");
5172     r = pMsiGetProductInfoExA(prodcode, usersid,
5173                               MSIINSTALLCONTEXT_USERUNMANAGED,
5174                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5175     ok(r == ERROR_UNKNOWN_PROPERTY,
5176        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5177     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5178     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5179
5180     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5181     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5182
5183     /* DisplayVersion value exists */
5184     sz = MAX_PATH;
5185     lstrcpyA(buf, "apple");
5186     r = pMsiGetProductInfoExA(prodcode, usersid,
5187                               MSIINSTALLCONTEXT_USERUNMANAGED,
5188                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5189     ok(r == ERROR_UNKNOWN_PROPERTY,
5190        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5191     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5192     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5193
5194     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5196
5197     /* ProductID value exists */
5198     sz = MAX_PATH;
5199     lstrcpyA(buf, "apple");
5200     r = pMsiGetProductInfoExA(prodcode, usersid,
5201                               MSIINSTALLCONTEXT_USERUNMANAGED,
5202                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5203     ok(r == ERROR_UNKNOWN_PROPERTY,
5204        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5205     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5206     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5207
5208     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5210
5211     /* RegCompany value exists */
5212     sz = MAX_PATH;
5213     lstrcpyA(buf, "apple");
5214     r = pMsiGetProductInfoExA(prodcode, usersid,
5215                               MSIINSTALLCONTEXT_USERUNMANAGED,
5216                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5217     ok(r == ERROR_UNKNOWN_PROPERTY,
5218        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5219     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5220     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5221
5222     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5224
5225     /* RegOwner value exists */
5226     sz = MAX_PATH;
5227     lstrcpyA(buf, "apple");
5228     r = pMsiGetProductInfoExA(prodcode, usersid,
5229                               MSIINSTALLCONTEXT_USERUNMANAGED,
5230                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5231     ok(r == ERROR_UNKNOWN_PROPERTY,
5232        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5233     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5234     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5235
5236     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5238
5239     /* Transforms value exists */
5240     sz = MAX_PATH;
5241     lstrcpyA(buf, "apple");
5242     r = pMsiGetProductInfoExA(prodcode, usersid,
5243                               MSIINSTALLCONTEXT_USERUNMANAGED,
5244                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5246     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5247     ok(sz == 5, "Expected 5, got %d\n", sz);
5248
5249     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5251
5252     /* Language value exists */
5253     sz = MAX_PATH;
5254     lstrcpyA(buf, "apple");
5255     r = pMsiGetProductInfoExA(prodcode, usersid,
5256                               MSIINSTALLCONTEXT_USERUNMANAGED,
5257                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5259     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5260     ok(sz == 4, "Expected 4, got %d\n", sz);
5261
5262     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5264
5265     /* ProductName value exists */
5266     sz = MAX_PATH;
5267     lstrcpyA(buf, "apple");
5268     r = pMsiGetProductInfoExA(prodcode, usersid,
5269                               MSIINSTALLCONTEXT_USERUNMANAGED,
5270                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5271     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5272     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5273     ok(sz == 4, "Expected 4, got %d\n", sz);
5274
5275     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5276     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5277
5278     /* FIXME */
5279
5280     /* AssignmentType value exists */
5281     sz = MAX_PATH;
5282     lstrcpyA(buf, "apple");
5283     r = pMsiGetProductInfoExA(prodcode, usersid,
5284                               MSIINSTALLCONTEXT_USERUNMANAGED,
5285                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5287     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5288     ok(sz == 0, "Expected 0, got %d\n", sz);
5289
5290     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5292
5293     /* FIXME */
5294
5295     /* PackageCode value exists */
5296     sz = MAX_PATH;
5297     lstrcpyA(buf, "apple");
5298     r = pMsiGetProductInfoExA(prodcode, usersid,
5299                               MSIINSTALLCONTEXT_USERUNMANAGED,
5300                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5301     todo_wine
5302     {
5303         ok(r == ERROR_BAD_CONFIGURATION,
5304            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5305         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5306         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5307     }
5308
5309     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5311
5312     /* Version value exists */
5313     sz = MAX_PATH;
5314     lstrcpyA(buf, "apple");
5315     r = pMsiGetProductInfoExA(prodcode, usersid,
5316                               MSIINSTALLCONTEXT_USERUNMANAGED,
5317                               INSTALLPROPERTY_VERSION, buf, &sz);
5318     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5319     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5320     ok(sz == 3, "Expected 3, got %d\n", sz);
5321
5322     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5324
5325     /* ProductIcon value exists */
5326     sz = MAX_PATH;
5327     lstrcpyA(buf, "apple");
5328     r = pMsiGetProductInfoExA(prodcode, usersid,
5329                               MSIINSTALLCONTEXT_USERUNMANAGED,
5330                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5331     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5332     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5333     ok(sz == 4, "Expected 4, got %d\n", sz);
5334
5335     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5337
5338     /* PackageName value exists */
5339     sz = MAX_PATH;
5340     lstrcpyA(buf, "apple");
5341     r = pMsiGetProductInfoExA(prodcode, usersid,
5342                               MSIINSTALLCONTEXT_USERUNMANAGED,
5343                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5344     todo_wine
5345     {
5346         ok(r == ERROR_UNKNOWN_PRODUCT,
5347            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5348         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5349         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5350     }
5351
5352     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5354
5355     /* AuthorizedLUAApp value exists */
5356     sz = MAX_PATH;
5357     lstrcpyA(buf, "apple");
5358     r = pMsiGetProductInfoExA(prodcode, usersid,
5359                               MSIINSTALLCONTEXT_USERUNMANAGED,
5360                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5361     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5362     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5363     ok(sz == 4, "Expected 4, got %d\n", sz);
5364
5365     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5366     RegDeleteValueA(prodkey, "PackageName");
5367     RegDeleteValueA(prodkey, "ProductIcon");
5368     RegDeleteValueA(prodkey, "Version");
5369     RegDeleteValueA(prodkey, "PackageCode");
5370     RegDeleteValueA(prodkey, "AssignmentType");
5371     RegDeleteValueA(prodkey, "ProductName");
5372     RegDeleteValueA(prodkey, "Language");
5373     RegDeleteValueA(prodkey, "Transforms");
5374     RegDeleteValueA(prodkey, "RegOwner");
5375     RegDeleteValueA(prodkey, "RegCompany");
5376     RegDeleteValueA(prodkey, "ProductID");
5377     RegDeleteValueA(prodkey, "DisplayVersion");
5378     RegDeleteValueA(prodkey, "VersionMajor");
5379     RegDeleteValueA(prodkey, "VersionMinor");
5380     RegDeleteValueA(prodkey, "URLUpdateInfo");
5381     RegDeleteValueA(prodkey, "URLInfoAbout");
5382     RegDeleteValueA(prodkey, "Publisher");
5383     RegDeleteValueA(prodkey, "LocalPackage");
5384     RegDeleteValueA(prodkey, "InstallSource");
5385     RegDeleteValueA(prodkey, "InstallLocation");
5386     RegDeleteValueA(prodkey, "DisplayName");
5387     RegDeleteValueA(prodkey, "InstallDate");
5388     RegDeleteValueA(prodkey, "HelpTelephone");
5389     RegDeleteValueA(prodkey, "HelpLink");
5390     RegDeleteValueA(prodkey, "LocalPackage");
5391     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5392     RegCloseKey(prodkey);
5393
5394     /* MSIINSTALLCONTEXT_USERMANAGED */
5395
5396     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5397     lstrcatA(keypath, usersid);
5398     lstrcatA(keypath, "\\Products\\");
5399     lstrcatA(keypath, prod_squashed);
5400
5401     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5403
5404     /* local user product key exists */
5405     sz = MAX_PATH;
5406     lstrcpyA(buf, "apple");
5407     r = pMsiGetProductInfoExA(prodcode, usersid,
5408                               MSIINSTALLCONTEXT_USERMANAGED,
5409                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5410     ok(r == ERROR_UNKNOWN_PRODUCT,
5411        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5412     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5413     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5414
5415     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5417
5418     /* InstallProperties key exists */
5419     sz = MAX_PATH;
5420     lstrcpyA(buf, "apple");
5421     r = pMsiGetProductInfoExA(prodcode, usersid,
5422                               MSIINSTALLCONTEXT_USERMANAGED,
5423                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5424     ok(r == ERROR_UNKNOWN_PRODUCT,
5425        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5426     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5427     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5428
5429     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5431
5432     /* ManagedLocalPackage value exists */
5433     sz = MAX_PATH;
5434     lstrcpyA(buf, "apple");
5435     r = pMsiGetProductInfoExA(prodcode, usersid,
5436                               MSIINSTALLCONTEXT_USERMANAGED,
5437                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5439     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5440     ok(sz == 1, "Expected 1, got %d\n", sz);
5441
5442     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5444
5445     /* HelpLink value exists */
5446     sz = MAX_PATH;
5447     lstrcpyA(buf, "apple");
5448     r = pMsiGetProductInfoExA(prodcode, usersid,
5449                               MSIINSTALLCONTEXT_USERMANAGED,
5450                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5452     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5453     ok(sz == 4, "Expected 4, got %d\n", sz);
5454
5455     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5457
5458     /* HelpTelephone value exists */
5459     sz = MAX_PATH;
5460     lstrcpyA(buf, "apple");
5461     r = pMsiGetProductInfoExA(prodcode, usersid,
5462                               MSIINSTALLCONTEXT_USERMANAGED,
5463                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5465     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5466     ok(sz == 5, "Expected 5, got %d\n", sz);
5467
5468     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5470
5471     /* InstallDate value exists */
5472     sz = MAX_PATH;
5473     lstrcpyA(buf, "apple");
5474     r = pMsiGetProductInfoExA(prodcode, usersid,
5475                               MSIINSTALLCONTEXT_USERMANAGED,
5476                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5477     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5478     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5479     ok(sz == 4, "Expected 4, got %d\n", sz);
5480
5481     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5482     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5483
5484     /* DisplayName value exists */
5485     sz = MAX_PATH;
5486     lstrcpyA(buf, "apple");
5487     r = pMsiGetProductInfoExA(prodcode, usersid,
5488                               MSIINSTALLCONTEXT_USERMANAGED,
5489                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5490     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5491     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5492     ok(sz == 4, "Expected 4, got %d\n", sz);
5493
5494     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5495     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5496
5497     /* InstallLocation value exists */
5498     sz = MAX_PATH;
5499     lstrcpyA(buf, "apple");
5500     r = pMsiGetProductInfoExA(prodcode, usersid,
5501                               MSIINSTALLCONTEXT_USERMANAGED,
5502                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5503     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5504     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5505     ok(sz == 3, "Expected 3, got %d\n", sz);
5506
5507     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5509
5510     /* InstallSource value exists */
5511     sz = MAX_PATH;
5512     lstrcpyA(buf, "apple");
5513     r = pMsiGetProductInfoExA(prodcode, usersid,
5514                               MSIINSTALLCONTEXT_USERMANAGED,
5515                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5517     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5518     ok(sz == 6, "Expected 6, got %d\n", sz);
5519
5520     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5521     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5522
5523     /* LocalPackage value exists */
5524     sz = MAX_PATH;
5525     lstrcpyA(buf, "apple");
5526     r = pMsiGetProductInfoExA(prodcode, usersid,
5527                               MSIINSTALLCONTEXT_USERMANAGED,
5528                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5530     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5531     ok(sz == 5, "Expected 5, got %d\n", sz);
5532
5533     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5535
5536     /* Publisher value exists */
5537     sz = MAX_PATH;
5538     lstrcpyA(buf, "apple");
5539     r = pMsiGetProductInfoExA(prodcode, usersid,
5540                               MSIINSTALLCONTEXT_USERMANAGED,
5541                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5543     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5544     ok(sz == 3, "Expected 3, got %d\n", sz);
5545
5546     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5548
5549     /* URLInfoAbout value exists */
5550     sz = MAX_PATH;
5551     lstrcpyA(buf, "apple");
5552     r = pMsiGetProductInfoExA(prodcode, usersid,
5553                               MSIINSTALLCONTEXT_USERMANAGED,
5554                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5556     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5557     ok(sz == 5, "Expected 5, got %d\n", sz);
5558
5559     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5561
5562     /* URLUpdateInfo value exists */
5563     sz = MAX_PATH;
5564     lstrcpyA(buf, "apple");
5565     r = pMsiGetProductInfoExA(prodcode, usersid,
5566                               MSIINSTALLCONTEXT_USERMANAGED,
5567                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5568     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5569     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5570     ok(sz == 6, "Expected 6, got %d\n", sz);
5571
5572     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5574
5575     /* VersionMinor value exists */
5576     sz = MAX_PATH;
5577     lstrcpyA(buf, "apple");
5578     r = pMsiGetProductInfoExA(prodcode, usersid,
5579                               MSIINSTALLCONTEXT_USERMANAGED,
5580                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5582     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5583     ok(sz == 1, "Expected 1, got %d\n", sz);
5584
5585     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5587
5588     /* VersionMajor value exists */
5589     sz = MAX_PATH;
5590     lstrcpyA(buf, "apple");
5591     r = pMsiGetProductInfoExA(prodcode, usersid,
5592                               MSIINSTALLCONTEXT_USERMANAGED,
5593                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5595     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5596     ok(sz == 1, "Expected 1, got %d\n", sz);
5597
5598     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5600
5601     /* DisplayVersion value exists */
5602     sz = MAX_PATH;
5603     lstrcpyA(buf, "apple");
5604     r = pMsiGetProductInfoExA(prodcode, usersid,
5605                               MSIINSTALLCONTEXT_USERMANAGED,
5606                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5608     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5609     ok(sz == 5, "Expected 5, got %d\n", sz);
5610
5611     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5613
5614     /* ProductID value exists */
5615     sz = MAX_PATH;
5616     lstrcpyA(buf, "apple");
5617     r = pMsiGetProductInfoExA(prodcode, usersid,
5618                               MSIINSTALLCONTEXT_USERMANAGED,
5619                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5621     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5622     ok(sz == 2, "Expected 2, got %d\n", sz);
5623
5624     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5626
5627     /* RegCompany value exists */
5628     sz = MAX_PATH;
5629     lstrcpyA(buf, "apple");
5630     r = pMsiGetProductInfoExA(prodcode, usersid,
5631                               MSIINSTALLCONTEXT_USERMANAGED,
5632                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5634     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5635     ok(sz == 4, "Expected 4, got %d\n", sz);
5636
5637     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5639
5640     /* RegOwner value exists */
5641     sz = MAX_PATH;
5642     lstrcpyA(buf, "apple");
5643     r = pMsiGetProductInfoExA(prodcode, usersid,
5644                               MSIINSTALLCONTEXT_USERMANAGED,
5645                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5647     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5648     ok(sz == 5, "Expected 5, got %d\n", sz);
5649
5650     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5652
5653     /* Transforms value exists */
5654     sz = MAX_PATH;
5655     lstrcpyA(buf, "apple");
5656     r = pMsiGetProductInfoExA(prodcode, usersid,
5657                               MSIINSTALLCONTEXT_USERMANAGED,
5658                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5659     ok(r == ERROR_UNKNOWN_PRODUCT,
5660        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5661     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5662     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5663
5664     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5666
5667     /* Language value exists */
5668     sz = MAX_PATH;
5669     lstrcpyA(buf, "apple");
5670     r = pMsiGetProductInfoExA(prodcode, usersid,
5671                               MSIINSTALLCONTEXT_USERMANAGED,
5672                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5673     ok(r == ERROR_UNKNOWN_PRODUCT,
5674        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5675     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5676     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5677
5678     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5680
5681     /* ProductName value exists */
5682     sz = MAX_PATH;
5683     lstrcpyA(buf, "apple");
5684     r = pMsiGetProductInfoExA(prodcode, usersid,
5685                               MSIINSTALLCONTEXT_USERMANAGED,
5686                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5687     ok(r == ERROR_UNKNOWN_PRODUCT,
5688        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5689     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5690     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5691
5692     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5694
5695     /* FIXME */
5696
5697     /* AssignmentType value exists */
5698     sz = MAX_PATH;
5699     lstrcpyA(buf, "apple");
5700     r = pMsiGetProductInfoExA(prodcode, usersid,
5701                               MSIINSTALLCONTEXT_USERMANAGED,
5702                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5703     ok(r == ERROR_UNKNOWN_PRODUCT,
5704        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5705     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5706     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5707
5708     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5710
5711     /* PackageCode value exists */
5712     sz = MAX_PATH;
5713     lstrcpyA(buf, "apple");
5714     r = pMsiGetProductInfoExA(prodcode, usersid,
5715                               MSIINSTALLCONTEXT_USERMANAGED,
5716                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5717     ok(r == ERROR_UNKNOWN_PRODUCT,
5718        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5719     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5720     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5721
5722     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5723     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5724
5725     /* Version value exists */
5726     sz = MAX_PATH;
5727     lstrcpyA(buf, "apple");
5728     r = pMsiGetProductInfoExA(prodcode, usersid,
5729                               MSIINSTALLCONTEXT_USERMANAGED,
5730                               INSTALLPROPERTY_VERSION, buf, &sz);
5731     ok(r == ERROR_UNKNOWN_PRODUCT,
5732        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5733     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5734     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5735
5736     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5738
5739     /* ProductIcon value exists */
5740     sz = MAX_PATH;
5741     lstrcpyA(buf, "apple");
5742     r = pMsiGetProductInfoExA(prodcode, usersid,
5743                               MSIINSTALLCONTEXT_USERMANAGED,
5744                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5745     ok(r == ERROR_UNKNOWN_PRODUCT,
5746        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5747     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5748     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5749
5750     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5752
5753     /* PackageName value exists */
5754     sz = MAX_PATH;
5755     lstrcpyA(buf, "apple");
5756     r = pMsiGetProductInfoExA(prodcode, usersid,
5757                               MSIINSTALLCONTEXT_USERMANAGED,
5758                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5759     ok(r == ERROR_UNKNOWN_PRODUCT,
5760        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5761     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5762     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5763
5764     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5766
5767     /* AuthorizedLUAApp value exists */
5768     sz = MAX_PATH;
5769     lstrcpyA(buf, "apple");
5770     r = pMsiGetProductInfoExA(prodcode, usersid,
5771                               MSIINSTALLCONTEXT_USERMANAGED,
5772                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5773     ok(r == ERROR_UNKNOWN_PRODUCT,
5774        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5775     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5776     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5777
5778     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5779     RegDeleteValueA(propkey, "PackageName");
5780     RegDeleteValueA(propkey, "ProductIcon");
5781     RegDeleteValueA(propkey, "Version");
5782     RegDeleteValueA(propkey, "PackageCode");
5783     RegDeleteValueA(propkey, "AssignmentType");
5784     RegDeleteValueA(propkey, "ProductName");
5785     RegDeleteValueA(propkey, "Language");
5786     RegDeleteValueA(propkey, "Transforms");
5787     RegDeleteValueA(propkey, "RegOwner");
5788     RegDeleteValueA(propkey, "RegCompany");
5789     RegDeleteValueA(propkey, "ProductID");
5790     RegDeleteValueA(propkey, "DisplayVersion");
5791     RegDeleteValueA(propkey, "VersionMajor");
5792     RegDeleteValueA(propkey, "VersionMinor");
5793     RegDeleteValueA(propkey, "URLUpdateInfo");
5794     RegDeleteValueA(propkey, "URLInfoAbout");
5795     RegDeleteValueA(propkey, "Publisher");
5796     RegDeleteValueA(propkey, "LocalPackage");
5797     RegDeleteValueA(propkey, "InstallSource");
5798     RegDeleteValueA(propkey, "InstallLocation");
5799     RegDeleteValueA(propkey, "DisplayName");
5800     RegDeleteValueA(propkey, "InstallDate");
5801     RegDeleteValueA(propkey, "HelpTelephone");
5802     RegDeleteValueA(propkey, "HelpLink");
5803     RegDeleteValueA(propkey, "ManagedLocalPackage");
5804     delete_key(propkey, "", access & KEY_WOW64_64KEY);
5805     RegCloseKey(propkey);
5806     delete_key(localkey, "", access & KEY_WOW64_64KEY);
5807     RegCloseKey(localkey);
5808
5809     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5810     lstrcatA(keypath, usersid);
5811     lstrcatA(keypath, "\\Installer\\Products\\");
5812     lstrcatA(keypath, prod_squashed);
5813
5814     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5815     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5816
5817     /* user product key exists */
5818     sz = MAX_PATH;
5819     lstrcpyA(buf, "apple");
5820     r = pMsiGetProductInfoExA(prodcode, usersid,
5821                               MSIINSTALLCONTEXT_USERMANAGED,
5822                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5823     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5824     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5825     ok(sz == 1, "Expected 1, got %d\n", sz);
5826
5827     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5828     RegCloseKey(userkey);
5829
5830     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5831     lstrcatA(keypath, prod_squashed);
5832
5833     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5835
5836     /* current user product key exists */
5837     sz = MAX_PATH;
5838     lstrcpyA(buf, "apple");
5839     r = pMsiGetProductInfoExA(prodcode, usersid,
5840                               MSIINSTALLCONTEXT_USERMANAGED,
5841                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5842     ok(r == ERROR_UNKNOWN_PRODUCT,
5843        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5844     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5845     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5846
5847     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5849
5850     /* HelpLink value exists, user product key does not exist */
5851     sz = MAX_PATH;
5852     lstrcpyA(buf, "apple");
5853     r = pMsiGetProductInfoExA(prodcode, usersid,
5854                               MSIINSTALLCONTEXT_USERMANAGED,
5855                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5856     ok(r == ERROR_UNKNOWN_PRODUCT,
5857        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5858     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5859     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5860
5861     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5862     lstrcatA(keypath, usersid);
5863     lstrcatA(keypath, "\\Installer\\Products\\");
5864     lstrcatA(keypath, prod_squashed);
5865
5866     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5868
5869     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5871
5872     /* HelpLink value exists, user product key does exist */
5873     sz = MAX_PATH;
5874     lstrcpyA(buf, "apple");
5875     r = pMsiGetProductInfoExA(prodcode, usersid,
5876                               MSIINSTALLCONTEXT_USERMANAGED,
5877                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5878     ok(r == ERROR_UNKNOWN_PROPERTY,
5879        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5880     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5881     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5882
5883     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5884     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5885
5886     /* HelpTelephone value exists */
5887     sz = MAX_PATH;
5888     lstrcpyA(buf, "apple");
5889     r = pMsiGetProductInfoExA(prodcode, usersid,
5890                               MSIINSTALLCONTEXT_USERMANAGED,
5891                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5892     ok(r == ERROR_UNKNOWN_PROPERTY,
5893        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5894     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5895     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5896
5897     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5899
5900     /* InstallDate value exists */
5901     sz = MAX_PATH;
5902     lstrcpyA(buf, "apple");
5903     r = pMsiGetProductInfoExA(prodcode, usersid,
5904                               MSIINSTALLCONTEXT_USERMANAGED,
5905                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5906     ok(r == ERROR_UNKNOWN_PROPERTY,
5907        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5908     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5909     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5910
5911     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5913
5914     /* DisplayName value exists */
5915     sz = MAX_PATH;
5916     lstrcpyA(buf, "apple");
5917     r = pMsiGetProductInfoExA(prodcode, usersid,
5918                               MSIINSTALLCONTEXT_USERMANAGED,
5919                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5920     ok(r == ERROR_UNKNOWN_PROPERTY,
5921        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5922     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5923     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5924
5925     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5926     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5927
5928     /* InstallLocation value exists */
5929     sz = MAX_PATH;
5930     lstrcpyA(buf, "apple");
5931     r = pMsiGetProductInfoExA(prodcode, usersid,
5932                               MSIINSTALLCONTEXT_USERMANAGED,
5933                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5934     ok(r == ERROR_UNKNOWN_PROPERTY,
5935        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5936     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5937     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5938
5939     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5941
5942     /* InstallSource value exists */
5943     sz = MAX_PATH;
5944     lstrcpyA(buf, "apple");
5945     r = pMsiGetProductInfoExA(prodcode, usersid,
5946                               MSIINSTALLCONTEXT_USERMANAGED,
5947                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5948     ok(r == ERROR_UNKNOWN_PROPERTY,
5949        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5950     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5951     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5952
5953     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5955
5956     /* LocalPackage value exists */
5957     sz = MAX_PATH;
5958     lstrcpyA(buf, "apple");
5959     r = pMsiGetProductInfoExA(prodcode, usersid,
5960                               MSIINSTALLCONTEXT_USERMANAGED,
5961                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5962     ok(r == ERROR_UNKNOWN_PROPERTY,
5963        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5964     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5965     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5966
5967     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5969
5970     /* Publisher value exists */
5971     sz = MAX_PATH;
5972     lstrcpyA(buf, "apple");
5973     r = pMsiGetProductInfoExA(prodcode, usersid,
5974                               MSIINSTALLCONTEXT_USERMANAGED,
5975                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5976     ok(r == ERROR_UNKNOWN_PROPERTY,
5977        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5978     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5979     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5980
5981     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5983
5984     /* URLInfoAbout value exists */
5985     sz = MAX_PATH;
5986     lstrcpyA(buf, "apple");
5987     r = pMsiGetProductInfoExA(prodcode, usersid,
5988                               MSIINSTALLCONTEXT_USERMANAGED,
5989                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5990     ok(r == ERROR_UNKNOWN_PROPERTY,
5991        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5992     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5993     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5994
5995     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5997
5998     /* URLUpdateInfo value exists */
5999     sz = MAX_PATH;
6000     lstrcpyA(buf, "apple");
6001     r = pMsiGetProductInfoExA(prodcode, usersid,
6002                               MSIINSTALLCONTEXT_USERMANAGED,
6003                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6004     ok(r == ERROR_UNKNOWN_PROPERTY,
6005        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6006     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6007     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6008
6009     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6010     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6011
6012     /* VersionMinor value exists */
6013     sz = MAX_PATH;
6014     lstrcpyA(buf, "apple");
6015     r = pMsiGetProductInfoExA(prodcode, usersid,
6016                               MSIINSTALLCONTEXT_USERMANAGED,
6017                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6018     ok(r == ERROR_UNKNOWN_PROPERTY,
6019        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6020     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6021     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6022
6023     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6025
6026     /* VersionMajor value exists */
6027     sz = MAX_PATH;
6028     lstrcpyA(buf, "apple");
6029     r = pMsiGetProductInfoExA(prodcode, usersid,
6030                               MSIINSTALLCONTEXT_USERMANAGED,
6031                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6032     ok(r == ERROR_UNKNOWN_PROPERTY,
6033        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6034     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6035     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6036
6037     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6039
6040     /* DisplayVersion value exists */
6041     sz = MAX_PATH;
6042     lstrcpyA(buf, "apple");
6043     r = pMsiGetProductInfoExA(prodcode, usersid,
6044                               MSIINSTALLCONTEXT_USERMANAGED,
6045                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6046     ok(r == ERROR_UNKNOWN_PROPERTY,
6047        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6048     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6049     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6050
6051     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6053
6054     /* ProductID value exists */
6055     sz = MAX_PATH;
6056     lstrcpyA(buf, "apple");
6057     r = pMsiGetProductInfoExA(prodcode, usersid,
6058                               MSIINSTALLCONTEXT_USERMANAGED,
6059                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6060     ok(r == ERROR_UNKNOWN_PROPERTY,
6061        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6062     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6063     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6064
6065     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6067
6068     /* RegCompany value exists */
6069     sz = MAX_PATH;
6070     lstrcpyA(buf, "apple");
6071     r = pMsiGetProductInfoExA(prodcode, usersid,
6072                               MSIINSTALLCONTEXT_USERMANAGED,
6073                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6074     ok(r == ERROR_UNKNOWN_PROPERTY,
6075        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6076     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6077     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6078
6079     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6081
6082     /* RegOwner value exists */
6083     sz = MAX_PATH;
6084     lstrcpyA(buf, "apple");
6085     r = pMsiGetProductInfoExA(prodcode, usersid,
6086                               MSIINSTALLCONTEXT_USERMANAGED,
6087                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6088     ok(r == ERROR_UNKNOWN_PROPERTY,
6089        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6090     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6091     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6092
6093     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6095
6096     /* Transforms value exists */
6097     sz = MAX_PATH;
6098     lstrcpyA(buf, "apple");
6099     r = pMsiGetProductInfoExA(prodcode, usersid,
6100                               MSIINSTALLCONTEXT_USERMANAGED,
6101                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6102     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6103     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6104     ok(sz == 5, "Expected 5, got %d\n", sz);
6105
6106     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6107     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6108
6109     /* Language value exists */
6110     sz = MAX_PATH;
6111     lstrcpyA(buf, "apple");
6112     r = pMsiGetProductInfoExA(prodcode, usersid,
6113                               MSIINSTALLCONTEXT_USERMANAGED,
6114                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6115     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6116     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6117     ok(sz == 4, "Expected 4, got %d\n", sz);
6118
6119     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6121
6122     /* ProductName value exists */
6123     sz = MAX_PATH;
6124     lstrcpyA(buf, "apple");
6125     r = pMsiGetProductInfoExA(prodcode, usersid,
6126                               MSIINSTALLCONTEXT_USERMANAGED,
6127                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6129     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6130     ok(sz == 4, "Expected 4, got %d\n", sz);
6131
6132     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6134
6135     /* FIXME */
6136
6137     /* AssignmentType value exists */
6138     sz = MAX_PATH;
6139     lstrcpyA(buf, "apple");
6140     r = pMsiGetProductInfoExA(prodcode, usersid,
6141                               MSIINSTALLCONTEXT_USERMANAGED,
6142                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6143     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6144     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6145     ok(sz == 0, "Expected 0, got %d\n", sz);
6146
6147     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6149
6150     /* FIXME */
6151
6152     /* PackageCode value exists */
6153     sz = MAX_PATH;
6154     lstrcpyA(buf, "apple");
6155     r = pMsiGetProductInfoExA(prodcode, usersid,
6156                               MSIINSTALLCONTEXT_USERMANAGED,
6157                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6158     todo_wine
6159     {
6160         ok(r == ERROR_BAD_CONFIGURATION,
6161            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6162         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6163         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6164     }
6165
6166     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6168
6169     /* Version value exists */
6170     sz = MAX_PATH;
6171     lstrcpyA(buf, "apple");
6172     r = pMsiGetProductInfoExA(prodcode, usersid,
6173                               MSIINSTALLCONTEXT_USERMANAGED,
6174                               INSTALLPROPERTY_VERSION, buf, &sz);
6175     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6176     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6177     ok(sz == 3, "Expected 3, got %d\n", sz);
6178
6179     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6181
6182     /* ProductIcon value exists */
6183     sz = MAX_PATH;
6184     lstrcpyA(buf, "apple");
6185     r = pMsiGetProductInfoExA(prodcode, usersid,
6186                               MSIINSTALLCONTEXT_USERMANAGED,
6187                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6189     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6190     ok(sz == 4, "Expected 4, got %d\n", sz);
6191
6192     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6194
6195     /* PackageName value exists */
6196     sz = MAX_PATH;
6197     lstrcpyA(buf, "apple");
6198     r = pMsiGetProductInfoExA(prodcode, usersid,
6199                               MSIINSTALLCONTEXT_USERMANAGED,
6200                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6201     todo_wine
6202     {
6203         ok(r == ERROR_UNKNOWN_PRODUCT,
6204            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6205         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6206         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6207     }
6208
6209     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6211
6212     /* AuthorizedLUAApp value exists */
6213     sz = MAX_PATH;
6214     lstrcpyA(buf, "apple");
6215     r = pMsiGetProductInfoExA(prodcode, usersid,
6216                               MSIINSTALLCONTEXT_USERMANAGED,
6217                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6219     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6220     ok(sz == 4, "Expected 4, got %d\n", sz);
6221
6222     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6223     RegDeleteValueA(userkey, "PackageName");
6224     RegDeleteValueA(userkey, "ProductIcon");
6225     RegDeleteValueA(userkey, "Version");
6226     RegDeleteValueA(userkey, "PackageCode");
6227     RegDeleteValueA(userkey, "AssignmentType");
6228     RegDeleteValueA(userkey, "ProductName");
6229     RegDeleteValueA(userkey, "Language");
6230     RegDeleteValueA(userkey, "Transforms");
6231     RegDeleteValueA(userkey, "RegOwner");
6232     RegDeleteValueA(userkey, "RegCompany");
6233     RegDeleteValueA(userkey, "ProductID");
6234     RegDeleteValueA(userkey, "DisplayVersion");
6235     RegDeleteValueA(userkey, "VersionMajor");
6236     RegDeleteValueA(userkey, "VersionMinor");
6237     RegDeleteValueA(userkey, "URLUpdateInfo");
6238     RegDeleteValueA(userkey, "URLInfoAbout");
6239     RegDeleteValueA(userkey, "Publisher");
6240     RegDeleteValueA(userkey, "LocalPackage");
6241     RegDeleteValueA(userkey, "InstallSource");
6242     RegDeleteValueA(userkey, "InstallLocation");
6243     RegDeleteValueA(userkey, "DisplayName");
6244     RegDeleteValueA(userkey, "InstallDate");
6245     RegDeleteValueA(userkey, "HelpTelephone");
6246     RegDeleteValueA(userkey, "HelpLink");
6247     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6248     RegCloseKey(userkey);
6249     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6250     RegCloseKey(prodkey);
6251
6252     /* MSIINSTALLCONTEXT_MACHINE */
6253
6254     /* szUserSid is non-NULL */
6255     sz = MAX_PATH;
6256     lstrcpyA(buf, "apple");
6257     r = pMsiGetProductInfoExA(prodcode, usersid,
6258                               MSIINSTALLCONTEXT_MACHINE,
6259                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6260     ok(r == ERROR_INVALID_PARAMETER,
6261        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6262     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6263     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6264
6265     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6266     lstrcatA(keypath, prod_squashed);
6267
6268     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6270
6271     /* local system product key exists */
6272     sz = MAX_PATH;
6273     lstrcpyA(buf, "apple");
6274     r = pMsiGetProductInfoExA(prodcode, NULL,
6275                               MSIINSTALLCONTEXT_MACHINE,
6276                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6277     ok(r == ERROR_UNKNOWN_PRODUCT,
6278        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6279     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6280     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6281
6282     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6283     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6284
6285     /* InstallProperties key exists */
6286     sz = MAX_PATH;
6287     lstrcpyA(buf, "apple");
6288     r = pMsiGetProductInfoExA(prodcode, NULL,
6289                               MSIINSTALLCONTEXT_MACHINE,
6290                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6291     ok(r == ERROR_UNKNOWN_PRODUCT,
6292        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6293     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6294     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6295
6296     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6298
6299     /* LocalPackage value exists */
6300     sz = MAX_PATH;
6301     lstrcpyA(buf, "apple");
6302     r = pMsiGetProductInfoExA(prodcode, NULL,
6303                               MSIINSTALLCONTEXT_MACHINE,
6304                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6306     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6307     ok(sz == 1, "Expected 1, got %d\n", sz);
6308
6309     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6311
6312     /* HelpLink value exists */
6313     sz = MAX_PATH;
6314     lstrcpyA(buf, "apple");
6315     r = pMsiGetProductInfoExA(prodcode, NULL,
6316                               MSIINSTALLCONTEXT_MACHINE,
6317                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6318     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6319     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6320     ok(sz == 4, "Expected 4, got %d\n", sz);
6321
6322     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6324
6325     /* HelpTelephone value exists */
6326     sz = MAX_PATH;
6327     lstrcpyA(buf, "apple");
6328     r = pMsiGetProductInfoExA(prodcode, NULL,
6329                               MSIINSTALLCONTEXT_MACHINE,
6330                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6331     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6332     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6333     ok(sz == 5, "Expected 5, got %d\n", sz);
6334
6335     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6337
6338     /* InstallDate value exists */
6339     sz = MAX_PATH;
6340     lstrcpyA(buf, "apple");
6341     r = pMsiGetProductInfoExA(prodcode, NULL,
6342                               MSIINSTALLCONTEXT_MACHINE,
6343                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6345     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6346     ok(sz == 4, "Expected 4, got %d\n", sz);
6347
6348     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6350
6351     /* DisplayName value exists */
6352     sz = MAX_PATH;
6353     lstrcpyA(buf, "apple");
6354     r = pMsiGetProductInfoExA(prodcode, NULL,
6355                               MSIINSTALLCONTEXT_MACHINE,
6356                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6358     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6359     ok(sz == 4, "Expected 4, got %d\n", sz);
6360
6361     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6363
6364     /* InstallLocation value exists */
6365     sz = MAX_PATH;
6366     lstrcpyA(buf, "apple");
6367     r = pMsiGetProductInfoExA(prodcode, NULL,
6368                               MSIINSTALLCONTEXT_MACHINE,
6369                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6371     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6372     ok(sz == 3, "Expected 3, got %d\n", sz);
6373
6374     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6376
6377     /* InstallSource value exists */
6378     sz = MAX_PATH;
6379     lstrcpyA(buf, "apple");
6380     r = pMsiGetProductInfoExA(prodcode, NULL,
6381                               MSIINSTALLCONTEXT_MACHINE,
6382                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6384     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6385     ok(sz == 6, "Expected 6, got %d\n", sz);
6386
6387     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6389
6390     /* LocalPackage value exists */
6391     sz = MAX_PATH;
6392     lstrcpyA(buf, "apple");
6393     r = pMsiGetProductInfoExA(prodcode, NULL,
6394                               MSIINSTALLCONTEXT_MACHINE,
6395                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6396     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6397     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6398     ok(sz == 5, "Expected 5, got %d\n", sz);
6399
6400     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6401     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6402
6403     /* Publisher value exists */
6404     sz = MAX_PATH;
6405     lstrcpyA(buf, "apple");
6406     r = pMsiGetProductInfoExA(prodcode, NULL,
6407                               MSIINSTALLCONTEXT_MACHINE,
6408                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6410     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6411     ok(sz == 3, "Expected 3, got %d\n", sz);
6412
6413     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6415
6416     /* URLInfoAbout value exists */
6417     sz = MAX_PATH;
6418     lstrcpyA(buf, "apple");
6419     r = pMsiGetProductInfoExA(prodcode, NULL,
6420                               MSIINSTALLCONTEXT_MACHINE,
6421                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6423     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6424     ok(sz == 5, "Expected 5, got %d\n", sz);
6425
6426     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6428
6429     /* URLUpdateInfo value exists */
6430     sz = MAX_PATH;
6431     lstrcpyA(buf, "apple");
6432     r = pMsiGetProductInfoExA(prodcode, NULL,
6433                               MSIINSTALLCONTEXT_MACHINE,
6434                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6435     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6436     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6437     ok(sz == 6, "Expected 6, got %d\n", sz);
6438
6439     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6441
6442     /* VersionMinor value exists */
6443     sz = MAX_PATH;
6444     lstrcpyA(buf, "apple");
6445     r = pMsiGetProductInfoExA(prodcode, NULL,
6446                               MSIINSTALLCONTEXT_MACHINE,
6447                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6448     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6449     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6450     ok(sz == 1, "Expected 1, got %d\n", sz);
6451
6452     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6454
6455     /* VersionMajor value exists */
6456     sz = MAX_PATH;
6457     lstrcpyA(buf, "apple");
6458     r = pMsiGetProductInfoExA(prodcode, NULL,
6459                               MSIINSTALLCONTEXT_MACHINE,
6460                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6461     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6462     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6463     ok(sz == 1, "Expected 1, got %d\n", sz);
6464
6465     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6467
6468     /* DisplayVersion value exists */
6469     sz = MAX_PATH;
6470     lstrcpyA(buf, "apple");
6471     r = pMsiGetProductInfoExA(prodcode, NULL,
6472                               MSIINSTALLCONTEXT_MACHINE,
6473                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6474     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6475     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6476     ok(sz == 5, "Expected 5, got %d\n", sz);
6477
6478     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6479     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6480
6481     /* ProductID value exists */
6482     sz = MAX_PATH;
6483     lstrcpyA(buf, "apple");
6484     r = pMsiGetProductInfoExA(prodcode, NULL,
6485                               MSIINSTALLCONTEXT_MACHINE,
6486                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6487     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6488     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6489     ok(sz == 2, "Expected 2, got %d\n", sz);
6490
6491     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6493
6494     /* RegCompany value exists */
6495     sz = MAX_PATH;
6496     lstrcpyA(buf, "apple");
6497     r = pMsiGetProductInfoExA(prodcode, NULL,
6498                               MSIINSTALLCONTEXT_MACHINE,
6499                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6501     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6502     ok(sz == 4, "Expected 4, got %d\n", sz);
6503
6504     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6505     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6506
6507     /* RegOwner value exists */
6508     sz = MAX_PATH;
6509     lstrcpyA(buf, "apple");
6510     r = pMsiGetProductInfoExA(prodcode, NULL,
6511                               MSIINSTALLCONTEXT_MACHINE,
6512                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6514     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6515     ok(sz == 5, "Expected 5, got %d\n", sz);
6516
6517     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6518     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6519
6520     /* Transforms value exists */
6521     sz = MAX_PATH;
6522     lstrcpyA(buf, "apple");
6523     r = pMsiGetProductInfoExA(prodcode, NULL,
6524                               MSIINSTALLCONTEXT_MACHINE,
6525                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6526     ok(r == ERROR_UNKNOWN_PRODUCT,
6527        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6528     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6529     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6530
6531     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6533
6534     /* Language value exists */
6535     sz = MAX_PATH;
6536     lstrcpyA(buf, "apple");
6537     r = pMsiGetProductInfoExA(prodcode, NULL,
6538                               MSIINSTALLCONTEXT_MACHINE,
6539                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6540     ok(r == ERROR_UNKNOWN_PRODUCT,
6541        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6542     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6543     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6544
6545     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6547
6548     /* ProductName value exists */
6549     sz = MAX_PATH;
6550     lstrcpyA(buf, "apple");
6551     r = pMsiGetProductInfoExA(prodcode, NULL,
6552                               MSIINSTALLCONTEXT_MACHINE,
6553                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6554     ok(r == ERROR_UNKNOWN_PRODUCT,
6555        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6556     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6557     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6558
6559     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6561
6562     /* FIXME */
6563
6564     /* AssignmentType value exists */
6565     sz = MAX_PATH;
6566     lstrcpyA(buf, "apple");
6567     r = pMsiGetProductInfoExA(prodcode, NULL,
6568                               MSIINSTALLCONTEXT_MACHINE,
6569                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6570     ok(r == ERROR_UNKNOWN_PRODUCT,
6571        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6572     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6573     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6574
6575     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6577
6578     /* PackageCode value exists */
6579     sz = MAX_PATH;
6580     lstrcpyA(buf, "apple");
6581     r = pMsiGetProductInfoExA(prodcode, NULL,
6582                               MSIINSTALLCONTEXT_MACHINE,
6583                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6584     ok(r == ERROR_UNKNOWN_PRODUCT,
6585        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6586     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6587     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6588
6589     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6591
6592     /* Version value exists */
6593     sz = MAX_PATH;
6594     lstrcpyA(buf, "apple");
6595     r = pMsiGetProductInfoExA(prodcode, NULL,
6596                               MSIINSTALLCONTEXT_MACHINE,
6597                               INSTALLPROPERTY_VERSION, buf, &sz);
6598     ok(r == ERROR_UNKNOWN_PRODUCT,
6599        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6600     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6601     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6602
6603     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6605
6606     /* ProductIcon value exists */
6607     sz = MAX_PATH;
6608     lstrcpyA(buf, "apple");
6609     r = pMsiGetProductInfoExA(prodcode, NULL,
6610                               MSIINSTALLCONTEXT_MACHINE,
6611                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6612     ok(r == ERROR_UNKNOWN_PRODUCT,
6613        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6614     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6615     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6616
6617     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6619
6620     /* PackageName value exists */
6621     sz = MAX_PATH;
6622     lstrcpyA(buf, "apple");
6623     r = pMsiGetProductInfoExA(prodcode, NULL,
6624                               MSIINSTALLCONTEXT_MACHINE,
6625                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6626     ok(r == ERROR_UNKNOWN_PRODUCT,
6627        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6628     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6629     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6630
6631     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6632     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6633
6634     /* AuthorizedLUAApp value exists */
6635     sz = MAX_PATH;
6636     lstrcpyA(buf, "apple");
6637     r = pMsiGetProductInfoExA(prodcode, NULL,
6638                               MSIINSTALLCONTEXT_MACHINE,
6639                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6640     ok(r == ERROR_UNKNOWN_PRODUCT,
6641        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6642     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6643     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6644
6645     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6646     RegDeleteValueA(propkey, "PackageName");
6647     RegDeleteValueA(propkey, "ProductIcon");
6648     RegDeleteValueA(propkey, "Version");
6649     RegDeleteValueA(propkey, "PackageCode");
6650     RegDeleteValueA(propkey, "AssignmentType");
6651     RegDeleteValueA(propkey, "ProductName");
6652     RegDeleteValueA(propkey, "Language");
6653     RegDeleteValueA(propkey, "Transforms");
6654     RegDeleteValueA(propkey, "RegOwner");
6655     RegDeleteValueA(propkey, "RegCompany");
6656     RegDeleteValueA(propkey, "ProductID");
6657     RegDeleteValueA(propkey, "DisplayVersion");
6658     RegDeleteValueA(propkey, "VersionMajor");
6659     RegDeleteValueA(propkey, "VersionMinor");
6660     RegDeleteValueA(propkey, "URLUpdateInfo");
6661     RegDeleteValueA(propkey, "URLInfoAbout");
6662     RegDeleteValueA(propkey, "Publisher");
6663     RegDeleteValueA(propkey, "LocalPackage");
6664     RegDeleteValueA(propkey, "InstallSource");
6665     RegDeleteValueA(propkey, "InstallLocation");
6666     RegDeleteValueA(propkey, "DisplayName");
6667     RegDeleteValueA(propkey, "InstallDate");
6668     RegDeleteValueA(propkey, "HelpTelephone");
6669     RegDeleteValueA(propkey, "HelpLink");
6670     RegDeleteValueA(propkey, "LocalPackage");
6671     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6672     RegCloseKey(propkey);
6673     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6674     RegCloseKey(localkey);
6675
6676     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6677     lstrcatA(keypath, prod_squashed);
6678
6679     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6681
6682     /* local classes product key exists */
6683     sz = MAX_PATH;
6684     lstrcpyA(buf, "apple");
6685     r = pMsiGetProductInfoExA(prodcode, NULL,
6686                               MSIINSTALLCONTEXT_MACHINE,
6687                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6689     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6690     ok(sz == 1, "Expected 1, got %d\n", sz);
6691
6692     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6694
6695     /* HelpLink value exists */
6696     sz = MAX_PATH;
6697     lstrcpyA(buf, "apple");
6698     r = pMsiGetProductInfoExA(prodcode, NULL,
6699                               MSIINSTALLCONTEXT_MACHINE,
6700                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6701     ok(r == ERROR_UNKNOWN_PROPERTY,
6702        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6703     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6704     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6705
6706     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6708
6709     /* HelpTelephone value exists */
6710     sz = MAX_PATH;
6711     lstrcpyA(buf, "apple");
6712     r = pMsiGetProductInfoExA(prodcode, NULL,
6713                               MSIINSTALLCONTEXT_MACHINE,
6714                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6715     ok(r == ERROR_UNKNOWN_PROPERTY,
6716        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6717     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6718     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6719
6720     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6721     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6722
6723     /* InstallDate value exists */
6724     sz = MAX_PATH;
6725     lstrcpyA(buf, "apple");
6726     r = pMsiGetProductInfoExA(prodcode, NULL,
6727                               MSIINSTALLCONTEXT_MACHINE,
6728                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6729     ok(r == ERROR_UNKNOWN_PROPERTY,
6730        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6731     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6732     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6733
6734     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6736
6737     /* DisplayName value exists */
6738     sz = MAX_PATH;
6739     lstrcpyA(buf, "apple");
6740     r = pMsiGetProductInfoExA(prodcode, NULL,
6741                               MSIINSTALLCONTEXT_MACHINE,
6742                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6743     ok(r == ERROR_UNKNOWN_PROPERTY,
6744        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6745     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6746     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6747
6748     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6750
6751     /* InstallLocation value exists */
6752     sz = MAX_PATH;
6753     lstrcpyA(buf, "apple");
6754     r = pMsiGetProductInfoExA(prodcode, NULL,
6755                               MSIINSTALLCONTEXT_MACHINE,
6756                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6757     ok(r == ERROR_UNKNOWN_PROPERTY,
6758        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6759     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6760     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6761
6762     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6764
6765     /* InstallSource value exists */
6766     sz = MAX_PATH;
6767     lstrcpyA(buf, "apple");
6768     r = pMsiGetProductInfoExA(prodcode, NULL,
6769                               MSIINSTALLCONTEXT_MACHINE,
6770                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6771     ok(r == ERROR_UNKNOWN_PROPERTY,
6772        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6773     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6774     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6775
6776     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6778
6779     /* LocalPackage value exists */
6780     sz = MAX_PATH;
6781     lstrcpyA(buf, "apple");
6782     r = pMsiGetProductInfoExA(prodcode, NULL,
6783                               MSIINSTALLCONTEXT_MACHINE,
6784                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6785     ok(r == ERROR_UNKNOWN_PROPERTY,
6786        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6787     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6788     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6789
6790     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6792
6793     /* Publisher value exists */
6794     sz = MAX_PATH;
6795     lstrcpyA(buf, "apple");
6796     r = pMsiGetProductInfoExA(prodcode, NULL,
6797                               MSIINSTALLCONTEXT_MACHINE,
6798                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6799     ok(r == ERROR_UNKNOWN_PROPERTY,
6800        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6801     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6802     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6803
6804     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6805     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6806
6807     /* URLInfoAbout value exists */
6808     sz = MAX_PATH;
6809     lstrcpyA(buf, "apple");
6810     r = pMsiGetProductInfoExA(prodcode, NULL,
6811                               MSIINSTALLCONTEXT_MACHINE,
6812                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6813     ok(r == ERROR_UNKNOWN_PROPERTY,
6814        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6815     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6816     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6817
6818     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6819     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6820
6821     /* URLUpdateInfo value exists */
6822     sz = MAX_PATH;
6823     lstrcpyA(buf, "apple");
6824     r = pMsiGetProductInfoExA(prodcode, NULL,
6825                               MSIINSTALLCONTEXT_MACHINE,
6826                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6827     ok(r == ERROR_UNKNOWN_PROPERTY,
6828        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6829     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6830     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6831
6832     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6833     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6834
6835     /* VersionMinor value exists */
6836     sz = MAX_PATH;
6837     lstrcpyA(buf, "apple");
6838     r = pMsiGetProductInfoExA(prodcode, NULL,
6839                               MSIINSTALLCONTEXT_MACHINE,
6840                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6841     ok(r == ERROR_UNKNOWN_PROPERTY,
6842        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6843     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6844     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6845
6846     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6847     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6848
6849     /* VersionMajor value exists */
6850     sz = MAX_PATH;
6851     lstrcpyA(buf, "apple");
6852     r = pMsiGetProductInfoExA(prodcode, NULL,
6853                               MSIINSTALLCONTEXT_MACHINE,
6854                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6855     ok(r == ERROR_UNKNOWN_PROPERTY,
6856        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6857     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6858     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6859
6860     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6862
6863     /* DisplayVersion value exists */
6864     sz = MAX_PATH;
6865     lstrcpyA(buf, "apple");
6866     r = pMsiGetProductInfoExA(prodcode, NULL,
6867                               MSIINSTALLCONTEXT_MACHINE,
6868                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6869     ok(r == ERROR_UNKNOWN_PROPERTY,
6870        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6871     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6872     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6873
6874     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6876
6877     /* ProductID value exists */
6878     sz = MAX_PATH;
6879     lstrcpyA(buf, "apple");
6880     r = pMsiGetProductInfoExA(prodcode, NULL,
6881                               MSIINSTALLCONTEXT_MACHINE,
6882                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6883     ok(r == ERROR_UNKNOWN_PROPERTY,
6884        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6885     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6886     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6887
6888     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6890
6891     /* RegCompany value exists */
6892     sz = MAX_PATH;
6893     lstrcpyA(buf, "apple");
6894     r = pMsiGetProductInfoExA(prodcode, NULL,
6895                               MSIINSTALLCONTEXT_MACHINE,
6896                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6897     ok(r == ERROR_UNKNOWN_PROPERTY,
6898        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6899     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6900     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6901
6902     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6903     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6904
6905     /* RegOwner value exists */
6906     sz = MAX_PATH;
6907     lstrcpyA(buf, "apple");
6908     r = pMsiGetProductInfoExA(prodcode, NULL,
6909                               MSIINSTALLCONTEXT_MACHINE,
6910                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6911     ok(r == ERROR_UNKNOWN_PROPERTY,
6912        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6913     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6914     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6915
6916     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6918
6919     /* Transforms value exists */
6920     sz = MAX_PATH;
6921     lstrcpyA(buf, "apple");
6922     r = pMsiGetProductInfoExA(prodcode, NULL,
6923                               MSIINSTALLCONTEXT_MACHINE,
6924                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6926     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6927     ok(sz == 5, "Expected 5, got %d\n", sz);
6928
6929     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6931
6932     /* Language value exists */
6933     sz = MAX_PATH;
6934     lstrcpyA(buf, "apple");
6935     r = pMsiGetProductInfoExA(prodcode, NULL,
6936                               MSIINSTALLCONTEXT_MACHINE,
6937                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6939     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6940     ok(sz == 4, "Expected 4, got %d\n", sz);
6941
6942     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6944
6945     /* ProductName value exists */
6946     sz = MAX_PATH;
6947     lstrcpyA(buf, "apple");
6948     r = pMsiGetProductInfoExA(prodcode, NULL,
6949                               MSIINSTALLCONTEXT_MACHINE,
6950                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6952     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6953     ok(sz == 4, "Expected 4, got %d\n", sz);
6954
6955     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6957
6958     /* FIXME */
6959
6960     /* AssignmentType value exists */
6961     sz = MAX_PATH;
6962     lstrcpyA(buf, "apple");
6963     r = pMsiGetProductInfoExA(prodcode, NULL,
6964                               MSIINSTALLCONTEXT_MACHINE,
6965                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6967     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6968     ok(sz == 0, "Expected 0, got %d\n", sz);
6969
6970     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6972
6973     /* FIXME */
6974
6975     /* PackageCode value exists */
6976     sz = MAX_PATH;
6977     lstrcpyA(buf, "apple");
6978     r = pMsiGetProductInfoExA(prodcode, NULL,
6979                               MSIINSTALLCONTEXT_MACHINE,
6980                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6981     todo_wine
6982     {
6983         ok(r == ERROR_BAD_CONFIGURATION,
6984            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6985         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6986         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6987     }
6988
6989     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6991
6992     /* Version value exists */
6993     sz = MAX_PATH;
6994     lstrcpyA(buf, "apple");
6995     r = pMsiGetProductInfoExA(prodcode, NULL,
6996                               MSIINSTALLCONTEXT_MACHINE,
6997                               INSTALLPROPERTY_VERSION, buf, &sz);
6998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6999     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7000     ok(sz == 3, "Expected 3, got %d\n", sz);
7001
7002     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7004
7005     /* ProductIcon value exists */
7006     sz = MAX_PATH;
7007     lstrcpyA(buf, "apple");
7008     r = pMsiGetProductInfoExA(prodcode, NULL,
7009                               MSIINSTALLCONTEXT_MACHINE,
7010                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7012     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7013     ok(sz == 4, "Expected 4, got %d\n", sz);
7014
7015     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7017
7018     /* PackageName value exists */
7019     sz = MAX_PATH;
7020     lstrcpyA(buf, "apple");
7021     r = pMsiGetProductInfoExA(prodcode, NULL,
7022                               MSIINSTALLCONTEXT_MACHINE,
7023                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7024     todo_wine
7025     {
7026         ok(r == ERROR_UNKNOWN_PRODUCT,
7027            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7028         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7029         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7030     }
7031
7032     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7034
7035     /* AuthorizedLUAApp value exists */
7036     sz = MAX_PATH;
7037     lstrcpyA(buf, "apple");
7038     r = pMsiGetProductInfoExA(prodcode, NULL,
7039                               MSIINSTALLCONTEXT_MACHINE,
7040                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7042     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7043     ok(sz == 4, "Expected 4, got %d\n", sz);
7044
7045     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7046     RegDeleteValueA(prodkey, "PackageName");
7047     RegDeleteValueA(prodkey, "ProductIcon");
7048     RegDeleteValueA(prodkey, "Version");
7049     RegDeleteValueA(prodkey, "PackageCode");
7050     RegDeleteValueA(prodkey, "AssignmentType");
7051     RegDeleteValueA(prodkey, "ProductName");
7052     RegDeleteValueA(prodkey, "Language");
7053     RegDeleteValueA(prodkey, "Transforms");
7054     RegDeleteValueA(prodkey, "RegOwner");
7055     RegDeleteValueA(prodkey, "RegCompany");
7056     RegDeleteValueA(prodkey, "ProductID");
7057     RegDeleteValueA(prodkey, "DisplayVersion");
7058     RegDeleteValueA(prodkey, "VersionMajor");
7059     RegDeleteValueA(prodkey, "VersionMinor");
7060     RegDeleteValueA(prodkey, "URLUpdateInfo");
7061     RegDeleteValueA(prodkey, "URLInfoAbout");
7062     RegDeleteValueA(prodkey, "Publisher");
7063     RegDeleteValueA(prodkey, "LocalPackage");
7064     RegDeleteValueA(prodkey, "InstallSource");
7065     RegDeleteValueA(prodkey, "InstallLocation");
7066     RegDeleteValueA(prodkey, "DisplayName");
7067     RegDeleteValueA(prodkey, "InstallDate");
7068     RegDeleteValueA(prodkey, "HelpTelephone");
7069     RegDeleteValueA(prodkey, "HelpLink");
7070     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7071     RegCloseKey(prodkey);
7072     LocalFree(usersid);
7073 }
7074
7075 #define INIT_USERINFO() \
7076     lstrcpyA(user, "apple"); \
7077     lstrcpyA(org, "orange"); \
7078     lstrcpyA(serial, "banana"); \
7079     usersz = orgsz = serialsz = MAX_PATH;
7080
7081 static void test_MsiGetUserInfo(void)
7082 {
7083     USERINFOSTATE state;
7084     CHAR user[MAX_PATH];
7085     CHAR org[MAX_PATH];
7086     CHAR serial[MAX_PATH];
7087     DWORD usersz, orgsz, serialsz;
7088     CHAR keypath[MAX_PATH * 2];
7089     CHAR prodcode[MAX_PATH];
7090     CHAR prod_squashed[MAX_PATH];
7091     HKEY prodkey, userprod, props;
7092     LPSTR usersid;
7093     LONG res;
7094     REGSAM access = KEY_ALL_ACCESS;
7095
7096     create_test_guid(prodcode, prod_squashed);
7097     usersid = get_user_sid();
7098
7099     if (is_wow64)
7100         access |= KEY_WOW64_64KEY;
7101
7102     /* NULL szProduct */
7103     INIT_USERINFO();
7104     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
7105     ok(state == USERINFOSTATE_INVALIDARG,
7106        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7107     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7108     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7109     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7110     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7111     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7112     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7113
7114     /* empty szProductCode */
7115     INIT_USERINFO();
7116     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
7117     ok(state == USERINFOSTATE_INVALIDARG,
7118        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7119     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7120     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7121     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7122     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7123     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7124     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7125
7126     /* garbage szProductCode */
7127     INIT_USERINFO();
7128     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
7129     ok(state == USERINFOSTATE_INVALIDARG,
7130        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7131     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7132     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7133     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7134     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7135     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7136     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7137
7138     /* guid without brackets */
7139     INIT_USERINFO();
7140     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7141                             user, &usersz, org, &orgsz, serial, &serialsz);
7142     ok(state == USERINFOSTATE_INVALIDARG,
7143        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7144     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7145     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7146     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7147     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7148     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7149     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7150
7151     /* guid with brackets */
7152     INIT_USERINFO();
7153     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7154                             user, &usersz, org, &orgsz, serial, &serialsz);
7155     ok(state == USERINFOSTATE_UNKNOWN,
7156        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7157     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7158     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7159     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7160     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7161     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7162     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7163
7164     /* NULL lpUserNameBuf */
7165     INIT_USERINFO();
7166     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7167     ok(state == USERINFOSTATE_UNKNOWN,
7168        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7169     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7170     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7171     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7172     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7173     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7174
7175     /* NULL pcchUserNameBuf */
7176     INIT_USERINFO();
7177     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
7178     ok(state == USERINFOSTATE_INVALIDARG,
7179        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7180     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7181     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7182     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7183     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7184     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7185
7186     /* both lpUserNameBuf and pcchUserNameBuf NULL */
7187     INIT_USERINFO();
7188     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7189     ok(state == USERINFOSTATE_UNKNOWN,
7190        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7191     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7192     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7193     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7194     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7195
7196     /* NULL lpOrgNameBuf */
7197     INIT_USERINFO();
7198     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
7199     ok(state == USERINFOSTATE_UNKNOWN,
7200        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7201     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7202     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7203     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7204     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7205     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7206
7207     /* NULL pcchOrgNameBuf */
7208     INIT_USERINFO();
7209     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7210     ok(state == USERINFOSTATE_INVALIDARG,
7211        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7212     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7213     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7214     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7215     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7216     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7217
7218     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7219     INIT_USERINFO();
7220     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7221     ok(state == USERINFOSTATE_UNKNOWN,
7222        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7223     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7224     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7225     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7226     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7227
7228     /* NULL lpSerialBuf */
7229     INIT_USERINFO();
7230     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7231     ok(state == USERINFOSTATE_UNKNOWN,
7232        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7233     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7234     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7235     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7236     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7237     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7238
7239     /* NULL pcchSerialBuf */
7240     INIT_USERINFO();
7241     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7242     ok(state == USERINFOSTATE_INVALIDARG,
7243        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7244     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7245     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7246     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7247     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7248     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7249
7250     /* both lpSerialBuf and pcchSerialBuf NULL */
7251     INIT_USERINFO();
7252     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7253     ok(state == USERINFOSTATE_UNKNOWN,
7254        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7255     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7256     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7257     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7258     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7259
7260     /* MSIINSTALLCONTEXT_USERMANAGED */
7261
7262     /* create local system product key */
7263     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7264     lstrcatA(keypath, usersid);
7265     lstrcatA(keypath, "\\Installer\\Products\\");
7266     lstrcatA(keypath, prod_squashed);
7267
7268     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7269     if (res == ERROR_ACCESS_DENIED)
7270     {
7271         skip("Not enough rights to perform tests\n");
7272         LocalFree(usersid);
7273         return;
7274     }
7275     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7276
7277     /* managed product key exists */
7278     INIT_USERINFO();
7279     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7280     ok(state == USERINFOSTATE_ABSENT,
7281        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7282     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7283     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7284     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7285     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7286     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7287     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7288
7289     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7290     lstrcatA(keypath, "Installer\\UserData\\");
7291     lstrcatA(keypath, usersid);
7292     lstrcatA(keypath, "\\Products\\");
7293     lstrcatA(keypath, prod_squashed);
7294
7295     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7297
7298     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7300
7301     /* InstallProperties key exists */
7302     INIT_USERINFO();
7303     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7304     ok(state == USERINFOSTATE_ABSENT,
7305        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7306     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7307     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7308     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7309     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7310     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7311     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7312
7313     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7314     INIT_USERINFO();
7315     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7316     ok(state == USERINFOSTATE_ABSENT,
7317        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7318     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7319     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7320     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7321     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7322
7323     /* RegOwner, RegCompany don't exist, out params are NULL */
7324     INIT_USERINFO();
7325     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7326     ok(state == USERINFOSTATE_ABSENT,
7327        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7328     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7329     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7330
7331     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7333
7334     /* RegOwner value exists */
7335     INIT_USERINFO();
7336     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7337     ok(state == USERINFOSTATE_ABSENT,
7338        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7339     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7340     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7341     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7342     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7343     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7344     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7345
7346     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7348
7349     /* RegCompany 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, "company"), "Expected \"company\", 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 == 7, "Expected 7, got %d\n", orgsz);
7359     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7360
7361     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7363
7364     /* ProductID value exists */
7365     INIT_USERINFO();
7366     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7367     ok(state == USERINFOSTATE_PRESENT,
7368        "Expected USERINFOSTATE_PRESENT, 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, "ID"), "Expected \"ID\", 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 == 2, "Expected 2, got %d\n", serialsz);
7375
7376     /* pcchUserNameBuf is too small */
7377     INIT_USERINFO();
7378     usersz = 0;
7379     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7380     ok(state == USERINFOSTATE_MOREDATA,
7381        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7382     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7383     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7384     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7385     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7386     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7387     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7388
7389     /* pcchUserNameBuf has no room for NULL terminator */
7390     INIT_USERINFO();
7391     usersz = 5;
7392     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7393     ok(state == USERINFOSTATE_MOREDATA,
7394        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7395     todo_wine
7396     {
7397         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7398     }
7399     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7400     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7401     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7402     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7403     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7404
7405     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7406     INIT_USERINFO();
7407     usersz = 0;
7408     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7409     ok(state == USERINFOSTATE_PRESENT,
7410        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7411     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7412     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7413     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7414     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7415     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7416     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7417
7418     RegDeleteValueA(props, "ProductID");
7419     RegDeleteValueA(props, "RegCompany");
7420     RegDeleteValueA(props, "RegOwner");
7421     delete_key(props, "", access & KEY_WOW64_64KEY);
7422     RegCloseKey(props);
7423     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7424     RegCloseKey(userprod);
7425     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7426     RegCloseKey(prodkey);
7427
7428     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7429
7430     /* create local system product key */
7431     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7432     lstrcatA(keypath, prod_squashed);
7433
7434     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7436
7437     /* product key exists */
7438     INIT_USERINFO();
7439     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7440     ok(state == USERINFOSTATE_ABSENT,
7441        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7442     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7443     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7444     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7445     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7446     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7447     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7448
7449     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7450     lstrcatA(keypath, "Installer\\UserData\\");
7451     lstrcatA(keypath, usersid);
7452     lstrcatA(keypath, "\\Products\\");
7453     lstrcatA(keypath, prod_squashed);
7454
7455     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7457
7458     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7460
7461     /* InstallProperties key exists */
7462     INIT_USERINFO();
7463     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7464     ok(state == USERINFOSTATE_ABSENT,
7465        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7466     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7467     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7468     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7469     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7470     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7471     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7472
7473     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7474     INIT_USERINFO();
7475     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7476     ok(state == USERINFOSTATE_ABSENT,
7477        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7478     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7479     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7480     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7481     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7482
7483     /* RegOwner, RegCompany don't exist, out params are NULL */
7484     INIT_USERINFO();
7485     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7486     ok(state == USERINFOSTATE_ABSENT,
7487        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7488     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7489     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7490
7491     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7493
7494     /* RegOwner value exists */
7495     INIT_USERINFO();
7496     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7497     ok(state == USERINFOSTATE_ABSENT,
7498        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7499     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7500     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7501     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7502     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7503     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7504     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7505
7506     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7508
7509     /* RegCompany 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, "company"), "Expected \"company\", 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 == 7, "Expected 7, got %d\n", orgsz);
7519     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7520
7521     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7523
7524     /* ProductID value exists */
7525     INIT_USERINFO();
7526     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7527     ok(state == USERINFOSTATE_PRESENT,
7528        "Expected USERINFOSTATE_PRESENT, 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, "ID"), "Expected \"ID\", 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 == 2, "Expected 2, got %d\n", serialsz);
7535
7536     RegDeleteValueA(props, "ProductID");
7537     RegDeleteValueA(props, "RegCompany");
7538     RegDeleteValueA(props, "RegOwner");
7539     delete_key(props, "", access & KEY_WOW64_64KEY);
7540     RegCloseKey(props);
7541     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7542     RegCloseKey(userprod);
7543     RegDeleteKeyA(prodkey, "");
7544     RegCloseKey(prodkey);
7545
7546     /* MSIINSTALLCONTEXT_MACHINE */
7547
7548     /* create local system product key */
7549     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7550     lstrcatA(keypath, prod_squashed);
7551
7552     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7554
7555     /* product key exists */
7556     INIT_USERINFO();
7557     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7558     ok(state == USERINFOSTATE_ABSENT,
7559        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7560     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7561     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7562     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7563     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7564     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7565     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7566
7567     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7568     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7569     lstrcatA(keypath, "\\Products\\");
7570     lstrcatA(keypath, prod_squashed);
7571
7572     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7574
7575     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7577
7578     /* InstallProperties key exists */
7579     INIT_USERINFO();
7580     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7581     ok(state == USERINFOSTATE_ABSENT,
7582        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7583     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7584     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7585     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7586     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7587     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7588     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7589
7590     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7591     INIT_USERINFO();
7592     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7593     ok(state == USERINFOSTATE_ABSENT,
7594        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7595     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7596     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7597     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7598     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7599
7600     /* RegOwner, RegCompany don't exist, out params are NULL */
7601     INIT_USERINFO();
7602     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7603     ok(state == USERINFOSTATE_ABSENT,
7604        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7605     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7606     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7607
7608     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7609     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7610
7611     /* RegOwner value exists */
7612     INIT_USERINFO();
7613     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7614     ok(state == USERINFOSTATE_ABSENT,
7615        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7616     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7617     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7618     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7619     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7620     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7621     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7622
7623     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7625
7626     /* RegCompany 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, "company"), "Expected \"company\", 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 == 7, "Expected 7, got %d\n", orgsz);
7636     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7637
7638     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7640
7641     /* ProductID value exists */
7642     INIT_USERINFO();
7643     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7644     ok(state == USERINFOSTATE_PRESENT,
7645        "Expected USERINFOSTATE_PRESENT, 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, "ID"), "Expected \"ID\", 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 == 2, "Expected 2, got %d\n", serialsz);
7652
7653     RegDeleteValueA(props, "ProductID");
7654     RegDeleteValueA(props, "RegCompany");
7655     RegDeleteValueA(props, "RegOwner");
7656     delete_key(props, "", access & KEY_WOW64_64KEY);
7657     RegCloseKey(props);
7658     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7659     RegCloseKey(userprod);
7660     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7661     RegCloseKey(prodkey);
7662     LocalFree(usersid);
7663 }
7664
7665 static void test_MsiOpenProduct(void)
7666 {
7667     MSIHANDLE hprod, hdb;
7668     CHAR val[MAX_PATH];
7669     CHAR path[MAX_PATH];
7670     CHAR keypath[MAX_PATH*2];
7671     CHAR prodcode[MAX_PATH];
7672     CHAR prod_squashed[MAX_PATH];
7673     HKEY prodkey, userkey, props;
7674     LPSTR usersid;
7675     DWORD size;
7676     LONG res;
7677     UINT r;
7678     REGSAM access = KEY_ALL_ACCESS;
7679
7680     GetCurrentDirectoryA(MAX_PATH, path);
7681     lstrcatA(path, "\\");
7682
7683     create_test_guid(prodcode, prod_squashed);
7684     usersid = get_user_sid();
7685
7686     if (is_wow64)
7687         access |= KEY_WOW64_64KEY;
7688
7689     hdb = create_package_db(prodcode);
7690     MsiCloseHandle(hdb);
7691
7692     /* NULL szProduct */
7693     hprod = 0xdeadbeef;
7694     r = MsiOpenProductA(NULL, &hprod);
7695     ok(r == ERROR_INVALID_PARAMETER,
7696        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7697     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7698
7699     /* empty szProduct */
7700     hprod = 0xdeadbeef;
7701     r = MsiOpenProductA("", &hprod);
7702     ok(r == ERROR_INVALID_PARAMETER,
7703        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7704     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7705
7706     /* garbage szProduct */
7707     hprod = 0xdeadbeef;
7708     r = MsiOpenProductA("garbage", &hprod);
7709     ok(r == ERROR_INVALID_PARAMETER,
7710        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7711     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7712
7713     /* guid without brackets */
7714     hprod = 0xdeadbeef;
7715     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7716     ok(r == ERROR_INVALID_PARAMETER,
7717        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7718     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7719
7720     /* guid with brackets */
7721     hprod = 0xdeadbeef;
7722     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7723     ok(r == ERROR_UNKNOWN_PRODUCT,
7724        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7725     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7726
7727     /* same length as guid, but random */
7728     hprod = 0xdeadbeef;
7729     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7730     ok(r == ERROR_INVALID_PARAMETER,
7731        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7732     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7733
7734     /* hProduct is NULL */
7735     hprod = 0xdeadbeef;
7736     r = MsiOpenProductA(prodcode, NULL);
7737     ok(r == ERROR_INVALID_PARAMETER,
7738        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7739     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7740
7741     /* MSIINSTALLCONTEXT_USERMANAGED */
7742
7743     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7744     lstrcatA(keypath, "Installer\\Managed\\");
7745     lstrcatA(keypath, usersid);
7746     lstrcatA(keypath, "\\Installer\\Products\\");
7747     lstrcatA(keypath, prod_squashed);
7748
7749     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7750     if (res == ERROR_ACCESS_DENIED)
7751     {
7752         skip("Not enough rights to perform tests\n");
7753         LocalFree(usersid);
7754         return;
7755     }
7756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7757
7758     /* managed product key exists */
7759     hprod = 0xdeadbeef;
7760     r = MsiOpenProductA(prodcode, &hprod);
7761     ok(r == ERROR_UNKNOWN_PRODUCT,
7762        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7763     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7764
7765     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7766     lstrcatA(keypath, "Installer\\UserData\\");
7767     lstrcatA(keypath, usersid);
7768     lstrcatA(keypath, "\\Products\\");
7769     lstrcatA(keypath, prod_squashed);
7770
7771     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7773
7774     /* user product key exists */
7775     hprod = 0xdeadbeef;
7776     r = MsiOpenProductA(prodcode, &hprod);
7777     ok(r == ERROR_UNKNOWN_PRODUCT,
7778        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7779     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7780
7781     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7783
7784     /* InstallProperties key exists */
7785     hprod = 0xdeadbeef;
7786     r = MsiOpenProductA(prodcode, &hprod);
7787     ok(r == ERROR_UNKNOWN_PRODUCT,
7788        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7789     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7790
7791     lstrcpyA(val, path);
7792     lstrcatA(val, "\\winetest.msi");
7793     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7794                          (const BYTE *)val, lstrlenA(val) + 1);
7795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7796
7797     /* ManagedLocalPackage value exists */
7798     hprod = 0xdeadbeef;
7799     r = MsiOpenProductA(prodcode, &hprod);
7800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7801     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7802
7803     size = MAX_PATH;
7804     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7806     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7807     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7808
7809     MsiCloseHandle(hprod);
7810
7811     RegDeleteValueA(props, "ManagedLocalPackage");
7812     delete_key(props, "", access & KEY_WOW64_64KEY);
7813     RegCloseKey(props);
7814     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7815     RegCloseKey(userkey);
7816     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7817     RegCloseKey(prodkey);
7818
7819     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7820
7821     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7822     lstrcatA(keypath, prod_squashed);
7823
7824     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7826
7827     /* unmanaged product key exists */
7828     hprod = 0xdeadbeef;
7829     r = MsiOpenProductA(prodcode, &hprod);
7830     ok(r == ERROR_UNKNOWN_PRODUCT,
7831        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7832     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7833
7834     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7835     lstrcatA(keypath, "Installer\\UserData\\");
7836     lstrcatA(keypath, usersid);
7837     lstrcatA(keypath, "\\Products\\");
7838     lstrcatA(keypath, prod_squashed);
7839
7840     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7842
7843     /* user product key exists */
7844     hprod = 0xdeadbeef;
7845     r = MsiOpenProductA(prodcode, &hprod);
7846     ok(r == ERROR_UNKNOWN_PRODUCT,
7847        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7848     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7849
7850     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7852
7853     /* InstallProperties key exists */
7854     hprod = 0xdeadbeef;
7855     r = MsiOpenProductA(prodcode, &hprod);
7856     ok(r == ERROR_UNKNOWN_PRODUCT,
7857        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7858     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7859
7860     lstrcpyA(val, path);
7861     lstrcatA(val, "\\winetest.msi");
7862     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7863                          (const BYTE *)val, lstrlenA(val) + 1);
7864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7865
7866     /* LocalPackage value exists */
7867     hprod = 0xdeadbeef;
7868     r = MsiOpenProductA(prodcode, &hprod);
7869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7870     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7871
7872     size = MAX_PATH;
7873     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7875     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7876     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7877
7878     MsiCloseHandle(hprod);
7879
7880     RegDeleteValueA(props, "LocalPackage");
7881     delete_key(props, "", access & KEY_WOW64_64KEY);
7882     RegCloseKey(props);
7883     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7884     RegCloseKey(userkey);
7885     RegDeleteKeyA(prodkey, "");
7886     RegCloseKey(prodkey);
7887
7888     /* MSIINSTALLCONTEXT_MACHINE */
7889
7890     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7891     lstrcatA(keypath, prod_squashed);
7892
7893     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7895
7896     /* managed product key exists */
7897     hprod = 0xdeadbeef;
7898     r = MsiOpenProductA(prodcode, &hprod);
7899     ok(r == ERROR_UNKNOWN_PRODUCT,
7900        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7901     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7902
7903     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7904     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7905     lstrcatA(keypath, prod_squashed);
7906
7907     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7909
7910     /* user product key exists */
7911     hprod = 0xdeadbeef;
7912     r = MsiOpenProductA(prodcode, &hprod);
7913     ok(r == ERROR_UNKNOWN_PRODUCT,
7914        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7915     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7916
7917     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7919
7920     /* InstallProperties key exists */
7921     hprod = 0xdeadbeef;
7922     r = MsiOpenProductA(prodcode, &hprod);
7923     ok(r == ERROR_UNKNOWN_PRODUCT,
7924        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7925     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7926
7927     lstrcpyA(val, path);
7928     lstrcatA(val, "\\winetest.msi");
7929     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7930                          (const BYTE *)val, lstrlenA(val) + 1);
7931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7932
7933     /* LocalPackage value exists */
7934     hprod = 0xdeadbeef;
7935     r = MsiOpenProductA(prodcode, &hprod);
7936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7937     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7938
7939     size = MAX_PATH;
7940     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7942     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7943     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7944
7945     MsiCloseHandle(hprod);
7946
7947     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7948                          (const BYTE *)"winetest.msi", 13);
7949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7950
7951     /* LocalPackage has just the package name */
7952     hprod = 0xdeadbeef;
7953     r = MsiOpenProductA(prodcode, &hprod);
7954     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7955     {
7956         skip("Not enough rights to perform tests\n");
7957         goto error;
7958     }
7959     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7960        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7961     if (r == ERROR_SUCCESS)
7962         MsiCloseHandle(hprod);
7963     else
7964         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7965
7966     lstrcpyA(val, path);
7967     lstrcatA(val, "\\winetest.msi");
7968     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7969                          (const BYTE *)val, lstrlenA(val) + 1);
7970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7971
7972     DeleteFileA(msifile);
7973
7974     /* local package does not exist */
7975     hprod = 0xdeadbeef;
7976     r = MsiOpenProductA(prodcode, &hprod);
7977     ok(r == ERROR_UNKNOWN_PRODUCT,
7978        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7979     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7980
7981 error:
7982     RegDeleteValueA(props, "LocalPackage");
7983     delete_key(props, "", access & KEY_WOW64_64KEY);
7984     RegCloseKey(props);
7985     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7986     RegCloseKey(userkey);
7987     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7988     RegCloseKey(prodkey);
7989
7990     DeleteFileA(msifile);
7991     LocalFree(usersid);
7992 }
7993
7994 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7995 {
7996     MSIINSTALLCONTEXT context;
7997     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7998     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7999     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8000     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8001     HKEY prodkey, patches, udprod, udpatch, hpatch;
8002     DWORD size, data;
8003     LONG res;
8004     UINT r;
8005     REGSAM access = KEY_ALL_ACCESS;
8006
8007     create_test_guid(prodcode, prod_squashed);
8008     create_test_guid(patch, patch_squashed);
8009
8010     if (is_wow64)
8011         access |= KEY_WOW64_64KEY;
8012
8013     /* MSIPATCHSTATE_APPLIED */
8014
8015     lstrcpyA(patchcode, "apple");
8016     lstrcpyA(targetprod, "banana");
8017     context = 0xdeadbeef;
8018     lstrcpyA(targetsid, "kiwi");
8019     size = MAX_PATH;
8020     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8021                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8022                            &context, targetsid, &size);
8023     if (r == ERROR_ACCESS_DENIED)
8024     {
8025         skip("Not enough rights to perform tests\n");
8026         return;
8027     }
8028     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8029     ok(!lstrcmpA(patchcode, "apple"),
8030        "Expected patchcode to be unchanged, got %s\n", patchcode);
8031     ok(!lstrcmpA(targetprod, "banana"),
8032        "Expected targetprod to be unchanged, got %s\n", targetprod);
8033     ok(context == 0xdeadbeef,
8034        "Expected context to be unchanged, got %d\n", context);
8035     ok(!lstrcmpA(targetsid, "kiwi"),
8036        "Expected targetsid to be unchanged, got %s\n", targetsid);
8037     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8038
8039     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8040     lstrcatA(keypath, expectedsid);
8041     lstrcatA(keypath, "\\Installer\\Products\\");
8042     lstrcatA(keypath, prod_squashed);
8043
8044     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8045     if (res == ERROR_ACCESS_DENIED)
8046     {
8047         skip("Not enough rights to perform tests\n");
8048         return;
8049     }
8050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8051
8052     /* managed product key exists */
8053     lstrcpyA(patchcode, "apple");
8054     lstrcpyA(targetprod, "banana");
8055     context = 0xdeadbeef;
8056     lstrcpyA(targetsid, "kiwi");
8057     size = MAX_PATH;
8058     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8059                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8060                            &context, targetsid, &size);
8061     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8062     ok(!lstrcmpA(patchcode, "apple"),
8063        "Expected patchcode to be unchanged, got %s\n", patchcode);
8064     ok(!lstrcmpA(targetprod, "banana"),
8065        "Expected targetprod to be unchanged, got %s\n", targetprod);
8066     ok(context == 0xdeadbeef,
8067        "Expected context to be unchanged, got %d\n", context);
8068     ok(!lstrcmpA(targetsid, "kiwi"),
8069        "Expected targetsid to be unchanged, got %s\n", targetsid);
8070     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8071
8072     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8074
8075     /* patches key exists */
8076     lstrcpyA(patchcode, "apple");
8077     lstrcpyA(targetprod, "banana");
8078     context = 0xdeadbeef;
8079     lstrcpyA(targetsid, "kiwi");
8080     size = MAX_PATH;
8081     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8082                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8083                            &context, targetsid, &size);
8084     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8085     ok(!lstrcmpA(patchcode, "apple"),
8086        "Expected patchcode to be unchanged, got %s\n", patchcode);
8087     ok(!lstrcmpA(targetprod, "banana"),
8088        "Expected targetprod to be unchanged, got %s\n", targetprod);
8089     ok(context == 0xdeadbeef,
8090        "Expected context to be unchanged, got %d\n", context);
8091     ok(!lstrcmpA(targetsid, "kiwi"),
8092        "Expected targetsid to be unchanged, got %s\n", targetsid);
8093     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8094
8095     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8096                          (const BYTE *)patch_squashed,
8097                          lstrlenA(patch_squashed) + 1);
8098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8099
8100     /* Patches value exists, is not REG_MULTI_SZ */
8101     lstrcpyA(patchcode, "apple");
8102     lstrcpyA(targetprod, "banana");
8103     context = 0xdeadbeef;
8104     lstrcpyA(targetsid, "kiwi");
8105     size = MAX_PATH;
8106     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8107                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8108                            &context, targetsid, &size);
8109     ok(r == ERROR_BAD_CONFIGURATION,
8110        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8111     ok(!lstrcmpA(patchcode, "apple"),
8112        "Expected patchcode to be unchanged, got %s\n", patchcode);
8113     ok(!lstrcmpA(targetprod, "banana"),
8114        "Expected targetprod to be unchanged, got %s\n", targetprod);
8115     ok(context == 0xdeadbeef,
8116        "Expected context to be unchanged, got %d\n", context);
8117     ok(!lstrcmpA(targetsid, "kiwi"),
8118        "Expected targetsid to be unchanged, got %s\n", targetsid);
8119     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8120
8121     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8122                          (const BYTE *)"a\0b\0c\0\0", 7);
8123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8124
8125     /* Patches value exists, is not a squashed guid */
8126     lstrcpyA(patchcode, "apple");
8127     lstrcpyA(targetprod, "banana");
8128     context = 0xdeadbeef;
8129     lstrcpyA(targetsid, "kiwi");
8130     size = MAX_PATH;
8131     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8132                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8133                            &context, targetsid, &size);
8134     ok(r == ERROR_BAD_CONFIGURATION,
8135        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8136     ok(!lstrcmpA(patchcode, "apple"),
8137        "Expected patchcode to be unchanged, got %s\n", patchcode);
8138     ok(!lstrcmpA(targetprod, "banana"),
8139        "Expected targetprod to be unchanged, got %s\n", targetprod);
8140     ok(context == 0xdeadbeef,
8141        "Expected context to be unchanged, got %d\n", context);
8142     ok(!lstrcmpA(targetsid, "kiwi"),
8143        "Expected targetsid to be unchanged, got %s\n", targetsid);
8144     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8145
8146     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8147     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8148                          (const BYTE *)patch_squashed,
8149                          lstrlenA(patch_squashed) + 2);
8150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8151
8152     /* Patches value exists */
8153     lstrcpyA(patchcode, "apple");
8154     lstrcpyA(targetprod, "banana");
8155     context = 0xdeadbeef;
8156     lstrcpyA(targetsid, "kiwi");
8157     size = MAX_PATH;
8158     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8159                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8160                            &context, targetsid, &size);
8161     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8162     ok(!lstrcmpA(patchcode, "apple"),
8163        "Expected patchcode to be unchanged, got %s\n", patchcode);
8164     ok(!lstrcmpA(targetprod, "banana"),
8165        "Expected targetprod to be unchanged, got %s\n", targetprod);
8166     ok(context == 0xdeadbeef,
8167        "Expected context to be unchanged, got %d\n", context);
8168     ok(!lstrcmpA(targetsid, "kiwi"),
8169        "Expected targetsid to be unchanged, got %s\n", targetsid);
8170     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8171
8172     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8173                          (const BYTE *)"whatever", 9);
8174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8175
8176     /* patch squashed value exists */
8177     lstrcpyA(patchcode, "apple");
8178     lstrcpyA(targetprod, "banana");
8179     context = 0xdeadbeef;
8180     lstrcpyA(targetsid, "kiwi");
8181     size = MAX_PATH;
8182     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8183                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8184                            &context, targetsid, &size);
8185     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8186     ok(!lstrcmpA(patchcode, patch),
8187        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8188     ok(!lstrcmpA(targetprod, prodcode),
8189        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8190     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8191        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8192     ok(!lstrcmpA(targetsid, expectedsid),
8193        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8194     ok(size == lstrlenA(expectedsid),
8195        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8196
8197     /* increase the index */
8198     lstrcpyA(patchcode, "apple");
8199     lstrcpyA(targetprod, "banana");
8200     context = 0xdeadbeef;
8201     lstrcpyA(targetsid, "kiwi");
8202     size = MAX_PATH;
8203     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8204                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
8205                            &context, targetsid, &size);
8206     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8207     ok(!lstrcmpA(patchcode, "apple"),
8208        "Expected patchcode to be unchanged, got %s\n", patchcode);
8209     ok(!lstrcmpA(targetprod, "banana"),
8210        "Expected targetprod to be unchanged, got %s\n", targetprod);
8211     ok(context == 0xdeadbeef,
8212        "Expected context to be unchanged, got %d\n", context);
8213     ok(!lstrcmpA(targetsid, "kiwi"),
8214        "Expected targetsid to be unchanged, got %s\n", targetsid);
8215     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8216
8217     /* increase again */
8218     lstrcpyA(patchcode, "apple");
8219     lstrcpyA(targetprod, "banana");
8220     context = 0xdeadbeef;
8221     lstrcpyA(targetsid, "kiwi");
8222     size = MAX_PATH;
8223     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8224                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8225                            &context, targetsid, &size);
8226     ok(r == ERROR_INVALID_PARAMETER,
8227        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8228     ok(!lstrcmpA(patchcode, "apple"),
8229        "Expected patchcode to be unchanged, got %s\n", patchcode);
8230     ok(!lstrcmpA(targetprod, "banana"),
8231        "Expected targetprod to be unchanged, got %s\n", targetprod);
8232     ok(context == 0xdeadbeef,
8233        "Expected context to be unchanged, got %d\n", context);
8234     ok(!lstrcmpA(targetsid, "kiwi"),
8235        "Expected targetsid to be unchanged, got %s\n", targetsid);
8236     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8237
8238     /* szPatchCode is NULL */
8239     lstrcpyA(targetprod, "banana");
8240     context = 0xdeadbeef;
8241     lstrcpyA(targetsid, "kiwi");
8242     size = MAX_PATH;
8243     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8244                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8245                            &context, targetsid, &size);
8246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8247     ok(!lstrcmpA(targetprod, prodcode),
8248        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8249     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8250        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8251     ok(!lstrcmpA(targetsid, expectedsid),
8252        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8253     ok(size == lstrlenA(expectedsid),
8254        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8255
8256     /* szTargetProductCode is NULL */
8257     lstrcpyA(patchcode, "apple");
8258     context = 0xdeadbeef;
8259     lstrcpyA(targetsid, "kiwi");
8260     size = MAX_PATH;
8261     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8262                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8263                            &context, targetsid, &size);
8264     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8265     ok(!lstrcmpA(patchcode, patch),
8266        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8267     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8268        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8269     ok(!lstrcmpA(targetsid, expectedsid),
8270        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8271     ok(size == lstrlenA(expectedsid),
8272        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8273
8274     /* pdwTargetProductContext is NULL */
8275     lstrcpyA(patchcode, "apple");
8276     lstrcpyA(targetprod, "banana");
8277     lstrcpyA(targetsid, "kiwi");
8278     size = MAX_PATH;
8279     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8280                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8281                            NULL, targetsid, &size);
8282     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8283     ok(!lstrcmpA(patchcode, patch),
8284        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8285     ok(!lstrcmpA(targetprod, prodcode),
8286        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8287     ok(!lstrcmpA(targetsid, expectedsid),
8288        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8289     ok(size == lstrlenA(expectedsid),
8290        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8291
8292     /* szTargetUserSid is NULL */
8293     lstrcpyA(patchcode, "apple");
8294     lstrcpyA(targetprod, "banana");
8295     context = 0xdeadbeef;
8296     size = MAX_PATH;
8297     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8298                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8299                            &context, NULL, &size);
8300     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8301     ok(!lstrcmpA(patchcode, patch),
8302        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8303     ok(!lstrcmpA(targetprod, prodcode),
8304        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8305     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8306        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8307     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8308        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8309
8310     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8311     lstrcpyA(patchcode, "apple");
8312     lstrcpyA(targetprod, "banana");
8313     context = 0xdeadbeef;
8314     lstrcpyA(targetsid, "kiwi");
8315     size = lstrlenA(expectedsid);
8316     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8317                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8318                            &context, targetsid, &size);
8319     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8320     ok(!lstrcmpA(patchcode, patch),
8321        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8322     ok(!lstrcmpA(targetprod, prodcode),
8323        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8324     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8325        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8326     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8327        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8328     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8329        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8330
8331     /* pcchTargetUserSid has enough room for NULL terminator */
8332     lstrcpyA(patchcode, "apple");
8333     lstrcpyA(targetprod, "banana");
8334     context = 0xdeadbeef;
8335     lstrcpyA(targetsid, "kiwi");
8336     size = lstrlenA(expectedsid) + 1;
8337     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8338                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8339                            &context, targetsid, &size);
8340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8341     ok(!lstrcmpA(patchcode, patch),
8342        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8343     ok(!lstrcmpA(targetprod, prodcode),
8344        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8345     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8346        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8347     ok(!lstrcmpA(targetsid, expectedsid),
8348        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8349     ok(size == lstrlenA(expectedsid),
8350        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8351
8352     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8353     lstrcpyA(patchcode, "apple");
8354     lstrcpyA(targetprod, "banana");
8355     context = 0xdeadbeef;
8356     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8357                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8358                            &context, NULL, NULL);
8359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8360     ok(!lstrcmpA(patchcode, patch),
8361        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8362     ok(!lstrcmpA(targetprod, prodcode),
8363        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8364     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8365        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8366
8367     /* MSIPATCHSTATE_SUPERSEDED */
8368
8369     lstrcpyA(patchcode, "apple");
8370     lstrcpyA(targetprod, "banana");
8371     context = 0xdeadbeef;
8372     lstrcpyA(targetsid, "kiwi");
8373     size = MAX_PATH;
8374     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8375                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8376                            &context, targetsid, &size);
8377     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8378     ok(!lstrcmpA(patchcode, "apple"),
8379        "Expected patchcode to be unchanged, got %s\n", patchcode);
8380     ok(!lstrcmpA(targetprod, "banana"),
8381        "Expected targetprod to be unchanged, got %s\n", targetprod);
8382     ok(context == 0xdeadbeef,
8383        "Expected context to be unchanged, got %d\n", context);
8384     ok(!lstrcmpA(targetsid, "kiwi"),
8385        "Expected targetsid to be unchanged, got %s\n", targetsid);
8386     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8387
8388     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8389     lstrcatA(keypath, expectedsid);
8390     lstrcatA(keypath, "\\Products\\");
8391     lstrcatA(keypath, prod_squashed);
8392
8393     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8395
8396     /* UserData product key exists */
8397     lstrcpyA(patchcode, "apple");
8398     lstrcpyA(targetprod, "banana");
8399     context = 0xdeadbeef;
8400     lstrcpyA(targetsid, "kiwi");
8401     size = MAX_PATH;
8402     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8403                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8404                            &context, targetsid, &size);
8405     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8406     ok(!lstrcmpA(patchcode, "apple"),
8407        "Expected patchcode to be unchanged, got %s\n", patchcode);
8408     ok(!lstrcmpA(targetprod, "banana"),
8409        "Expected targetprod to be unchanged, got %s\n", targetprod);
8410     ok(context == 0xdeadbeef,
8411        "Expected context to be unchanged, got %d\n", context);
8412     ok(!lstrcmpA(targetsid, "kiwi"),
8413        "Expected targetsid to be unchanged, got %s\n", targetsid);
8414     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8415
8416     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8418
8419     /* UserData patches key exists */
8420     lstrcpyA(patchcode, "apple");
8421     lstrcpyA(targetprod, "banana");
8422     context = 0xdeadbeef;
8423     lstrcpyA(targetsid, "kiwi");
8424     size = MAX_PATH;
8425     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8426                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8427                            &context, targetsid, &size);
8428     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8429     ok(!lstrcmpA(patchcode, "apple"),
8430        "Expected patchcode to be unchanged, got %s\n", patchcode);
8431     ok(!lstrcmpA(targetprod, "banana"),
8432        "Expected targetprod to be unchanged, got %s\n", targetprod);
8433     ok(context == 0xdeadbeef,
8434        "Expected context to be unchanged, got %d\n", context);
8435     ok(!lstrcmpA(targetsid, "kiwi"),
8436        "Expected targetsid to be unchanged, got %s\n", targetsid);
8437     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8438
8439     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8441
8442     /* specific UserData patch key exists */
8443     lstrcpyA(patchcode, "apple");
8444     lstrcpyA(targetprod, "banana");
8445     context = 0xdeadbeef;
8446     lstrcpyA(targetsid, "kiwi");
8447     size = MAX_PATH;
8448     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8449                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8450                            &context, targetsid, &size);
8451     ok(r == ERROR_BAD_CONFIGURATION,
8452        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8453     ok(!lstrcmpA(patchcode, "apple"),
8454        "Expected patchcode to be unchanged, got %s\n", patchcode);
8455     ok(!lstrcmpA(targetprod, "banana"),
8456        "Expected targetprod to be unchanged, got %s\n", targetprod);
8457     ok(context == 0xdeadbeef,
8458        "Expected context to be unchanged, got %d\n", context);
8459     ok(!lstrcmpA(targetsid, "kiwi"),
8460        "Expected targetsid to be unchanged, got %s\n", targetsid);
8461     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8462
8463     data = MSIPATCHSTATE_SUPERSEDED;
8464     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8465                          (const BYTE *)&data, sizeof(DWORD));
8466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8467
8468     /* State value exists */
8469     lstrcpyA(patchcode, "apple");
8470     lstrcpyA(targetprod, "banana");
8471     context = 0xdeadbeef;
8472     lstrcpyA(targetsid, "kiwi");
8473     size = MAX_PATH;
8474     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8475                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8476                            &context, targetsid, &size);
8477     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8478     ok(!lstrcmpA(patchcode, patch),
8479        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8480     ok(!lstrcmpA(targetprod, prodcode),
8481        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8482     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8483        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8484     ok(!lstrcmpA(targetsid, expectedsid),
8485        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8486     ok(size == lstrlenA(expectedsid),
8487        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8488
8489     /* MSIPATCHSTATE_OBSOLETED */
8490
8491     lstrcpyA(patchcode, "apple");
8492     lstrcpyA(targetprod, "banana");
8493     context = 0xdeadbeef;
8494     lstrcpyA(targetsid, "kiwi");
8495     size = MAX_PATH;
8496     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8497                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8498                            &context, targetsid, &size);
8499     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8500     ok(!lstrcmpA(patchcode, "apple"),
8501        "Expected patchcode to be unchanged, got %s\n", patchcode);
8502     ok(!lstrcmpA(targetprod, "banana"),
8503        "Expected targetprod to be unchanged, got %s\n", targetprod);
8504     ok(context == 0xdeadbeef,
8505        "Expected context to be unchanged, got %d\n", context);
8506     ok(!lstrcmpA(targetsid, "kiwi"),
8507        "Expected targetsid to be unchanged, got %s\n", targetsid);
8508     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8509
8510     data = MSIPATCHSTATE_OBSOLETED;
8511     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8512                          (const BYTE *)&data, sizeof(DWORD));
8513     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8514
8515     /* State value is obsoleted */
8516     lstrcpyA(patchcode, "apple");
8517     lstrcpyA(targetprod, "banana");
8518     context = 0xdeadbeef;
8519     lstrcpyA(targetsid, "kiwi");
8520     size = MAX_PATH;
8521     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8522                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8523                            &context, targetsid, &size);
8524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8525     ok(!lstrcmpA(patchcode, patch),
8526        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8527     ok(!lstrcmpA(targetprod, prodcode),
8528        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8529     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8530        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8531     ok(!lstrcmpA(targetsid, expectedsid),
8532        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8533     ok(size == lstrlenA(expectedsid),
8534        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8535
8536     /* MSIPATCHSTATE_REGISTERED */
8537     /* FIXME */
8538
8539     /* MSIPATCHSTATE_ALL */
8540
8541     /* 1st */
8542     lstrcpyA(patchcode, "apple");
8543     lstrcpyA(targetprod, "banana");
8544     context = 0xdeadbeef;
8545     lstrcpyA(targetsid, "kiwi");
8546     size = MAX_PATH;
8547     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8548                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8549                            &context, targetsid, &size);
8550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8551     ok(!lstrcmpA(patchcode, patch),
8552        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8553     ok(!lstrcmpA(targetprod, prodcode),
8554        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8555     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8556        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8557     ok(!lstrcmpA(targetsid, expectedsid),
8558        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8559     ok(size == lstrlenA(expectedsid),
8560        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8561
8562     /* same patch in multiple places, only one is enumerated */
8563     lstrcpyA(patchcode, "apple");
8564     lstrcpyA(targetprod, "banana");
8565     context = 0xdeadbeef;
8566     lstrcpyA(targetsid, "kiwi");
8567     size = MAX_PATH;
8568     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8569                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8570                            &context, targetsid, &size);
8571     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8572     ok(!lstrcmpA(patchcode, "apple"),
8573        "Expected patchcode to be unchanged, got %s\n", patchcode);
8574     ok(!lstrcmpA(targetprod, "banana"),
8575        "Expected targetprod to be unchanged, got %s\n", targetprod);
8576     ok(context == 0xdeadbeef,
8577        "Expected context to be unchanged, got %d\n", context);
8578     ok(!lstrcmpA(targetsid, "kiwi"),
8579        "Expected targetsid to be unchanged, got %s\n", targetsid);
8580     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8581
8582     RegDeleteValueA(hpatch, "State");
8583     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8584     RegCloseKey(hpatch);
8585     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8586     RegCloseKey(udpatch);
8587     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8588     RegCloseKey(udprod);
8589     RegDeleteValueA(patches, "Patches");
8590     delete_key(patches, "", access & KEY_WOW64_64KEY);
8591     RegCloseKey(patches);
8592     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8593     RegCloseKey(prodkey);
8594 }
8595
8596 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8597 {
8598     MSIINSTALLCONTEXT context;
8599     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8600     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8601     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8602     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8603     HKEY prodkey, patches, udprod, udpatch;
8604     HKEY userkey, hpatch;
8605     DWORD size, data;
8606     LONG res;
8607     UINT r;
8608     REGSAM access = KEY_ALL_ACCESS;
8609
8610     create_test_guid(prodcode, prod_squashed);
8611     create_test_guid(patch, patch_squashed);
8612
8613     if (is_wow64)
8614         access |= KEY_WOW64_64KEY;
8615
8616     /* MSIPATCHSTATE_APPLIED */
8617
8618     lstrcpyA(patchcode, "apple");
8619     lstrcpyA(targetprod, "banana");
8620     context = 0xdeadbeef;
8621     lstrcpyA(targetsid, "kiwi");
8622     size = MAX_PATH;
8623     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8624                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8625                            &context, targetsid, &size);
8626     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8627     ok(!lstrcmpA(patchcode, "apple"),
8628        "Expected patchcode to be unchanged, got %s\n", patchcode);
8629     ok(!lstrcmpA(targetprod, "banana"),
8630        "Expected targetprod to be unchanged, got %s\n", targetprod);
8631     ok(context == 0xdeadbeef,
8632        "Expected context to be unchanged, got %d\n", context);
8633     ok(!lstrcmpA(targetsid, "kiwi"),
8634        "Expected targetsid to be unchanged, got %s\n", targetsid);
8635     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8636
8637     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8638     lstrcatA(keypath, prod_squashed);
8639
8640     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8642
8643     /* current user product key exists */
8644     lstrcpyA(patchcode, "apple");
8645     lstrcpyA(targetprod, "banana");
8646     context = 0xdeadbeef;
8647     lstrcpyA(targetsid, "kiwi");
8648     size = MAX_PATH;
8649     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8650                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8651                            &context, targetsid, &size);
8652     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8653     ok(!lstrcmpA(patchcode, "apple"),
8654        "Expected patchcode to be unchanged, got %s\n", patchcode);
8655     ok(!lstrcmpA(targetprod, "banana"),
8656        "Expected targetprod to be unchanged, got %s\n", targetprod);
8657     ok(context == 0xdeadbeef,
8658        "Expected context to be unchanged, got %d\n", context);
8659     ok(!lstrcmpA(targetsid, "kiwi"),
8660        "Expected targetsid to be unchanged, got %s\n", targetsid);
8661     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8662
8663     res = RegCreateKeyA(prodkey, "Patches", &patches);
8664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8665
8666     /* Patches key exists */
8667     lstrcpyA(patchcode, "apple");
8668     lstrcpyA(targetprod, "banana");
8669     context = 0xdeadbeef;
8670     lstrcpyA(targetsid, "kiwi");
8671     size = MAX_PATH;
8672     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8673                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8674                            &context, targetsid, &size);
8675     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8676     ok(!lstrcmpA(patchcode, "apple"),
8677        "Expected patchcode to be unchanged, got %s\n", patchcode);
8678     ok(!lstrcmpA(targetprod, "banana"),
8679        "Expected targetprod to be unchanged, got %s\n", targetprod);
8680     ok(context == 0xdeadbeef,
8681        "Expected context to be unchanged, got %d\n", context);
8682     ok(!lstrcmpA(targetsid, "kiwi"),
8683        "Expected targetsid to be unchanged, got %s\n", targetsid);
8684     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8685
8686     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8687                          (const BYTE *)patch_squashed,
8688                          lstrlenA(patch_squashed) + 1);
8689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8690
8691     /* Patches value exists, is not REG_MULTI_SZ */
8692     lstrcpyA(patchcode, "apple");
8693     lstrcpyA(targetprod, "banana");
8694     context = 0xdeadbeef;
8695     lstrcpyA(targetsid, "kiwi");
8696     size = MAX_PATH;
8697     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8698                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8699                            &context, targetsid, &size);
8700     ok(r == ERROR_BAD_CONFIGURATION,
8701        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8702     ok(!lstrcmpA(patchcode, "apple"),
8703        "Expected patchcode to be unchanged, got %s\n", patchcode);
8704     ok(!lstrcmpA(targetprod, "banana"),
8705        "Expected targetprod to be unchanged, got %s\n", targetprod);
8706     ok(context == 0xdeadbeef,
8707        "Expected context to be unchanged, got %d\n", context);
8708     ok(!lstrcmpA(targetsid, "kiwi"),
8709        "Expected targetsid to be unchanged, got %s\n", targetsid);
8710     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8711
8712     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8713                          (const BYTE *)"a\0b\0c\0\0", 7);
8714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8715
8716     /* Patches value exists, is not a squashed guid */
8717     lstrcpyA(patchcode, "apple");
8718     lstrcpyA(targetprod, "banana");
8719     context = 0xdeadbeef;
8720     lstrcpyA(targetsid, "kiwi");
8721     size = MAX_PATH;
8722     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8723                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8724                            &context, targetsid, &size);
8725     ok(r == ERROR_BAD_CONFIGURATION,
8726        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8727     ok(!lstrcmpA(patchcode, "apple"),
8728        "Expected patchcode to be unchanged, got %s\n", patchcode);
8729     ok(!lstrcmpA(targetprod, "banana"),
8730        "Expected targetprod to be unchanged, got %s\n", targetprod);
8731     ok(context == 0xdeadbeef,
8732        "Expected context to be unchanged, got %d\n", context);
8733     ok(!lstrcmpA(targetsid, "kiwi"),
8734        "Expected targetsid to be unchanged, got %s\n", targetsid);
8735     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8736
8737     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8738     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8739                          (const BYTE *)patch_squashed,
8740                          lstrlenA(patch_squashed) + 2);
8741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8742
8743     /* Patches value exists */
8744     lstrcpyA(patchcode, "apple");
8745     lstrcpyA(targetprod, "banana");
8746     context = 0xdeadbeef;
8747     lstrcpyA(targetsid, "kiwi");
8748     size = MAX_PATH;
8749     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8750                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8751                            &context, targetsid, &size);
8752     ok(r == ERROR_NO_MORE_ITEMS ||
8753        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8754        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8755     ok(!lstrcmpA(patchcode, "apple"),
8756        "Expected patchcode to be unchanged, got %s\n", patchcode);
8757     ok(!lstrcmpA(targetprod, "banana"),
8758        "Expected targetprod to be unchanged, got %s\n", targetprod);
8759     ok(context == 0xdeadbeef,
8760        "Expected context to be unchanged, got %d\n", context);
8761     ok(!lstrcmpA(targetsid, "kiwi"),
8762        "Expected targetsid to be unchanged, got %s\n", targetsid);
8763     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8764
8765     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8766                          (const BYTE *)"whatever", 9);
8767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8768
8769     /* patch code value exists */
8770     lstrcpyA(patchcode, "apple");
8771     lstrcpyA(targetprod, "banana");
8772     context = 0xdeadbeef;
8773     lstrcpyA(targetsid, "kiwi");
8774     size = MAX_PATH;
8775     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8776                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8777                            &context, targetsid, &size);
8778     ok(r == ERROR_NO_MORE_ITEMS ||
8779        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8780        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8781     ok(!lstrcmpA(patchcode, "apple"),
8782        "Expected patchcode to be unchanged, got %s\n", patchcode);
8783     ok(!lstrcmpA(targetprod, "banana"),
8784        "Expected targetprod to be unchanged, got %s\n", targetprod);
8785     ok(context == 0xdeadbeef,
8786        "Expected context to be unchanged, got %d\n", context);
8787     ok(!lstrcmpA(targetsid, "kiwi"),
8788        "Expected targetsid to be unchanged, got %s\n", targetsid);
8789     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8790
8791     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8792     lstrcatA(keypath, expectedsid);
8793     lstrcatA(keypath, "\\Patches\\");
8794     lstrcatA(keypath, patch_squashed);
8795
8796     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8797     if (res == ERROR_ACCESS_DENIED)
8798     {
8799         skip("Not enough rights to perform tests\n");
8800         goto error;
8801     }
8802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8803
8804     /* userdata patch key exists */
8805     lstrcpyA(patchcode, "apple");
8806     lstrcpyA(targetprod, "banana");
8807     context = 0xdeadbeef;
8808     lstrcpyA(targetsid, "kiwi");
8809     size = MAX_PATH;
8810     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8811                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8812                            &context, targetsid, &size);
8813     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8814     ok(!lstrcmpA(patchcode, patch),
8815        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8816     ok(!lstrcmpA(targetprod, prodcode),
8817        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8818     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8819        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8820     ok(!lstrcmpA(targetsid, expectedsid),
8821        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8822     ok(size == lstrlenA(expectedsid),
8823        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8824
8825     /* MSIPATCHSTATE_SUPERSEDED */
8826
8827     lstrcpyA(patchcode, "apple");
8828     lstrcpyA(targetprod, "banana");
8829     context = 0xdeadbeef;
8830     lstrcpyA(targetsid, "kiwi");
8831     size = MAX_PATH;
8832     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8833                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8834                            &context, targetsid, &size);
8835     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8836     ok(!lstrcmpA(patchcode, "apple"),
8837        "Expected patchcode to be unchanged, got %s\n", patchcode);
8838     ok(!lstrcmpA(targetprod, "banana"),
8839        "Expected targetprod to be unchanged, got %s\n", targetprod);
8840     ok(context == 0xdeadbeef,
8841        "Expected context to be unchanged, got %d\n", context);
8842     ok(!lstrcmpA(targetsid, "kiwi"),
8843        "Expected targetsid to be unchanged, got %s\n", targetsid);
8844     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8845
8846     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8847     lstrcatA(keypath, expectedsid);
8848     lstrcatA(keypath, "\\Products\\");
8849     lstrcatA(keypath, prod_squashed);
8850
8851     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8852     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8853
8854     /* UserData product key exists */
8855     lstrcpyA(patchcode, "apple");
8856     lstrcpyA(targetprod, "banana");
8857     context = 0xdeadbeef;
8858     lstrcpyA(targetsid, "kiwi");
8859     size = MAX_PATH;
8860     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8861                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8862                            &context, targetsid, &size);
8863     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8864     ok(!lstrcmpA(patchcode, "apple"),
8865        "Expected patchcode to be unchanged, got %s\n", patchcode);
8866     ok(!lstrcmpA(targetprod, "banana"),
8867        "Expected targetprod to be unchanged, got %s\n", targetprod);
8868     ok(context == 0xdeadbeef,
8869        "Expected context to be unchanged, got %d\n", context);
8870     ok(!lstrcmpA(targetsid, "kiwi"),
8871        "Expected targetsid to be unchanged, got %s\n", targetsid);
8872     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8873
8874     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8876
8877     /* UserData patches key exists */
8878     lstrcpyA(patchcode, "apple");
8879     lstrcpyA(targetprod, "banana");
8880     context = 0xdeadbeef;
8881     lstrcpyA(targetsid, "kiwi");
8882     size = MAX_PATH;
8883     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8884                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8885                            &context, targetsid, &size);
8886     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8887     ok(!lstrcmpA(patchcode, "apple"),
8888        "Expected patchcode to be unchanged, got %s\n", patchcode);
8889     ok(!lstrcmpA(targetprod, "banana"),
8890        "Expected targetprod to be unchanged, got %s\n", targetprod);
8891     ok(context == 0xdeadbeef,
8892        "Expected context to be unchanged, got %d\n", context);
8893     ok(!lstrcmpA(targetsid, "kiwi"),
8894        "Expected targetsid to be unchanged, got %s\n", targetsid);
8895     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8896
8897     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8899
8900     /* specific UserData patch key exists */
8901     lstrcpyA(patchcode, "apple");
8902     lstrcpyA(targetprod, "banana");
8903     context = 0xdeadbeef;
8904     lstrcpyA(targetsid, "kiwi");
8905     size = MAX_PATH;
8906     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8907                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8908                            &context, targetsid, &size);
8909     ok(r == ERROR_BAD_CONFIGURATION,
8910        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8911     ok(!lstrcmpA(patchcode, "apple"),
8912        "Expected patchcode to be unchanged, got %s\n", patchcode);
8913     ok(!lstrcmpA(targetprod, "banana"),
8914        "Expected targetprod to be unchanged, got %s\n", targetprod);
8915     ok(context == 0xdeadbeef,
8916        "Expected context to be unchanged, got %d\n", context);
8917     ok(!lstrcmpA(targetsid, "kiwi"),
8918        "Expected targetsid to be unchanged, got %s\n", targetsid);
8919     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8920
8921     data = MSIPATCHSTATE_SUPERSEDED;
8922     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8923                          (const BYTE *)&data, sizeof(DWORD));
8924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8925
8926     /* State value exists */
8927     lstrcpyA(patchcode, "apple");
8928     lstrcpyA(targetprod, "banana");
8929     context = 0xdeadbeef;
8930     lstrcpyA(targetsid, "kiwi");
8931     size = MAX_PATH;
8932     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8933                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8934                            &context, targetsid, &size);
8935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8936     ok(!lstrcmpA(patchcode, patch),
8937        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8938     ok(!lstrcmpA(targetprod, prodcode),
8939        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8940     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8941        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8942     ok(!lstrcmpA(targetsid, expectedsid),
8943        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8944     ok(size == lstrlenA(expectedsid),
8945        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8946
8947     /* MSIPATCHSTATE_OBSOLETED */
8948
8949     lstrcpyA(patchcode, "apple");
8950     lstrcpyA(targetprod, "banana");
8951     context = 0xdeadbeef;
8952     lstrcpyA(targetsid, "kiwi");
8953     size = MAX_PATH;
8954     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8955                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8956                            &context, targetsid, &size);
8957     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8958     ok(!lstrcmpA(patchcode, "apple"),
8959        "Expected patchcode to be unchanged, got %s\n", patchcode);
8960     ok(!lstrcmpA(targetprod, "banana"),
8961        "Expected targetprod to be unchanged, got %s\n", targetprod);
8962     ok(context == 0xdeadbeef,
8963        "Expected context to be unchanged, got %d\n", context);
8964     ok(!lstrcmpA(targetsid, "kiwi"),
8965        "Expected targetsid to be unchanged, got %s\n", targetsid);
8966     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8967
8968     data = MSIPATCHSTATE_OBSOLETED;
8969     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8970                          (const BYTE *)&data, sizeof(DWORD));
8971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8972
8973     /* State value is obsoleted */
8974     lstrcpyA(patchcode, "apple");
8975     lstrcpyA(targetprod, "banana");
8976     context = 0xdeadbeef;
8977     lstrcpyA(targetsid, "kiwi");
8978     size = MAX_PATH;
8979     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8980                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8981                            &context, targetsid, &size);
8982     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8983     ok(!lstrcmpA(patchcode, patch),
8984        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8985     ok(!lstrcmpA(targetprod, prodcode),
8986        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8987     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8988        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8989     ok(!lstrcmpA(targetsid, expectedsid),
8990        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8991     ok(size == lstrlenA(expectedsid),
8992        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8993
8994     /* MSIPATCHSTATE_REGISTERED */
8995     /* FIXME */
8996
8997     /* MSIPATCHSTATE_ALL */
8998
8999     /* 1st */
9000     lstrcpyA(patchcode, "apple");
9001     lstrcpyA(targetprod, "banana");
9002     context = 0xdeadbeef;
9003     lstrcpyA(targetsid, "kiwi");
9004     size = MAX_PATH;
9005     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9006                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9007                            &context, targetsid, &size);
9008     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9009     ok(!lstrcmpA(patchcode, patch),
9010        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9011     ok(!lstrcmpA(targetprod, prodcode),
9012        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9013     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9014        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9015     ok(!lstrcmpA(targetsid, expectedsid),
9016        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9017     ok(size == lstrlenA(expectedsid),
9018        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9019
9020     /* same patch in multiple places, only one is enumerated */
9021     lstrcpyA(patchcode, "apple");
9022     lstrcpyA(targetprod, "banana");
9023     context = 0xdeadbeef;
9024     lstrcpyA(targetsid, "kiwi");
9025     size = MAX_PATH;
9026     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9027                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9028                            &context, targetsid, &size);
9029     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9030     ok(!lstrcmpA(patchcode, "apple"),
9031        "Expected patchcode to be unchanged, got %s\n", patchcode);
9032     ok(!lstrcmpA(targetprod, "banana"),
9033        "Expected targetprod to be unchanged, got %s\n", targetprod);
9034     ok(context == 0xdeadbeef,
9035        "Expected context to be unchanged, got %d\n", context);
9036     ok(!lstrcmpA(targetsid, "kiwi"),
9037        "Expected targetsid to be unchanged, got %s\n", targetsid);
9038     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9039
9040     RegDeleteValueA(hpatch, "State");
9041     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9042     RegCloseKey(hpatch);
9043     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9044     RegCloseKey(udpatch);
9045     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9046     RegCloseKey(udprod);
9047     delete_key(userkey, "", access & KEY_WOW64_64KEY);
9048     RegCloseKey(userkey);
9049     RegDeleteValueA(patches, patch_squashed);
9050     RegDeleteValueA(patches, "Patches");
9051
9052 error:
9053     RegDeleteKeyA(patches, "");
9054     RegCloseKey(patches);
9055     RegDeleteKeyA(prodkey, "");
9056     RegCloseKey(prodkey);
9057 }
9058
9059 static void test_MsiEnumPatchesEx_machine(void)
9060 {
9061     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9062     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9063     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9064     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9065     HKEY prodkey, patches, udprod, udpatch;
9066     HKEY hpatch;
9067     MSIINSTALLCONTEXT context;
9068     DWORD size, data;
9069     LONG res;
9070     UINT r;
9071     REGSAM access = KEY_ALL_ACCESS;
9072
9073     create_test_guid(prodcode, prod_squashed);
9074     create_test_guid(patch, patch_squashed);
9075
9076     if (is_wow64)
9077         access |= KEY_WOW64_64KEY;
9078
9079     /* MSIPATCHSTATE_APPLIED */
9080
9081     lstrcpyA(patchcode, "apple");
9082     lstrcpyA(targetprod, "banana");
9083     context = 0xdeadbeef;
9084     lstrcpyA(targetsid, "kiwi");
9085     size = MAX_PATH;
9086     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9087                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9088                            &context, targetsid, &size);
9089     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9090     ok(!lstrcmpA(patchcode, "apple"),
9091        "Expected patchcode to be unchanged, got %s\n", patchcode);
9092     ok(!lstrcmpA(targetprod, "banana"),
9093        "Expected targetprod to be unchanged, got %s\n", targetprod);
9094     ok(context == 0xdeadbeef,
9095        "Expected context to be unchanged, got %d\n", context);
9096     ok(!lstrcmpA(targetsid, "kiwi"),
9097        "Expected targetsid to be unchanged, got %s\n", targetsid);
9098     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9099
9100     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9101     lstrcatA(keypath, prod_squashed);
9102
9103     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9104     if (res == ERROR_ACCESS_DENIED)
9105     {
9106         skip("Not enough rights to perform tests\n");
9107         return;
9108     }
9109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9110
9111     /* local product key exists */
9112     lstrcpyA(patchcode, "apple");
9113     lstrcpyA(targetprod, "banana");
9114     context = 0xdeadbeef;
9115     lstrcpyA(targetsid, "kiwi");
9116     size = MAX_PATH;
9117     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9118                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9119                            &context, targetsid, &size);
9120     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9121     ok(!lstrcmpA(patchcode, "apple"),
9122        "Expected patchcode to be unchanged, got %s\n", patchcode);
9123     ok(!lstrcmpA(targetprod, "banana"),
9124        "Expected targetprod to be unchanged, got %s\n", targetprod);
9125     ok(context == 0xdeadbeef,
9126        "Expected context to be unchanged, got %d\n", context);
9127     ok(!lstrcmpA(targetsid, "kiwi"),
9128        "Expected targetsid to be unchanged, got %s\n", targetsid);
9129     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9130
9131     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9133
9134     /* Patches key exists */
9135     lstrcpyA(patchcode, "apple");
9136     lstrcpyA(targetprod, "banana");
9137     context = 0xdeadbeef;
9138     lstrcpyA(targetsid, "kiwi");
9139     size = MAX_PATH;
9140     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9141                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9142                            &context, targetsid, &size);
9143     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9144     ok(!lstrcmpA(patchcode, "apple"),
9145        "Expected patchcode to be unchanged, got %s\n", patchcode);
9146     ok(!lstrcmpA(targetprod, "banana"),
9147        "Expected targetprod to be unchanged, got %s\n", targetprod);
9148     ok(context == 0xdeadbeef,
9149        "Expected context to be unchanged, got %d\n", context);
9150     ok(!lstrcmpA(targetsid, "kiwi"),
9151        "Expected targetsid to be unchanged, got %s\n", targetsid);
9152     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9153
9154     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9155                          (const BYTE *)patch_squashed,
9156                          lstrlenA(patch_squashed) + 1);
9157     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9158
9159     /* Patches value exists, is not REG_MULTI_SZ */
9160     lstrcpyA(patchcode, "apple");
9161     lstrcpyA(targetprod, "banana");
9162     context = 0xdeadbeef;
9163     lstrcpyA(targetsid, "kiwi");
9164     size = MAX_PATH;
9165     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9166                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9167                            &context, targetsid, &size);
9168     ok(r == ERROR_BAD_CONFIGURATION,
9169        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9170     ok(!lstrcmpA(patchcode, "apple"),
9171        "Expected patchcode to be unchanged, got %s\n", patchcode);
9172     ok(!lstrcmpA(targetprod, "banana"),
9173        "Expected targetprod to be unchanged, got %s\n", targetprod);
9174     ok(context == 0xdeadbeef,
9175        "Expected context to be unchanged, got %d\n", context);
9176     ok(!lstrcmpA(targetsid, "kiwi"),
9177        "Expected targetsid to be unchanged, got %s\n", targetsid);
9178     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9179
9180     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9181                          (const BYTE *)"a\0b\0c\0\0", 7);
9182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9183
9184     /* Patches value exists, is not a squashed guid */
9185     lstrcpyA(patchcode, "apple");
9186     lstrcpyA(targetprod, "banana");
9187     context = 0xdeadbeef;
9188     lstrcpyA(targetsid, "kiwi");
9189     size = MAX_PATH;
9190     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9191                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9192                            &context, targetsid, &size);
9193     ok(r == ERROR_BAD_CONFIGURATION,
9194        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9195     ok(!lstrcmpA(patchcode, "apple"),
9196        "Expected patchcode to be unchanged, got %s\n", patchcode);
9197     ok(!lstrcmpA(targetprod, "banana"),
9198        "Expected targetprod to be unchanged, got %s\n", targetprod);
9199     ok(context == 0xdeadbeef,
9200        "Expected context to be unchanged, got %d\n", context);
9201     ok(!lstrcmpA(targetsid, "kiwi"),
9202        "Expected targetsid to be unchanged, got %s\n", targetsid);
9203     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9204
9205     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9206     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9207                          (const BYTE *)patch_squashed,
9208                          lstrlenA(patch_squashed) + 2);
9209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9210
9211     /* Patches value exists */
9212     lstrcpyA(patchcode, "apple");
9213     lstrcpyA(targetprod, "banana");
9214     context = 0xdeadbeef;
9215     lstrcpyA(targetsid, "kiwi");
9216     size = MAX_PATH;
9217     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9218                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9219                            &context, targetsid, &size);
9220     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9221     ok(!lstrcmpA(patchcode, "apple"),
9222        "Expected patchcode to be unchanged, got %s\n", patchcode);
9223     ok(!lstrcmpA(targetprod, "banana"),
9224        "Expected targetprod to be unchanged, got %s\n", targetprod);
9225     ok(context == 0xdeadbeef,
9226        "Expected context to be unchanged, got %d\n", context);
9227     ok(!lstrcmpA(targetsid, "kiwi"),
9228        "Expected targetsid to be unchanged, got %s\n", targetsid);
9229     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9230
9231     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9232                          (const BYTE *)"whatever", 9);
9233     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9234
9235     /* patch code value exists */
9236     lstrcpyA(patchcode, "apple");
9237     lstrcpyA(targetprod, "banana");
9238     context = 0xdeadbeef;
9239     lstrcpyA(targetsid, "kiwi");
9240     size = MAX_PATH;
9241     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9242                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9243                            &context, targetsid, &size);
9244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9245     ok(!lstrcmpA(patchcode, patch),
9246        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9247     ok(!lstrcmpA(targetprod, prodcode),
9248        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9249     ok(context == MSIINSTALLCONTEXT_MACHINE,
9250        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9251     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9252     ok(size == 0, "Expected 0, got %d\n", size);
9253
9254     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9255     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9256     lstrcatA(keypath, prod_squashed);
9257
9258     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9260
9261     /* local UserData product key exists */
9262     lstrcpyA(patchcode, "apple");
9263     lstrcpyA(targetprod, "banana");
9264     context = 0xdeadbeef;
9265     lstrcpyA(targetsid, "kiwi");
9266     size = MAX_PATH;
9267     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9268                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9269                            &context, targetsid, &size);
9270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9271     ok(!lstrcmpA(patchcode, patch),
9272        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9273     ok(!lstrcmpA(targetprod, prodcode),
9274        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9275     ok(context == MSIINSTALLCONTEXT_MACHINE,
9276        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9277     ok(!lstrcmpA(targetsid, ""),
9278        "Expected \"\", got \"%s\"\n", targetsid);
9279     ok(size == 0, "Expected 0, got %d\n", size);
9280
9281     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9283
9284     /* local UserData Patches key exists */
9285     lstrcpyA(patchcode, "apple");
9286     lstrcpyA(targetprod, "banana");
9287     context = 0xdeadbeef;
9288     lstrcpyA(targetsid, "kiwi");
9289     size = MAX_PATH;
9290     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9291                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9292                            &context, targetsid, &size);
9293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9294     ok(!lstrcmpA(patchcode, patch),
9295        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9296     ok(!lstrcmpA(targetprod, prodcode),
9297        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9298     ok(context == MSIINSTALLCONTEXT_MACHINE,
9299        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9300     ok(!lstrcmpA(targetsid, ""),
9301        "Expected \"\", got \"%s\"\n", targetsid);
9302     ok(size == 0, "Expected 0, got %d\n", size);
9303
9304     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9306
9307     /* local UserData Product patch key exists */
9308     lstrcpyA(patchcode, "apple");
9309     lstrcpyA(targetprod, "banana");
9310     context = 0xdeadbeef;
9311     lstrcpyA(targetsid, "kiwi");
9312     size = MAX_PATH;
9313     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9314                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9315                            &context, targetsid, &size);
9316     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9317     ok(!lstrcmpA(patchcode, "apple"),
9318        "Expected patchcode to be unchanged, got %s\n", patchcode);
9319     ok(!lstrcmpA(targetprod, "banana"),
9320        "Expected targetprod to be unchanged, got %s\n", targetprod);
9321     ok(context == 0xdeadbeef,
9322        "Expected context to be unchanged, got %d\n", context);
9323     ok(!lstrcmpA(targetsid, "kiwi"),
9324        "Expected targetsid to be unchanged, got %s\n", targetsid);
9325     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9326
9327     data = MSIPATCHSTATE_APPLIED;
9328     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9329                          (const BYTE *)&data, sizeof(DWORD));
9330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9331
9332     /* State value exists */
9333     lstrcpyA(patchcode, "apple");
9334     lstrcpyA(targetprod, "banana");
9335     context = 0xdeadbeef;
9336     lstrcpyA(targetsid, "kiwi");
9337     size = MAX_PATH;
9338     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9339                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9340                            &context, targetsid, &size);
9341     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9342     ok(!lstrcmpA(patchcode, patch),
9343        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9344     ok(!lstrcmpA(targetprod, prodcode),
9345        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9346     ok(context == MSIINSTALLCONTEXT_MACHINE,
9347        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9348     ok(!lstrcmpA(targetsid, ""),
9349        "Expected \"\", got \"%s\"\n", targetsid);
9350     ok(size == 0, "Expected 0, got %d\n", size);
9351
9352     /* MSIPATCHSTATE_SUPERSEDED */
9353
9354     lstrcpyA(patchcode, "apple");
9355     lstrcpyA(targetprod, "banana");
9356     context = 0xdeadbeef;
9357     lstrcpyA(targetsid, "kiwi");
9358     size = MAX_PATH;
9359     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9360                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9361                            &context, targetsid, &size);
9362     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9363     ok(!lstrcmpA(patchcode, "apple"),
9364        "Expected patchcode to be unchanged, got %s\n", patchcode);
9365     ok(!lstrcmpA(targetprod, "banana"),
9366        "Expected targetprod to be unchanged, got %s\n", targetprod);
9367     ok(context == 0xdeadbeef,
9368        "Expected context to be unchanged, got %d\n", context);
9369     ok(!lstrcmpA(targetsid, "kiwi"),
9370        "Expected targetsid to be unchanged, got %s\n", targetsid);
9371     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9372
9373     data = MSIPATCHSTATE_SUPERSEDED;
9374     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9375                          (const BYTE *)&data, sizeof(DWORD));
9376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9377
9378     /* State value is MSIPATCHSTATE_SUPERSEDED */
9379     lstrcpyA(patchcode, "apple");
9380     lstrcpyA(targetprod, "banana");
9381     context = 0xdeadbeef;
9382     lstrcpyA(targetsid, "kiwi");
9383     size = MAX_PATH;
9384     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9385                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9386                            &context, targetsid, &size);
9387     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9388     ok(!lstrcmpA(patchcode, patch),
9389        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9390     ok(!lstrcmpA(targetprod, prodcode),
9391        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9392     ok(context == MSIINSTALLCONTEXT_MACHINE,
9393        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9394     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9395     ok(size == 0, "Expected 0, got %d\n", size);
9396
9397     /* MSIPATCHSTATE_OBSOLETED */
9398
9399     lstrcpyA(patchcode, "apple");
9400     lstrcpyA(targetprod, "banana");
9401     context = 0xdeadbeef;
9402     lstrcpyA(targetsid, "kiwi");
9403     size = MAX_PATH;
9404     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9405                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9406                            &context, targetsid, &size);
9407     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9408     ok(!lstrcmpA(patchcode, "apple"),
9409        "Expected patchcode to be unchanged, got %s\n", patchcode);
9410     ok(!lstrcmpA(targetprod, "banana"),
9411        "Expected targetprod to be unchanged, got %s\n", targetprod);
9412     ok(context == 0xdeadbeef,
9413        "Expected context to be unchanged, got %d\n", context);
9414     ok(!lstrcmpA(targetsid, "kiwi"),
9415        "Expected targetsid to be unchanged, got %s\n", targetsid);
9416     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9417
9418     data = MSIPATCHSTATE_OBSOLETED;
9419     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9420                          (const BYTE *)&data, sizeof(DWORD));
9421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9422
9423     /* State value is obsoleted */
9424     lstrcpyA(patchcode, "apple");
9425     lstrcpyA(targetprod, "banana");
9426     context = 0xdeadbeef;
9427     lstrcpyA(targetsid, "kiwi");
9428     size = MAX_PATH;
9429     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9430                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9431                            &context, targetsid, &size);
9432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9433     ok(!lstrcmpA(patchcode, patch),
9434        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9435     ok(!lstrcmpA(targetprod, prodcode),
9436        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9437     ok(context == MSIINSTALLCONTEXT_MACHINE,
9438        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9439     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9440     ok(size == 0, "Expected 0, got %d\n", size);
9441
9442     /* MSIPATCHSTATE_REGISTERED */
9443     /* FIXME */
9444
9445     /* MSIPATCHSTATE_ALL */
9446
9447     /* 1st */
9448     lstrcpyA(patchcode, "apple");
9449     lstrcpyA(targetprod, "banana");
9450     context = 0xdeadbeef;
9451     lstrcpyA(targetsid, "kiwi");
9452     size = MAX_PATH;
9453     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9454                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9455                            &context, targetsid, &size);
9456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9457     ok(!lstrcmpA(patchcode, patch),
9458        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9459     ok(!lstrcmpA(targetprod, prodcode),
9460        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9461     ok(context == MSIINSTALLCONTEXT_MACHINE,
9462        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9463     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9464     ok(size == 0, "Expected 0, got %d\n", size);
9465
9466     /* same patch in multiple places, only one is enumerated */
9467     lstrcpyA(patchcode, "apple");
9468     lstrcpyA(targetprod, "banana");
9469     context = 0xdeadbeef;
9470     lstrcpyA(targetsid, "kiwi");
9471     size = MAX_PATH;
9472     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9473                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9474                            &context, targetsid, &size);
9475     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9476     ok(!lstrcmpA(patchcode, "apple"),
9477        "Expected patchcode to be unchanged, got %s\n", patchcode);
9478     ok(!lstrcmpA(targetprod, "banana"),
9479        "Expected targetprod to be unchanged, got %s\n", targetprod);
9480     ok(context == 0xdeadbeef,
9481        "Expected context to be unchanged, got %d\n", context);
9482     ok(!lstrcmpA(targetsid, "kiwi"),
9483        "Expected targetsid to be unchanged, got %s\n", targetsid);
9484     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9485
9486     RegDeleteValueA(patches, patch_squashed);
9487     RegDeleteValueA(patches, "Patches");
9488     delete_key(patches, "", access & KEY_WOW64_64KEY);
9489     RegCloseKey(patches);
9490     RegDeleteValueA(hpatch, "State");
9491     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9492     RegCloseKey(hpatch);
9493     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9494     RegCloseKey(udpatch);
9495     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9496     RegCloseKey(udprod);
9497     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9498     RegCloseKey(prodkey);
9499 }
9500
9501 static void test_MsiEnumPatchesEx(void)
9502 {
9503     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9504     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9505     CHAR patchcode[MAX_PATH];
9506     MSIINSTALLCONTEXT context;
9507     LPSTR usersid;
9508     DWORD size;
9509     UINT r;
9510
9511     if (!pMsiEnumPatchesExA)
9512     {
9513         win_skip("MsiEnumPatchesExA not implemented\n");
9514         return;
9515     }
9516
9517     create_test_guid(prodcode, prod_squashed);
9518     usersid = get_user_sid();
9519
9520     /* empty szProductCode */
9521     lstrcpyA(patchcode, "apple");
9522     lstrcpyA(targetprod, "banana");
9523     context = 0xdeadbeef;
9524     lstrcpyA(targetsid, "kiwi");
9525     size = MAX_PATH;
9526     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9527                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9528                            targetsid, &size);
9529     ok(r == ERROR_INVALID_PARAMETER,
9530        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9531     ok(!lstrcmpA(patchcode, "apple"),
9532        "Expected patchcode to be unchanged, got %s\n", patchcode);
9533     ok(!lstrcmpA(targetprod, "banana"),
9534        "Expected targetprod to be unchanged, got %s\n", targetprod);
9535     ok(context == 0xdeadbeef,
9536        "Expected context to be unchanged, got %d\n", context);
9537     ok(!lstrcmpA(targetsid, "kiwi"),
9538        "Expected targetsid to be unchanged, got %s\n", targetsid);
9539     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9540
9541     /* garbage szProductCode */
9542     lstrcpyA(patchcode, "apple");
9543     lstrcpyA(targetprod, "banana");
9544     context = 0xdeadbeef;
9545     lstrcpyA(targetsid, "kiwi");
9546     size = MAX_PATH;
9547     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9548                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9549                            targetsid, &size);
9550     ok(r == ERROR_INVALID_PARAMETER,
9551        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9552     ok(!lstrcmpA(patchcode, "apple"),
9553        "Expected patchcode to be unchanged, got %s\n", patchcode);
9554     ok(!lstrcmpA(targetprod, "banana"),
9555        "Expected targetprod to be unchanged, got %s\n", targetprod);
9556     ok(context == 0xdeadbeef,
9557        "Expected context to be unchanged, got %d\n", context);
9558     ok(!lstrcmpA(targetsid, "kiwi"),
9559        "Expected targetsid to be unchanged, got %s\n", targetsid);
9560     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9561
9562     /* guid without brackets */
9563     lstrcpyA(patchcode, "apple");
9564     lstrcpyA(targetprod, "banana");
9565     context = 0xdeadbeef;
9566     lstrcpyA(targetsid, "kiwi");
9567     size = MAX_PATH;
9568     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9569                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9570                            0, patchcode, targetprod, &context,
9571                            targetsid, &size);
9572     ok(r == ERROR_INVALID_PARAMETER,
9573        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9574     ok(!lstrcmpA(patchcode, "apple"),
9575        "Expected patchcode to be unchanged, got %s\n", patchcode);
9576     ok(!lstrcmpA(targetprod, "banana"),
9577        "Expected targetprod to be unchanged, got %s\n", targetprod);
9578     ok(context == 0xdeadbeef,
9579        "Expected context to be unchanged, got %d\n", context);
9580     ok(!lstrcmpA(targetsid, "kiwi"),
9581        "Expected targetsid to be unchanged, got %s\n", targetsid);
9582     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9583
9584     /* guid with brackets */
9585     lstrcpyA(patchcode, "apple");
9586     lstrcpyA(targetprod, "banana");
9587     context = 0xdeadbeef;
9588     lstrcpyA(targetsid, "kiwi");
9589     size = MAX_PATH;
9590     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9591                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9592                            0, patchcode, targetprod, &context,
9593                            targetsid, &size);
9594     ok(r == ERROR_NO_MORE_ITEMS,
9595        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9596     ok(!lstrcmpA(patchcode, "apple"),
9597        "Expected patchcode to be unchanged, got %s\n", patchcode);
9598     ok(!lstrcmpA(targetprod, "banana"),
9599        "Expected targetprod to be unchanged, got %s\n", targetprod);
9600     ok(context == 0xdeadbeef,
9601        "Expected context to be unchanged, got %d\n", context);
9602     ok(!lstrcmpA(targetsid, "kiwi"),
9603        "Expected targetsid to be unchanged, got %s\n", targetsid);
9604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9605
9606     /* szUserSid is S-1-5-18 */
9607     lstrcpyA(patchcode, "apple");
9608     lstrcpyA(targetprod, "banana");
9609     context = 0xdeadbeef;
9610     lstrcpyA(targetsid, "kiwi");
9611     size = MAX_PATH;
9612     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9613                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9614                            0, patchcode, targetprod, &context,
9615                            targetsid, &size);
9616     ok(r == ERROR_INVALID_PARAMETER,
9617        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9618     ok(!lstrcmpA(patchcode, "apple"),
9619        "Expected patchcode to be unchanged, got %s\n", patchcode);
9620     ok(!lstrcmpA(targetprod, "banana"),
9621        "Expected targetprod to be unchanged, got %s\n", targetprod);
9622     ok(context == 0xdeadbeef,
9623        "Expected context to be unchanged, got %d\n", context);
9624     ok(!lstrcmpA(targetsid, "kiwi"),
9625        "Expected targetsid to be unchanged, got %s\n", targetsid);
9626     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9627
9628     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9629     lstrcpyA(patchcode, "apple");
9630     lstrcpyA(targetprod, "banana");
9631     context = 0xdeadbeef;
9632     lstrcpyA(targetsid, "kiwi");
9633     size = MAX_PATH;
9634     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9635                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9636                            &context, targetsid, &size);
9637     ok(r == ERROR_INVALID_PARAMETER,
9638        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9639     ok(!lstrcmpA(patchcode, "apple"),
9640        "Expected patchcode to be unchanged, got %s\n", patchcode);
9641     ok(!lstrcmpA(targetprod, "banana"),
9642        "Expected targetprod to be unchanged, got %s\n", targetprod);
9643     ok(context == 0xdeadbeef,
9644        "Expected context to be unchanged, got %d\n", context);
9645     ok(!lstrcmpA(targetsid, "kiwi"),
9646        "Expected targetsid to be unchanged, got %s\n", targetsid);
9647     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9648
9649     /* dwContext is out of bounds */
9650     lstrcpyA(patchcode, "apple");
9651     lstrcpyA(targetprod, "banana");
9652     context = 0xdeadbeef;
9653     lstrcpyA(targetsid, "kiwi");
9654     size = MAX_PATH;
9655     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9656                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9657                            &context, targetsid, &size);
9658     ok(r == ERROR_INVALID_PARAMETER,
9659        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9660     ok(!lstrcmpA(patchcode, "apple"),
9661        "Expected patchcode to be unchanged, got %s\n", patchcode);
9662     ok(!lstrcmpA(targetprod, "banana"),
9663        "Expected targetprod to be unchanged, got %s\n", targetprod);
9664     ok(context == 0xdeadbeef,
9665        "Expected context to be unchanged, got %d\n", context);
9666     ok(!lstrcmpA(targetsid, "kiwi"),
9667        "Expected targetsid to be unchanged, got %s\n", targetsid);
9668     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9669
9670     /* dwContext is out of bounds */
9671     lstrcpyA(patchcode, "apple");
9672     lstrcpyA(targetprod, "banana");
9673     context = 0xdeadbeef;
9674     lstrcpyA(targetsid, "kiwi");
9675     size = MAX_PATH;
9676     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9677                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9678                            &context, targetsid, &size);
9679     ok(r == ERROR_INVALID_PARAMETER,
9680        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9681     ok(!lstrcmpA(patchcode, "apple"),
9682        "Expected patchcode to be unchanged, got %s\n", patchcode);
9683     ok(!lstrcmpA(targetprod, "banana"),
9684        "Expected targetprod to be unchanged, got %s\n", targetprod);
9685     ok(context == 0xdeadbeef,
9686        "Expected context to be unchanged, got %d\n", context);
9687     ok(!lstrcmpA(targetsid, "kiwi"),
9688        "Expected targetsid to be unchanged, got %s\n", targetsid);
9689     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9690
9691     /* dwFilter is out of bounds */
9692     lstrcpyA(patchcode, "apple");
9693     lstrcpyA(targetprod, "banana");
9694     context = 0xdeadbeef;
9695     lstrcpyA(targetsid, "kiwi");
9696     size = MAX_PATH;
9697     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9698                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9699                            &context, targetsid, &size);
9700     ok(r == ERROR_INVALID_PARAMETER,
9701        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9702     ok(!lstrcmpA(patchcode, "apple"),
9703        "Expected patchcode to be unchanged, got %s\n", patchcode);
9704     ok(!lstrcmpA(targetprod, "banana"),
9705        "Expected targetprod to be unchanged, got %s\n", targetprod);
9706     ok(context == 0xdeadbeef,
9707        "Expected context to be unchanged, got %d\n", context);
9708     ok(!lstrcmpA(targetsid, "kiwi"),
9709        "Expected targetsid to be unchanged, got %s\n", targetsid);
9710     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9711
9712     /* dwFilter is out of bounds */
9713     lstrcpyA(patchcode, "apple");
9714     lstrcpyA(targetprod, "banana");
9715     context = 0xdeadbeef;
9716     lstrcpyA(targetsid, "kiwi");
9717     size = MAX_PATH;
9718     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9719                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9720                            &context, targetsid, &size);
9721     ok(r == ERROR_INVALID_PARAMETER,
9722        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9723     ok(!lstrcmpA(patchcode, "apple"),
9724        "Expected patchcode to be unchanged, got %s\n", patchcode);
9725     ok(!lstrcmpA(targetprod, "banana"),
9726        "Expected targetprod to be unchanged, got %s\n", targetprod);
9727     ok(context == 0xdeadbeef,
9728        "Expected context to be unchanged, got %d\n", context);
9729     ok(!lstrcmpA(targetsid, "kiwi"),
9730        "Expected targetsid to be unchanged, got %s\n", targetsid);
9731     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9732
9733     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9734     lstrcpyA(patchcode, "apple");
9735     lstrcpyA(targetprod, "banana");
9736     context = 0xdeadbeef;
9737     lstrcpyA(targetsid, "kiwi");
9738     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9739                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9740                            &context, targetsid, NULL);
9741     ok(r == ERROR_INVALID_PARAMETER,
9742        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9743     ok(!lstrcmpA(patchcode, "apple"),
9744        "Expected patchcode to be unchanged, got %s\n", patchcode);
9745     ok(!lstrcmpA(targetprod, "banana"),
9746        "Expected targetprod to be unchanged, got %s\n", targetprod);
9747     ok(context == 0xdeadbeef,
9748        "Expected context to be unchanged, got %d\n", context);
9749     ok(!lstrcmpA(targetsid, "kiwi"),
9750        "Expected targetsid to be unchanged, got %s\n", targetsid);
9751
9752     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9753     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9754     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9755     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9756     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9757     /* FIXME: Successfully test userunmanaged with a different user */
9758     test_MsiEnumPatchesEx_machine();
9759     LocalFree(usersid);
9760 }
9761
9762 static void test_MsiEnumPatches(void)
9763 {
9764     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9765     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9766     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9767     CHAR transforms[MAX_PATH];
9768     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9769     HKEY prodkey, patches, udprod;
9770     HKEY userkey, hpatch, udpatch;
9771     DWORD size, data;
9772     LPSTR usersid;
9773     LONG res;
9774     UINT r;
9775     REGSAM access = KEY_ALL_ACCESS;
9776
9777     create_test_guid(prodcode, prod_squashed);
9778     create_test_guid(patchcode, patch_squashed);
9779     usersid = get_user_sid();
9780
9781     if (is_wow64)
9782         access |= KEY_WOW64_64KEY;
9783
9784     /* NULL szProduct */
9785     size = MAX_PATH;
9786     lstrcpyA(patch, "apple");
9787     lstrcpyA(transforms, "banana");
9788     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9789     ok(r == ERROR_INVALID_PARAMETER,
9790        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9791     ok(!lstrcmpA(patch, "apple"),
9792        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9793     ok(!lstrcmpA(transforms, "banana"),
9794        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9795     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9796
9797     /* empty szProduct */
9798     size = MAX_PATH;
9799     lstrcpyA(patch, "apple");
9800     lstrcpyA(transforms, "banana");
9801     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9802     ok(r == ERROR_INVALID_PARAMETER,
9803        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9804     ok(!lstrcmpA(patch, "apple"),
9805        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9806     ok(!lstrcmpA(transforms, "banana"),
9807        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9808     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9809
9810     /* garbage szProduct */
9811     size = MAX_PATH;
9812     lstrcpyA(patch, "apple");
9813     lstrcpyA(transforms, "banana");
9814     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9815     ok(r == ERROR_INVALID_PARAMETER,
9816        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9817     ok(!lstrcmpA(patch, "apple"),
9818        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9819     ok(!lstrcmpA(transforms, "banana"),
9820        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9821     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9822
9823     /* guid without brackets */
9824     size = MAX_PATH;
9825     lstrcpyA(patch, "apple");
9826     lstrcpyA(transforms, "banana");
9827     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9828                         transforms, &size);
9829     ok(r == ERROR_INVALID_PARAMETER,
9830        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9831     ok(!lstrcmpA(patch, "apple"),
9832        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9833     ok(!lstrcmpA(transforms, "banana"),
9834        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9835     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9836
9837     /* guid with brackets */
9838     size = MAX_PATH;
9839     lstrcpyA(patch, "apple");
9840     lstrcpyA(transforms, "banana");
9841     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9842                         transforms, &size);
9843     ok(r == ERROR_UNKNOWN_PRODUCT,
9844        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9845     ok(!lstrcmpA(patch, "apple"),
9846        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9847     ok(!lstrcmpA(transforms, "banana"),
9848        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9849     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9850
9851     /* same length as guid, but random */
9852     size = MAX_PATH;
9853     lstrcpyA(patch, "apple");
9854     lstrcpyA(transforms, "banana");
9855     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9856                         transforms, &size);
9857     ok(r == ERROR_INVALID_PARAMETER,
9858        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9859     ok(!lstrcmpA(patch, "apple"),
9860        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9861     ok(!lstrcmpA(transforms, "banana"),
9862        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9863     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9864
9865     /* MSIINSTALLCONTEXT_USERMANAGED */
9866
9867     size = MAX_PATH;
9868     lstrcpyA(patch, "apple");
9869     lstrcpyA(transforms, "banana");
9870     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9871     ok(r == ERROR_UNKNOWN_PRODUCT,
9872        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9873     ok(!lstrcmpA(patch, "apple"),
9874        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9875     ok(!lstrcmpA(transforms, "banana"),
9876        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9877     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9878
9879     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9880     lstrcatA(keypath, usersid);
9881     lstrcatA(keypath, "\\Installer\\Products\\");
9882     lstrcatA(keypath, prod_squashed);
9883
9884     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9885     if (res == ERROR_ACCESS_DENIED)
9886     {
9887         skip("Not enough rights to perform tests\n");
9888         LocalFree(usersid);
9889         return;
9890     }
9891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9892
9893     /* managed product key exists */
9894     size = MAX_PATH;
9895     lstrcpyA(patch, "apple");
9896     lstrcpyA(transforms, "banana");
9897     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9898     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9899     ok(!lstrcmpA(patch, "apple"),
9900        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9901     ok(!lstrcmpA(transforms, "banana"),
9902        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9903     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9904
9905     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9907
9908     /* patches 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 ||
9914        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9915        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9916     ok(!lstrcmpA(patch, "apple"),
9917        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9918     ok(!lstrcmpA(transforms, "banana"),
9919        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9920     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9921
9922     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9923                          (const BYTE *)patch_squashed,
9924                          lstrlenA(patch_squashed) + 1);
9925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9926
9927     /* Patches value exists, is not REG_MULTI_SZ */
9928     size = MAX_PATH;
9929     lstrcpyA(patch, "apple");
9930     lstrcpyA(transforms, "banana");
9931     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9932     ok(r == ERROR_BAD_CONFIGURATION ||
9933        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9934        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9935     ok(!lstrcmpA(patch, "apple"),
9936        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9937     ok(!lstrcmpA(transforms, "banana"),
9938        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9939     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9940
9941     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9942                          (const BYTE *)"a\0b\0c\0\0", 7);
9943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9944
9945     /* Patches value exists, is not a squashed guid */
9946     size = MAX_PATH;
9947     lstrcpyA(patch, "apple");
9948     lstrcpyA(transforms, "banana");
9949     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9950     ok(r == ERROR_BAD_CONFIGURATION,
9951        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9952     ok(!lstrcmpA(patch, "apple"),
9953        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9954     ok(!lstrcmpA(transforms, "banana"),
9955        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9956     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9957
9958     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9959     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9960                          (const BYTE *)patch_squashed,
9961                          lstrlenA(patch_squashed) + 2);
9962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9963
9964     /* Patches value exists */
9965     size = MAX_PATH;
9966     lstrcpyA(patch, "apple");
9967     lstrcpyA(transforms, "banana");
9968     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9969     ok(r == ERROR_NO_MORE_ITEMS ||
9970        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9971        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9972     ok(!lstrcmpA(patch, "apple") ||
9973        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9974        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9975     ok(!lstrcmpA(transforms, "banana"),
9976        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9977     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9978
9979     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9980                          (const BYTE *)"whatever", 9);
9981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9982
9983     /* patch squashed value exists */
9984     size = MAX_PATH;
9985     lstrcpyA(patch, "apple");
9986     lstrcpyA(transforms, "banana");
9987     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9988     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9989     ok(!lstrcmpA(patch, patchcode),
9990        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9991     ok(!lstrcmpA(transforms, "whatever"),
9992        "Expected \"whatever\", got \"%s\"\n", transforms);
9993     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9994
9995     /* lpPatchBuf is NULL */
9996     size = MAX_PATH;
9997     lstrcpyA(transforms, "banana");
9998     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9999     ok(r == ERROR_INVALID_PARAMETER,
10000        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10001     ok(!lstrcmpA(transforms, "banana"),
10002        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10003     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10004
10005     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
10006     size = MAX_PATH;
10007     lstrcpyA(patch, "apple");
10008     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
10009     ok(r == ERROR_INVALID_PARAMETER,
10010        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10011     ok(!lstrcmpA(patch, "apple"),
10012        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10013     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10014
10015     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
10016     lstrcpyA(patch, "apple");
10017     lstrcpyA(transforms, "banana");
10018     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
10019     ok(r == ERROR_INVALID_PARAMETER,
10020        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10021     ok(!lstrcmpA(patch, "apple"),
10022        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10023     ok(!lstrcmpA(transforms, "banana"),
10024        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10025
10026     /* pcchTransformsBuf is too small */
10027     size = 6;
10028     lstrcpyA(patch, "apple");
10029     lstrcpyA(transforms, "banana");
10030     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10031     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10032     ok(!lstrcmpA(patch, patchcode),
10033        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10034     ok(!lstrcmpA(transforms, "whate") ||
10035        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10036        "Expected \"whate\", got \"%s\"\n", transforms);
10037     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
10038
10039     /* increase the index */
10040     size = MAX_PATH;
10041     lstrcpyA(patch, "apple");
10042     lstrcpyA(transforms, "banana");
10043     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
10044     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10045     ok(!lstrcmpA(patch, "apple"),
10046        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10047     ok(!lstrcmpA(transforms, "banana"),
10048        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10049     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10050
10051     /* increase again */
10052     size = MAX_PATH;
10053     lstrcpyA(patch, "apple");
10054     lstrcpyA(transforms, "banana");
10055     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
10056     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10057     ok(!lstrcmpA(patch, "apple"),
10058        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10059     ok(!lstrcmpA(transforms, "banana"),
10060        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10061     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10062
10063     RegDeleteValueA(patches, "Patches");
10064     delete_key(patches, "", access & KEY_WOW64_64KEY);
10065     RegCloseKey(patches);
10066     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10067     RegCloseKey(prodkey);
10068
10069     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10070
10071     size = MAX_PATH;
10072     lstrcpyA(patch, "apple");
10073     lstrcpyA(transforms, "banana");
10074     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10075     ok(r == ERROR_UNKNOWN_PRODUCT,
10076        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10077     ok(!lstrcmpA(patch, "apple"),
10078        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10079     ok(!lstrcmpA(transforms, "banana"),
10080        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10081     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10082
10083     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10084     lstrcatA(keypath, prod_squashed);
10085
10086     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10088
10089     /* current user product key exists */
10090     size = MAX_PATH;
10091     lstrcpyA(patch, "apple");
10092     lstrcpyA(transforms, "banana");
10093     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10094     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10095     ok(!lstrcmpA(patch, "apple"),
10096        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10097     ok(!lstrcmpA(transforms, "banana"),
10098        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10099     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10100
10101     res = RegCreateKeyA(prodkey, "Patches", &patches);
10102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10103
10104     /* Patches 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 ||
10110        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10111        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10112     ok(!lstrcmpA(patch, "apple"),
10113        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10114     ok(!lstrcmpA(transforms, "banana"),
10115        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10116     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10117
10118     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10119                          (const BYTE *)patch_squashed,
10120                          lstrlenA(patch_squashed) + 1);
10121     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10122
10123     /* Patches value exists, is not REG_MULTI_SZ */
10124     size = MAX_PATH;
10125     lstrcpyA(patch, "apple");
10126     lstrcpyA(transforms, "banana");
10127     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10128     ok(r == ERROR_BAD_CONFIGURATION ||
10129        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10130        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10131     ok(!lstrcmpA(patch, "apple"),
10132        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10133     ok(!lstrcmpA(transforms, "banana"),
10134        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10135     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10136
10137     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10138                          (const BYTE *)"a\0b\0c\0\0", 7);
10139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10140
10141     /* Patches value exists, is not a squashed guid */
10142     size = MAX_PATH;
10143     lstrcpyA(patch, "apple");
10144     lstrcpyA(transforms, "banana");
10145     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10146     ok(r == ERROR_BAD_CONFIGURATION,
10147        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10148     ok(!lstrcmpA(patch, "apple"),
10149        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10150     ok(!lstrcmpA(transforms, "banana"),
10151        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10152     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10153
10154     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10155     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10156                          (const BYTE *)patch_squashed,
10157                          lstrlenA(patch_squashed) + 2);
10158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10159
10160     /* Patches value exists */
10161     size = MAX_PATH;
10162     lstrcpyA(patch, "apple");
10163     lstrcpyA(transforms, "banana");
10164     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10165     ok(r == ERROR_NO_MORE_ITEMS ||
10166        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10167        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10168     ok(!lstrcmpA(patch, "apple") ||
10169        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10170        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10171     ok(!lstrcmpA(transforms, "banana"),
10172        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10173     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10174
10175     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10176                          (const BYTE *)"whatever", 9);
10177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10178
10179     /* patch code value exists */
10180     size = MAX_PATH;
10181     lstrcpyA(patch, "apple");
10182     lstrcpyA(transforms, "banana");
10183     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10184     ok(r == ERROR_NO_MORE_ITEMS ||
10185        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10186        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10187     ok(!lstrcmpA(patch, "apple") ||
10188        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10189        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10190     ok(!lstrcmpA(transforms, "banana") ||
10191        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10192        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10193     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10194
10195     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10196     lstrcatA(keypath, usersid);
10197     lstrcatA(keypath, "\\Patches\\");
10198     lstrcatA(keypath, patch_squashed);
10199
10200     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10202
10203     /* userdata patch key exists */
10204     size = MAX_PATH;
10205     lstrcpyA(patch, "apple");
10206     lstrcpyA(transforms, "banana");
10207     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10208     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10209     ok(!lstrcmpA(patch, patchcode),
10210        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10211     ok(!lstrcmpA(transforms, "whatever"),
10212        "Expected \"whatever\", got \"%s\"\n", transforms);
10213     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10214
10215     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10216     RegCloseKey(userkey);
10217     RegDeleteValueA(patches, patch_squashed);
10218     RegDeleteValueA(patches, "Patches");
10219     RegDeleteKeyA(patches, "");
10220     RegCloseKey(patches);
10221     RegDeleteKeyA(prodkey, "");
10222     RegCloseKey(prodkey);
10223
10224     /* MSIINSTALLCONTEXT_MACHINE */
10225
10226     size = MAX_PATH;
10227     lstrcpyA(patch, "apple");
10228     lstrcpyA(transforms, "banana");
10229     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10230     ok(r == ERROR_UNKNOWN_PRODUCT,
10231        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10232     ok(!lstrcmpA(patch, "apple"),
10233        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10234     ok(!lstrcmpA(transforms, "banana"),
10235        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10236     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10237
10238     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10239     lstrcatA(keypath, prod_squashed);
10240
10241     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10243
10244     /* local product key exists */
10245     size = MAX_PATH;
10246     lstrcpyA(patch, "apple");
10247     lstrcpyA(transforms, "banana");
10248     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10249     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10250     ok(!lstrcmpA(patch, "apple"),
10251        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10252     ok(!lstrcmpA(transforms, "banana"),
10253        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10254     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10255
10256     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10258
10259     /* Patches 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 ||
10265        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10266        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10267     ok(!lstrcmpA(patch, "apple"),
10268        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10269     ok(!lstrcmpA(transforms, "banana"),
10270        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10271     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10272
10273     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10274                          (const BYTE *)patch_squashed,
10275                          lstrlenA(patch_squashed) + 1);
10276     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10277
10278     /* Patches value exists, is not REG_MULTI_SZ */
10279     size = MAX_PATH;
10280     lstrcpyA(patch, "apple");
10281     lstrcpyA(transforms, "banana");
10282     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10283     ok(r == ERROR_BAD_CONFIGURATION ||
10284        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10285        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10286     ok(!lstrcmpA(patch, "apple"),
10287        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10288     ok(!lstrcmpA(transforms, "banana"),
10289        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10290     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10291
10292     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10293                          (const BYTE *)"a\0b\0c\0\0", 7);
10294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10295
10296     /* Patches value exists, is not a squashed guid */
10297     size = MAX_PATH;
10298     lstrcpyA(patch, "apple");
10299     lstrcpyA(transforms, "banana");
10300     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10301     ok(r == ERROR_BAD_CONFIGURATION,
10302        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10303     ok(!lstrcmpA(patch, "apple"),
10304        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10305     ok(!lstrcmpA(transforms, "banana"),
10306        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10307     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10308
10309     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10310     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10311                          (const BYTE *)patch_squashed,
10312                          lstrlenA(patch_squashed) + 2);
10313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10314
10315     /* Patches value exists */
10316     size = MAX_PATH;
10317     lstrcpyA(patch, "apple");
10318     lstrcpyA(transforms, "banana");
10319     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10320     ok(r == ERROR_NO_MORE_ITEMS ||
10321        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10322        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10323     ok(!lstrcmpA(patch, "apple") ||
10324        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10325        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10326     ok(!lstrcmpA(transforms, "banana"),
10327        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10328     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10329
10330     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10331                          (const BYTE *)"whatever", 9);
10332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10333
10334     /* patch code value exists */
10335     size = MAX_PATH;
10336     lstrcpyA(patch, "apple");
10337     lstrcpyA(transforms, "banana");
10338     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10339     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10340     ok(!lstrcmpA(patch, patchcode),
10341        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10342     ok(!lstrcmpA(transforms, "whatever"),
10343        "Expected \"whatever\", got \"%s\"\n", transforms);
10344     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10345
10346     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10347     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10348     lstrcatA(keypath, prod_squashed);
10349
10350     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10352
10353     /* local UserData product key exists */
10354     size = MAX_PATH;
10355     lstrcpyA(patch, "apple");
10356     lstrcpyA(transforms, "banana");
10357     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10358     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10359     ok(!lstrcmpA(patch, patchcode),
10360        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10361     ok(!lstrcmpA(transforms, "whatever"),
10362        "Expected \"whatever\", got \"%s\"\n", transforms);
10363     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10364
10365     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10367
10368     /* local UserData Patches 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(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10382
10383     /* local UserData Product patch 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_NO_MORE_ITEMS ||
10389        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10390        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10391     ok(!lstrcmpA(patch, "apple") ||
10392        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10393        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10394     ok(!lstrcmpA(transforms, "banana") ||
10395        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10396        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10397     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10398
10399     data = MSIPATCHSTATE_APPLIED;
10400     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10401                          (const BYTE *)&data, sizeof(DWORD));
10402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10403
10404     /* State value exists */
10405     size = MAX_PATH;
10406     lstrcpyA(patch, "apple");
10407     lstrcpyA(transforms, "banana");
10408     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10410     ok(!lstrcmpA(patch, patchcode),
10411        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10412     ok(!lstrcmpA(transforms, "whatever"),
10413        "Expected \"whatever\", got \"%s\"\n", transforms);
10414     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10415
10416     /* now duplicate some of the tests for the W version */
10417
10418     /* pcchTransformsBuf is too small */
10419     size = 6;
10420     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10421     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10422     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10423     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10424     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10425     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10426     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10427     ok(!lstrcmpA(patch, patchcode),
10428        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10429     ok(!lstrcmpA(transforms, "whate") ||
10430        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10431        "Expected \"whate\", got \"%s\"\n", transforms);
10432     ok(size == 8, "Expected 8, got %d\n", size);
10433
10434     /* patch code value exists */
10435     size = 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_SUCCESS, "Expected ERROR_SUCCESS, 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, "whatever"),
10445        "Expected \"whatever\", got \"%s\"\n", transforms);
10446     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10447
10448     RegDeleteValueA(patches, patch_squashed);
10449     RegDeleteValueA(patches, "Patches");
10450     delete_key(patches, "", access & KEY_WOW64_64KEY);
10451     RegCloseKey(patches);
10452     RegDeleteValueA(hpatch, "State");
10453     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10454     RegCloseKey(hpatch);
10455     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10456     RegCloseKey(udpatch);
10457     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10458     RegCloseKey(udprod);
10459     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10460     RegCloseKey(prodkey);
10461     LocalFree(usersid);
10462 }
10463
10464 static void test_MsiGetPatchInfoEx(void)
10465 {
10466     CHAR keypath[MAX_PATH], val[MAX_PATH];
10467     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10468     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10469     HKEY prodkey, patches, udprod, props;
10470     HKEY hpatch, udpatch, prodpatches;
10471     LPSTR usersid;
10472     DWORD size;
10473     LONG res;
10474     UINT r;
10475     REGSAM access = KEY_ALL_ACCESS;
10476
10477     if (!pMsiGetPatchInfoExA)
10478     {
10479         win_skip("MsiGetPatchInfoEx not implemented\n");
10480         return;
10481     }
10482
10483     create_test_guid(prodcode, prod_squashed);
10484     create_test_guid(patchcode, patch_squashed);
10485     usersid = get_user_sid();
10486
10487     if (is_wow64)
10488         access |= KEY_WOW64_64KEY;
10489
10490     /* NULL szPatchCode */
10491     lstrcpyA(val, "apple");
10492     size = MAX_PATH;
10493     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10494                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10495     ok(r == ERROR_INVALID_PARAMETER,
10496        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10497     ok(!lstrcmpA(val, "apple"),
10498        "Expected val to be unchanged, got \"%s\"\n", val);
10499     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10500
10501     /* empty szPatchCode */
10502     size = MAX_PATH;
10503     lstrcpyA(val, "apple");
10504     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10505                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10506     ok(r == ERROR_INVALID_PARAMETER,
10507        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10508     ok(!lstrcmpA(val, "apple"),
10509        "Expected val to be unchanged, got \"%s\"\n", val);
10510     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10511
10512     /* garbage szPatchCode */
10513     size = MAX_PATH;
10514     lstrcpyA(val, "apple");
10515     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10516                             MSIINSTALLCONTEXT_USERMANAGED,
10517                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10518     ok(r == ERROR_INVALID_PARAMETER,
10519        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10520     ok(!lstrcmpA(val, "apple"),
10521        "Expected val to be unchanged, got \"%s\"\n", val);
10522     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10523
10524     /* guid without brackets */
10525     size = MAX_PATH;
10526     lstrcpyA(val, "apple");
10527     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10528                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10529                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10530     ok(r == ERROR_INVALID_PARAMETER,
10531        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10532     ok(!lstrcmpA(val, "apple"),
10533        "Expected val to be unchanged, got \"%s\"\n", val);
10534     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10535
10536     /* guid with brackets */
10537     size = MAX_PATH;
10538     lstrcpyA(val, "apple");
10539     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10540                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10541                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10542     ok(r == ERROR_UNKNOWN_PRODUCT,
10543        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10544     ok(!lstrcmpA(val, "apple"),
10545        "Expected val to be unchanged, got \"%s\"\n", val);
10546     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10547
10548     /* same length as guid, but random */
10549     size = MAX_PATH;
10550     lstrcpyA(val, "apple");
10551     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10552                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10553                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10554     ok(r == ERROR_INVALID_PARAMETER,
10555        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10556     ok(!lstrcmpA(val, "apple"),
10557        "Expected val to be unchanged, got \"%s\"\n", val);
10558     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10559
10560     /* NULL szProductCode */
10561     lstrcpyA(val, "apple");
10562     size = MAX_PATH;
10563     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10564                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10565     ok(r == ERROR_INVALID_PARAMETER,
10566        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10567     ok(!lstrcmpA(val, "apple"),
10568        "Expected val to be unchanged, got \"%s\"\n", val);
10569     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10570
10571     /* empty szProductCode */
10572     size = MAX_PATH;
10573     lstrcpyA(val, "apple");
10574     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10575                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10576     ok(r == ERROR_INVALID_PARAMETER,
10577        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10578     ok(!lstrcmpA(val, "apple"),
10579        "Expected val to be unchanged, got \"%s\"\n", val);
10580     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10581
10582     /* garbage szProductCode */
10583     size = MAX_PATH;
10584     lstrcpyA(val, "apple");
10585     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10586                             MSIINSTALLCONTEXT_USERMANAGED,
10587                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10588     ok(r == ERROR_INVALID_PARAMETER,
10589        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10590     ok(!lstrcmpA(val, "apple"),
10591        "Expected val to be unchanged, got \"%s\"\n", val);
10592     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10593
10594     /* guid without brackets */
10595     size = MAX_PATH;
10596     lstrcpyA(val, "apple");
10597     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10598                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10599                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10600     ok(r == ERROR_INVALID_PARAMETER,
10601        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10602     ok(!lstrcmpA(val, "apple"),
10603        "Expected val to be unchanged, got \"%s\"\n", val);
10604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10605
10606     /* guid with brackets */
10607     size = MAX_PATH;
10608     lstrcpyA(val, "apple");
10609     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10610                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10611                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10612     ok(r == ERROR_UNKNOWN_PRODUCT,
10613        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10614     ok(!lstrcmpA(val, "apple"),
10615        "Expected val to be unchanged, got \"%s\"\n", val);
10616     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10617
10618     /* same length as guid, but random */
10619     size = MAX_PATH;
10620     lstrcpyA(val, "apple");
10621     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10622                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10623                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10624     ok(r == ERROR_INVALID_PARAMETER,
10625        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10626     ok(!lstrcmpA(val, "apple"),
10627        "Expected val to be unchanged, got \"%s\"\n", val);
10628     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10629
10630     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10631     size = MAX_PATH;
10632     lstrcpyA(val, "apple");
10633     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10634                             MSIINSTALLCONTEXT_USERMANAGED,
10635                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10636     ok(r == ERROR_INVALID_PARAMETER,
10637        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10638     ok(!lstrcmpA(val, "apple"),
10639        "Expected val to be unchanged, got \"%s\"\n", val);
10640     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10641
10642     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10643     size = MAX_PATH;
10644     lstrcpyA(val, "apple");
10645     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10646                             MSIINSTALLCONTEXT_USERUNMANAGED,
10647                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10648     ok(r == ERROR_INVALID_PARAMETER,
10649        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10650     ok(!lstrcmpA(val, "apple"),
10651        "Expected val to be unchanged, got \"%s\"\n", val);
10652     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10653
10654     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10655     size = MAX_PATH;
10656     lstrcpyA(val, "apple");
10657     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10658                             MSIINSTALLCONTEXT_MACHINE,
10659                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10660     ok(r == ERROR_INVALID_PARAMETER,
10661        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10662     ok(!lstrcmpA(val, "apple"),
10663        "Expected val to be unchanged, got \"%s\"\n", val);
10664     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10665
10666     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10667     size = MAX_PATH;
10668     lstrcpyA(val, "apple");
10669     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10670                             MSIINSTALLCONTEXT_MACHINE,
10671                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10672     ok(r == ERROR_INVALID_PARAMETER,
10673        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10674     ok(!lstrcmpA(val, "apple"),
10675        "Expected val to be unchanged, got \"%s\"\n", val);
10676     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10677
10678     /* dwContext is out of range */
10679     size = MAX_PATH;
10680     lstrcpyA(val, "apple");
10681     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10682                             MSIINSTALLCONTEXT_NONE,
10683                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10684     ok(r == ERROR_INVALID_PARAMETER,
10685        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10686     ok(!lstrcmpA(val, "apple"),
10687        "Expected val to be unchanged, got \"%s\"\n", val);
10688     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10689
10690     /* dwContext is out of range */
10691     size = MAX_PATH;
10692     lstrcpyA(val, "apple");
10693     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10694                             MSIINSTALLCONTEXT_ALL,
10695                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10696     ok(r == ERROR_INVALID_PARAMETER,
10697        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10698     ok(!lstrcmpA(val, "apple"),
10699        "Expected val to be unchanged, got \"%s\"\n", val);
10700     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10701
10702     /* dwContext is invalid */
10703     size = MAX_PATH;
10704     lstrcpyA(val, "apple");
10705     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10706                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10707     ok(r == ERROR_INVALID_PARAMETER,
10708        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10709     ok(!lstrcmpA(val, "apple"),
10710        "Expected val to be unchanged, got \"%s\"\n", val);
10711     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10712
10713     /* MSIINSTALLCONTEXT_USERMANAGED */
10714
10715     size = MAX_PATH;
10716     lstrcpyA(val, "apple");
10717     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10718                             MSIINSTALLCONTEXT_USERMANAGED,
10719                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10720     ok(r == ERROR_UNKNOWN_PRODUCT,
10721        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10722     ok(!lstrcmpA(val, "apple"),
10723        "Expected val to be unchanged, got \"%s\"\n", val);
10724     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10725
10726     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10727     lstrcatA(keypath, usersid);
10728     lstrcatA(keypath, "\\Products\\");
10729     lstrcatA(keypath, prod_squashed);
10730
10731     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10732     if (res == ERROR_ACCESS_DENIED)
10733     {
10734         skip("Not enough rights to perform tests\n");
10735         LocalFree(usersid);
10736         return;
10737     }
10738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10739
10740     /* local UserData product key exists */
10741     size = MAX_PATH;
10742     lstrcpyA(val, "apple");
10743     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10744                             MSIINSTALLCONTEXT_USERMANAGED,
10745                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10746     ok(r == ERROR_UNKNOWN_PRODUCT,
10747        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10748     ok(!lstrcmpA(val, "apple"),
10749        "Expected val to be unchanged, got \"%s\"\n", val);
10750     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10751
10752     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10754
10755     /* InstallProperties 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_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10762     ok(!lstrcmpA(val, "apple"),
10763        "Expected val to be unchanged, got \"%s\"\n", val);
10764     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10765
10766     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10768
10769     /* Patches key exists */
10770     size = MAX_PATH;
10771     lstrcpyA(val, "apple");
10772     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10773                             MSIINSTALLCONTEXT_USERMANAGED,
10774                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10775     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10776     ok(!lstrcmpA(val, "apple"),
10777        "Expected val to be unchanged, got \"%s\"\n", val);
10778     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10779
10780     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10782
10783     /* Patches key exists */
10784     size = MAX_PATH;
10785     lstrcpyA(val, "apple");
10786     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10787                             MSIINSTALLCONTEXT_USERMANAGED,
10788                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10789     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10790     ok(!lstrcmpA(val, "apple"),
10791        "Expected val to be unchanged, got \"%s\"\n", val);
10792     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10793
10794     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10795     lstrcatA(keypath, usersid);
10796     lstrcatA(keypath, "\\Installer\\Products\\");
10797     lstrcatA(keypath, prod_squashed);
10798
10799     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10801
10802     /* managed product key exists */
10803     size = MAX_PATH;
10804     lstrcpyA(val, "apple");
10805     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10806                             MSIINSTALLCONTEXT_USERMANAGED,
10807                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10808     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10809     ok(!lstrcmpA(val, "apple"),
10810        "Expected val to be unchanged, got \"%s\"\n", val);
10811     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10812
10813     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10815
10816     /* Patches key exists */
10817     size = MAX_PATH;
10818     lstrcpyA(val, "apple");
10819     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10820                             MSIINSTALLCONTEXT_USERMANAGED,
10821                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10822     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10823     ok(!lstrcmpA(val, "apple"),
10824        "Expected val to be unchanged, got \"%s\"\n", val);
10825     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10826
10827     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10828                          (const BYTE *)"transforms", 11);
10829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10830
10831     /* specific patch value 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10843     lstrcatA(keypath, usersid);
10844     lstrcatA(keypath, "\\Patches\\");
10845     lstrcatA(keypath, patch_squashed);
10846
10847     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10849
10850     /* UserData Patches key exists */
10851     size = MAX_PATH;
10852     lstrcpyA(val, "apple");
10853     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10854                             MSIINSTALLCONTEXT_USERMANAGED,
10855                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10856     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10857     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10858     ok(size == 0, "Expected 0, got %d\n", size);
10859
10860     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10861                          (const BYTE *)"pack", 5);
10862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10863
10864     /* ManagedLocalPatch value exists */
10865     size = MAX_PATH;
10866     lstrcpyA(val, "apple");
10867     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10868                             MSIINSTALLCONTEXT_USERMANAGED,
10869                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10871     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10872     ok(size == 4, "Expected 4, got %d\n", size);
10873
10874     size = MAX_PATH;
10875     lstrcpyA(val, "apple");
10876     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10877                             MSIINSTALLCONTEXT_USERMANAGED,
10878                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10879     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10880     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10881     ok(size == 10, "Expected 10, got %d\n", size);
10882
10883     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10884                          (const BYTE *)"mydate", 7);
10885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10886
10887     /* Installed value exists */
10888     size = MAX_PATH;
10889     lstrcpyA(val, "apple");
10890     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10891                             MSIINSTALLCONTEXT_USERMANAGED,
10892                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10893     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10894     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10895     ok(size == 6, "Expected 6, got %d\n", size);
10896
10897     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10898                          (const BYTE *)"yes", 4);
10899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10900
10901     /* Uninstallable value exists */
10902     size = MAX_PATH;
10903     lstrcpyA(val, "apple");
10904     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10905                             MSIINSTALLCONTEXT_USERMANAGED,
10906                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10907     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10908     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10909     ok(size == 3, "Expected 3, got %d\n", size);
10910
10911     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10912                          (const BYTE *)"good", 5);
10913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10914
10915     /* State value exists */
10916     size = MAX_PATH;
10917     lstrcpyA(val, "apple");
10918     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10919                             MSIINSTALLCONTEXT_USERMANAGED,
10920                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10921     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10922     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10923     ok(size == 4, "Expected 4, got %d\n", size);
10924
10925     size = 1;
10926     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10927                          (const BYTE *)&size, sizeof(DWORD));
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     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10938     ok(size == 1, "Expected 1, got %d\n", size);
10939
10940     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10941                          (const BYTE *)"display", 8);
10942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10943
10944     /* DisplayName value exists */
10945     size = MAX_PATH;
10946     lstrcpyA(val, "apple");
10947     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10948                             MSIINSTALLCONTEXT_USERMANAGED,
10949                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10950     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10951     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10952     ok(size == 7, "Expected 7, got %d\n", size);
10953
10954     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10955                          (const BYTE *)"moreinfo", 9);
10956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10957
10958     /* MoreInfoURL value exists */
10959     size = MAX_PATH;
10960     lstrcpyA(val, "apple");
10961     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10962                             MSIINSTALLCONTEXT_USERMANAGED,
10963                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10965     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10966     ok(size == 8, "Expected 8, got %d\n", size);
10967
10968     /* szProperty is invalid */
10969     size = MAX_PATH;
10970     lstrcpyA(val, "apple");
10971     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10972                             MSIINSTALLCONTEXT_USERMANAGED,
10973                             "IDontExist", val, &size);
10974     ok(r == ERROR_UNKNOWN_PROPERTY,
10975        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10976     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10977     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10978
10979     /* lpValue is NULL, while pcchValue is non-NULL */
10980     size = MAX_PATH;
10981     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10982                             MSIINSTALLCONTEXT_USERMANAGED,
10983                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10984     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10985     ok(size == 16, "Expected 16, got %d\n", size);
10986
10987     /* pcchValue is NULL, while lpValue is non-NULL */
10988     lstrcpyA(val, "apple");
10989     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10990                             MSIINSTALLCONTEXT_USERMANAGED,
10991                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10992     ok(r == ERROR_INVALID_PARAMETER,
10993        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10994     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10995
10996     /* both lpValue and pcchValue are NULL */
10997     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10998                             MSIINSTALLCONTEXT_USERMANAGED,
10999                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
11000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11001
11002     /* pcchValue doesn't have enough room for NULL terminator */
11003     size = 8;
11004     lstrcpyA(val, "apple");
11005     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11006                             MSIINSTALLCONTEXT_USERMANAGED,
11007                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11008     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11009     ok(!lstrcmpA(val, "moreinf"),
11010        "Expected \"moreinf\", got \"%s\"\n", val);
11011     ok(size == 16, "Expected 16, got %d\n", size);
11012
11013     /* pcchValue has exactly enough room for NULL terminator */
11014     size = 9;
11015     lstrcpyA(val, "apple");
11016     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11017                             MSIINSTALLCONTEXT_USERMANAGED,
11018                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11019     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11020     ok(!lstrcmpA(val, "moreinfo"),
11021        "Expected \"moreinfo\", got \"%s\"\n", val);
11022     ok(size == 8, "Expected 8, got %d\n", size);
11023
11024     /* pcchValue is too small, lpValue is NULL */
11025     size = 0;
11026     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11027                             MSIINSTALLCONTEXT_USERMANAGED,
11028                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
11029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11030     ok(size == 16, "Expected 16, got %d\n", size);
11031
11032     RegDeleteValueA(prodpatches, patch_squashed);
11033     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11034     RegCloseKey(prodpatches);
11035     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11036     RegCloseKey(prodkey);
11037
11038     /* UserData is sufficient for all properties
11039      * except INSTALLPROPERTY_TRANSFORMS
11040      */
11041     size = MAX_PATH;
11042     lstrcpyA(val, "apple");
11043     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11044                             MSIINSTALLCONTEXT_USERMANAGED,
11045                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11047     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11048     ok(size == 4, "Expected 4, got %d\n", size);
11049
11050     /* UserData is sufficient for all properties
11051      * except INSTALLPROPERTY_TRANSFORMS
11052      */
11053     size = MAX_PATH;
11054     lstrcpyA(val, "apple");
11055     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11056                             MSIINSTALLCONTEXT_USERMANAGED,
11057                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11058     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11059     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11060     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11061
11062     RegDeleteValueA(hpatch, "MoreInfoURL");
11063     RegDeleteValueA(hpatch, "Display");
11064     RegDeleteValueA(hpatch, "State");
11065     RegDeleteValueA(hpatch, "Uninstallable");
11066     RegDeleteValueA(hpatch, "Installed");
11067     RegDeleteValueA(udpatch, "ManagedLocalPackage");
11068     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11069     RegCloseKey(udpatch);
11070     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11071     RegCloseKey(hpatch);
11072     delete_key(patches, "", access & KEY_WOW64_64KEY);
11073     RegCloseKey(patches);
11074     delete_key(props, "", access & KEY_WOW64_64KEY);
11075     RegCloseKey(props);
11076     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11077     RegCloseKey(udprod);
11078
11079     /* MSIINSTALLCONTEXT_USERUNMANAGED */
11080
11081     size = MAX_PATH;
11082     lstrcpyA(val, "apple");
11083     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11084                             MSIINSTALLCONTEXT_USERUNMANAGED,
11085                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11086     ok(r == ERROR_UNKNOWN_PRODUCT,
11087        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11088     ok(!lstrcmpA(val, "apple"),
11089        "Expected val to be unchanged, got \"%s\"\n", val);
11090     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11091
11092     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11093     lstrcatA(keypath, usersid);
11094     lstrcatA(keypath, "\\Products\\");
11095     lstrcatA(keypath, prod_squashed);
11096
11097     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11099
11100     /* local UserData product key exists */
11101     size = MAX_PATH;
11102     lstrcpyA(val, "apple");
11103     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11104                             MSIINSTALLCONTEXT_USERUNMANAGED,
11105                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11106     ok(r == ERROR_UNKNOWN_PRODUCT,
11107        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11108     ok(!lstrcmpA(val, "apple"),
11109        "Expected val to be unchanged, got \"%s\"\n", val);
11110     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11111
11112     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11114
11115     /* InstallProperties 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_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11122     ok(!lstrcmpA(val, "apple"),
11123        "Expected val to be unchanged, got \"%s\"\n", val);
11124     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11125
11126     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11128
11129     /* Patches key exists */
11130     size = MAX_PATH;
11131     lstrcpyA(val, "apple");
11132     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11133                             MSIINSTALLCONTEXT_USERUNMANAGED,
11134                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11135     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11136     ok(!lstrcmpA(val, "apple"),
11137        "Expected val to be unchanged, got \"%s\"\n", val);
11138     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11139
11140     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11142
11143     /* Patches key exists */
11144     size = MAX_PATH;
11145     lstrcpyA(val, "apple");
11146     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11147                             MSIINSTALLCONTEXT_USERUNMANAGED,
11148                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11149     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11150     ok(!lstrcmpA(val, "apple"),
11151        "Expected val to be unchanged, got \"%s\"\n", val);
11152     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11153
11154     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11155     lstrcatA(keypath, prod_squashed);
11156
11157     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11159
11160     /* current user product key exists */
11161     size = MAX_PATH;
11162     lstrcpyA(val, "apple");
11163     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11164                             MSIINSTALLCONTEXT_USERUNMANAGED,
11165                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11166     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11167     ok(!lstrcmpA(val, "apple"),
11168        "Expected val to be unchanged, got \"%s\"\n", val);
11169     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11170
11171     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
11172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11173
11174     /* Patches key exists */
11175     size = MAX_PATH;
11176     lstrcpyA(val, "apple");
11177     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11178                             MSIINSTALLCONTEXT_USERUNMANAGED,
11179                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11180     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11181     ok(!lstrcmpA(val, "apple"),
11182        "Expected val to be unchanged, got \"%s\"\n", val);
11183     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11184
11185     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11186                          (const BYTE *)"transforms", 11);
11187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11188
11189     /* specific patch value 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11201     lstrcatA(keypath, usersid);
11202     lstrcatA(keypath, "\\Patches\\");
11203     lstrcatA(keypath, patch_squashed);
11204
11205     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11207
11208     /* UserData Patches key exists */
11209     size = MAX_PATH;
11210     lstrcpyA(val, "apple");
11211     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11212                             MSIINSTALLCONTEXT_USERUNMANAGED,
11213                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11215     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11216     ok(size == 0, "Expected 0, got %d\n", size);
11217
11218     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11219                          (const BYTE *)"pack", 5);
11220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11221
11222     /* LocalPatch value exists */
11223     size = MAX_PATH;
11224     lstrcpyA(val, "apple");
11225     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11226                             MSIINSTALLCONTEXT_USERUNMANAGED,
11227                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11229     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11230     ok(size == 4, "Expected 4, got %d\n", size);
11231
11232     size = MAX_PATH;
11233     lstrcpyA(val, "apple");
11234     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11235                             MSIINSTALLCONTEXT_USERUNMANAGED,
11236                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11237     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11238     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11239     ok(size == 10, "Expected 10, got %d\n", size);
11240
11241     RegDeleteValueA(prodpatches, patch_squashed);
11242     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11243     RegCloseKey(prodpatches);
11244     RegDeleteKeyA(prodkey, "");
11245     RegCloseKey(prodkey);
11246
11247     /* UserData is sufficient for all properties
11248      * except INSTALLPROPERTY_TRANSFORMS
11249      */
11250     size = MAX_PATH;
11251     lstrcpyA(val, "apple");
11252     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11253                             MSIINSTALLCONTEXT_USERUNMANAGED,
11254                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11255     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11256     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11257     ok(size == 4, "Expected 4, got %d\n", size);
11258
11259     /* UserData is sufficient for all properties
11260      * except INSTALLPROPERTY_TRANSFORMS
11261      */
11262     size = MAX_PATH;
11263     lstrcpyA(val, "apple");
11264     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11265                             MSIINSTALLCONTEXT_USERUNMANAGED,
11266                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11267     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11268     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11269     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11270
11271     RegDeleteValueA(udpatch, "LocalPackage");
11272     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11273     RegCloseKey(udpatch);
11274     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11275     RegCloseKey(hpatch);
11276     delete_key(patches, "", access & KEY_WOW64_64KEY);
11277     RegCloseKey(patches);
11278     delete_key(props, "", access & KEY_WOW64_64KEY);
11279     RegCloseKey(props);
11280     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11281     RegCloseKey(udprod);
11282
11283     /* MSIINSTALLCONTEXT_MACHINE */
11284
11285     size = MAX_PATH;
11286     lstrcpyA(val, "apple");
11287     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11288                             MSIINSTALLCONTEXT_MACHINE,
11289                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11290     ok(r == ERROR_UNKNOWN_PRODUCT,
11291        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11292     ok(!lstrcmpA(val, "apple"),
11293        "Expected val to be unchanged, got \"%s\"\n", val);
11294     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11295
11296     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11297     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11298     lstrcatA(keypath, prod_squashed);
11299
11300     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11301     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11302
11303     /* local UserData product key exists */
11304     size = MAX_PATH;
11305     lstrcpyA(val, "apple");
11306     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11307                             MSIINSTALLCONTEXT_MACHINE,
11308                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11309     ok(r == ERROR_UNKNOWN_PRODUCT,
11310        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11311     ok(!lstrcmpA(val, "apple"),
11312        "Expected val to be unchanged, got \"%s\"\n", val);
11313     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11314
11315     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11317
11318     /* InstallProperties 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_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11325     ok(!lstrcmpA(val, "apple"),
11326        "Expected val to be unchanged, got \"%s\"\n", val);
11327     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11328
11329     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11331
11332     /* Patches key exists */
11333     size = MAX_PATH;
11334     lstrcpyA(val, "apple");
11335     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11336                             MSIINSTALLCONTEXT_MACHINE,
11337                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11338     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11339     ok(!lstrcmpA(val, "apple"),
11340        "Expected val to be unchanged, got \"%s\"\n", val);
11341     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11342
11343     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11345
11346     /* Patches key exists */
11347     size = MAX_PATH;
11348     lstrcpyA(val, "apple");
11349     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11350                             MSIINSTALLCONTEXT_MACHINE,
11351                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11352     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11353     ok(!lstrcmpA(val, "apple"),
11354        "Expected val to be unchanged, got \"%s\"\n", val);
11355     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11356
11357     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11358     lstrcatA(keypath, prod_squashed);
11359
11360     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11362
11363     /* local product key exists */
11364     size = MAX_PATH;
11365     lstrcpyA(val, "apple");
11366     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11367                             MSIINSTALLCONTEXT_MACHINE,
11368                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11369     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11370     ok(!lstrcmpA(val, "apple"),
11371        "Expected val to be unchanged, got \"%s\"\n", val);
11372     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11373
11374     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11376
11377     /* Patches key exists */
11378     size = MAX_PATH;
11379     lstrcpyA(val, "apple");
11380     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11381                             MSIINSTALLCONTEXT_MACHINE,
11382                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11383     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11384     ok(!lstrcmpA(val, "apple"),
11385        "Expected val to be unchanged, got \"%s\"\n", val);
11386     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11387
11388     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11389                          (const BYTE *)"transforms", 11);
11390     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11391
11392     /* specific patch value 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11404     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11405     lstrcatA(keypath, patch_squashed);
11406
11407     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11409
11410     /* UserData Patches key exists */
11411     size = MAX_PATH;
11412     lstrcpyA(val, "apple");
11413     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11414                             MSIINSTALLCONTEXT_MACHINE,
11415                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11417     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11418     ok(size == 0, "Expected 0, got %d\n", size);
11419
11420     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11421                          (const BYTE *)"pack", 5);
11422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11423
11424     /* LocalPatch value exists */
11425     size = MAX_PATH;
11426     lstrcpyA(val, "apple");
11427     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11428                             MSIINSTALLCONTEXT_MACHINE,
11429                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11431     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11432     ok(size == 4, "Expected 4, got %d\n", size);
11433
11434     size = MAX_PATH;
11435     lstrcpyA(val, "apple");
11436     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11437                             MSIINSTALLCONTEXT_MACHINE,
11438                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11439     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11440     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11441     ok(size == 10, "Expected 10, got %d\n", size);
11442
11443     RegDeleteValueA(prodpatches, patch_squashed);
11444     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11445     RegCloseKey(prodpatches);
11446     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11447     RegCloseKey(prodkey);
11448
11449     /* UserData is sufficient for all properties
11450      * except INSTALLPROPERTY_TRANSFORMS
11451      */
11452     size = MAX_PATH;
11453     lstrcpyA(val, "apple");
11454     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11455                             MSIINSTALLCONTEXT_MACHINE,
11456                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11458     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11459     ok(size == 4, "Expected 4, got %d\n", size);
11460
11461     /* UserData is sufficient for all properties
11462      * except INSTALLPROPERTY_TRANSFORMS
11463      */
11464     size = MAX_PATH;
11465     lstrcpyA(val, "apple");
11466     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11467                             MSIINSTALLCONTEXT_MACHINE,
11468                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11469     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11470     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11471     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11472
11473     RegDeleteValueA(udpatch, "LocalPackage");
11474     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11475     RegCloseKey(udpatch);
11476     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11477     RegCloseKey(hpatch);
11478     delete_key(patches, "", access & KEY_WOW64_64KEY);
11479     RegCloseKey(patches);
11480     delete_key(props, "", access & KEY_WOW64_64KEY);
11481     RegCloseKey(props);
11482     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11483     RegCloseKey(udprod);
11484     LocalFree(usersid);
11485 }
11486
11487 static void test_MsiGetPatchInfo(void)
11488 {
11489     UINT r;
11490     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11491     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11492     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11493     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11494     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11495     DWORD size;
11496     LONG res;
11497     REGSAM access = KEY_ALL_ACCESS;
11498
11499     create_test_guid(patch_code, patch_squashed);
11500     create_test_guid(prod_code, prod_squashed);
11501     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11502
11503     if (is_wow64)
11504         access |= KEY_WOW64_64KEY;
11505
11506     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11507     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11508
11509     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11510     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11511
11512     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11513     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11514
11515     size = 0;
11516     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11517     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11518
11519     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11520     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11521
11522     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11523     lstrcatA(keypath, prod_squashed);
11524
11525     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11526     if (res == ERROR_ACCESS_DENIED)
11527     {
11528         skip("Not enough rights to perform tests\n");
11529         return;
11530     }
11531     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11532
11533     /* product key exists */
11534     size = MAX_PATH;
11535     lstrcpyA(val, "apple");
11536     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11537     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11538     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11539     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11540
11541     res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11542     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11543
11544     /* patches key exists */
11545     size = MAX_PATH;
11546     lstrcpyA(val, "apple");
11547     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11548     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11549     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11550     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11551
11552     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11553     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11554
11555     /* patch key exists */
11556     size = MAX_PATH;
11557     lstrcpyA(val, "apple");
11558     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11559     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11560     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11561     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11562
11563     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11564     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11565     lstrcatA(keypath, prod_squashed);
11566
11567     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11569
11570     /* UserData product 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     res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11579     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11580
11581     /* InstallProperties key exists */
11582     size = MAX_PATH;
11583     lstrcpyA(val, "apple");
11584     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11585     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11586     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11587     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11588
11589     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11590     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11591
11592     /* UserData Patches key exists */
11593     size = MAX_PATH;
11594     lstrcpyA(val, "apple");
11595     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11596     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11597     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11598     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11599
11600     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11602
11603     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11605
11606     /* UserData product patch key exists */
11607     size = MAX_PATH;
11608     lstrcpyA(val, "apple");
11609     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11610     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11611     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11612     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11613
11614     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11615     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11616     lstrcatA(keypath, patch_squashed);
11617
11618     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11619     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11620
11621     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11622     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11623
11624     /* UserData Patch key exists */
11625     size = 0;
11626     lstrcpyA(val, "apple");
11627     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11628     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11629     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11630     ok(size == 11, "expected 11 got %u\n", size);
11631
11632     size = MAX_PATH;
11633     lstrcpyA(val, "apple");
11634     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11635     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11636     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11637     ok(size == 11, "expected 11 got %u\n", size);
11638
11639     size = 0;
11640     valW[0] = 0;
11641     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11642     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11643     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11644     ok(size == 11, "expected 11 got %u\n", size);
11645
11646     size = MAX_PATH;
11647     valW[0] = 0;
11648     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11649     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11650     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11651     ok(size == 11, "expected 11 got %u\n", size);
11652
11653     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11654     RegCloseKey(hkey_udproductpatch);
11655     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11656     RegCloseKey(hkey_udproductpatches);
11657     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11658     RegCloseKey(hkey_udpatch);
11659     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11660     RegCloseKey(hkey_patches);
11661     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11662     RegCloseKey(hkey_product);
11663     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11664     RegCloseKey(hkey_patch);
11665     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11666     RegCloseKey(hkey_udpatches);
11667     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11668     RegCloseKey(hkey_udprops);
11669     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11670     RegCloseKey(hkey_udproduct);
11671 }
11672
11673 static void test_MsiEnumProducts(void)
11674 {
11675     UINT r;
11676     int found1, found2, found3;
11677     DWORD index;
11678     char product1[39], product2[39], product3[39], guid[39];
11679     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11680     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11681     char *usersid;
11682     HKEY key1, key2, key3;
11683     REGSAM access = KEY_ALL_ACCESS;
11684
11685     create_test_guid(product1, product_squashed1);
11686     create_test_guid(product2, product_squashed2);
11687     create_test_guid(product3, product_squashed3);
11688     usersid = get_user_sid();
11689
11690     if (is_wow64)
11691         access |= KEY_WOW64_64KEY;
11692
11693     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11694     strcat(keypath1, product_squashed1);
11695
11696     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11697     if (r == ERROR_ACCESS_DENIED)
11698     {
11699         skip("Not enough rights to perform tests\n");
11700         LocalFree(usersid);
11701         return;
11702     }
11703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11704
11705     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11706     strcat(keypath2, usersid);
11707     strcat(keypath2, "\\Installer\\Products\\");
11708     strcat(keypath2, product_squashed2);
11709
11710     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11711     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11712
11713     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11714     strcat(keypath3, product_squashed3);
11715
11716     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11717     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11718
11719     index = 0;
11720     r = MsiEnumProductsA(index, guid);
11721     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11722
11723     r = MsiEnumProductsA(index, NULL);
11724     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11725
11726     index = 2;
11727     r = MsiEnumProductsA(index, guid);
11728     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11729
11730     index = 0;
11731     r = MsiEnumProductsA(index, guid);
11732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11733
11734     found1 = found2 = found3 = 0;
11735     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11736     {
11737         if (!strcmp(product1, guid)) found1 = 1;
11738         if (!strcmp(product2, guid)) found2 = 1;
11739         if (!strcmp(product3, guid)) found3 = 1;
11740         index++;
11741     }
11742     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11743     ok(found1, "product1 not found\n");
11744     ok(found2, "product2 not found\n");
11745     ok(found3, "product3 not found\n");
11746
11747     delete_key(key1, "", access & KEY_WOW64_64KEY);
11748     delete_key(key2, "", access & KEY_WOW64_64KEY);
11749     RegDeleteKeyA(key3, "");
11750     RegCloseKey(key1);
11751     RegCloseKey(key2);
11752     RegCloseKey(key3);
11753     LocalFree(usersid);
11754 }
11755
11756 START_TEST(msi)
11757 {
11758     init_functionpointers();
11759
11760     if (pIsWow64Process)
11761         pIsWow64Process(GetCurrentProcess(), &is_wow64);
11762
11763     test_usefeature();
11764     test_null();
11765     test_getcomponentpath();
11766     test_MsiGetFileHash();
11767
11768     if (!pConvertSidToStringSidA)
11769         win_skip("ConvertSidToStringSidA not implemented\n");
11770     else
11771     {
11772         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11773         test_MsiQueryProductState();
11774         test_MsiQueryFeatureState();
11775         test_MsiQueryComponentState();
11776         test_MsiGetComponentPath();
11777         test_MsiGetProductCode();
11778         test_MsiEnumClients();
11779         test_MsiGetProductInfo();
11780         test_MsiGetProductInfoEx();
11781         test_MsiGetUserInfo();
11782         test_MsiOpenProduct();
11783         test_MsiEnumPatchesEx();
11784         test_MsiEnumPatches();
11785         test_MsiGetPatchInfoEx();
11786         test_MsiGetPatchInfo();
11787         test_MsiEnumProducts();
11788     }
11789
11790     test_MsiGetFileVersion();
11791 }