mshtml: Added IHTMLWindow2::focus implementation.
[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 == 0 ||
488            broken(ret != 0), /* win95 */
489            "Hash incorrect\n");
490
491         DeleteFile(name);
492     }
493 }
494
495 /* copied from dlls/msi/registry.c */
496 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
497 {
498     DWORD i,n=1;
499     GUID guid;
500
501     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
502         return FALSE;
503
504     for(i=0; i<8; i++)
505         out[7-i] = in[n++];
506     n++;
507     for(i=0; i<4; i++)
508         out[11-i] = in[n++];
509     n++;
510     for(i=0; i<4; i++)
511         out[15-i] = in[n++];
512     n++;
513     for(i=0; i<2; i++)
514     {
515         out[17+i*2] = in[n++];
516         out[16+i*2] = in[n++];
517     }
518     n++;
519     for( ; i<8; i++)
520     {
521         out[17+i*2] = in[n++];
522         out[16+i*2] = in[n++];
523     }
524     out[32]=0;
525     return TRUE;
526 }
527
528 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
529 {
530     WCHAR guidW[MAX_PATH];
531     WCHAR squashedW[MAX_PATH];
532     GUID guid;
533     HRESULT hr;
534     int size;
535
536     hr = CoCreateGuid(&guid);
537     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
538
539     size = StringFromGUID2(&guid, guidW, MAX_PATH);
540     ok(size == 39, "Expected 39, got %d\n", hr);
541
542     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
543     squash_guid(guidW, squashedW);
544     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
545 }
546
547 static void get_user_sid(LPSTR *usersid)
548 {
549     HANDLE token;
550     DWORD size;
551     PTOKEN_USER user;
552
553     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
554
555     size = 0;
556     GetTokenInformation(token, TokenUser, NULL, size, &size);
557     user = HeapAlloc(GetProcessHeap(), 0, size);
558
559     GetTokenInformation(token, TokenUser, user, size, &size);
560     pConvertSidToStringSidA(user->User.Sid, usersid);
561
562     HeapFree(GetProcessHeap(), 0, user);
563     CloseHandle(token);
564 }
565
566 static void test_MsiQueryProductState(void)
567 {
568     CHAR prodcode[MAX_PATH];
569     CHAR prod_squashed[MAX_PATH];
570     CHAR keypath[MAX_PATH*2];
571     LPSTR usersid;
572     INSTALLSTATE state;
573     LONG res;
574     HKEY userkey, localkey, props;
575     HKEY prodkey;
576     DWORD data, error;
577     REGSAM access = KEY_ALL_ACCESS;
578
579     create_test_guid(prodcode, prod_squashed);
580     get_user_sid(&usersid);
581
582     if (is_wow64)
583         access |= KEY_WOW64_64KEY;
584
585     /* NULL prodcode */
586     SetLastError(0xdeadbeef);
587     state = MsiQueryProductStateA(NULL);
588     error = GetLastError();
589     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
590     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
591
592     /* empty prodcode */
593     SetLastError(0xdeadbeef);
594     state = MsiQueryProductStateA("");
595     error = GetLastError();
596     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
597     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
598
599     /* garbage prodcode */
600     SetLastError(0xdeadbeef);
601     state = MsiQueryProductStateA("garbage");
602     error = GetLastError();
603     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
604     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
605
606     /* guid without brackets */
607     SetLastError(0xdeadbeef);
608     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
609     error = GetLastError();
610     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
611     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
612
613     /* guid with brackets */
614     SetLastError(0xdeadbeef);
615     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
616     error = GetLastError();
617     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
618     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
619        "expected ERROR_SUCCESS, got %u\n", error);
620
621     /* same length as guid, but random */
622     SetLastError(0xdeadbeef);
623     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
624     error = GetLastError();
625     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
626     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
627
628     /* MSIINSTALLCONTEXT_USERUNMANAGED */
629
630     SetLastError(0xdeadbeef);
631     state = MsiQueryProductStateA(prodcode);
632     error = GetLastError();
633     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
634     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
635        "expected ERROR_SUCCESS, got %u\n", error);
636
637     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
638     lstrcatA(keypath, prod_squashed);
639
640     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
642
643     /* user product key exists */
644     SetLastError(0xdeadbeef);
645     state = MsiQueryProductStateA(prodcode);
646     error = GetLastError();
647     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
648     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
649        "expected ERROR_SUCCESS, got %u\n", error);
650
651     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
652     lstrcatA(keypath, prodcode);
653
654     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
655     if (res == ERROR_ACCESS_DENIED)
656     {
657         skip("Not enough rights to perform tests\n");
658         RegDeleteKeyA(userkey, "");
659         LocalFree(usersid);
660         return;
661     }
662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
663
664     /* local uninstall key exists */
665     SetLastError(0xdeadbeef);
666     state = MsiQueryProductStateA(prodcode);
667     error = GetLastError();
668     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
669     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
670        "expected ERROR_SUCCESS, got %u\n", error);
671
672     data = 1;
673     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
675
676     /* WindowsInstaller value exists */
677     SetLastError(0xdeadbeef);
678     state = MsiQueryProductStateA(prodcode);
679     error = GetLastError();
680     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
681     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
682        "expected ERROR_SUCCESS, got %u\n", error);
683
684     RegDeleteValueA(localkey, "WindowsInstaller");
685     delete_key(localkey, "", access & KEY_WOW64_64KEY);
686
687     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
688     lstrcatA(keypath, usersid);
689     lstrcatA(keypath, "\\Products\\");
690     lstrcatA(keypath, prod_squashed);
691
692     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
694
695     /* local product key exists */
696     SetLastError(0xdeadbeef);
697     state = MsiQueryProductStateA(prodcode);
698     error = GetLastError();
699     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
700     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
701        "expected ERROR_SUCCESS, got %u\n", error);
702
703     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
704     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
705
706     /* install properties key exists */
707     SetLastError(0xdeadbeef);
708     state = MsiQueryProductStateA(prodcode);
709     error = GetLastError();
710     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
711     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
712        "expected ERROR_SUCCESS, got %u\n", error);
713
714     data = 1;
715     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
717
718     /* WindowsInstaller value exists */
719     SetLastError(0xdeadbeef);
720     state = MsiQueryProductStateA(prodcode);
721     error = GetLastError();
722     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
723     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
724        "expected ERROR_SUCCESS, got %u\n", error);
725
726     data = 2;
727     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
729
730     /* WindowsInstaller value is not 1 */
731     SetLastError(0xdeadbeef);
732     state = MsiQueryProductStateA(prodcode);
733     error = GetLastError();
734     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
735     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
736        "expected ERROR_SUCCESS, got %u\n", error);
737
738     RegDeleteKeyA(userkey, "");
739
740     /* user product key does not exist */
741     SetLastError(0xdeadbeef);
742     state = MsiQueryProductStateA(prodcode);
743     error = GetLastError();
744     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
745     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
746        "expected ERROR_SUCCESS, got %u\n", error);
747
748     RegDeleteValueA(props, "WindowsInstaller");
749     delete_key(props, "", access & KEY_WOW64_64KEY);
750     RegCloseKey(props);
751     delete_key(localkey, "", access & KEY_WOW64_64KEY);
752     RegCloseKey(localkey);
753     RegDeleteKeyA(userkey, "");
754     RegCloseKey(userkey);
755
756     /* MSIINSTALLCONTEXT_USERMANAGED */
757
758     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
759     lstrcatA(keypath, usersid);
760     lstrcatA(keypath, "\\Installer\\Products\\");
761     lstrcatA(keypath, prod_squashed);
762
763     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
765
766     state = MsiQueryProductStateA(prodcode);
767     ok(state == INSTALLSTATE_ADVERTISED,
768        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
769
770     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
771     lstrcatA(keypath, usersid);
772     lstrcatA(keypath, "\\Products\\");
773     lstrcatA(keypath, prod_squashed);
774
775     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
777
778     state = MsiQueryProductStateA(prodcode);
779     ok(state == INSTALLSTATE_ADVERTISED,
780        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
781
782     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
784
785     state = MsiQueryProductStateA(prodcode);
786     ok(state == INSTALLSTATE_ADVERTISED,
787        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
788
789     data = 1;
790     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
792
793     /* WindowsInstaller value exists */
794     state = MsiQueryProductStateA(prodcode);
795     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
796
797     RegDeleteValueA(props, "WindowsInstaller");
798     delete_key(props, "", access & KEY_WOW64_64KEY);
799     RegCloseKey(props);
800     delete_key(localkey, "", access & KEY_WOW64_64KEY);
801     RegCloseKey(localkey);
802     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
803     RegCloseKey(prodkey);
804
805     /* MSIINSTALLCONTEXT_MACHINE */
806
807     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
808     lstrcatA(keypath, prod_squashed);
809
810     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
812
813     state = MsiQueryProductStateA(prodcode);
814     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
815
816     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
817     lstrcatA(keypath, "S-1-5-18\\Products\\");
818     lstrcatA(keypath, prod_squashed);
819
820     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
821     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
822
823     state = MsiQueryProductStateA(prodcode);
824     ok(state == INSTALLSTATE_ADVERTISED,
825        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
826
827     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
828     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
829
830     state = MsiQueryProductStateA(prodcode);
831     ok(state == INSTALLSTATE_ADVERTISED,
832        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
833
834     data = 1;
835     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
837
838     /* WindowsInstaller value exists */
839     state = MsiQueryProductStateA(prodcode);
840     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
841
842     RegDeleteValueA(props, "WindowsInstaller");
843     delete_key(props, "", access & KEY_WOW64_64KEY);
844     RegCloseKey(props);
845     delete_key(localkey, "", access & KEY_WOW64_64KEY);
846     RegCloseKey(localkey);
847     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
848     RegCloseKey(prodkey);
849
850     LocalFree(usersid);
851 }
852
853 static const char table_enc85[] =
854 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
855 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
856 "yz{}~";
857
858 /*
859  *  Encodes a base85 guid given a GUID pointer
860  *  Caller should provide a 21 character buffer for the encoded string.
861  */
862 static void encode_base85_guid( GUID *guid, LPWSTR str )
863 {
864     unsigned int x, *p, i;
865
866     p = (unsigned int*) guid;
867     for( i=0; i<4; i++ )
868     {
869         x = p[i];
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         x = x/85;
878         *str++ = table_enc85[x%85];
879     }
880     *str = 0;
881 }
882
883 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
884 {
885     WCHAR guidW[MAX_PATH];
886     WCHAR base85W[MAX_PATH];
887     WCHAR squashedW[MAX_PATH];
888     GUID guid;
889     HRESULT hr;
890     int size;
891
892     hr = CoCreateGuid(&guid);
893     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
894
895     size = StringFromGUID2(&guid, guidW, MAX_PATH);
896     ok(size == 39, "Expected 39, got %d\n", hr);
897
898     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
899     encode_base85_guid(&guid, base85W);
900     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
901     squash_guid(guidW, squashedW);
902     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
903 }
904
905 static void test_MsiQueryFeatureState(void)
906 {
907     HKEY userkey, localkey, compkey, compkey2;
908     CHAR prodcode[MAX_PATH];
909     CHAR prod_squashed[MAX_PATH];
910     CHAR component[MAX_PATH];
911     CHAR comp_base85[MAX_PATH];
912     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
913     CHAR keypath[MAX_PATH*2];
914     INSTALLSTATE state;
915     LPSTR usersid;
916     LONG res;
917     REGSAM access = KEY_ALL_ACCESS;
918     DWORD error;
919
920     create_test_guid(prodcode, prod_squashed);
921     compose_base85_guid(component, comp_base85, comp_squashed);
922     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
923     get_user_sid(&usersid);
924
925     if (is_wow64)
926         access |= KEY_WOW64_64KEY;
927
928     /* NULL prodcode */
929     SetLastError(0xdeadbeef);
930     state = MsiQueryFeatureStateA(NULL, "feature");
931     error = GetLastError();
932     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
933     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
934
935     /* empty prodcode */
936     SetLastError(0xdeadbeef);
937     state = MsiQueryFeatureStateA("", "feature");
938     error = GetLastError();
939     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
940     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
941
942     /* garbage prodcode */
943     SetLastError(0xdeadbeef);
944     state = MsiQueryFeatureStateA("garbage", "feature");
945     error = GetLastError();
946     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
947     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
948
949     /* guid without brackets */
950     SetLastError(0xdeadbeef);
951     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
952     error = GetLastError();
953     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
954     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
955
956     /* guid with brackets */
957     SetLastError(0xdeadbeef);
958     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
959     error = GetLastError();
960     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
961     ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
962        "expected ERROR_SUCCESS, got %u\n", error);
963
964     /* same length as guid, but random */
965     SetLastError(0xdeadbeef);
966     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
967     error = GetLastError();
968     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
969     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
970
971     /* NULL szFeature */
972     SetLastError(0xdeadbeef);
973     state = MsiQueryFeatureStateA(prodcode, NULL);
974     error = GetLastError();
975     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
976     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
977
978     /* empty szFeature */
979     SetLastError(0xdeadbeef);
980     state = MsiQueryFeatureStateA(prodcode, "");
981     error = GetLastError();
982     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
983     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
984        "expected ERROR_SUCCESS, got %u\n", error);
985
986     /* feature key does not exist yet */
987     SetLastError(0xdeadbeef);
988     state = MsiQueryFeatureStateA(prodcode, "feature");
989     error = GetLastError();
990     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
991     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
992        "expected ERROR_SUCCESS, got %u\n", error);
993
994     /* MSIINSTALLCONTEXT_USERUNMANAGED */
995
996     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
997     lstrcatA(keypath, prod_squashed);
998
999     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1001
1002     /* feature key exists */
1003     SetLastError(0xdeadbeef);
1004     state = MsiQueryFeatureStateA(prodcode, "feature");
1005     error = GetLastError();
1006     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1007     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1008        "expected ERROR_SUCCESS, got %u\n", error);
1009
1010     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1012
1013     /* feature value exists */
1014     SetLastError(0xdeadbeef);
1015     state = MsiQueryFeatureStateA(prodcode, "feature");
1016     error = GetLastError();
1017     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1018     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1019        "expected ERROR_SUCCESS, got %u\n", error);
1020
1021     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1022     lstrcatA(keypath, usersid);
1023     lstrcatA(keypath, "\\Products\\");
1024     lstrcatA(keypath, prod_squashed);
1025     lstrcatA(keypath, "\\Features");
1026
1027     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1028     if (res == ERROR_ACCESS_DENIED)
1029     {
1030         skip("Not enough rights to perform tests\n");
1031         RegDeleteKeyA(userkey, "");
1032         RegCloseKey(userkey);
1033         LocalFree(usersid);
1034         return;
1035     }
1036     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1037
1038     /* userdata features key exists */
1039     SetLastError(0xdeadbeef);
1040     state = MsiQueryFeatureStateA(prodcode, "feature");
1041     error = GetLastError();
1042     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1043     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1044        "expected ERROR_SUCCESS, got %u\n", error);
1045
1046     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1048
1049     SetLastError(0xdeadbeef);
1050     state = MsiQueryFeatureStateA(prodcode, "feature");
1051     error = GetLastError();
1052     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1053     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1054        "expected ERROR_SUCCESS, got %u\n", error);
1055
1056     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1057     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1058
1059     SetLastError(0xdeadbeef);
1060     state = MsiQueryFeatureStateA(prodcode, "feature");
1061     error = GetLastError();
1062     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1063     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1064        "expected ERROR_SUCCESS, got %u\n", error);
1065
1066     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1068
1069     SetLastError(0xdeadbeef);
1070     state = MsiQueryFeatureStateA(prodcode, "feature");
1071     error = GetLastError();
1072     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1073     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1074        "expected ERROR_SUCCESS, got %u\n", error);
1075
1076     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1078
1079     SetLastError(0xdeadbeef);
1080     state = MsiQueryFeatureStateA(prodcode, "feature");
1081     error = GetLastError();
1082     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1083     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1084        "expected ERROR_SUCCESS, got %u\n", error);
1085
1086     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1087     lstrcatA(keypath, usersid);
1088     lstrcatA(keypath, "\\Components\\");
1089     lstrcatA(keypath, comp_squashed);
1090
1091     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1093
1094     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1095     lstrcatA(keypath, usersid);
1096     lstrcatA(keypath, "\\Components\\");
1097     lstrcatA(keypath, comp_squashed2);
1098
1099     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1101
1102     SetLastError(0xdeadbeef);
1103     state = MsiQueryFeatureStateA(prodcode, "feature");
1104     error = GetLastError();
1105     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1106     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1107        "expected ERROR_SUCCESS, got %u\n", error);
1108
1109     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1111
1112     SetLastError(0xdeadbeef);
1113     state = MsiQueryFeatureStateA(prodcode, "feature");
1114     error = GetLastError();
1115     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1116     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1117        "expected ERROR_SUCCESS, got %u\n", error);
1118
1119     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1121
1122     SetLastError(0xdeadbeef);
1123     state = MsiQueryFeatureStateA(prodcode, "feature");
1124     error = GetLastError();
1125     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1126     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1127        "expected ERROR_SUCCESS, got %u\n", error);
1128
1129     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1131
1132     /* INSTALLSTATE_LOCAL */
1133     SetLastError(0xdeadbeef);
1134     state = MsiQueryFeatureStateA(prodcode, "feature");
1135     error = GetLastError();
1136     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1137     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1138        "expected ERROR_SUCCESS, got %u\n", error);
1139
1140     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1142
1143     /* INSTALLSTATE_SOURCE */
1144     SetLastError(0xdeadbeef);
1145     state = MsiQueryFeatureStateA(prodcode, "feature");
1146     error = GetLastError();
1147     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1148     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1149        "expected ERROR_SUCCESS, got %u\n", error);
1150
1151     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1153
1154     /* bad INSTALLSTATE_SOURCE */
1155     SetLastError(0xdeadbeef);
1156     state = MsiQueryFeatureStateA(prodcode, "feature");
1157     error = GetLastError();
1158     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1159     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1160        "expected ERROR_SUCCESS, got %u\n", error);
1161
1162     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1164
1165     /* INSTALLSTATE_SOURCE */
1166     SetLastError(0xdeadbeef);
1167     state = MsiQueryFeatureStateA(prodcode, "feature");
1168     error = GetLastError();
1169     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1170     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1171        "expected ERROR_SUCCESS, got %u\n", error);
1172
1173     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1175
1176     /* bad INSTALLSTATE_SOURCE */
1177     SetLastError(0xdeadbeef);
1178     state = MsiQueryFeatureStateA(prodcode, "feature");
1179     error = GetLastError();
1180     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1181     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1182        "expected ERROR_SUCCESS, got %u\n", error);
1183
1184     RegDeleteValueA(compkey, prod_squashed);
1185     RegDeleteValueA(compkey2, prod_squashed);
1186     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1187     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1188     RegDeleteValueA(localkey, "feature");
1189     RegDeleteValueA(userkey, "feature");
1190     RegDeleteKeyA(userkey, "");
1191     RegCloseKey(compkey);
1192     RegCloseKey(compkey2);
1193     RegCloseKey(localkey);
1194     RegCloseKey(userkey);
1195
1196     /* MSIINSTALLCONTEXT_USERMANAGED */
1197
1198     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1199     lstrcatA(keypath, usersid);
1200     lstrcatA(keypath, "\\Installer\\Features\\");
1201     lstrcatA(keypath, prod_squashed);
1202
1203     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1205
1206     /* feature key exists */
1207     state = MsiQueryFeatureStateA(prodcode, "feature");
1208     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1209
1210     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1212
1213     /* feature value exists */
1214     state = MsiQueryFeatureStateA(prodcode, "feature");
1215     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1216
1217     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1218     lstrcatA(keypath, usersid);
1219     lstrcatA(keypath, "\\Products\\");
1220     lstrcatA(keypath, prod_squashed);
1221     lstrcatA(keypath, "\\Features");
1222
1223     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1225
1226     /* userdata features key exists */
1227     state = MsiQueryFeatureStateA(prodcode, "feature");
1228     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1229
1230     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1231     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1232
1233     state = MsiQueryFeatureStateA(prodcode, "feature");
1234     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1235
1236     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1238
1239     state = MsiQueryFeatureStateA(prodcode, "feature");
1240     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1241
1242     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1244
1245     state = MsiQueryFeatureStateA(prodcode, "feature");
1246     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1247
1248     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1249     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1250
1251     state = MsiQueryFeatureStateA(prodcode, "feature");
1252     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1253
1254     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1255     lstrcatA(keypath, usersid);
1256     lstrcatA(keypath, "\\Components\\");
1257     lstrcatA(keypath, comp_squashed);
1258
1259     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1260     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1261
1262     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1263     lstrcatA(keypath, usersid);
1264     lstrcatA(keypath, "\\Components\\");
1265     lstrcatA(keypath, comp_squashed2);
1266
1267     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1269
1270     state = MsiQueryFeatureStateA(prodcode, "feature");
1271     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1272
1273     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1275
1276     state = MsiQueryFeatureStateA(prodcode, "feature");
1277     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1278
1279     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1281
1282     state = MsiQueryFeatureStateA(prodcode, "feature");
1283     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1284
1285     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1286     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1287
1288     state = MsiQueryFeatureStateA(prodcode, "feature");
1289     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1290
1291     RegDeleteValueA(compkey, prod_squashed);
1292     RegDeleteValueA(compkey2, prod_squashed);
1293     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1294     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1295     RegDeleteValueA(localkey, "feature");
1296     RegDeleteValueA(userkey, "feature");
1297     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1298     RegCloseKey(compkey);
1299     RegCloseKey(compkey2);
1300     RegCloseKey(localkey);
1301     RegCloseKey(userkey);
1302
1303     /* MSIINSTALLCONTEXT_MACHINE */
1304
1305     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1306     lstrcatA(keypath, prod_squashed);
1307
1308     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1310
1311     /* feature key exists */
1312     state = MsiQueryFeatureStateA(prodcode, "feature");
1313     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1314
1315     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1317
1318     /* feature value exists */
1319     state = MsiQueryFeatureStateA(prodcode, "feature");
1320     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1321
1322     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1323     lstrcatA(keypath, "S-1-5-18\\Products\\");
1324     lstrcatA(keypath, prod_squashed);
1325     lstrcatA(keypath, "\\Features");
1326
1327     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1329
1330     /* userdata features key exists */
1331     state = MsiQueryFeatureStateA(prodcode, "feature");
1332     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1333
1334     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1336
1337     state = MsiQueryFeatureStateA(prodcode, "feature");
1338     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1339
1340     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1342
1343     state = MsiQueryFeatureStateA(prodcode, "feature");
1344     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1345
1346     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1348
1349     state = MsiQueryFeatureStateA(prodcode, "feature");
1350     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1351
1352     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1354
1355     state = MsiQueryFeatureStateA(prodcode, "feature");
1356     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1357
1358     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1359     lstrcatA(keypath, "S-1-5-18\\Components\\");
1360     lstrcatA(keypath, comp_squashed);
1361
1362     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1364
1365     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1366     lstrcatA(keypath, "S-1-5-18\\Components\\");
1367     lstrcatA(keypath, comp_squashed2);
1368
1369     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1371
1372     state = MsiQueryFeatureStateA(prodcode, "feature");
1373     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1374
1375     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1377
1378     state = MsiQueryFeatureStateA(prodcode, "feature");
1379     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1380
1381     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1383
1384     state = MsiQueryFeatureStateA(prodcode, "feature");
1385     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1386
1387     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1389
1390     state = MsiQueryFeatureStateA(prodcode, "feature");
1391     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1392
1393     RegDeleteValueA(compkey, prod_squashed);
1394     RegDeleteValueA(compkey2, prod_squashed);
1395     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1396     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1397     RegDeleteValueA(localkey, "feature");
1398     RegDeleteValueA(userkey, "feature");
1399     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1400     RegCloseKey(compkey);
1401     RegCloseKey(compkey2);
1402     RegCloseKey(localkey);
1403     RegCloseKey(userkey);
1404     LocalFree(usersid);
1405 }
1406
1407 static void test_MsiQueryComponentState(void)
1408 {
1409     HKEY compkey, prodkey;
1410     CHAR prodcode[MAX_PATH];
1411     CHAR prod_squashed[MAX_PATH];
1412     CHAR component[MAX_PATH];
1413     CHAR comp_base85[MAX_PATH];
1414     CHAR comp_squashed[MAX_PATH];
1415     CHAR keypath[MAX_PATH];
1416     INSTALLSTATE state;
1417     LPSTR usersid;
1418     LONG res;
1419     UINT r;
1420     REGSAM access = KEY_ALL_ACCESS;
1421     DWORD error;
1422
1423     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1424
1425     if (!pMsiQueryComponentStateA)
1426     {
1427         win_skip("MsiQueryComponentStateA not implemented\n");
1428         return;
1429     }
1430
1431     create_test_guid(prodcode, prod_squashed);
1432     compose_base85_guid(component, comp_base85, comp_squashed);
1433     get_user_sid(&usersid);
1434
1435     if (is_wow64)
1436         access |= KEY_WOW64_64KEY;
1437
1438     /* NULL szProductCode */
1439     state = MAGIC_ERROR;
1440     SetLastError(0xdeadbeef);
1441     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1442     error = GetLastError();
1443     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1444     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1445     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1446
1447     /* empty szProductCode */
1448     state = MAGIC_ERROR;
1449     SetLastError(0xdeadbeef);
1450     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1451     error = GetLastError();
1452     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1453     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1454     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1455
1456     /* random szProductCode */
1457     state = MAGIC_ERROR;
1458     SetLastError(0xdeadbeef);
1459     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1460     error = GetLastError();
1461     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1462     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1463     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1464
1465     /* GUID-length szProductCode */
1466     state = MAGIC_ERROR;
1467     SetLastError(0xdeadbeef);
1468     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1469     error = GetLastError();
1470     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1471     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1472     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1473
1474     /* GUID-length with brackets */
1475     state = MAGIC_ERROR;
1476     SetLastError(0xdeadbeef);
1477     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1478     error = GetLastError();
1479     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1480     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1481     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1482
1483     /* actual GUID */
1484     state = MAGIC_ERROR;
1485     SetLastError(0xdeadbeef);
1486     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1487     error = GetLastError();
1488     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1489     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1490     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1491
1492     state = MAGIC_ERROR;
1493     SetLastError(0xdeadbeef);
1494     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1495     error = GetLastError();
1496     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1497     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1498     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1499
1500     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1501     lstrcatA(keypath, prod_squashed);
1502
1503     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1504     if (res == ERROR_ACCESS_DENIED)
1505     {
1506         skip("Not enough rights to perform tests\n");
1507         LocalFree(usersid);
1508         return;
1509     }
1510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1511
1512     state = MAGIC_ERROR;
1513     SetLastError(0xdeadbeef);
1514     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1515     error = GetLastError();
1516     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1517     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1518     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1519
1520     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1521     RegCloseKey(prodkey);
1522
1523     /* create local system product key */
1524     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1525     lstrcatA(keypath, prod_squashed);
1526     lstrcatA(keypath, "\\InstallProperties");
1527
1528     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1530
1531     /* local system product key exists */
1532     state = MAGIC_ERROR;
1533     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1534     error = GetLastError();
1535     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1536     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1537     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1538
1539     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1541
1542     /* LocalPackage value exists */
1543     state = MAGIC_ERROR;
1544     SetLastError(0xdeadbeef);
1545     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1546     error = GetLastError();
1547     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1548     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1549     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1550
1551     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1552     lstrcatA(keypath, comp_squashed);
1553
1554     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1556
1557     /* component key exists */
1558     state = MAGIC_ERROR;
1559     SetLastError(0xdeadbeef);
1560     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1561     error = GetLastError();
1562     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1563     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1564     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1565
1566     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1568
1569     /* component\product exists */
1570     state = MAGIC_ERROR;
1571     SetLastError(0xdeadbeef);
1572     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1573     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1574     error = GetLastError();
1575     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1576        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1577     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1578
1579     /* NULL component, product exists */
1580     state = MAGIC_ERROR;
1581     SetLastError(0xdeadbeef);
1582     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1583     error = GetLastError();
1584     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1585     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1586     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1587
1588     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1590
1591     /* INSTALLSTATE_LOCAL */
1592     state = MAGIC_ERROR;
1593     SetLastError(0xdeadbeef);
1594     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1595     error = GetLastError();
1596     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1597     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1598     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1599
1600     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1602
1603     /* INSTALLSTATE_SOURCE */
1604     state = MAGIC_ERROR;
1605     SetLastError(0xdeadbeef);
1606     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1607     error = GetLastError();
1608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1609     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1610     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1611
1612     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1614
1615     /* bad INSTALLSTATE_SOURCE */
1616     state = MAGIC_ERROR;
1617     SetLastError(0xdeadbeef);
1618     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1619     error = GetLastError();
1620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1621     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1622     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1623
1624     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1626
1627     /* INSTALLSTATE_SOURCE */
1628     state = MAGIC_ERROR;
1629     SetLastError(0xdeadbeef);
1630     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1631     error = GetLastError();
1632     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1633     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1634     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1635
1636     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1638
1639     /* bad INSTALLSTATE_SOURCE */
1640     state = MAGIC_ERROR;
1641     SetLastError(0xdeadbeef);
1642     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1643     error = GetLastError();
1644     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1645     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1646     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1647
1648     RegDeleteValueA(prodkey, "LocalPackage");
1649     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1650     RegDeleteValueA(compkey, prod_squashed);
1651     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1652     RegCloseKey(prodkey);
1653     RegCloseKey(compkey);
1654
1655     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1656
1657     state = MAGIC_ERROR;
1658     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1659     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1660     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1661
1662     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1663     lstrcatA(keypath, prod_squashed);
1664
1665     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1667
1668     state = MAGIC_ERROR;
1669     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1670     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1671     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1672
1673     RegDeleteKeyA(prodkey, "");
1674     RegCloseKey(prodkey);
1675
1676     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1677     lstrcatA(keypath, usersid);
1678     lstrcatA(keypath, "\\Products\\");
1679     lstrcatA(keypath, prod_squashed);
1680     lstrcatA(keypath, "\\InstallProperties");
1681
1682     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1683     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1684
1685     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1687
1688     RegCloseKey(prodkey);
1689
1690     state = MAGIC_ERROR;
1691     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1692     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1693     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1694
1695     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1696     lstrcatA(keypath, usersid);
1697     lstrcatA(keypath, "\\Components\\");
1698     lstrcatA(keypath, comp_squashed);
1699
1700     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1702
1703     /* component key exists */
1704     state = MAGIC_ERROR;
1705     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1706     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1707     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1708
1709     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1711
1712     /* component\product exists */
1713     state = MAGIC_ERROR;
1714     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1715     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1716     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1717        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1718
1719     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1721
1722     state = MAGIC_ERROR;
1723     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1724     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1725     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1726
1727     /* MSIINSTALLCONTEXT_USERMANAGED */
1728
1729     state = MAGIC_ERROR;
1730     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1731     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1732     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1733
1734     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1735     lstrcatA(keypath, prod_squashed);
1736
1737     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1739
1740     state = MAGIC_ERROR;
1741     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1742     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1743     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1744
1745     RegDeleteKeyA(prodkey, "");
1746     RegCloseKey(prodkey);
1747
1748     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1749     lstrcatA(keypath, usersid);
1750     lstrcatA(keypath, "\\Installer\\Products\\");
1751     lstrcatA(keypath, prod_squashed);
1752
1753     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1754     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1755
1756     state = MAGIC_ERROR;
1757     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1758     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1759     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1760
1761     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1762     RegCloseKey(prodkey);
1763
1764     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1765     lstrcatA(keypath, usersid);
1766     lstrcatA(keypath, "\\Products\\");
1767     lstrcatA(keypath, prod_squashed);
1768     lstrcatA(keypath, "\\InstallProperties");
1769
1770     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1772
1773     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1774     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1775
1776     state = MAGIC_ERROR;
1777     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1778     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1779     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1780
1781     RegDeleteValueA(prodkey, "LocalPackage");
1782     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1783     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1784     RegDeleteValueA(compkey, prod_squashed);
1785     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1786     RegCloseKey(prodkey);
1787     RegCloseKey(compkey);
1788     LocalFree(usersid);
1789 }
1790
1791 static void test_MsiGetComponentPath(void)
1792 {
1793     HKEY compkey, prodkey, installprop;
1794     CHAR prodcode[MAX_PATH];
1795     CHAR prod_squashed[MAX_PATH];
1796     CHAR component[MAX_PATH];
1797     CHAR comp_base85[MAX_PATH];
1798     CHAR comp_squashed[MAX_PATH];
1799     CHAR keypath[MAX_PATH];
1800     CHAR path[MAX_PATH];
1801     INSTALLSTATE state;
1802     LPSTR usersid;
1803     DWORD size, val;
1804     REGSAM access = KEY_ALL_ACCESS;
1805     LONG res;
1806
1807     create_test_guid(prodcode, prod_squashed);
1808     compose_base85_guid(component, comp_base85, comp_squashed);
1809     get_user_sid(&usersid);
1810
1811     if (is_wow64)
1812         access |= KEY_WOW64_64KEY;
1813
1814     /* NULL szProduct */
1815     size = MAX_PATH;
1816     state = MsiGetComponentPathA(NULL, component, path, &size);
1817     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1818     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1819
1820     /* NULL szComponent */
1821     size = MAX_PATH;
1822     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1823     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1824     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1825
1826     size = MAX_PATH;
1827     state = MsiLocateComponentA(NULL, path, &size);
1828     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1829     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1830
1831     /* NULL lpPathBuf */
1832     size = MAX_PATH;
1833     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1834     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1835     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1836
1837     size = MAX_PATH;
1838     state = MsiLocateComponentA(component, NULL, &size);
1839     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1840     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1841
1842     /* NULL pcchBuf */
1843     size = MAX_PATH;
1844     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1845     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1846     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1847
1848     size = MAX_PATH;
1849     state = MsiLocateComponentA(component, path, NULL);
1850     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1851     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1852
1853     /* all params valid */
1854     size = MAX_PATH;
1855     state = MsiGetComponentPathA(prodcode, component, path, &size);
1856     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1857     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1858
1859     size = MAX_PATH;
1860     state = MsiLocateComponentA(component, path, &size);
1861     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1862     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1863
1864     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1865     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1866     lstrcatA(keypath, comp_squashed);
1867
1868     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1869     if (res == ERROR_ACCESS_DENIED)
1870     {
1871         skip("Not enough rights to perform tests\n");
1872         LocalFree(usersid);
1873         return;
1874     }
1875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1876
1877     /* local system component key exists */
1878     size = MAX_PATH;
1879     state = MsiGetComponentPathA(prodcode, component, path, &size);
1880     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1881     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1882
1883     size = MAX_PATH;
1884     state = MsiLocateComponentA(component, path, &size);
1885     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1886     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1887
1888     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1890
1891     /* product value exists */
1892     path[0] = 0;
1893     size = MAX_PATH;
1894     state = MsiGetComponentPathA(prodcode, component, path, &size);
1895     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1896     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1897     ok(size == 10, "Expected 10, got %d\n", size);
1898
1899     path[0] = 0;
1900     size = MAX_PATH;
1901     state = MsiLocateComponentA(component, path, &size);
1902     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1903     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1904     ok(size == 10, "Expected 10, got %d\n", size);
1905
1906     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1907     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1908     lstrcatA(keypath, prod_squashed);
1909     lstrcatA(keypath, "\\InstallProperties");
1910
1911     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1913
1914     val = 1;
1915     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1917
1918     /* install properties key exists */
1919     path[0] = 0;
1920     size = MAX_PATH;
1921     state = MsiGetComponentPathA(prodcode, component, path, &size);
1922     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1923     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1924     ok(size == 10, "Expected 10, got %d\n", size);
1925
1926     path[0] = 0;
1927     size = MAX_PATH;
1928     state = MsiLocateComponentA(component, path, &size);
1929     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1930     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1931     ok(size == 10, "Expected 10, got %d\n", size);
1932
1933     create_file("C:\\imapath", "C:\\imapath", 11);
1934
1935     /* file exists */
1936     path[0] = 0;
1937     size = MAX_PATH;
1938     state = MsiGetComponentPathA(prodcode, component, path, &size);
1939     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1940     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1941     ok(size == 10, "Expected 10, got %d\n", size);
1942
1943     path[0] = 0;
1944     size = MAX_PATH;
1945     state = MsiLocateComponentA(component, path, &size);
1946     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1947     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1948     ok(size == 10, "Expected 10, got %d\n", size);
1949
1950     RegDeleteValueA(compkey, prod_squashed);
1951     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1952     RegDeleteValueA(installprop, "WindowsInstaller");
1953     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1954     RegCloseKey(compkey);
1955     RegCloseKey(installprop);
1956     DeleteFileA("C:\\imapath");
1957
1958     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1959     lstrcatA(keypath, "Installer\\UserData\\");
1960     lstrcatA(keypath, usersid);
1961     lstrcatA(keypath, "\\Components\\");
1962     lstrcatA(keypath, comp_squashed);
1963
1964     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1965     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1966
1967     /* user managed component key exists */
1968     size = MAX_PATH;
1969     state = MsiGetComponentPathA(prodcode, component, path, &size);
1970     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1971     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1972
1973     size = MAX_PATH;
1974     state = MsiLocateComponentA(component, path, &size);
1975     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1976     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1977
1978     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1980
1981     /* product value exists */
1982     path[0] = 0;
1983     size = MAX_PATH;
1984     state = MsiGetComponentPathA(prodcode, component, path, &size);
1985     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1986     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1987     ok(size == 10, "Expected 10, got %d\n", size);
1988
1989     path[0] = 0;
1990     size = MAX_PATH;
1991     state = MsiLocateComponentA(component, path, &size);
1992     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1993     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1994     ok(size == 10, "Expected 10, got %d\n", size);
1995
1996     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1997     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1998     lstrcatA(keypath, prod_squashed);
1999     lstrcatA(keypath, "\\InstallProperties");
2000
2001     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2003
2004     val = 1;
2005     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2007
2008     /* install properties key exists */
2009     path[0] = 0;
2010     size = MAX_PATH;
2011     state = MsiGetComponentPathA(prodcode, component, path, &size);
2012     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2013     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2014     ok(size == 10, "Expected 10, got %d\n", size);
2015
2016     path[0] = 0;
2017     size = MAX_PATH;
2018     state = MsiLocateComponentA(component, path, &size);
2019     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2020     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2021     ok(size == 10, "Expected 10, got %d\n", size);
2022
2023     create_file("C:\\imapath", "C:\\imapath", 11);
2024
2025     /* file exists */
2026     path[0] = 0;
2027     size = MAX_PATH;
2028     state = MsiGetComponentPathA(prodcode, component, path, &size);
2029     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2030     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2031     ok(size == 10, "Expected 10, got %d\n", size);
2032
2033     path[0] = 0;
2034     size = MAX_PATH;
2035     state = MsiLocateComponentA(component, path, &size);
2036     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2037     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2038     ok(size == 10, "Expected 10, got %d\n", size);
2039
2040     RegDeleteValueA(compkey, prod_squashed);
2041     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2042     RegDeleteValueA(installprop, "WindowsInstaller");
2043     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2044     RegCloseKey(compkey);
2045     RegCloseKey(installprop);
2046     DeleteFileA("C:\\imapath");
2047
2048     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2049     lstrcatA(keypath, "Installer\\Managed\\");
2050     lstrcatA(keypath, usersid);
2051     lstrcatA(keypath, "\\Installer\\Products\\");
2052     lstrcatA(keypath, prod_squashed);
2053
2054     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2056
2057     /* user managed product key exists */
2058     size = MAX_PATH;
2059     state = MsiGetComponentPathA(prodcode, component, path, &size);
2060     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2061     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2062
2063     size = MAX_PATH;
2064     state = MsiLocateComponentA(component, path, &size);
2065     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2066     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2067
2068     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2069     lstrcatA(keypath, "Installer\\UserData\\");
2070     lstrcatA(keypath, usersid);
2071     lstrcatA(keypath, "\\Components\\");
2072     lstrcatA(keypath, comp_squashed);
2073
2074     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2076
2077     /* user managed component key exists */
2078     size = MAX_PATH;
2079     state = MsiGetComponentPathA(prodcode, component, path, &size);
2080     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2081     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2082
2083     size = MAX_PATH;
2084     state = MsiLocateComponentA(component, path, &size);
2085     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2086     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2087
2088     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2090
2091     /* product value exists */
2092     path[0] = 0;
2093     size = MAX_PATH;
2094     state = MsiGetComponentPathA(prodcode, component, path, &size);
2095     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2096     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2097     ok(size == 10, "Expected 10, got %d\n", size);
2098
2099     path[0] = 0;
2100     size = MAX_PATH;
2101     state = MsiLocateComponentA(component, path, &size);
2102     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2103     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2104     ok(size == 10, "Expected 10, got %d\n", size);
2105
2106     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2107     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2108     lstrcatA(keypath, prod_squashed);
2109     lstrcatA(keypath, "\\InstallProperties");
2110
2111     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2113
2114     val = 1;
2115     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2117
2118     /* install properties key exists */
2119     path[0] = 0;
2120     size = MAX_PATH;
2121     state = MsiGetComponentPathA(prodcode, component, path, &size);
2122     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2123     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2124     ok(size == 10, "Expected 10, got %d\n", size);
2125
2126     path[0] = 0;
2127     size = MAX_PATH;
2128     state = MsiLocateComponentA(component, path, &size);
2129     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2130     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2131     ok(size == 10, "Expected 10, got %d\n", size);
2132
2133     create_file("C:\\imapath", "C:\\imapath", 11);
2134
2135     /* file exists */
2136     path[0] = 0;
2137     size = MAX_PATH;
2138     state = MsiGetComponentPathA(prodcode, component, path, &size);
2139     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2140     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2141     ok(size == 10, "Expected 10, got %d\n", size);
2142
2143     path[0] = 0;
2144     size = MAX_PATH;
2145     state = MsiLocateComponentA(component, path, &size);
2146     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2147     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2148     ok(size == 10, "Expected 10, got %d\n", size);
2149
2150     RegDeleteValueA(compkey, prod_squashed);
2151     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2152     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2153     RegDeleteValueA(installprop, "WindowsInstaller");
2154     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2155     RegCloseKey(prodkey);
2156     RegCloseKey(compkey);
2157     RegCloseKey(installprop);
2158     DeleteFileA("C:\\imapath");
2159
2160     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2161     lstrcatA(keypath, prod_squashed);
2162
2163     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2165
2166     /* user unmanaged product key exists */
2167     size = MAX_PATH;
2168     state = MsiGetComponentPathA(prodcode, component, path, &size);
2169     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2170     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2171
2172     size = MAX_PATH;
2173     state = MsiLocateComponentA(component, path, &size);
2174     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2175     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2176
2177     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2178     lstrcatA(keypath, "Installer\\UserData\\");
2179     lstrcatA(keypath, usersid);
2180     lstrcatA(keypath, "\\Components\\");
2181     lstrcatA(keypath, comp_squashed);
2182
2183     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2185
2186     /* user unmanaged component key exists */
2187     size = MAX_PATH;
2188     state = MsiGetComponentPathA(prodcode, component, path, &size);
2189     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2190     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2191
2192     size = MAX_PATH;
2193     state = MsiLocateComponentA(component, path, &size);
2194     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2195     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2196
2197     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2199
2200     /* product value exists */
2201     path[0] = 0;
2202     size = MAX_PATH;
2203     state = MsiGetComponentPathA(prodcode, component, path, &size);
2204     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2205     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2206     ok(size == 10, "Expected 10, got %d\n", size);
2207
2208     path[0] = 0;
2209     size = MAX_PATH;
2210     state = MsiLocateComponentA(component, path, &size);
2211     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2212     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2213     ok(size == 10, "Expected 10, got %d\n", size);
2214
2215     create_file("C:\\imapath", "C:\\imapath", 11);
2216
2217     /* file exists */
2218     path[0] = 0;
2219     size = MAX_PATH;
2220     state = MsiGetComponentPathA(prodcode, component, path, &size);
2221     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2222     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2223     ok(size == 10, "Expected 10, got %d\n", size);
2224
2225     path[0] = 0;
2226     size = MAX_PATH;
2227     state = MsiLocateComponentA(component, path, &size);
2228     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2229     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2230     ok(size == 10, "Expected 10, got %d\n", size);
2231
2232     RegDeleteValueA(compkey, prod_squashed);
2233     RegDeleteKeyA(prodkey, "");
2234     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2235     RegCloseKey(prodkey);
2236     RegCloseKey(compkey);
2237     DeleteFileA("C:\\imapath");
2238
2239     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2240     lstrcatA(keypath, prod_squashed);
2241
2242     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2244
2245     /* local classes product key exists */
2246     size = MAX_PATH;
2247     state = MsiGetComponentPathA(prodcode, component, path, &size);
2248     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2249     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2250
2251     size = MAX_PATH;
2252     state = MsiLocateComponentA(component, path, &size);
2253     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2254     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2255
2256     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2257     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2258     lstrcatA(keypath, comp_squashed);
2259
2260     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2262
2263     /* local user component key exists */
2264     size = MAX_PATH;
2265     state = MsiGetComponentPathA(prodcode, component, path, &size);
2266     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2267     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2268
2269     size = MAX_PATH;
2270     state = MsiLocateComponentA(component, path, &size);
2271     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2272     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2273
2274     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2275     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2276
2277     /* product value exists */
2278     path[0] = 0;
2279     size = MAX_PATH;
2280     state = MsiGetComponentPathA(prodcode, component, path, &size);
2281     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2282     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2283     ok(size == 10, "Expected 10, got %d\n", size);
2284
2285     path[0] = 0;
2286     size = MAX_PATH;
2287     state = MsiLocateComponentA(component, path, &size);
2288     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2289     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2290     ok(size == 10, "Expected 10, got %d\n", size);
2291
2292     create_file("C:\\imapath", "C:\\imapath", 11);
2293
2294     /* file exists */
2295     path[0] = 0;
2296     size = MAX_PATH;
2297     state = MsiGetComponentPathA(prodcode, component, path, &size);
2298     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2299     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2300     ok(size == 10, "Expected 10, got %d\n", size);
2301
2302     path[0] = 0;
2303     size = MAX_PATH;
2304     state = MsiLocateComponentA(component, path, &size);
2305     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2306     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2307     ok(size == 10, "Expected 10, got %d\n", size);
2308
2309     RegDeleteValueA(compkey, prod_squashed);
2310     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2311     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2312     RegCloseKey(prodkey);
2313     RegCloseKey(compkey);
2314     DeleteFileA("C:\\imapath");
2315     LocalFree(usersid);
2316 }
2317
2318 static void test_MsiGetProductCode(void)
2319 {
2320     HKEY compkey, prodkey;
2321     CHAR prodcode[MAX_PATH];
2322     CHAR prod_squashed[MAX_PATH];
2323     CHAR prodcode2[MAX_PATH];
2324     CHAR prod2_squashed[MAX_PATH];
2325     CHAR component[MAX_PATH];
2326     CHAR comp_base85[MAX_PATH];
2327     CHAR comp_squashed[MAX_PATH];
2328     CHAR keypath[MAX_PATH];
2329     CHAR product[MAX_PATH];
2330     LPSTR usersid;
2331     LONG res;
2332     UINT r;
2333     REGSAM access = KEY_ALL_ACCESS;
2334
2335     create_test_guid(prodcode, prod_squashed);
2336     create_test_guid(prodcode2, prod2_squashed);
2337     compose_base85_guid(component, comp_base85, comp_squashed);
2338     get_user_sid(&usersid);
2339
2340     if (is_wow64)
2341         access |= KEY_WOW64_64KEY;
2342
2343     /* szComponent is NULL */
2344     lstrcpyA(product, "prod");
2345     r = MsiGetProductCodeA(NULL, product);
2346     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2347     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2348
2349     /* szComponent is empty */
2350     lstrcpyA(product, "prod");
2351     r = MsiGetProductCodeA("", product);
2352     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2353     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2354
2355     /* garbage szComponent */
2356     lstrcpyA(product, "prod");
2357     r = MsiGetProductCodeA("garbage", product);
2358     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2359     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2360
2361     /* guid without brackets */
2362     lstrcpyA(product, "prod");
2363     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2364     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2365     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2366
2367     /* guid with brackets */
2368     lstrcpyA(product, "prod");
2369     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2370     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2371     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2372
2373     /* same length as guid, but random */
2374     lstrcpyA(product, "prod");
2375     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2376     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2377     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2378
2379     /* all params correct, szComponent not published */
2380     lstrcpyA(product, "prod");
2381     r = MsiGetProductCodeA(component, product);
2382     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2383     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2384
2385     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2386     lstrcatA(keypath, "Installer\\UserData\\");
2387     lstrcatA(keypath, usersid);
2388     lstrcatA(keypath, "\\Components\\");
2389     lstrcatA(keypath, comp_squashed);
2390
2391     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2392     if (res == ERROR_ACCESS_DENIED)
2393     {
2394         skip("Not enough rights to perform tests\n");
2395         LocalFree(usersid);
2396         return;
2397     }
2398     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2399
2400     /* user unmanaged component key exists */
2401     lstrcpyA(product, "prod");
2402     r = MsiGetProductCodeA(component, product);
2403     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2404     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2405
2406     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2408
2409     /* product value exists */
2410     lstrcpyA(product, "prod");
2411     r = MsiGetProductCodeA(component, product);
2412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2413     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2414
2415     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2417
2418     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2419     lstrcatA(keypath, "Installer\\Managed\\");
2420     lstrcatA(keypath, usersid);
2421     lstrcatA(keypath, "\\Installer\\Products\\");
2422     lstrcatA(keypath, prod_squashed);
2423
2424     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2426
2427     /* user managed product key of first product exists */
2428     lstrcpyA(product, "prod");
2429     r = MsiGetProductCodeA(component, product);
2430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2431     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2432
2433     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2434     RegCloseKey(prodkey);
2435
2436     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2437     lstrcatA(keypath, prod_squashed);
2438
2439     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2441
2442     /* user unmanaged product key exists */
2443     lstrcpyA(product, "prod");
2444     r = MsiGetProductCodeA(component, product);
2445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2446     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2447
2448     RegDeleteKeyA(prodkey, "");
2449     RegCloseKey(prodkey);
2450
2451     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2452     lstrcatA(keypath, prod_squashed);
2453
2454     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2456
2457     /* local classes product key exists */
2458     lstrcpyA(product, "prod");
2459     r = MsiGetProductCodeA(component, product);
2460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2461     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2462
2463     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2464     RegCloseKey(prodkey);
2465
2466     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2467     lstrcatA(keypath, "Installer\\Managed\\");
2468     lstrcatA(keypath, usersid);
2469     lstrcatA(keypath, "\\Installer\\Products\\");
2470     lstrcatA(keypath, prod2_squashed);
2471
2472     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2474
2475     /* user managed product key of second product exists */
2476     lstrcpyA(product, "prod");
2477     r = MsiGetProductCodeA(component, product);
2478     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2479     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2480
2481     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2482     RegCloseKey(prodkey);
2483     RegDeleteValueA(compkey, prod_squashed);
2484     RegDeleteValueA(compkey, prod2_squashed);
2485     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2486     RegCloseKey(compkey);
2487
2488     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2489     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2490     lstrcatA(keypath, comp_squashed);
2491
2492     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2493     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2494
2495     /* local user component key exists */
2496     lstrcpyA(product, "prod");
2497     r = MsiGetProductCodeA(component, product);
2498     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2499     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2500
2501     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2502     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2503
2504     /* product value exists */
2505     lstrcpyA(product, "prod");
2506     r = MsiGetProductCodeA(component, product);
2507     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2508     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2509
2510     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2511     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2512
2513     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2514     lstrcatA(keypath, "Installer\\Managed\\");
2515     lstrcatA(keypath, usersid);
2516     lstrcatA(keypath, "\\Installer\\Products\\");
2517     lstrcatA(keypath, prod_squashed);
2518
2519     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2521
2522     /* user managed product key of first product exists */
2523     lstrcpyA(product, "prod");
2524     r = MsiGetProductCodeA(component, product);
2525     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2526     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2527
2528     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2529     RegCloseKey(prodkey);
2530
2531     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2532     lstrcatA(keypath, prod_squashed);
2533
2534     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2536
2537     /* user unmanaged product key exists */
2538     lstrcpyA(product, "prod");
2539     r = MsiGetProductCodeA(component, product);
2540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2541     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2542
2543     RegDeleteKeyA(prodkey, "");
2544     RegCloseKey(prodkey);
2545
2546     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2547     lstrcatA(keypath, prod_squashed);
2548
2549     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2551
2552     /* local classes product key exists */
2553     lstrcpyA(product, "prod");
2554     r = MsiGetProductCodeA(component, product);
2555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2556     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2557
2558     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2559     RegCloseKey(prodkey);
2560
2561     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2562     lstrcatA(keypath, "Installer\\Managed\\");
2563     lstrcatA(keypath, usersid);
2564     lstrcatA(keypath, "\\Installer\\Products\\");
2565     lstrcatA(keypath, prod2_squashed);
2566
2567     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2569
2570     /* user managed product key of second product exists */
2571     lstrcpyA(product, "prod");
2572     r = MsiGetProductCodeA(component, product);
2573     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2574     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2575
2576     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2577     RegCloseKey(prodkey);
2578     RegDeleteValueA(compkey, prod_squashed);
2579     RegDeleteValueA(compkey, prod2_squashed);
2580     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2581     RegCloseKey(compkey);
2582     LocalFree(usersid);
2583 }
2584
2585 static void test_MsiEnumClients(void)
2586 {
2587     HKEY compkey;
2588     CHAR prodcode[MAX_PATH];
2589     CHAR prod_squashed[MAX_PATH];
2590     CHAR prodcode2[MAX_PATH];
2591     CHAR prod2_squashed[MAX_PATH];
2592     CHAR component[MAX_PATH];
2593     CHAR comp_base85[MAX_PATH];
2594     CHAR comp_squashed[MAX_PATH];
2595     CHAR product[MAX_PATH];
2596     CHAR keypath[MAX_PATH];
2597     LPSTR usersid;
2598     LONG res;
2599     UINT r;
2600     REGSAM access = KEY_ALL_ACCESS;
2601
2602     create_test_guid(prodcode, prod_squashed);
2603     create_test_guid(prodcode2, prod2_squashed);
2604     compose_base85_guid(component, comp_base85, comp_squashed);
2605     get_user_sid(&usersid);
2606
2607     if (is_wow64)
2608         access |= KEY_WOW64_64KEY;
2609
2610     /* NULL szComponent */
2611     product[0] = '\0';
2612     r = MsiEnumClientsA(NULL, 0, product);
2613     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2614     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2615
2616     /* empty szComponent */
2617     product[0] = '\0';
2618     r = MsiEnumClientsA("", 0, product);
2619     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2620     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2621
2622     /* NULL lpProductBuf */
2623     r = MsiEnumClientsA(component, 0, NULL);
2624     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2625
2626     /* all params correct, component missing */
2627     product[0] = '\0';
2628     r = MsiEnumClientsA(component, 0, product);
2629     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2630     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2631
2632     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2633     lstrcatA(keypath, "Installer\\UserData\\");
2634     lstrcatA(keypath, usersid);
2635     lstrcatA(keypath, "\\Components\\");
2636     lstrcatA(keypath, comp_squashed);
2637
2638     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2639     if (res == ERROR_ACCESS_DENIED)
2640     {
2641         skip("Not enough rights to perform tests\n");
2642         LocalFree(usersid);
2643         return;
2644     }
2645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2646
2647     /* user unmanaged component key exists */
2648     product[0] = '\0';
2649     r = MsiEnumClientsA(component, 0, product);
2650     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2651     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2652
2653     /* index > 0, no products exist */
2654     product[0] = '\0';
2655     r = MsiEnumClientsA(component, 1, product);
2656     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2657     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2658
2659     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2661
2662     /* product value exists */
2663     r = MsiEnumClientsA(component, 0, product);
2664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2665     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2666
2667     /* try index 0 again */
2668     product[0] = '\0';
2669     r = MsiEnumClientsA(component, 0, product);
2670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2671     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2672
2673     /* try index 1, second product value does not exist */
2674     product[0] = '\0';
2675     r = MsiEnumClientsA(component, 1, product);
2676     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2677     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2678
2679     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2681
2682     /* try index 1, second product value does exist */
2683     product[0] = '\0';
2684     r = MsiEnumClientsA(component, 1, product);
2685     todo_wine
2686     {
2687         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2688         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2689     }
2690
2691     /* start the enumeration over */
2692     product[0] = '\0';
2693     r = MsiEnumClientsA(component, 0, product);
2694     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2695     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2696        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2697
2698     /* correctly query second product */
2699     product[0] = '\0';
2700     r = MsiEnumClientsA(component, 1, product);
2701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2702     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2703        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2704
2705     RegDeleteValueA(compkey, prod_squashed);
2706     RegDeleteValueA(compkey, prod2_squashed);
2707     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2708     RegCloseKey(compkey);
2709
2710     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2711     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2712     lstrcatA(keypath, comp_squashed);
2713
2714     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2716
2717     /* user local component key exists */
2718     product[0] = '\0';
2719     r = MsiEnumClientsA(component, 0, product);
2720     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2721     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2722
2723     /* index > 0, no products exist */
2724     product[0] = '\0';
2725     r = MsiEnumClientsA(component, 1, product);
2726     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2727     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2728
2729     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2731
2732     /* product value exists */
2733     product[0] = '\0';
2734     r = MsiEnumClientsA(component, 0, product);
2735     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2736     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2737
2738     /* try index 0 again */
2739     product[0] = '\0';
2740     r = MsiEnumClientsA(component, 0, product);
2741     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2742
2743     /* try index 1, second product value does not exist */
2744     product[0] = '\0';
2745     r = MsiEnumClientsA(component, 1, product);
2746     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2747     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2748
2749     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2751
2752     /* try index 1, second product value does exist */
2753     product[0] = '\0';
2754     r = MsiEnumClientsA(component, 1, product);
2755     todo_wine
2756     {
2757         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2758         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2759     }
2760
2761     /* start the enumeration over */
2762     product[0] = '\0';
2763     r = MsiEnumClientsA(component, 0, product);
2764     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2765     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2766        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2767
2768     /* correctly query second product */
2769     product[0] = '\0';
2770     r = MsiEnumClientsA(component, 1, product);
2771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2772     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2773        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2774
2775     RegDeleteValueA(compkey, prod_squashed);
2776     RegDeleteValueA(compkey, prod2_squashed);
2777     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2778     RegCloseKey(compkey);
2779     LocalFree(usersid);
2780 }
2781
2782 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2783                              LPSTR *langcheck, LPDWORD langchecksz)
2784 {
2785     LPSTR version;
2786     VS_FIXEDFILEINFO *ffi;
2787     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2788     USHORT *lang;
2789
2790     version = HeapAlloc(GetProcessHeap(), 0, size);
2791     GetFileVersionInfoA(path, 0, size, version);
2792
2793     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2794     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2795     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2796             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2797             LOWORD(ffi->dwFileVersionLS));
2798     *verchecksz = lstrlenA(*vercheck);
2799
2800     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2801     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2802     sprintf(*langcheck, "%d", *lang);
2803     *langchecksz = lstrlenA(*langcheck);
2804
2805     HeapFree(GetProcessHeap(), 0, version);
2806 }
2807
2808 static void test_MsiGetFileVersion(void)
2809 {
2810     UINT r;
2811     DWORD versz, langsz;
2812     char version[MAX_PATH];
2813     char lang[MAX_PATH];
2814     char path[MAX_PATH];
2815     LPSTR vercheck, langcheck;
2816     DWORD verchecksz, langchecksz;
2817
2818     /* NULL szFilePath */
2819     versz = MAX_PATH;
2820     langsz = MAX_PATH;
2821     lstrcpyA(version, "version");
2822     lstrcpyA(lang, "lang");
2823     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2824     ok(r == ERROR_INVALID_PARAMETER,
2825        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2826     ok(!lstrcmpA(version, "version"),
2827        "Expected version to be unchanged, got %s\n", version);
2828     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2829     ok(!lstrcmpA(lang, "lang"),
2830        "Expected lang to be unchanged, got %s\n", lang);
2831     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2832
2833     /* empty szFilePath */
2834     versz = MAX_PATH;
2835     langsz = MAX_PATH;
2836     lstrcpyA(version, "version");
2837     lstrcpyA(lang, "lang");
2838     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2839     ok(r == ERROR_FILE_NOT_FOUND,
2840        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2841     ok(!lstrcmpA(version, "version"),
2842        "Expected version to be unchanged, got %s\n", version);
2843     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2844     ok(!lstrcmpA(lang, "lang"),
2845        "Expected lang to be unchanged, got %s\n", lang);
2846     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2847
2848     /* nonexistent szFilePath */
2849     versz = MAX_PATH;
2850     langsz = MAX_PATH;
2851     lstrcpyA(version, "version");
2852     lstrcpyA(lang, "lang");
2853     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2854     ok(r == ERROR_FILE_NOT_FOUND,
2855        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2856     ok(!lstrcmpA(version, "version"),
2857        "Expected version to be unchanged, got %s\n", version);
2858     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2859     ok(!lstrcmpA(lang, "lang"),
2860        "Expected lang to be unchanged, got %s\n", lang);
2861     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2862
2863     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2864     versz = MAX_PATH;
2865     langsz = MAX_PATH;
2866     lstrcpyA(version, "version");
2867     lstrcpyA(lang, "lang");
2868     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2869     ok(r == ERROR_INVALID_PARAMETER,
2870        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2871     ok(!lstrcmpA(version, "version"),
2872        "Expected version to be unchanged, got %s\n", version);
2873     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2874     ok(!lstrcmpA(lang, "lang"),
2875        "Expected lang to be unchanged, got %s\n", lang);
2876     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2877
2878     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2879     versz = MAX_PATH;
2880     langsz = MAX_PATH;
2881     lstrcpyA(version, "version");
2882     lstrcpyA(lang, "lang");
2883     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2884     ok(r == ERROR_INVALID_PARAMETER,
2885        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2886     ok(!lstrcmpA(version, "version"),
2887        "Expected version to be unchanged, got %s\n", version);
2888     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2889     ok(!lstrcmpA(lang, "lang"),
2890        "Expected lang to be unchanged, got %s\n", lang);
2891     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2892
2893     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2894     versz = 0;
2895     langsz = MAX_PATH;
2896     lstrcpyA(version, "version");
2897     lstrcpyA(lang, "lang");
2898     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2899     ok(r == ERROR_FILE_NOT_FOUND,
2900        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2901     ok(!lstrcmpA(version, "version"),
2902        "Expected version to be unchanged, got %s\n", version);
2903     ok(versz == 0, "Expected 0, got %d\n", versz);
2904     ok(!lstrcmpA(lang, "lang"),
2905        "Expected lang to be unchanged, got %s\n", lang);
2906     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2907
2908     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2909     versz = MAX_PATH;
2910     langsz = 0;
2911     lstrcpyA(version, "version");
2912     lstrcpyA(lang, "lang");
2913     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2914     ok(r == ERROR_FILE_NOT_FOUND,
2915        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2916     ok(!lstrcmpA(version, "version"),
2917        "Expected version to be unchanged, got %s\n", version);
2918     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2919     ok(!lstrcmpA(lang, "lang"),
2920        "Expected lang to be unchanged, got %s\n", lang);
2921     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2922
2923     /* nonexistent szFilePath, rest NULL */
2924     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2925     ok(r == ERROR_FILE_NOT_FOUND,
2926        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2927
2928     create_file("ver.txt", "ver.txt", 20);
2929
2930     /* file exists, no version information */
2931     versz = MAX_PATH;
2932     langsz = MAX_PATH;
2933     lstrcpyA(version, "version");
2934     lstrcpyA(lang, "lang");
2935     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2936     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2937     ok(!lstrcmpA(version, "version"),
2938        "Expected version to be unchanged, got %s\n", version);
2939     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2940     ok(!lstrcmpA(lang, "lang"),
2941        "Expected lang to be unchanged, got %s\n", lang);
2942     ok(r == ERROR_FILE_INVALID,
2943        "Expected ERROR_FILE_INVALID, got %d\n", r);
2944
2945     DeleteFileA("ver.txt");
2946
2947     /* relative path, has version information */
2948     versz = MAX_PATH;
2949     langsz = MAX_PATH;
2950     lstrcpyA(version, "version");
2951     lstrcpyA(lang, "lang");
2952     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2953     todo_wine
2954     {
2955         ok(r == ERROR_FILE_NOT_FOUND,
2956            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2957         ok(!lstrcmpA(version, "version"),
2958            "Expected version to be unchanged, got %s\n", version);
2959         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2960         ok(!lstrcmpA(lang, "lang"),
2961            "Expected lang to be unchanged, got %s\n", lang);
2962         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2963     }
2964
2965     GetSystemDirectoryA(path, MAX_PATH);
2966     lstrcatA(path, "\\kernel32.dll");
2967
2968     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2969
2970     /* absolute path, has version information */
2971     versz = MAX_PATH;
2972     langsz = MAX_PATH;
2973     lstrcpyA(version, "version");
2974     lstrcpyA(lang, "lang");
2975     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2977     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2978     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2979     ok(!lstrcmpA(version, vercheck),
2980         "Expected %s, got %s\n", vercheck, version);
2981
2982     /* only check version */
2983     versz = MAX_PATH;
2984     lstrcpyA(version, "version");
2985     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2987     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2988     ok(!lstrcmpA(version, vercheck),
2989        "Expected %s, got %s\n", vercheck, version);
2990
2991     /* only check language */
2992     langsz = MAX_PATH;
2993     lstrcpyA(lang, "lang");
2994     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2995     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2996     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2997
2998     /* check neither version nor language */
2999     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
3000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3001
3002     /* get pcchVersionBuf */
3003     versz = MAX_PATH;
3004     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
3005     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3006     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3007
3008     /* get pcchLangBuf */
3009     langsz = MAX_PATH;
3010     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
3011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3012     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3013
3014     /* pcchVersionBuf not big enough */
3015     versz = 5;
3016     lstrcpyA(version, "version");
3017     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
3018     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3019     ok(!strncmp(version, vercheck, 4),
3020        "Expected first 4 characters of %s, got %s\n", vercheck, version);
3021     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3022
3023     /* pcchLangBuf not big enough */
3024     langsz = 3;
3025     lstrcpyA(lang, "lang");
3026     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
3027     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3028     ok(!strncmp(lang, langcheck, 2),
3029        "Expected first character of %s, got %s\n", langcheck, lang);
3030     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3031
3032     HeapFree(GetProcessHeap(), 0, vercheck);
3033     HeapFree(GetProcessHeap(), 0, langcheck);
3034 }
3035
3036 static void test_MsiGetProductInfo(void)
3037 {
3038     UINT r;
3039     LONG res;
3040     HKEY propkey, source;
3041     HKEY prodkey, localkey;
3042     CHAR prodcode[MAX_PATH];
3043     CHAR prod_squashed[MAX_PATH];
3044     CHAR packcode[MAX_PATH];
3045     CHAR pack_squashed[MAX_PATH];
3046     CHAR buf[MAX_PATH];
3047     CHAR keypath[MAX_PATH];
3048     LPSTR usersid;
3049     DWORD sz, val = 42;
3050     REGSAM access = KEY_ALL_ACCESS;
3051
3052     create_test_guid(prodcode, prod_squashed);
3053     create_test_guid(packcode, pack_squashed);
3054     get_user_sid(&usersid);
3055
3056     if (is_wow64)
3057         access |= KEY_WOW64_64KEY;
3058
3059     /* NULL szProduct */
3060     sz = MAX_PATH;
3061     lstrcpyA(buf, "apple");
3062     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
3063     ok(r == ERROR_INVALID_PARAMETER,
3064        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3065     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3066     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3067
3068     /* empty szProduct */
3069     sz = MAX_PATH;
3070     lstrcpyA(buf, "apple");
3071     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
3072     ok(r == ERROR_INVALID_PARAMETER,
3073        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3074     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3075     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3076
3077     /* garbage szProduct */
3078     sz = MAX_PATH;
3079     lstrcpyA(buf, "apple");
3080     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
3081     ok(r == ERROR_INVALID_PARAMETER,
3082        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3083     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3084     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3085
3086     /* guid without brackets */
3087     sz = MAX_PATH;
3088     lstrcpyA(buf, "apple");
3089     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
3090                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3091     ok(r == ERROR_INVALID_PARAMETER,
3092        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3093     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3094     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3095
3096     /* guid with brackets */
3097     sz = MAX_PATH;
3098     lstrcpyA(buf, "apple");
3099     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
3100                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3101     ok(r == ERROR_UNKNOWN_PRODUCT,
3102        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3103     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3104     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3105
3106     /* same length as guid, but random */
3107     sz = MAX_PATH;
3108     lstrcpyA(buf, "apple");
3109     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
3110                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3111     ok(r == ERROR_INVALID_PARAMETER,
3112        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3113     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3114     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3115
3116     /* not installed, NULL szAttribute */
3117     sz = MAX_PATH;
3118     lstrcpyA(buf, "apple");
3119     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
3120     ok(r == ERROR_INVALID_PARAMETER,
3121        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3122     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3123     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3124
3125     /* not installed, NULL lpValueBuf */
3126     sz = MAX_PATH;
3127     lstrcpyA(buf, "apple");
3128     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3129     ok(r == ERROR_UNKNOWN_PRODUCT,
3130        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3131     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3132     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3133
3134     /* not installed, NULL pcchValueBuf */
3135     sz = MAX_PATH;
3136     lstrcpyA(buf, "apple");
3137     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
3138     ok(r == ERROR_INVALID_PARAMETER,
3139        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3140     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3141     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3142
3143     /* created guid cannot possibly be an installed product code */
3144     sz = MAX_PATH;
3145     lstrcpyA(buf, "apple");
3146     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3147     ok(r == ERROR_UNKNOWN_PRODUCT,
3148        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3149     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3150     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3151
3152     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3153     lstrcatA(keypath, usersid);
3154     lstrcatA(keypath, "\\Installer\\Products\\");
3155     lstrcatA(keypath, prod_squashed);
3156
3157     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3158     if (res == ERROR_ACCESS_DENIED)
3159     {
3160         skip("Not enough rights to perform tests\n");
3161         LocalFree(usersid);
3162         return;
3163     }
3164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3165
3166     /* managed product code exists */
3167     sz = MAX_PATH;
3168     lstrcpyA(buf, "apple");
3169     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3170     ok(r == ERROR_UNKNOWN_PROPERTY,
3171        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3172     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3173     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3174
3175     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3176     RegCloseKey(prodkey);
3177
3178     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3179     lstrcatA(keypath, usersid);
3180     lstrcatA(keypath, "\\Products\\");
3181     lstrcatA(keypath, prod_squashed);
3182
3183     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3185
3186     /* local user product code exists */
3187     sz = MAX_PATH;
3188     lstrcpyA(buf, "apple");
3189     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3190     ok(r == ERROR_UNKNOWN_PRODUCT,
3191        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3192     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3193     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3194
3195     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3196     lstrcatA(keypath, usersid);
3197     lstrcatA(keypath, "\\Installer\\Products\\");
3198     lstrcatA(keypath, prod_squashed);
3199
3200     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3202
3203     /* both local and managed product code exist */
3204     sz = MAX_PATH;
3205     lstrcpyA(buf, "apple");
3206     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3207     ok(r == ERROR_UNKNOWN_PROPERTY,
3208        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3209     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3210     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3211
3212     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3213     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3214
3215     /* InstallProperties key exists */
3216     sz = MAX_PATH;
3217     lstrcpyA(buf, "apple");
3218     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3220     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3221     ok(sz == 0, "Expected 0, got %d\n", sz);
3222
3223     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3225
3226     /* HelpLink value exists */
3227     sz = MAX_PATH;
3228     lstrcpyA(buf, "apple");
3229     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3230     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3231     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3232     ok(sz == 4, "Expected 4, got %d\n", sz);
3233
3234     /* pcchBuf is NULL */
3235     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3237
3238     /* lpValueBuf is NULL */
3239     sz = MAX_PATH;
3240     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3242     ok(sz == 4, "Expected 4, got %d\n", sz);
3243
3244     /* lpValueBuf is NULL, pcchValueBuf is too small */
3245     sz = 2;
3246     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3248     ok(sz == 4, "Expected 4, got %d\n", sz);
3249
3250     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3251     sz = 2;
3252     lstrcpyA(buf, "apple");
3253     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3254     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3255     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3256     ok(sz == 4, "Expected 4, got %d\n", sz);
3257
3258     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3259     sz = 4;
3260     lstrcpyA(buf, "apple");
3261     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3262     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3263     ok(!lstrcmpA(buf, "apple"),
3264        "Expected buf to remain unchanged, got \"%s\"\n", buf);
3265     ok(sz == 4, "Expected 4, got %d\n", sz);
3266
3267     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3269
3270     /* random property not supported by MSI, value exists */
3271     sz = MAX_PATH;
3272     lstrcpyA(buf, "apple");
3273     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3274     ok(r == ERROR_UNKNOWN_PROPERTY,
3275        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3276     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3277     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3278
3279     RegDeleteValueA(propkey, "IMadeThis");
3280     RegDeleteValueA(propkey, "HelpLink");
3281     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3282     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3283     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3284     RegCloseKey(propkey);
3285     RegCloseKey(localkey);
3286     RegCloseKey(prodkey);
3287
3288     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3289     lstrcatA(keypath, prod_squashed);
3290
3291     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3292     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3293
3294     /* user product key exists */
3295     sz = MAX_PATH;
3296     lstrcpyA(buf, "apple");
3297     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3298     ok(r == ERROR_UNKNOWN_PROPERTY,
3299        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3300     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3301     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3302
3303     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3304     lstrcatA(keypath, usersid);
3305     lstrcatA(keypath, "\\Products\\");
3306     lstrcatA(keypath, prod_squashed);
3307
3308     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3310
3311     /* local user product key exists */
3312     sz = MAX_PATH;
3313     lstrcpyA(buf, "apple");
3314     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3315     ok(r == ERROR_UNKNOWN_PROPERTY,
3316        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3317     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3318     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3319
3320     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3322
3323     /* InstallProperties key exists */
3324     sz = MAX_PATH;
3325     lstrcpyA(buf, "apple");
3326     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3327     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3328     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3329     ok(sz == 0, "Expected 0, got %d\n", sz);
3330
3331     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3333
3334     /* HelpLink value exists */
3335     sz = MAX_PATH;
3336     lstrcpyA(buf, "apple");
3337     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3338     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3339     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3340     ok(sz == 4, "Expected 4, got %d\n", sz);
3341
3342     RegDeleteValueA(propkey, "HelpLink");
3343     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3344     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3345     RegDeleteKeyA(prodkey, "");
3346     RegCloseKey(propkey);
3347     RegCloseKey(localkey);
3348     RegCloseKey(prodkey);
3349
3350     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3351     lstrcatA(keypath, prod_squashed);
3352
3353     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3355
3356     /* classes product key exists */
3357     sz = MAX_PATH;
3358     lstrcpyA(buf, "apple");
3359     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3360     ok(r == ERROR_UNKNOWN_PROPERTY,
3361        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3362     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3363     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3364
3365     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3366     lstrcatA(keypath, usersid);
3367     lstrcatA(keypath, "\\Products\\");
3368     lstrcatA(keypath, prod_squashed);
3369
3370     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3372
3373     /* local user product key exists */
3374     sz = MAX_PATH;
3375     lstrcpyA(buf, "apple");
3376     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3377     ok(r == ERROR_UNKNOWN_PROPERTY,
3378        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3379     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3380     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3381
3382     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3384
3385     /* InstallProperties key exists */
3386     sz = MAX_PATH;
3387     lstrcpyA(buf, "apple");
3388     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3389     ok(r == ERROR_UNKNOWN_PROPERTY,
3390        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3391     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3392     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3393
3394     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3395     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3396     RegCloseKey(propkey);
3397     RegCloseKey(localkey);
3398
3399     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3400     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3401     lstrcatA(keypath, prod_squashed);
3402
3403     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3405
3406     /* Local System product key exists */
3407     sz = MAX_PATH;
3408     lstrcpyA(buf, "apple");
3409     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3410     ok(r == ERROR_UNKNOWN_PROPERTY,
3411         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3412     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3413     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3414
3415     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3417
3418     /* InstallProperties key exists */
3419     sz = MAX_PATH;
3420     lstrcpyA(buf, "apple");
3421     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3423     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3424     ok(sz == 0, "Expected 0, got %d\n", sz);
3425
3426     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3428
3429     /* HelpLink value exists */
3430     sz = MAX_PATH;
3431     lstrcpyA(buf, "apple");
3432     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3434     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3435     ok(sz == 4, "Expected 4, got %d\n", sz);
3436
3437     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3438                          (const BYTE *)&val, sizeof(DWORD));
3439     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3440
3441     /* HelpLink type is REG_DWORD */
3442     sz = MAX_PATH;
3443     lstrcpyA(buf, "apple");
3444     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3446     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3447     ok(sz == 2, "Expected 2, got %d\n", sz);
3448
3449     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3451
3452     /* DisplayName value exists */
3453     sz = MAX_PATH;
3454     lstrcpyA(buf, "apple");
3455     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3457     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3458     ok(sz == 4, "Expected 4, got %d\n", sz);
3459
3460     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3461                          (const BYTE *)&val, sizeof(DWORD));
3462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3463
3464     /* DisplayName type is REG_DWORD */
3465     sz = MAX_PATH;
3466     lstrcpyA(buf, "apple");
3467     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3468     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3469     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3470     ok(sz == 2, "Expected 2, got %d\n", sz);
3471
3472     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3474
3475     /* DisplayVersion value exists */
3476     sz = MAX_PATH;
3477     lstrcpyA(buf, "apple");
3478     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3480     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3481     ok(sz == 5, "Expected 5, got %d\n", sz);
3482
3483     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3484                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3485     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3486
3487     /* DisplayVersion type is REG_DWORD */
3488     sz = MAX_PATH;
3489     lstrcpyA(buf, "apple");
3490     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3492     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3493     ok(sz == 2, "Expected 2, got %d\n", sz);
3494
3495     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3496     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3497
3498     /* HelpTelephone value exists */
3499     sz = MAX_PATH;
3500     lstrcpyA(buf, "apple");
3501     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3502     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3503     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3504     ok(sz == 4, "Expected 4, got %d\n", sz);
3505
3506     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3507                          (const BYTE *)&val, sizeof(DWORD));
3508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3509
3510     /* HelpTelephone type is REG_DWORD */
3511     sz = MAX_PATH;
3512     lstrcpyA(buf, "apple");
3513     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3514     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3515     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3516     ok(sz == 2, "Expected 2, got %d\n", sz);
3517
3518     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3519     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3520
3521     /* InstallLocation value exists */
3522     sz = MAX_PATH;
3523     lstrcpyA(buf, "apple");
3524     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3525     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3526     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3527     ok(sz == 3, "Expected 3, got %d\n", sz);
3528
3529     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3530                          (const BYTE *)&val, sizeof(DWORD));
3531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3532
3533     /* InstallLocation type is REG_DWORD */
3534     sz = MAX_PATH;
3535     lstrcpyA(buf, "apple");
3536     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3537     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3538     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3539     ok(sz == 2, "Expected 2, got %d\n", sz);
3540
3541     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3543
3544     /* InstallSource value exists */
3545     sz = MAX_PATH;
3546     lstrcpyA(buf, "apple");
3547     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3548     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3549     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3550     ok(sz == 6, "Expected 6, got %d\n", sz);
3551
3552     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3553                          (const BYTE *)&val, sizeof(DWORD));
3554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3555
3556     /* InstallSource type is REG_DWORD */
3557     sz = MAX_PATH;
3558     lstrcpyA(buf, "apple");
3559     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3561     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3562     ok(sz == 2, "Expected 2, got %d\n", sz);
3563
3564     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3566
3567     /* InstallDate value exists */
3568     sz = MAX_PATH;
3569     lstrcpyA(buf, "apple");
3570     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3572     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3573     ok(sz == 4, "Expected 4, got %d\n", sz);
3574
3575     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3576                          (const BYTE *)&val, sizeof(DWORD));
3577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3578
3579     /* InstallDate type is REG_DWORD */
3580     sz = MAX_PATH;
3581     lstrcpyA(buf, "apple");
3582     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3583     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3584     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3585     ok(sz == 2, "Expected 2, got %d\n", sz);
3586
3587     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3589
3590     /* Publisher value exists */
3591     sz = MAX_PATH;
3592     lstrcpyA(buf, "apple");
3593     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3595     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3596     ok(sz == 3, "Expected 3, got %d\n", sz);
3597
3598     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3599                          (const BYTE *)&val, sizeof(DWORD));
3600     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3601
3602     /* Publisher type is REG_DWORD */
3603     sz = MAX_PATH;
3604     lstrcpyA(buf, "apple");
3605     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3606     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3607     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3608     ok(sz == 2, "Expected 2, got %d\n", sz);
3609
3610     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3612
3613     /* LocalPackage value exists */
3614     sz = MAX_PATH;
3615     lstrcpyA(buf, "apple");
3616     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3617     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3618     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3619     ok(sz == 4, "Expected 4, got %d\n", sz);
3620
3621     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3622                          (const BYTE *)&val, sizeof(DWORD));
3623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3624
3625     /* LocalPackage type is REG_DWORD */
3626     sz = MAX_PATH;
3627     lstrcpyA(buf, "apple");
3628     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3629     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3630     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3631     ok(sz == 2, "Expected 2, got %d\n", sz);
3632
3633     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3635
3636     /* UrlInfoAbout value exists */
3637     sz = MAX_PATH;
3638     lstrcpyA(buf, "apple");
3639     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3640     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3641     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3642     ok(sz == 5, "Expected 5, got %d\n", sz);
3643
3644     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3645                          (const BYTE *)&val, sizeof(DWORD));
3646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3647
3648     /* UrlInfoAbout type is REG_DWORD */
3649     sz = MAX_PATH;
3650     lstrcpyA(buf, "apple");
3651     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3652     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3653     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3654     ok(sz == 2, "Expected 2, got %d\n", sz);
3655
3656     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3658
3659     /* UrlUpdateInfo value exists */
3660     sz = MAX_PATH;
3661     lstrcpyA(buf, "apple");
3662     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3663     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3664     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3665     ok(sz == 4, "Expected 4, got %d\n", sz);
3666
3667     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3668                          (const BYTE *)&val, sizeof(DWORD));
3669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3670
3671     /* UrlUpdateInfo type is REG_DWORD */
3672     sz = MAX_PATH;
3673     lstrcpyA(buf, "apple");
3674     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3675     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3676     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3677     ok(sz == 2, "Expected 2, got %d\n", sz);
3678
3679     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3681
3682     /* VersionMinor value exists */
3683     sz = MAX_PATH;
3684     lstrcpyA(buf, "apple");
3685     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3686     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3687     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3688     ok(sz == 1, "Expected 1, got %d\n", sz);
3689
3690     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3691                          (const BYTE *)&val, sizeof(DWORD));
3692     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3693
3694     /* VersionMinor type is REG_DWORD */
3695     sz = MAX_PATH;
3696     lstrcpyA(buf, "apple");
3697     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3699     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3700     ok(sz == 2, "Expected 2, got %d\n", sz);
3701
3702     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3704
3705     /* VersionMajor value exists */
3706     sz = MAX_PATH;
3707     lstrcpyA(buf, "apple");
3708     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3709     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3710     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3711     ok(sz == 1, "Expected 1, got %d\n", sz);
3712
3713     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3714                          (const BYTE *)&val, sizeof(DWORD));
3715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3716
3717     /* VersionMajor type is REG_DWORD */
3718     sz = MAX_PATH;
3719     lstrcpyA(buf, "apple");
3720     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3721     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3722     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3723     ok(sz == 2, "Expected 2, got %d\n", sz);
3724
3725     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3727
3728     /* ProductID value exists */
3729     sz = MAX_PATH;
3730     lstrcpyA(buf, "apple");
3731     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3733     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3734     ok(sz == 2, "Expected 2, got %d\n", sz);
3735
3736     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3737                          (const BYTE *)&val, sizeof(DWORD));
3738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3739
3740     /* ProductID type is REG_DWORD */
3741     sz = MAX_PATH;
3742     lstrcpyA(buf, "apple");
3743     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3744     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3745     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3746     ok(sz == 2, "Expected 2, got %d\n", sz);
3747
3748     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3750
3751     /* RegCompany value exists */
3752     sz = MAX_PATH;
3753     lstrcpyA(buf, "apple");
3754     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3756     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3757     ok(sz == 4, "Expected 4, got %d\n", sz);
3758
3759     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3760                          (const BYTE *)&val, sizeof(DWORD));
3761     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3762
3763     /* RegCompany type is REG_DWORD */
3764     sz = MAX_PATH;
3765     lstrcpyA(buf, "apple");
3766     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3767     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3768     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3769     ok(sz == 2, "Expected 2, got %d\n", sz);
3770
3771     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3773
3774     /* RegOwner value exists */
3775     sz = MAX_PATH;
3776     lstrcpyA(buf, "apple");
3777     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3778     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3779     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3780     ok(sz == 3, "Expected 3, got %d\n", sz);
3781
3782     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3783                          (const BYTE *)&val, sizeof(DWORD));
3784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3785
3786     /* RegOwner type is REG_DWORD */
3787     sz = MAX_PATH;
3788     lstrcpyA(buf, "apple");
3789     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3790     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3791     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3792     ok(sz == 2, "Expected 2, got %d\n", sz);
3793
3794     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3796
3797     /* InstanceType value exists */
3798     sz = MAX_PATH;
3799     lstrcpyA(buf, "apple");
3800     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3801     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3802     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3803     ok(sz == 0, "Expected 0, got %d\n", sz);
3804
3805     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3806                          (const BYTE *)&val, sizeof(DWORD));
3807     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3808
3809     /* InstanceType type is REG_DWORD */
3810     sz = MAX_PATH;
3811     lstrcpyA(buf, "apple");
3812     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3813     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3814     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3815     ok(sz == 0, "Expected 0, got %d\n", sz);
3816
3817     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3818     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3819
3820     /* InstanceType value exists */
3821     sz = MAX_PATH;
3822     lstrcpyA(buf, "apple");
3823     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3825     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3826     ok(sz == 4, "Expected 4, got %d\n", sz);
3827
3828     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3829                          (const BYTE *)&val, sizeof(DWORD));
3830     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3831
3832     /* InstanceType type is REG_DWORD */
3833     sz = MAX_PATH;
3834     lstrcpyA(buf, "apple");
3835     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3836     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3837     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3838     ok(sz == 2, "Expected 2, got %d\n", sz);
3839
3840     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3842
3843     /* Transforms value exists */
3844     sz = MAX_PATH;
3845     lstrcpyA(buf, "apple");
3846     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3847     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3848     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3849     ok(sz == 0, "Expected 0, got %d\n", sz);
3850
3851     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3852                          (const BYTE *)&val, sizeof(DWORD));
3853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3854
3855     /* Transforms type is REG_DWORD */
3856     sz = MAX_PATH;
3857     lstrcpyA(buf, "apple");
3858     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3859     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3860     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3861     ok(sz == 0, "Expected 0, got %d\n", sz);
3862
3863     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3865
3866     /* Transforms value exists */
3867     sz = MAX_PATH;
3868     lstrcpyA(buf, "apple");
3869     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3871     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3872     ok(sz == 6, "Expected 6, got %d\n", sz);
3873
3874     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3875                          (const BYTE *)&val, sizeof(DWORD));
3876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3877
3878     /* Transforms type is REG_DWORD */
3879     sz = MAX_PATH;
3880     lstrcpyA(buf, "apple");
3881     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3882     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3883     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3884     ok(sz == 2, "Expected 2, got %d\n", sz);
3885
3886     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3888
3889     /* Language value exists */
3890     sz = MAX_PATH;
3891     lstrcpyA(buf, "apple");
3892     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3893     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3894     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3895     ok(sz == 0, "Expected 0, got %d\n", sz);
3896
3897     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3898                          (const BYTE *)&val, sizeof(DWORD));
3899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3900
3901     /* Language type is REG_DWORD */
3902     sz = MAX_PATH;
3903     lstrcpyA(buf, "apple");
3904     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3905     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3906     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3907     ok(sz == 0, "Expected 0, got %d\n", sz);
3908
3909     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3911
3912     /* Language value exists */
3913     sz = MAX_PATH;
3914     lstrcpyA(buf, "apple");
3915     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3917     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3918     ok(sz == 4, "Expected 4, got %d\n", sz);
3919
3920     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3921                          (const BYTE *)&val, sizeof(DWORD));
3922     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3923
3924     /* Language type is REG_DWORD */
3925     sz = MAX_PATH;
3926     lstrcpyA(buf, "apple");
3927     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3929     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3930     ok(sz == 2, "Expected 2, got %d\n", sz);
3931
3932     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3934
3935     /* ProductName value exists */
3936     sz = MAX_PATH;
3937     lstrcpyA(buf, "apple");
3938     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3940     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3941     ok(sz == 0, "Expected 0, got %d\n", sz);
3942
3943     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3944                          (const BYTE *)&val, sizeof(DWORD));
3945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3946
3947     /* ProductName type is REG_DWORD */
3948     sz = MAX_PATH;
3949     lstrcpyA(buf, "apple");
3950     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3952     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3953     ok(sz == 0, "Expected 0, got %d\n", sz);
3954
3955     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3957
3958     /* ProductName value exists */
3959     sz = MAX_PATH;
3960     lstrcpyA(buf, "apple");
3961     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3962     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3963     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3964     ok(sz == 4, "Expected 4, got %d\n", sz);
3965
3966     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3967                          (const BYTE *)&val, sizeof(DWORD));
3968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3969
3970     /* ProductName type is REG_DWORD */
3971     sz = MAX_PATH;
3972     lstrcpyA(buf, "apple");
3973     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3975     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3976     ok(sz == 2, "Expected 2, got %d\n", sz);
3977
3978     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3980
3981     /* Assignment value exists */
3982     sz = MAX_PATH;
3983     lstrcpyA(buf, "apple");
3984     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3986     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3987     ok(sz == 0, "Expected 0, got %d\n", sz);
3988
3989     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3990                          (const BYTE *)&val, sizeof(DWORD));
3991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3992
3993     /* Assignment type is REG_DWORD */
3994     sz = MAX_PATH;
3995     lstrcpyA(buf, "apple");
3996     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3998     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3999     ok(sz == 0, "Expected 0, got %d\n", sz);
4000
4001     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
4002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4003
4004     /* Assignment value exists */
4005     sz = MAX_PATH;
4006     lstrcpyA(buf, "apple");
4007     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4008     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4009     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
4010     ok(sz == 2, "Expected 2, got %d\n", sz);
4011
4012     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
4013                          (const BYTE *)&val, sizeof(DWORD));
4014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4015
4016     /* Assignment type is REG_DWORD */
4017     sz = MAX_PATH;
4018     lstrcpyA(buf, "apple");
4019     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4020     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4021     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4022     ok(sz == 2, "Expected 2, got %d\n", sz);
4023
4024     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4026
4027     /* PackageCode value exists */
4028     sz = MAX_PATH;
4029     lstrcpyA(buf, "apple");
4030     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4032     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4033     ok(sz == 0, "Expected 0, got %d\n", sz);
4034
4035     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
4036                          (const BYTE *)&val, sizeof(DWORD));
4037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4038
4039     /* PackageCode type is REG_DWORD */
4040     sz = MAX_PATH;
4041     lstrcpyA(buf, "apple");
4042     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4044     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4045     ok(sz == 0, "Expected 0, got %d\n", sz);
4046
4047     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4049
4050     /* PackageCode value exists */
4051     sz = MAX_PATH;
4052     lstrcpyA(buf, "apple");
4053     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4054     ok(r == ERROR_BAD_CONFIGURATION,
4055        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4056     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
4057     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4058
4059     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
4060                          (const BYTE *)&val, sizeof(DWORD));
4061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4062
4063     /* PackageCode type is REG_DWORD */
4064     sz = MAX_PATH;
4065     lstrcpyA(buf, "apple");
4066     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4067     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4068     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4069     ok(sz == 2, "Expected 2, got %d\n", sz);
4070
4071     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
4072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4073
4074     /* PackageCode value exists */
4075     sz = MAX_PATH;
4076     lstrcpyA(buf, "apple");
4077     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4078     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4079     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
4080     ok(sz == 38, "Expected 38, got %d\n", sz);
4081
4082     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4084
4085     /* Version value exists */
4086     sz = MAX_PATH;
4087     lstrcpyA(buf, "apple");
4088     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4090     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4091     ok(sz == 0, "Expected 0, got %d\n", sz);
4092
4093     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
4094                          (const BYTE *)&val, sizeof(DWORD));
4095     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4096
4097     /* Version type is REG_DWORD */
4098     sz = MAX_PATH;
4099     lstrcpyA(buf, "apple");
4100     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4102     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4103     ok(sz == 0, "Expected 0, got %d\n", sz);
4104
4105     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4107
4108     /* Version value exists */
4109     sz = MAX_PATH;
4110     lstrcpyA(buf, "apple");
4111     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4113     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4114     ok(sz == 3, "Expected 3, got %d\n", sz);
4115
4116     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
4117                          (const BYTE *)&val, sizeof(DWORD));
4118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4119
4120     /* Version type is REG_DWORD */
4121     sz = MAX_PATH;
4122     lstrcpyA(buf, "apple");
4123     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4125     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4126     ok(sz == 2, "Expected 2, got %d\n", sz);
4127
4128     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4130
4131     /* ProductIcon value exists */
4132     sz = MAX_PATH;
4133     lstrcpyA(buf, "apple");
4134     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4135     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4136     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4137     ok(sz == 0, "Expected 0, got %d\n", sz);
4138
4139     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
4140                          (const BYTE *)&val, sizeof(DWORD));
4141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4142
4143     /* ProductIcon type is REG_DWORD */
4144     sz = MAX_PATH;
4145     lstrcpyA(buf, "apple");
4146     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4148     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4149     ok(sz == 0, "Expected 0, got %d\n", sz);
4150
4151     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4153
4154     /* ProductIcon value exists */
4155     sz = MAX_PATH;
4156     lstrcpyA(buf, "apple");
4157     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4159     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
4160     ok(sz == 3, "Expected 3, got %d\n", sz);
4161
4162     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
4163                          (const BYTE *)&val, sizeof(DWORD));
4164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4165
4166     /* ProductIcon type is REG_DWORD */
4167     sz = MAX_PATH;
4168     lstrcpyA(buf, "apple");
4169     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4170     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4171     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4172     ok(sz == 2, "Expected 2, got %d\n", sz);
4173
4174     /* SourceList key does not exist */
4175     sz = MAX_PATH;
4176     lstrcpyA(buf, "apple");
4177     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4178     ok(r == ERROR_UNKNOWN_PRODUCT,
4179        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4180     ok(!lstrcmpA(buf, "apple"),
4181        "Expected buf to be unchanged, got \"%s\"\n", buf);
4182     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
4183
4184     res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
4185     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4186
4187     /* SourceList key exists, but PackageName val does not exist */
4188     sz = MAX_PATH;
4189     lstrcpyA(buf, "apple");
4190     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4191     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4192     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4193     ok(sz == 0, "Expected 0, got %d\n", sz);
4194
4195     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
4196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4197
4198     /* PackageName val exists */
4199     sz = MAX_PATH;
4200     lstrcpyA(buf, "apple");
4201     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4202     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4203     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4204     ok(sz == 8, "Expected 8, got %d\n", sz);
4205
4206     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4207                          (const BYTE *)&val, sizeof(DWORD));
4208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4209
4210     /* PackageName type is REG_DWORD */
4211     sz = MAX_PATH;
4212     lstrcpyA(buf, "apple");
4213     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4215     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4216     ok(sz == 2, "Expected 2, got %d\n", sz);
4217
4218     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4219     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4220
4221     /* Authorized value exists */
4222     sz = MAX_PATH;
4223     lstrcpyA(buf, "apple");
4224     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4225     if (r != ERROR_UNKNOWN_PROPERTY)
4226     {
4227         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4228         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4229         ok(sz == 0, "Expected 0, got %d\n", sz);
4230     }
4231
4232     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4233                          (const BYTE *)&val, sizeof(DWORD));
4234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4235
4236     /* AuthorizedLUAApp type is REG_DWORD */
4237     sz = MAX_PATH;
4238     lstrcpyA(buf, "apple");
4239     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4240     if (r != ERROR_UNKNOWN_PROPERTY)
4241     {
4242         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4243         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4244         ok(sz == 0, "Expected 0, got %d\n", sz);
4245     }
4246
4247     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4249
4250     /* Authorized value exists */
4251     sz = MAX_PATH;
4252     lstrcpyA(buf, "apple");
4253     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4254     if (r != ERROR_UNKNOWN_PROPERTY)
4255     {
4256         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4257         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4258         ok(sz == 4, "Expected 4, got %d\n", sz);
4259     }
4260
4261     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4262                          (const BYTE *)&val, sizeof(DWORD));
4263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4264
4265     /* AuthorizedLUAApp type is REG_DWORD */
4266     sz = MAX_PATH;
4267     lstrcpyA(buf, "apple");
4268     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4269     if (r != ERROR_UNKNOWN_PROPERTY)
4270     {
4271         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4272         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4273         ok(sz == 2, "Expected 2, got %d\n", sz);
4274     }
4275
4276     RegDeleteValueA(propkey, "HelpLink");
4277     RegDeleteValueA(propkey, "DisplayName");
4278     RegDeleteValueA(propkey, "DisplayVersion");
4279     RegDeleteValueA(propkey, "HelpTelephone");
4280     RegDeleteValueA(propkey, "InstallLocation");
4281     RegDeleteValueA(propkey, "InstallSource");
4282     RegDeleteValueA(propkey, "InstallDate");
4283     RegDeleteValueA(propkey, "Publisher");
4284     RegDeleteValueA(propkey, "LocalPackage");
4285     RegDeleteValueA(propkey, "UrlInfoAbout");
4286     RegDeleteValueA(propkey, "UrlUpdateInfo");
4287     RegDeleteValueA(propkey, "VersionMinor");
4288     RegDeleteValueA(propkey, "VersionMajor");
4289     RegDeleteValueA(propkey, "ProductID");
4290     RegDeleteValueA(propkey, "RegCompany");
4291     RegDeleteValueA(propkey, "RegOwner");
4292     RegDeleteValueA(propkey, "InstanceType");
4293     RegDeleteValueA(propkey, "Transforms");
4294     RegDeleteValueA(propkey, "Language");
4295     RegDeleteValueA(propkey, "ProductName");
4296     RegDeleteValueA(propkey, "Assignment");
4297     RegDeleteValueA(propkey, "PackageCode");
4298     RegDeleteValueA(propkey, "Version");
4299     RegDeleteValueA(propkey, "ProductIcon");
4300     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4301     delete_key(propkey, "", access & KEY_WOW64_64KEY);
4302     delete_key(localkey, "", access & KEY_WOW64_64KEY);
4303     RegDeleteValueA(prodkey, "InstanceType");
4304     RegDeleteValueA(prodkey, "Transforms");
4305     RegDeleteValueA(prodkey, "Language");
4306     RegDeleteValueA(prodkey, "ProductName");
4307     RegDeleteValueA(prodkey, "Assignment");
4308     RegDeleteValueA(prodkey, "PackageCode");
4309     RegDeleteValueA(prodkey, "Version");
4310     RegDeleteValueA(prodkey, "ProductIcon");
4311     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4312     RegDeleteValueA(source, "PackageName");
4313     delete_key(source, "", access & KEY_WOW64_64KEY);
4314     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4315     RegCloseKey(propkey);
4316     RegCloseKey(localkey);
4317     RegCloseKey(source);
4318     RegCloseKey(prodkey);
4319     LocalFree(usersid);
4320 }
4321
4322 static void test_MsiGetProductInfoEx(void)
4323 {
4324     UINT r;
4325     LONG res;
4326     HKEY propkey, userkey;
4327     HKEY prodkey, localkey;
4328     CHAR prodcode[MAX_PATH];
4329     CHAR prod_squashed[MAX_PATH];
4330     CHAR packcode[MAX_PATH];
4331     CHAR pack_squashed[MAX_PATH];
4332     CHAR buf[MAX_PATH];
4333     CHAR keypath[MAX_PATH];
4334     LPSTR usersid;
4335     DWORD sz;
4336     REGSAM access = KEY_ALL_ACCESS;
4337
4338     if (!pMsiGetProductInfoExA)
4339     {
4340         win_skip("MsiGetProductInfoExA is not available\n");
4341         return;
4342     }
4343
4344     create_test_guid(prodcode, prod_squashed);
4345     create_test_guid(packcode, pack_squashed);
4346     get_user_sid(&usersid);
4347
4348     if (is_wow64)
4349         access |= KEY_WOW64_64KEY;
4350
4351     /* NULL szProductCode */
4352     sz = MAX_PATH;
4353     lstrcpyA(buf, "apple");
4354     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4355                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4356     ok(r == ERROR_INVALID_PARAMETER,
4357        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4358     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4359     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4360
4361     /* empty szProductCode */
4362     sz = MAX_PATH;
4363     lstrcpyA(buf, "apple");
4364     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4365                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4366     ok(r == ERROR_INVALID_PARAMETER,
4367        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4368     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4369     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4370
4371     /* garbage szProductCode */
4372     sz = MAX_PATH;
4373     lstrcpyA(buf, "apple");
4374     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4375                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4376     ok(r == ERROR_INVALID_PARAMETER,
4377        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4378     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4379     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4380
4381     /* guid without brackets */
4382     sz = MAX_PATH;
4383     lstrcpyA(buf, "apple");
4384     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4385                               MSIINSTALLCONTEXT_USERUNMANAGED,
4386                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4387     ok(r == ERROR_INVALID_PARAMETER,
4388        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4389     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4390     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4391
4392     /* guid with brackets */
4393     sz = MAX_PATH;
4394     lstrcpyA(buf, "apple");
4395     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4396                               MSIINSTALLCONTEXT_USERUNMANAGED,
4397                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4398     ok(r == ERROR_UNKNOWN_PRODUCT,
4399        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4400     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4401     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4402
4403     /* szValue is non-NULL while pcchValue is NULL */
4404     lstrcpyA(buf, "apple");
4405     r = pMsiGetProductInfoExA(prodcode, usersid,
4406                               MSIINSTALLCONTEXT_USERUNMANAGED,
4407                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4408     ok(r == ERROR_INVALID_PARAMETER,
4409        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4410     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4411
4412     /* dwContext is out of range */
4413     sz = MAX_PATH;
4414     lstrcpyA(buf, "apple");
4415     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4416                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4417     ok(r == ERROR_INVALID_PARAMETER,
4418        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4419     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4420     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4421
4422     /* szProperty is NULL */
4423     sz = MAX_PATH;
4424     lstrcpyA(buf, "apple");
4425     r = pMsiGetProductInfoExA(prodcode, usersid,
4426                               MSIINSTALLCONTEXT_USERUNMANAGED,
4427                               NULL, buf, &sz);
4428     ok(r == ERROR_INVALID_PARAMETER,
4429        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4430     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4431     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4432
4433     /* szProperty is empty */
4434     sz = MAX_PATH;
4435     lstrcpyA(buf, "apple");
4436     r = pMsiGetProductInfoExA(prodcode, usersid,
4437                               MSIINSTALLCONTEXT_USERUNMANAGED,
4438                               "", buf, &sz);
4439     ok(r == ERROR_INVALID_PARAMETER,
4440        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4441     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4442     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4443
4444     /* szProperty is not a valid property */
4445     sz = MAX_PATH;
4446     lstrcpyA(buf, "apple");
4447     r = pMsiGetProductInfoExA(prodcode, usersid,
4448                               MSIINSTALLCONTEXT_USERUNMANAGED,
4449                               "notvalid", buf, &sz);
4450     ok(r == ERROR_UNKNOWN_PRODUCT,
4451        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4452     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4453     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4454
4455     /* same length as guid, but random */
4456     sz = MAX_PATH;
4457     lstrcpyA(buf, "apple");
4458     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4459                               MSIINSTALLCONTEXT_USERUNMANAGED,
4460                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4461     ok(r == ERROR_INVALID_PARAMETER,
4462        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4463     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4464     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4465
4466     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4467
4468     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4469     lstrcatA(keypath, usersid);
4470     lstrcatA(keypath, "\\Products\\");
4471     lstrcatA(keypath, prod_squashed);
4472
4473     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4474     if (res == ERROR_ACCESS_DENIED)
4475     {
4476         skip("Not enough rights to perform tests\n");
4477         LocalFree(usersid);
4478         return;
4479     }
4480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4481
4482     /* local user product key exists */
4483     sz = MAX_PATH;
4484     lstrcpyA(buf, "apple");
4485     r = pMsiGetProductInfoExA(prodcode, usersid,
4486                               MSIINSTALLCONTEXT_USERUNMANAGED,
4487                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4488     ok(r == ERROR_UNKNOWN_PRODUCT,
4489        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4490     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4491     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4492
4493     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4495
4496     /* InstallProperties key exists */
4497     sz = MAX_PATH;
4498     lstrcpyA(buf, "apple");
4499     r = pMsiGetProductInfoExA(prodcode, usersid,
4500                               MSIINSTALLCONTEXT_USERUNMANAGED,
4501                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4502     ok(r == ERROR_UNKNOWN_PRODUCT,
4503        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4504     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4505     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4506
4507     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4509
4510     /* LocalPackage value exists */
4511     sz = MAX_PATH;
4512     lstrcpyA(buf, "apple");
4513     r = pMsiGetProductInfoExA(prodcode, usersid,
4514                               MSIINSTALLCONTEXT_USERUNMANAGED,
4515                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4517     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4518     ok(sz == 1, "Expected 1, got %d\n", sz);
4519
4520     RegDeleteValueA(propkey, "LocalPackage");
4521
4522     /* LocalPackage value must exist */
4523     sz = MAX_PATH;
4524     lstrcpyA(buf, "apple");
4525     r = pMsiGetProductInfoExA(prodcode, usersid,
4526                               MSIINSTALLCONTEXT_USERUNMANAGED,
4527                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4528     ok(r == ERROR_UNKNOWN_PRODUCT,
4529        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4530     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4531     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4532
4533     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4535
4536     /* LocalPackage exists, but HelpLink does not exist */
4537     sz = MAX_PATH;
4538     lstrcpyA(buf, "apple");
4539     r = pMsiGetProductInfoExA(prodcode, usersid,
4540                               MSIINSTALLCONTEXT_USERUNMANAGED,
4541                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4543     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4544     ok(sz == 0, "Expected 0, got %d\n", sz);
4545
4546     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4548
4549     /* HelpLink value exists */
4550     sz = MAX_PATH;
4551     lstrcpyA(buf, "apple");
4552     r = pMsiGetProductInfoExA(prodcode, usersid,
4553                               MSIINSTALLCONTEXT_USERUNMANAGED,
4554                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4556     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4557     ok(sz == 4, "Expected 4, got %d\n", sz);
4558
4559     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4561
4562     /* HelpTelephone value exists */
4563     sz = MAX_PATH;
4564     lstrcpyA(buf, "apple");
4565     r = pMsiGetProductInfoExA(prodcode, usersid,
4566                               MSIINSTALLCONTEXT_USERUNMANAGED,
4567                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4568     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4569     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4570     ok(sz == 5, "Expected 5, got %d\n", sz);
4571
4572     /* szValue and pcchValue are NULL */
4573     r = pMsiGetProductInfoExA(prodcode, usersid,
4574                               MSIINSTALLCONTEXT_USERUNMANAGED,
4575                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4577
4578     /* pcchValue is exactly 5 */
4579     sz = 5;
4580     lstrcpyA(buf, "apple");
4581     r = pMsiGetProductInfoExA(prodcode, usersid,
4582                               MSIINSTALLCONTEXT_USERUNMANAGED,
4583                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4584     ok(r == ERROR_MORE_DATA,
4585        "Expected ERROR_MORE_DATA, got %d\n", r);
4586     ok(sz == 10, "Expected 10, got %d\n", sz);
4587
4588     /* szValue is NULL, pcchValue is exactly 5 */
4589     sz = 5;
4590     r = pMsiGetProductInfoExA(prodcode, usersid,
4591                               MSIINSTALLCONTEXT_USERUNMANAGED,
4592                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4593     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4594     ok(sz == 10, "Expected 10, got %d\n", sz);
4595
4596     /* szValue is NULL, pcchValue is MAX_PATH */
4597     sz = MAX_PATH;
4598     r = pMsiGetProductInfoExA(prodcode, usersid,
4599                               MSIINSTALLCONTEXT_USERUNMANAGED,
4600                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4602     ok(sz == 10, "Expected 10, got %d\n", sz);
4603
4604     /* pcchValue is exactly 0 */
4605     sz = 0;
4606     lstrcpyA(buf, "apple");
4607     r = pMsiGetProductInfoExA(prodcode, usersid,
4608                               MSIINSTALLCONTEXT_USERUNMANAGED,
4609                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4610     ok(r == ERROR_MORE_DATA,
4611        "Expected ERROR_MORE_DATA, got %d\n", r);
4612     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4613     ok(sz == 10, "Expected 10, got %d\n", sz);
4614
4615     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4616     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4617
4618     /* szProperty is not a valid property */
4619     sz = MAX_PATH;
4620     lstrcpyA(buf, "apple");
4621     r = pMsiGetProductInfoExA(prodcode, usersid,
4622                               MSIINSTALLCONTEXT_USERUNMANAGED,
4623                               "notvalid", buf, &sz);
4624     ok(r == ERROR_UNKNOWN_PROPERTY,
4625        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4626     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4627     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4628
4629     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4631
4632     /* InstallDate value exists */
4633     sz = MAX_PATH;
4634     lstrcpyA(buf, "apple");
4635     r = pMsiGetProductInfoExA(prodcode, usersid,
4636                               MSIINSTALLCONTEXT_USERUNMANAGED,
4637                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4638     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4639     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4640     ok(sz == 4, "Expected 4, got %d\n", sz);
4641
4642     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4644
4645     /* DisplayName value exists */
4646     sz = MAX_PATH;
4647     lstrcpyA(buf, "apple");
4648     r = pMsiGetProductInfoExA(prodcode, usersid,
4649                               MSIINSTALLCONTEXT_USERUNMANAGED,
4650                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4651     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4652     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4653     ok(sz == 4, "Expected 4, got %d\n", sz);
4654
4655     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4657
4658     /* InstallLocation value exists */
4659     sz = MAX_PATH;
4660     lstrcpyA(buf, "apple");
4661     r = pMsiGetProductInfoExA(prodcode, usersid,
4662                               MSIINSTALLCONTEXT_USERUNMANAGED,
4663                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4665     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4666     ok(sz == 3, "Expected 3, got %d\n", sz);
4667
4668     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4670
4671     /* InstallSource value exists */
4672     sz = MAX_PATH;
4673     lstrcpyA(buf, "apple");
4674     r = pMsiGetProductInfoExA(prodcode, usersid,
4675                               MSIINSTALLCONTEXT_USERUNMANAGED,
4676                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4678     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4679     ok(sz == 6, "Expected 6, got %d\n", sz);
4680
4681     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4683
4684     /* LocalPackage value exists */
4685     sz = MAX_PATH;
4686     lstrcpyA(buf, "apple");
4687     r = pMsiGetProductInfoExA(prodcode, usersid,
4688                               MSIINSTALLCONTEXT_USERUNMANAGED,
4689                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4691     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4692     ok(sz == 5, "Expected 5, got %d\n", sz);
4693
4694     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4696
4697     /* Publisher value exists */
4698     sz = MAX_PATH;
4699     lstrcpyA(buf, "apple");
4700     r = pMsiGetProductInfoExA(prodcode, usersid,
4701                               MSIINSTALLCONTEXT_USERUNMANAGED,
4702                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4704     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4705     ok(sz == 3, "Expected 3, got %d\n", sz);
4706
4707     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4709
4710     /* URLInfoAbout value exists */
4711     sz = MAX_PATH;
4712     lstrcpyA(buf, "apple");
4713     r = pMsiGetProductInfoExA(prodcode, usersid,
4714                               MSIINSTALLCONTEXT_USERUNMANAGED,
4715                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4717     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4718     ok(sz == 5, "Expected 5, got %d\n", sz);
4719
4720     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4721     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4722
4723     /* URLUpdateInfo value exists */
4724     sz = MAX_PATH;
4725     lstrcpyA(buf, "apple");
4726     r = pMsiGetProductInfoExA(prodcode, usersid,
4727                               MSIINSTALLCONTEXT_USERUNMANAGED,
4728                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4730     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4731     ok(sz == 6, "Expected 6, got %d\n", sz);
4732
4733     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4735
4736     /* VersionMinor value exists */
4737     sz = MAX_PATH;
4738     lstrcpyA(buf, "apple");
4739     r = pMsiGetProductInfoExA(prodcode, usersid,
4740                               MSIINSTALLCONTEXT_USERUNMANAGED,
4741                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4742     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4744     ok(sz == 1, "Expected 1, got %d\n", sz);
4745
4746     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4748
4749     /* VersionMajor value exists */
4750     sz = MAX_PATH;
4751     lstrcpyA(buf, "apple");
4752     r = pMsiGetProductInfoExA(prodcode, usersid,
4753                               MSIINSTALLCONTEXT_USERUNMANAGED,
4754                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4756     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4757     ok(sz == 1, "Expected 1, got %d\n", sz);
4758
4759     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4761
4762     /* DisplayVersion value exists */
4763     sz = MAX_PATH;
4764     lstrcpyA(buf, "apple");
4765     r = pMsiGetProductInfoExA(prodcode, usersid,
4766                               MSIINSTALLCONTEXT_USERUNMANAGED,
4767                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4769     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4770     ok(sz == 5, "Expected 5, got %d\n", sz);
4771
4772     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4774
4775     /* ProductID value exists */
4776     sz = MAX_PATH;
4777     lstrcpyA(buf, "apple");
4778     r = pMsiGetProductInfoExA(prodcode, usersid,
4779                               MSIINSTALLCONTEXT_USERUNMANAGED,
4780                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4782     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4783     ok(sz == 2, "Expected 2, got %d\n", sz);
4784
4785     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4787
4788     /* RegCompany value exists */
4789     sz = MAX_PATH;
4790     lstrcpyA(buf, "apple");
4791     r = pMsiGetProductInfoExA(prodcode, usersid,
4792                               MSIINSTALLCONTEXT_USERUNMANAGED,
4793                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4795     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4796     ok(sz == 4, "Expected 4, got %d\n", sz);
4797
4798     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4800
4801     /* RegOwner value exists */
4802     sz = MAX_PATH;
4803     lstrcpyA(buf, "apple");
4804     r = pMsiGetProductInfoExA(prodcode, usersid,
4805                               MSIINSTALLCONTEXT_USERUNMANAGED,
4806                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4808     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4809     ok(sz == 5, "Expected 5, got %d\n", sz);
4810
4811     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4812     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4813
4814     /* Transforms value exists */
4815     sz = MAX_PATH;
4816     lstrcpyA(buf, "apple");
4817     r = pMsiGetProductInfoExA(prodcode, usersid,
4818                               MSIINSTALLCONTEXT_USERUNMANAGED,
4819                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4820     ok(r == ERROR_UNKNOWN_PRODUCT,
4821        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4822     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4823     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4824
4825     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4826     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4827
4828     /* Language value exists */
4829     sz = MAX_PATH;
4830     lstrcpyA(buf, "apple");
4831     r = pMsiGetProductInfoExA(prodcode, usersid,
4832                               MSIINSTALLCONTEXT_USERUNMANAGED,
4833                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4834     ok(r == ERROR_UNKNOWN_PRODUCT,
4835        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4836     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4837     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4838
4839     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4841
4842     /* ProductName value exists */
4843     sz = MAX_PATH;
4844     lstrcpyA(buf, "apple");
4845     r = pMsiGetProductInfoExA(prodcode, usersid,
4846                               MSIINSTALLCONTEXT_USERUNMANAGED,
4847                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4848     ok(r == ERROR_UNKNOWN_PRODUCT,
4849        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4850     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4851     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4852
4853     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4854     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4855
4856     /* FIXME */
4857
4858     /* AssignmentType value exists */
4859     sz = MAX_PATH;
4860     lstrcpyA(buf, "apple");
4861     r = pMsiGetProductInfoExA(prodcode, usersid,
4862                               MSIINSTALLCONTEXT_USERUNMANAGED,
4863                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4864     ok(r == ERROR_UNKNOWN_PRODUCT,
4865        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4866     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4867     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4868
4869     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4871
4872     /* PackageCode value exists */
4873     sz = MAX_PATH;
4874     lstrcpyA(buf, "apple");
4875     r = pMsiGetProductInfoExA(prodcode, usersid,
4876                               MSIINSTALLCONTEXT_USERUNMANAGED,
4877                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4878     ok(r == ERROR_UNKNOWN_PRODUCT,
4879        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4880     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4881     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4882
4883     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4884     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4885
4886     /* Version value exists */
4887     sz = MAX_PATH;
4888     lstrcpyA(buf, "apple");
4889     r = pMsiGetProductInfoExA(prodcode, usersid,
4890                               MSIINSTALLCONTEXT_USERUNMANAGED,
4891                               INSTALLPROPERTY_VERSION, buf, &sz);
4892     ok(r == ERROR_UNKNOWN_PRODUCT,
4893        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4894     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4895     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4896
4897     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4899
4900     /* ProductIcon value exists */
4901     sz = MAX_PATH;
4902     lstrcpyA(buf, "apple");
4903     r = pMsiGetProductInfoExA(prodcode, usersid,
4904                               MSIINSTALLCONTEXT_USERUNMANAGED,
4905                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4906     ok(r == ERROR_UNKNOWN_PRODUCT,
4907        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4908     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4909     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4910
4911     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4913
4914     /* PackageName value exists */
4915     sz = MAX_PATH;
4916     lstrcpyA(buf, "apple");
4917     r = pMsiGetProductInfoExA(prodcode, usersid,
4918                               MSIINSTALLCONTEXT_USERUNMANAGED,
4919                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4920     ok(r == ERROR_UNKNOWN_PRODUCT,
4921        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4922     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4923     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4924
4925     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4926     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4927
4928     /* AuthorizedLUAApp value exists */
4929     sz = MAX_PATH;
4930     lstrcpyA(buf, "apple");
4931     r = pMsiGetProductInfoExA(prodcode, usersid,
4932                               MSIINSTALLCONTEXT_USERUNMANAGED,
4933                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4934     ok(r == ERROR_UNKNOWN_PRODUCT,
4935        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4936     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4937     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4938
4939     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4940     RegDeleteValueA(propkey, "PackageName");
4941     RegDeleteValueA(propkey, "ProductIcon");
4942     RegDeleteValueA(propkey, "Version");
4943     RegDeleteValueA(propkey, "PackageCode");
4944     RegDeleteValueA(propkey, "AssignmentType");
4945     RegDeleteValueA(propkey, "ProductName");
4946     RegDeleteValueA(propkey, "Language");
4947     RegDeleteValueA(propkey, "Transforms");
4948     RegDeleteValueA(propkey, "RegOwner");
4949     RegDeleteValueA(propkey, "RegCompany");
4950     RegDeleteValueA(propkey, "ProductID");
4951     RegDeleteValueA(propkey, "DisplayVersion");
4952     RegDeleteValueA(propkey, "VersionMajor");
4953     RegDeleteValueA(propkey, "VersionMinor");
4954     RegDeleteValueA(propkey, "URLUpdateInfo");
4955     RegDeleteValueA(propkey, "URLInfoAbout");
4956     RegDeleteValueA(propkey, "Publisher");
4957     RegDeleteValueA(propkey, "LocalPackage");
4958     RegDeleteValueA(propkey, "InstallSource");
4959     RegDeleteValueA(propkey, "InstallLocation");
4960     RegDeleteValueA(propkey, "DisplayName");
4961     RegDeleteValueA(propkey, "InstallDate");
4962     RegDeleteValueA(propkey, "HelpTelephone");
4963     RegDeleteValueA(propkey, "HelpLink");
4964     RegDeleteValueA(propkey, "LocalPackage");
4965     RegDeleteKeyA(propkey, "");
4966     RegCloseKey(propkey);
4967     RegDeleteKeyA(localkey, "");
4968     RegCloseKey(localkey);
4969
4970     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4971     lstrcatA(keypath, usersid);
4972     lstrcatA(keypath, "\\Installer\\Products\\");
4973     lstrcatA(keypath, prod_squashed);
4974
4975     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
4976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4977
4978     /* user product key exists */
4979     sz = MAX_PATH;
4980     lstrcpyA(buf, "apple");
4981     r = pMsiGetProductInfoExA(prodcode, usersid,
4982                               MSIINSTALLCONTEXT_USERUNMANAGED,
4983                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4984     ok(r == ERROR_UNKNOWN_PRODUCT,
4985        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4986     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4987     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4988
4989     RegDeleteKeyA(userkey, "");
4990     RegCloseKey(userkey);
4991
4992     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4993     lstrcatA(keypath, prod_squashed);
4994
4995     res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4997
4998     sz = MAX_PATH;
4999     lstrcpyA(buf, "apple");
5000     r = pMsiGetProductInfoExA(prodcode, usersid,
5001                               MSIINSTALLCONTEXT_USERUNMANAGED,
5002                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5003     ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
5004     if (r == ERROR_UNKNOWN_PRODUCT)
5005     {
5006         win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
5007         delete_key(prodkey, "", access);
5008         RegCloseKey(prodkey);
5009         return;
5010     }
5011     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5012     ok(sz == 1, "Expected 1, got %d\n", sz);
5013
5014     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5015     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5016
5017     /* HelpLink value exists */
5018     sz = MAX_PATH;
5019     lstrcpyA(buf, "apple");
5020     r = pMsiGetProductInfoExA(prodcode, usersid,
5021                               MSIINSTALLCONTEXT_USERUNMANAGED,
5022                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5023     ok(r == ERROR_UNKNOWN_PROPERTY,
5024        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5025     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5026     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5027
5028     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5030
5031     /* HelpTelephone value exists */
5032     sz = MAX_PATH;
5033     lstrcpyA(buf, "apple");
5034     r = pMsiGetProductInfoExA(prodcode, usersid,
5035                               MSIINSTALLCONTEXT_USERUNMANAGED,
5036                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5037     ok(r == ERROR_UNKNOWN_PROPERTY,
5038        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5039     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5040     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5041
5042     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5044
5045     /* InstallDate value exists */
5046     sz = MAX_PATH;
5047     lstrcpyA(buf, "apple");
5048     r = pMsiGetProductInfoExA(prodcode, usersid,
5049                               MSIINSTALLCONTEXT_USERUNMANAGED,
5050                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5051     ok(r == ERROR_UNKNOWN_PROPERTY,
5052        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5053     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5054     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5055
5056     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5057     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5058
5059     /* DisplayName value exists */
5060     sz = MAX_PATH;
5061     lstrcpyA(buf, "apple");
5062     r = pMsiGetProductInfoExA(prodcode, usersid,
5063                               MSIINSTALLCONTEXT_USERUNMANAGED,
5064                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5065     ok(r == ERROR_UNKNOWN_PROPERTY,
5066        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5067     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5068     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5069
5070     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5072
5073     /* InstallLocation value exists */
5074     sz = MAX_PATH;
5075     lstrcpyA(buf, "apple");
5076     r = pMsiGetProductInfoExA(prodcode, usersid,
5077                               MSIINSTALLCONTEXT_USERUNMANAGED,
5078                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5079     ok(r == ERROR_UNKNOWN_PROPERTY,
5080        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5081     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5082     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5083
5084     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5086
5087     /* InstallSource value exists */
5088     sz = MAX_PATH;
5089     lstrcpyA(buf, "apple");
5090     r = pMsiGetProductInfoExA(prodcode, usersid,
5091                               MSIINSTALLCONTEXT_USERUNMANAGED,
5092                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5093     ok(r == ERROR_UNKNOWN_PROPERTY,
5094        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5095     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5096     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5097
5098     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5100
5101     /* LocalPackage value exists */
5102     sz = MAX_PATH;
5103     lstrcpyA(buf, "apple");
5104     r = pMsiGetProductInfoExA(prodcode, usersid,
5105                               MSIINSTALLCONTEXT_USERUNMANAGED,
5106                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5107     ok(r == ERROR_UNKNOWN_PROPERTY,
5108        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5109     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5110     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5111
5112     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5114
5115     /* Publisher value exists */
5116     sz = MAX_PATH;
5117     lstrcpyA(buf, "apple");
5118     r = pMsiGetProductInfoExA(prodcode, usersid,
5119                               MSIINSTALLCONTEXT_USERUNMANAGED,
5120                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5121     ok(r == ERROR_UNKNOWN_PROPERTY,
5122        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5123     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5124     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5125
5126     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5128
5129     /* URLInfoAbout value exists */
5130     sz = MAX_PATH;
5131     lstrcpyA(buf, "apple");
5132     r = pMsiGetProductInfoExA(prodcode, usersid,
5133                               MSIINSTALLCONTEXT_USERUNMANAGED,
5134                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5135     ok(r == ERROR_UNKNOWN_PROPERTY,
5136        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5137     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5138     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5139
5140     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5142
5143     /* URLUpdateInfo value exists */
5144     sz = MAX_PATH;
5145     lstrcpyA(buf, "apple");
5146     r = pMsiGetProductInfoExA(prodcode, usersid,
5147                               MSIINSTALLCONTEXT_USERUNMANAGED,
5148                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5149     ok(r == ERROR_UNKNOWN_PROPERTY,
5150        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5151     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5152     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5153
5154     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5156
5157     /* VersionMinor value exists */
5158     sz = MAX_PATH;
5159     lstrcpyA(buf, "apple");
5160     r = pMsiGetProductInfoExA(prodcode, usersid,
5161                               MSIINSTALLCONTEXT_USERUNMANAGED,
5162                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5163     ok(r == ERROR_UNKNOWN_PROPERTY,
5164        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5165     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5166     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5167
5168     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5170
5171     /* VersionMajor value exists */
5172     sz = MAX_PATH;
5173     lstrcpyA(buf, "apple");
5174     r = pMsiGetProductInfoExA(prodcode, usersid,
5175                               MSIINSTALLCONTEXT_USERUNMANAGED,
5176                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5177     ok(r == ERROR_UNKNOWN_PROPERTY,
5178        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5179     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5180     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5181
5182     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5184
5185     /* DisplayVersion value exists */
5186     sz = MAX_PATH;
5187     lstrcpyA(buf, "apple");
5188     r = pMsiGetProductInfoExA(prodcode, usersid,
5189                               MSIINSTALLCONTEXT_USERUNMANAGED,
5190                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5191     ok(r == ERROR_UNKNOWN_PROPERTY,
5192        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5193     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5194     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5195
5196     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5198
5199     /* ProductID value exists */
5200     sz = MAX_PATH;
5201     lstrcpyA(buf, "apple");
5202     r = pMsiGetProductInfoExA(prodcode, usersid,
5203                               MSIINSTALLCONTEXT_USERUNMANAGED,
5204                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5205     ok(r == ERROR_UNKNOWN_PROPERTY,
5206        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5207     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5208     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5209
5210     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5212
5213     /* RegCompany value exists */
5214     sz = MAX_PATH;
5215     lstrcpyA(buf, "apple");
5216     r = pMsiGetProductInfoExA(prodcode, usersid,
5217                               MSIINSTALLCONTEXT_USERUNMANAGED,
5218                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5219     ok(r == ERROR_UNKNOWN_PROPERTY,
5220        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5221     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5222     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5223
5224     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5226
5227     /* RegOwner value exists */
5228     sz = MAX_PATH;
5229     lstrcpyA(buf, "apple");
5230     r = pMsiGetProductInfoExA(prodcode, usersid,
5231                               MSIINSTALLCONTEXT_USERUNMANAGED,
5232                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5233     ok(r == ERROR_UNKNOWN_PROPERTY,
5234        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5235     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5236     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5237
5238     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5240
5241     /* Transforms value exists */
5242     sz = MAX_PATH;
5243     lstrcpyA(buf, "apple");
5244     r = pMsiGetProductInfoExA(prodcode, usersid,
5245                               MSIINSTALLCONTEXT_USERUNMANAGED,
5246                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5248     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5249     ok(sz == 5, "Expected 5, got %d\n", sz);
5250
5251     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5253
5254     /* Language value exists */
5255     sz = MAX_PATH;
5256     lstrcpyA(buf, "apple");
5257     r = pMsiGetProductInfoExA(prodcode, usersid,
5258                               MSIINSTALLCONTEXT_USERUNMANAGED,
5259                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5261     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5262     ok(sz == 4, "Expected 4, got %d\n", sz);
5263
5264     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5266
5267     /* ProductName value exists */
5268     sz = MAX_PATH;
5269     lstrcpyA(buf, "apple");
5270     r = pMsiGetProductInfoExA(prodcode, usersid,
5271                               MSIINSTALLCONTEXT_USERUNMANAGED,
5272                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5274     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5275     ok(sz == 4, "Expected 4, got %d\n", sz);
5276
5277     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5279
5280     /* FIXME */
5281
5282     /* AssignmentType value exists */
5283     sz = MAX_PATH;
5284     lstrcpyA(buf, "apple");
5285     r = pMsiGetProductInfoExA(prodcode, usersid,
5286                               MSIINSTALLCONTEXT_USERUNMANAGED,
5287                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5289     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5290     ok(sz == 0, "Expected 0, got %d\n", sz);
5291
5292     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5294
5295     /* FIXME */
5296
5297     /* PackageCode value exists */
5298     sz = MAX_PATH;
5299     lstrcpyA(buf, "apple");
5300     r = pMsiGetProductInfoExA(prodcode, usersid,
5301                               MSIINSTALLCONTEXT_USERUNMANAGED,
5302                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5303     todo_wine
5304     {
5305         ok(r == ERROR_BAD_CONFIGURATION,
5306            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5307         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5308         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5309     }
5310
5311     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5312     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5313
5314     /* Version value exists */
5315     sz = MAX_PATH;
5316     lstrcpyA(buf, "apple");
5317     r = pMsiGetProductInfoExA(prodcode, usersid,
5318                               MSIINSTALLCONTEXT_USERUNMANAGED,
5319                               INSTALLPROPERTY_VERSION, buf, &sz);
5320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5321     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5322     ok(sz == 3, "Expected 3, got %d\n", sz);
5323
5324     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5326
5327     /* ProductIcon value exists */
5328     sz = MAX_PATH;
5329     lstrcpyA(buf, "apple");
5330     r = pMsiGetProductInfoExA(prodcode, usersid,
5331                               MSIINSTALLCONTEXT_USERUNMANAGED,
5332                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5334     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5335     ok(sz == 4, "Expected 4, got %d\n", sz);
5336
5337     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5339
5340     /* PackageName value exists */
5341     sz = MAX_PATH;
5342     lstrcpyA(buf, "apple");
5343     r = pMsiGetProductInfoExA(prodcode, usersid,
5344                               MSIINSTALLCONTEXT_USERUNMANAGED,
5345                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5346     todo_wine
5347     {
5348         ok(r == ERROR_UNKNOWN_PRODUCT,
5349            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5350         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5351         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5352     }
5353
5354     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5356
5357     /* AuthorizedLUAApp value exists */
5358     sz = MAX_PATH;
5359     lstrcpyA(buf, "apple");
5360     r = pMsiGetProductInfoExA(prodcode, usersid,
5361                               MSIINSTALLCONTEXT_USERUNMANAGED,
5362                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5364     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5365     ok(sz == 4, "Expected 4, got %d\n", sz);
5366
5367     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5368     RegDeleteValueA(prodkey, "PackageName");
5369     RegDeleteValueA(prodkey, "ProductIcon");
5370     RegDeleteValueA(prodkey, "Version");
5371     RegDeleteValueA(prodkey, "PackageCode");
5372     RegDeleteValueA(prodkey, "AssignmentType");
5373     RegDeleteValueA(prodkey, "ProductName");
5374     RegDeleteValueA(prodkey, "Language");
5375     RegDeleteValueA(prodkey, "Transforms");
5376     RegDeleteValueA(prodkey, "RegOwner");
5377     RegDeleteValueA(prodkey, "RegCompany");
5378     RegDeleteValueA(prodkey, "ProductID");
5379     RegDeleteValueA(prodkey, "DisplayVersion");
5380     RegDeleteValueA(prodkey, "VersionMajor");
5381     RegDeleteValueA(prodkey, "VersionMinor");
5382     RegDeleteValueA(prodkey, "URLUpdateInfo");
5383     RegDeleteValueA(prodkey, "URLInfoAbout");
5384     RegDeleteValueA(prodkey, "Publisher");
5385     RegDeleteValueA(prodkey, "LocalPackage");
5386     RegDeleteValueA(prodkey, "InstallSource");
5387     RegDeleteValueA(prodkey, "InstallLocation");
5388     RegDeleteValueA(prodkey, "DisplayName");
5389     RegDeleteValueA(prodkey, "InstallDate");
5390     RegDeleteValueA(prodkey, "HelpTelephone");
5391     RegDeleteValueA(prodkey, "HelpLink");
5392     RegDeleteValueA(prodkey, "LocalPackage");
5393     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5394     RegCloseKey(prodkey);
5395
5396     /* MSIINSTALLCONTEXT_USERMANAGED */
5397
5398     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5399     lstrcatA(keypath, usersid);
5400     lstrcatA(keypath, "\\Products\\");
5401     lstrcatA(keypath, prod_squashed);
5402
5403     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5405
5406     /* local user product key exists */
5407     sz = MAX_PATH;
5408     lstrcpyA(buf, "apple");
5409     r = pMsiGetProductInfoExA(prodcode, usersid,
5410                               MSIINSTALLCONTEXT_USERMANAGED,
5411                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5412     ok(r == ERROR_UNKNOWN_PRODUCT,
5413        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5414     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5415     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5416
5417     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5419
5420     /* InstallProperties key exists */
5421     sz = MAX_PATH;
5422     lstrcpyA(buf, "apple");
5423     r = pMsiGetProductInfoExA(prodcode, usersid,
5424                               MSIINSTALLCONTEXT_USERMANAGED,
5425                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5426     ok(r == ERROR_UNKNOWN_PRODUCT,
5427        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5428     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5429     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5430
5431     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5432     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5433
5434     /* ManagedLocalPackage value exists */
5435     sz = MAX_PATH;
5436     lstrcpyA(buf, "apple");
5437     r = pMsiGetProductInfoExA(prodcode, usersid,
5438                               MSIINSTALLCONTEXT_USERMANAGED,
5439                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5441     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5442     ok(sz == 1, "Expected 1, got %d\n", sz);
5443
5444     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5446
5447     /* HelpLink value exists */
5448     sz = MAX_PATH;
5449     lstrcpyA(buf, "apple");
5450     r = pMsiGetProductInfoExA(prodcode, usersid,
5451                               MSIINSTALLCONTEXT_USERMANAGED,
5452                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5453     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5454     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5455     ok(sz == 4, "Expected 4, got %d\n", sz);
5456
5457     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5459
5460     /* HelpTelephone value exists */
5461     sz = MAX_PATH;
5462     lstrcpyA(buf, "apple");
5463     r = pMsiGetProductInfoExA(prodcode, usersid,
5464                               MSIINSTALLCONTEXT_USERMANAGED,
5465                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5466     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5467     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5468     ok(sz == 5, "Expected 5, got %d\n", sz);
5469
5470     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5472
5473     /* InstallDate value exists */
5474     sz = MAX_PATH;
5475     lstrcpyA(buf, "apple");
5476     r = pMsiGetProductInfoExA(prodcode, usersid,
5477                               MSIINSTALLCONTEXT_USERMANAGED,
5478                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5480     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5481     ok(sz == 4, "Expected 4, got %d\n", sz);
5482
5483     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5485
5486     /* DisplayName value exists */
5487     sz = MAX_PATH;
5488     lstrcpyA(buf, "apple");
5489     r = pMsiGetProductInfoExA(prodcode, usersid,
5490                               MSIINSTALLCONTEXT_USERMANAGED,
5491                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5493     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5494     ok(sz == 4, "Expected 4, got %d\n", sz);
5495
5496     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5497     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5498
5499     /* InstallLocation value exists */
5500     sz = MAX_PATH;
5501     lstrcpyA(buf, "apple");
5502     r = pMsiGetProductInfoExA(prodcode, usersid,
5503                               MSIINSTALLCONTEXT_USERMANAGED,
5504                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5506     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5507     ok(sz == 3, "Expected 3, got %d\n", sz);
5508
5509     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5511
5512     /* InstallSource value exists */
5513     sz = MAX_PATH;
5514     lstrcpyA(buf, "apple");
5515     r = pMsiGetProductInfoExA(prodcode, usersid,
5516                               MSIINSTALLCONTEXT_USERMANAGED,
5517                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5518     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5519     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5520     ok(sz == 6, "Expected 6, got %d\n", sz);
5521
5522     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5524
5525     /* LocalPackage value exists */
5526     sz = MAX_PATH;
5527     lstrcpyA(buf, "apple");
5528     r = pMsiGetProductInfoExA(prodcode, usersid,
5529                               MSIINSTALLCONTEXT_USERMANAGED,
5530                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5531     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5532     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5533     ok(sz == 5, "Expected 5, got %d\n", sz);
5534
5535     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5536     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5537
5538     /* Publisher value exists */
5539     sz = MAX_PATH;
5540     lstrcpyA(buf, "apple");
5541     r = pMsiGetProductInfoExA(prodcode, usersid,
5542                               MSIINSTALLCONTEXT_USERMANAGED,
5543                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5545     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5546     ok(sz == 3, "Expected 3, got %d\n", sz);
5547
5548     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5550
5551     /* URLInfoAbout value exists */
5552     sz = MAX_PATH;
5553     lstrcpyA(buf, "apple");
5554     r = pMsiGetProductInfoExA(prodcode, usersid,
5555                               MSIINSTALLCONTEXT_USERMANAGED,
5556                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5557     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5558     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5559     ok(sz == 5, "Expected 5, got %d\n", sz);
5560
5561     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5563
5564     /* URLUpdateInfo value exists */
5565     sz = MAX_PATH;
5566     lstrcpyA(buf, "apple");
5567     r = pMsiGetProductInfoExA(prodcode, usersid,
5568                               MSIINSTALLCONTEXT_USERMANAGED,
5569                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5570     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5571     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5572     ok(sz == 6, "Expected 6, got %d\n", sz);
5573
5574     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5576
5577     /* VersionMinor value exists */
5578     sz = MAX_PATH;
5579     lstrcpyA(buf, "apple");
5580     r = pMsiGetProductInfoExA(prodcode, usersid,
5581                               MSIINSTALLCONTEXT_USERMANAGED,
5582                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5583     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5584     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5585     ok(sz == 1, "Expected 1, got %d\n", sz);
5586
5587     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5589
5590     /* VersionMajor value exists */
5591     sz = MAX_PATH;
5592     lstrcpyA(buf, "apple");
5593     r = pMsiGetProductInfoExA(prodcode, usersid,
5594                               MSIINSTALLCONTEXT_USERMANAGED,
5595                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5596     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5597     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5598     ok(sz == 1, "Expected 1, got %d\n", sz);
5599
5600     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5602
5603     /* DisplayVersion value exists */
5604     sz = MAX_PATH;
5605     lstrcpyA(buf, "apple");
5606     r = pMsiGetProductInfoExA(prodcode, usersid,
5607                               MSIINSTALLCONTEXT_USERMANAGED,
5608                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5609     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5610     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5611     ok(sz == 5, "Expected 5, got %d\n", sz);
5612
5613     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5615
5616     /* ProductID value exists */
5617     sz = MAX_PATH;
5618     lstrcpyA(buf, "apple");
5619     r = pMsiGetProductInfoExA(prodcode, usersid,
5620                               MSIINSTALLCONTEXT_USERMANAGED,
5621                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5622     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5623     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5624     ok(sz == 2, "Expected 2, got %d\n", sz);
5625
5626     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5628
5629     /* RegCompany value exists */
5630     sz = MAX_PATH;
5631     lstrcpyA(buf, "apple");
5632     r = pMsiGetProductInfoExA(prodcode, usersid,
5633                               MSIINSTALLCONTEXT_USERMANAGED,
5634                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5636     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5637     ok(sz == 4, "Expected 4, got %d\n", sz);
5638
5639     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5641
5642     /* RegOwner value exists */
5643     sz = MAX_PATH;
5644     lstrcpyA(buf, "apple");
5645     r = pMsiGetProductInfoExA(prodcode, usersid,
5646                               MSIINSTALLCONTEXT_USERMANAGED,
5647                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5649     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5650     ok(sz == 5, "Expected 5, got %d\n", sz);
5651
5652     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5654
5655     /* Transforms value exists */
5656     sz = MAX_PATH;
5657     lstrcpyA(buf, "apple");
5658     r = pMsiGetProductInfoExA(prodcode, usersid,
5659                               MSIINSTALLCONTEXT_USERMANAGED,
5660                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5661     ok(r == ERROR_UNKNOWN_PRODUCT,
5662        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5663     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5664     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5665
5666     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5668
5669     /* Language value exists */
5670     sz = MAX_PATH;
5671     lstrcpyA(buf, "apple");
5672     r = pMsiGetProductInfoExA(prodcode, usersid,
5673                               MSIINSTALLCONTEXT_USERMANAGED,
5674                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5675     ok(r == ERROR_UNKNOWN_PRODUCT,
5676        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5677     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5678     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5679
5680     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5681     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5682
5683     /* ProductName value exists */
5684     sz = MAX_PATH;
5685     lstrcpyA(buf, "apple");
5686     r = pMsiGetProductInfoExA(prodcode, usersid,
5687                               MSIINSTALLCONTEXT_USERMANAGED,
5688                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5689     ok(r == ERROR_UNKNOWN_PRODUCT,
5690        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5691     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5692     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5693
5694     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5696
5697     /* FIXME */
5698
5699     /* AssignmentType value exists */
5700     sz = MAX_PATH;
5701     lstrcpyA(buf, "apple");
5702     r = pMsiGetProductInfoExA(prodcode, usersid,
5703                               MSIINSTALLCONTEXT_USERMANAGED,
5704                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5705     ok(r == ERROR_UNKNOWN_PRODUCT,
5706        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5707     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5708     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5709
5710     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5711     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5712
5713     /* PackageCode value exists */
5714     sz = MAX_PATH;
5715     lstrcpyA(buf, "apple");
5716     r = pMsiGetProductInfoExA(prodcode, usersid,
5717                               MSIINSTALLCONTEXT_USERMANAGED,
5718                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5719     ok(r == ERROR_UNKNOWN_PRODUCT,
5720        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5721     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5722     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5723
5724     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5726
5727     /* Version value exists */
5728     sz = MAX_PATH;
5729     lstrcpyA(buf, "apple");
5730     r = pMsiGetProductInfoExA(prodcode, usersid,
5731                               MSIINSTALLCONTEXT_USERMANAGED,
5732                               INSTALLPROPERTY_VERSION, buf, &sz);
5733     ok(r == ERROR_UNKNOWN_PRODUCT,
5734        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5735     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5736     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5737
5738     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5740
5741     /* ProductIcon value exists */
5742     sz = MAX_PATH;
5743     lstrcpyA(buf, "apple");
5744     r = pMsiGetProductInfoExA(prodcode, usersid,
5745                               MSIINSTALLCONTEXT_USERMANAGED,
5746                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5747     ok(r == ERROR_UNKNOWN_PRODUCT,
5748        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5749     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5750     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5751
5752     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5754
5755     /* PackageName value exists */
5756     sz = MAX_PATH;
5757     lstrcpyA(buf, "apple");
5758     r = pMsiGetProductInfoExA(prodcode, usersid,
5759                               MSIINSTALLCONTEXT_USERMANAGED,
5760                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5761     ok(r == ERROR_UNKNOWN_PRODUCT,
5762        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5763     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5764     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5765
5766     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5768
5769     /* AuthorizedLUAApp value exists */
5770     sz = MAX_PATH;
5771     lstrcpyA(buf, "apple");
5772     r = pMsiGetProductInfoExA(prodcode, usersid,
5773                               MSIINSTALLCONTEXT_USERMANAGED,
5774                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5775     ok(r == ERROR_UNKNOWN_PRODUCT,
5776        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5777     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5778     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5779
5780     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5781     RegDeleteValueA(propkey, "PackageName");
5782     RegDeleteValueA(propkey, "ProductIcon");
5783     RegDeleteValueA(propkey, "Version");
5784     RegDeleteValueA(propkey, "PackageCode");
5785     RegDeleteValueA(propkey, "AssignmentType");
5786     RegDeleteValueA(propkey, "ProductName");
5787     RegDeleteValueA(propkey, "Language");
5788     RegDeleteValueA(propkey, "Transforms");
5789     RegDeleteValueA(propkey, "RegOwner");
5790     RegDeleteValueA(propkey, "RegCompany");
5791     RegDeleteValueA(propkey, "ProductID");
5792     RegDeleteValueA(propkey, "DisplayVersion");
5793     RegDeleteValueA(propkey, "VersionMajor");
5794     RegDeleteValueA(propkey, "VersionMinor");
5795     RegDeleteValueA(propkey, "URLUpdateInfo");
5796     RegDeleteValueA(propkey, "URLInfoAbout");
5797     RegDeleteValueA(propkey, "Publisher");
5798     RegDeleteValueA(propkey, "LocalPackage");
5799     RegDeleteValueA(propkey, "InstallSource");
5800     RegDeleteValueA(propkey, "InstallLocation");
5801     RegDeleteValueA(propkey, "DisplayName");
5802     RegDeleteValueA(propkey, "InstallDate");
5803     RegDeleteValueA(propkey, "HelpTelephone");
5804     RegDeleteValueA(propkey, "HelpLink");
5805     RegDeleteValueA(propkey, "ManagedLocalPackage");
5806     delete_key(propkey, "", access & KEY_WOW64_64KEY);
5807     RegCloseKey(propkey);
5808     delete_key(localkey, "", access & KEY_WOW64_64KEY);
5809     RegCloseKey(localkey);
5810
5811     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5812     lstrcatA(keypath, usersid);
5813     lstrcatA(keypath, "\\Installer\\Products\\");
5814     lstrcatA(keypath, prod_squashed);
5815
5816     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5817     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5818
5819     /* user product key exists */
5820     sz = MAX_PATH;
5821     lstrcpyA(buf, "apple");
5822     r = pMsiGetProductInfoExA(prodcode, usersid,
5823                               MSIINSTALLCONTEXT_USERMANAGED,
5824                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5825     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5826     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5827     ok(sz == 1, "Expected 1, got %d\n", sz);
5828
5829     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5830     RegCloseKey(userkey);
5831
5832     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5833     lstrcatA(keypath, prod_squashed);
5834
5835     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5837
5838     /* current user product key exists */
5839     sz = MAX_PATH;
5840     lstrcpyA(buf, "apple");
5841     r = pMsiGetProductInfoExA(prodcode, usersid,
5842                               MSIINSTALLCONTEXT_USERMANAGED,
5843                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5844     ok(r == ERROR_UNKNOWN_PRODUCT,
5845        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5846     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5847     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5848
5849     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5850     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5851
5852     /* HelpLink value exists, user product key does not exist */
5853     sz = MAX_PATH;
5854     lstrcpyA(buf, "apple");
5855     r = pMsiGetProductInfoExA(prodcode, usersid,
5856                               MSIINSTALLCONTEXT_USERMANAGED,
5857                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5858     ok(r == ERROR_UNKNOWN_PRODUCT,
5859        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5860     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5861     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5862
5863     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5864     lstrcatA(keypath, usersid);
5865     lstrcatA(keypath, "\\Installer\\Products\\");
5866     lstrcatA(keypath, prod_squashed);
5867
5868     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5869     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5870
5871     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5872     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5873
5874     /* HelpLink value exists, user product key does exist */
5875     sz = MAX_PATH;
5876     lstrcpyA(buf, "apple");
5877     r = pMsiGetProductInfoExA(prodcode, usersid,
5878                               MSIINSTALLCONTEXT_USERMANAGED,
5879                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5880     ok(r == ERROR_UNKNOWN_PROPERTY,
5881        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5882     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5883     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5884
5885     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5887
5888     /* HelpTelephone value exists */
5889     sz = MAX_PATH;
5890     lstrcpyA(buf, "apple");
5891     r = pMsiGetProductInfoExA(prodcode, usersid,
5892                               MSIINSTALLCONTEXT_USERMANAGED,
5893                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5894     ok(r == ERROR_UNKNOWN_PROPERTY,
5895        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5896     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5897     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5898
5899     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5901
5902     /* InstallDate value exists */
5903     sz = MAX_PATH;
5904     lstrcpyA(buf, "apple");
5905     r = pMsiGetProductInfoExA(prodcode, usersid,
5906                               MSIINSTALLCONTEXT_USERMANAGED,
5907                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5908     ok(r == ERROR_UNKNOWN_PROPERTY,
5909        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5910     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5911     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5912
5913     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5915
5916     /* DisplayName value exists */
5917     sz = MAX_PATH;
5918     lstrcpyA(buf, "apple");
5919     r = pMsiGetProductInfoExA(prodcode, usersid,
5920                               MSIINSTALLCONTEXT_USERMANAGED,
5921                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5922     ok(r == ERROR_UNKNOWN_PROPERTY,
5923        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5924     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5925     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5926
5927     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5929
5930     /* InstallLocation value exists */
5931     sz = MAX_PATH;
5932     lstrcpyA(buf, "apple");
5933     r = pMsiGetProductInfoExA(prodcode, usersid,
5934                               MSIINSTALLCONTEXT_USERMANAGED,
5935                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5936     ok(r == ERROR_UNKNOWN_PROPERTY,
5937        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5938     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5939     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5940
5941     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5943
5944     /* InstallSource value exists */
5945     sz = MAX_PATH;
5946     lstrcpyA(buf, "apple");
5947     r = pMsiGetProductInfoExA(prodcode, usersid,
5948                               MSIINSTALLCONTEXT_USERMANAGED,
5949                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5950     ok(r == ERROR_UNKNOWN_PROPERTY,
5951        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5952     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5953     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5954
5955     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5957
5958     /* LocalPackage value exists */
5959     sz = MAX_PATH;
5960     lstrcpyA(buf, "apple");
5961     r = pMsiGetProductInfoExA(prodcode, usersid,
5962                               MSIINSTALLCONTEXT_USERMANAGED,
5963                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5964     ok(r == ERROR_UNKNOWN_PROPERTY,
5965        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5966     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5967     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5968
5969     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5971
5972     /* Publisher value exists */
5973     sz = MAX_PATH;
5974     lstrcpyA(buf, "apple");
5975     r = pMsiGetProductInfoExA(prodcode, usersid,
5976                               MSIINSTALLCONTEXT_USERMANAGED,
5977                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5978     ok(r == ERROR_UNKNOWN_PROPERTY,
5979        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5980     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5981     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5982
5983     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5985
5986     /* URLInfoAbout value exists */
5987     sz = MAX_PATH;
5988     lstrcpyA(buf, "apple");
5989     r = pMsiGetProductInfoExA(prodcode, usersid,
5990                               MSIINSTALLCONTEXT_USERMANAGED,
5991                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5992     ok(r == ERROR_UNKNOWN_PROPERTY,
5993        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5994     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5995     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5996
5997     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5999
6000     /* URLUpdateInfo value exists */
6001     sz = MAX_PATH;
6002     lstrcpyA(buf, "apple");
6003     r = pMsiGetProductInfoExA(prodcode, usersid,
6004                               MSIINSTALLCONTEXT_USERMANAGED,
6005                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6006     ok(r == ERROR_UNKNOWN_PROPERTY,
6007        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6008     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6009     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6010
6011     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6013
6014     /* VersionMinor value exists */
6015     sz = MAX_PATH;
6016     lstrcpyA(buf, "apple");
6017     r = pMsiGetProductInfoExA(prodcode, usersid,
6018                               MSIINSTALLCONTEXT_USERMANAGED,
6019                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6020     ok(r == ERROR_UNKNOWN_PROPERTY,
6021        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6022     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6023     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6024
6025     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6026     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6027
6028     /* VersionMajor value exists */
6029     sz = MAX_PATH;
6030     lstrcpyA(buf, "apple");
6031     r = pMsiGetProductInfoExA(prodcode, usersid,
6032                               MSIINSTALLCONTEXT_USERMANAGED,
6033                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6034     ok(r == ERROR_UNKNOWN_PROPERTY,
6035        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6036     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6037     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6038
6039     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6041
6042     /* DisplayVersion value exists */
6043     sz = MAX_PATH;
6044     lstrcpyA(buf, "apple");
6045     r = pMsiGetProductInfoExA(prodcode, usersid,
6046                               MSIINSTALLCONTEXT_USERMANAGED,
6047                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6048     ok(r == ERROR_UNKNOWN_PROPERTY,
6049        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6050     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6051     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6052
6053     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6055
6056     /* ProductID value exists */
6057     sz = MAX_PATH;
6058     lstrcpyA(buf, "apple");
6059     r = pMsiGetProductInfoExA(prodcode, usersid,
6060                               MSIINSTALLCONTEXT_USERMANAGED,
6061                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6062     ok(r == ERROR_UNKNOWN_PROPERTY,
6063        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6064     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6065     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6066
6067     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6069
6070     /* RegCompany value exists */
6071     sz = MAX_PATH;
6072     lstrcpyA(buf, "apple");
6073     r = pMsiGetProductInfoExA(prodcode, usersid,
6074                               MSIINSTALLCONTEXT_USERMANAGED,
6075                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6076     ok(r == ERROR_UNKNOWN_PROPERTY,
6077        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6078     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6079     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6080
6081     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6083
6084     /* RegOwner value exists */
6085     sz = MAX_PATH;
6086     lstrcpyA(buf, "apple");
6087     r = pMsiGetProductInfoExA(prodcode, usersid,
6088                               MSIINSTALLCONTEXT_USERMANAGED,
6089                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6090     ok(r == ERROR_UNKNOWN_PROPERTY,
6091        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6092     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6093     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6094
6095     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6096     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6097
6098     /* Transforms value exists */
6099     sz = MAX_PATH;
6100     lstrcpyA(buf, "apple");
6101     r = pMsiGetProductInfoExA(prodcode, usersid,
6102                               MSIINSTALLCONTEXT_USERMANAGED,
6103                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6104     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6105     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6106     ok(sz == 5, "Expected 5, got %d\n", sz);
6107
6108     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6110
6111     /* Language value exists */
6112     sz = MAX_PATH;
6113     lstrcpyA(buf, "apple");
6114     r = pMsiGetProductInfoExA(prodcode, usersid,
6115                               MSIINSTALLCONTEXT_USERMANAGED,
6116                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6118     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6119     ok(sz == 4, "Expected 4, got %d\n", sz);
6120
6121     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6123
6124     /* ProductName value exists */
6125     sz = MAX_PATH;
6126     lstrcpyA(buf, "apple");
6127     r = pMsiGetProductInfoExA(prodcode, usersid,
6128                               MSIINSTALLCONTEXT_USERMANAGED,
6129                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6131     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6132     ok(sz == 4, "Expected 4, got %d\n", sz);
6133
6134     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6136
6137     /* FIXME */
6138
6139     /* AssignmentType value exists */
6140     sz = MAX_PATH;
6141     lstrcpyA(buf, "apple");
6142     r = pMsiGetProductInfoExA(prodcode, usersid,
6143                               MSIINSTALLCONTEXT_USERMANAGED,
6144                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6146     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6147     ok(sz == 0, "Expected 0, got %d\n", sz);
6148
6149     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6151
6152     /* FIXME */
6153
6154     /* PackageCode value exists */
6155     sz = MAX_PATH;
6156     lstrcpyA(buf, "apple");
6157     r = pMsiGetProductInfoExA(prodcode, usersid,
6158                               MSIINSTALLCONTEXT_USERMANAGED,
6159                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6160     todo_wine
6161     {
6162         ok(r == ERROR_BAD_CONFIGURATION,
6163            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6164         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6165         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6166     }
6167
6168     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6170
6171     /* Version value exists */
6172     sz = MAX_PATH;
6173     lstrcpyA(buf, "apple");
6174     r = pMsiGetProductInfoExA(prodcode, usersid,
6175                               MSIINSTALLCONTEXT_USERMANAGED,
6176                               INSTALLPROPERTY_VERSION, buf, &sz);
6177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6178     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6179     ok(sz == 3, "Expected 3, got %d\n", sz);
6180
6181     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6183
6184     /* ProductIcon value exists */
6185     sz = MAX_PATH;
6186     lstrcpyA(buf, "apple");
6187     r = pMsiGetProductInfoExA(prodcode, usersid,
6188                               MSIINSTALLCONTEXT_USERMANAGED,
6189                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6190     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6191     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6192     ok(sz == 4, "Expected 4, got %d\n", sz);
6193
6194     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6196
6197     /* PackageName value exists */
6198     sz = MAX_PATH;
6199     lstrcpyA(buf, "apple");
6200     r = pMsiGetProductInfoExA(prodcode, usersid,
6201                               MSIINSTALLCONTEXT_USERMANAGED,
6202                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6203     todo_wine
6204     {
6205         ok(r == ERROR_UNKNOWN_PRODUCT,
6206            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6207         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6208         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6209     }
6210
6211     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6213
6214     /* AuthorizedLUAApp value exists */
6215     sz = MAX_PATH;
6216     lstrcpyA(buf, "apple");
6217     r = pMsiGetProductInfoExA(prodcode, usersid,
6218                               MSIINSTALLCONTEXT_USERMANAGED,
6219                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6220     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6221     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6222     ok(sz == 4, "Expected 4, got %d\n", sz);
6223
6224     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6225     RegDeleteValueA(userkey, "PackageName");
6226     RegDeleteValueA(userkey, "ProductIcon");
6227     RegDeleteValueA(userkey, "Version");
6228     RegDeleteValueA(userkey, "PackageCode");
6229     RegDeleteValueA(userkey, "AssignmentType");
6230     RegDeleteValueA(userkey, "ProductName");
6231     RegDeleteValueA(userkey, "Language");
6232     RegDeleteValueA(userkey, "Transforms");
6233     RegDeleteValueA(userkey, "RegOwner");
6234     RegDeleteValueA(userkey, "RegCompany");
6235     RegDeleteValueA(userkey, "ProductID");
6236     RegDeleteValueA(userkey, "DisplayVersion");
6237     RegDeleteValueA(userkey, "VersionMajor");
6238     RegDeleteValueA(userkey, "VersionMinor");
6239     RegDeleteValueA(userkey, "URLUpdateInfo");
6240     RegDeleteValueA(userkey, "URLInfoAbout");
6241     RegDeleteValueA(userkey, "Publisher");
6242     RegDeleteValueA(userkey, "LocalPackage");
6243     RegDeleteValueA(userkey, "InstallSource");
6244     RegDeleteValueA(userkey, "InstallLocation");
6245     RegDeleteValueA(userkey, "DisplayName");
6246     RegDeleteValueA(userkey, "InstallDate");
6247     RegDeleteValueA(userkey, "HelpTelephone");
6248     RegDeleteValueA(userkey, "HelpLink");
6249     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6250     RegCloseKey(userkey);
6251     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6252     RegCloseKey(prodkey);
6253
6254     /* MSIINSTALLCONTEXT_MACHINE */
6255
6256     /* szUserSid is non-NULL */
6257     sz = MAX_PATH;
6258     lstrcpyA(buf, "apple");
6259     r = pMsiGetProductInfoExA(prodcode, usersid,
6260                               MSIINSTALLCONTEXT_MACHINE,
6261                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6262     ok(r == ERROR_INVALID_PARAMETER,
6263        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6264     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6265     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6266
6267     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6268     lstrcatA(keypath, prod_squashed);
6269
6270     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6272
6273     /* local system product key exists */
6274     sz = MAX_PATH;
6275     lstrcpyA(buf, "apple");
6276     r = pMsiGetProductInfoExA(prodcode, NULL,
6277                               MSIINSTALLCONTEXT_MACHINE,
6278                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6279     ok(r == ERROR_UNKNOWN_PRODUCT,
6280        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6281     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6282     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6283
6284     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6286
6287     /* InstallProperties key exists */
6288     sz = MAX_PATH;
6289     lstrcpyA(buf, "apple");
6290     r = pMsiGetProductInfoExA(prodcode, NULL,
6291                               MSIINSTALLCONTEXT_MACHINE,
6292                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6293     ok(r == ERROR_UNKNOWN_PRODUCT,
6294        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6295     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6296     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6297
6298     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6300
6301     /* LocalPackage value exists */
6302     sz = MAX_PATH;
6303     lstrcpyA(buf, "apple");
6304     r = pMsiGetProductInfoExA(prodcode, NULL,
6305                               MSIINSTALLCONTEXT_MACHINE,
6306                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6307     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6308     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6309     ok(sz == 1, "Expected 1, got %d\n", sz);
6310
6311     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6312     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6313
6314     /* HelpLink value exists */
6315     sz = MAX_PATH;
6316     lstrcpyA(buf, "apple");
6317     r = pMsiGetProductInfoExA(prodcode, NULL,
6318                               MSIINSTALLCONTEXT_MACHINE,
6319                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6321     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6322     ok(sz == 4, "Expected 4, got %d\n", sz);
6323
6324     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6326
6327     /* HelpTelephone value exists */
6328     sz = MAX_PATH;
6329     lstrcpyA(buf, "apple");
6330     r = pMsiGetProductInfoExA(prodcode, NULL,
6331                               MSIINSTALLCONTEXT_MACHINE,
6332                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6334     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6335     ok(sz == 5, "Expected 5, got %d\n", sz);
6336
6337     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6339
6340     /* InstallDate value exists */
6341     sz = MAX_PATH;
6342     lstrcpyA(buf, "apple");
6343     r = pMsiGetProductInfoExA(prodcode, NULL,
6344                               MSIINSTALLCONTEXT_MACHINE,
6345                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6347     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6348     ok(sz == 4, "Expected 4, got %d\n", sz);
6349
6350     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6352
6353     /* DisplayName value exists */
6354     sz = MAX_PATH;
6355     lstrcpyA(buf, "apple");
6356     r = pMsiGetProductInfoExA(prodcode, NULL,
6357                               MSIINSTALLCONTEXT_MACHINE,
6358                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6360     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6361     ok(sz == 4, "Expected 4, got %d\n", sz);
6362
6363     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6365
6366     /* InstallLocation value exists */
6367     sz = MAX_PATH;
6368     lstrcpyA(buf, "apple");
6369     r = pMsiGetProductInfoExA(prodcode, NULL,
6370                               MSIINSTALLCONTEXT_MACHINE,
6371                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6373     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6374     ok(sz == 3, "Expected 3, got %d\n", sz);
6375
6376     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6378
6379     /* InstallSource value exists */
6380     sz = MAX_PATH;
6381     lstrcpyA(buf, "apple");
6382     r = pMsiGetProductInfoExA(prodcode, NULL,
6383                               MSIINSTALLCONTEXT_MACHINE,
6384                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6385     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6386     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6387     ok(sz == 6, "Expected 6, got %d\n", sz);
6388
6389     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6390     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6391
6392     /* LocalPackage value exists */
6393     sz = MAX_PATH;
6394     lstrcpyA(buf, "apple");
6395     r = pMsiGetProductInfoExA(prodcode, NULL,
6396                               MSIINSTALLCONTEXT_MACHINE,
6397                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6398     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6399     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6400     ok(sz == 5, "Expected 5, got %d\n", sz);
6401
6402     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6404
6405     /* Publisher value exists */
6406     sz = MAX_PATH;
6407     lstrcpyA(buf, "apple");
6408     r = pMsiGetProductInfoExA(prodcode, NULL,
6409                               MSIINSTALLCONTEXT_MACHINE,
6410                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6412     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6413     ok(sz == 3, "Expected 3, got %d\n", sz);
6414
6415     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6417
6418     /* URLInfoAbout value exists */
6419     sz = MAX_PATH;
6420     lstrcpyA(buf, "apple");
6421     r = pMsiGetProductInfoExA(prodcode, NULL,
6422                               MSIINSTALLCONTEXT_MACHINE,
6423                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6425     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6426     ok(sz == 5, "Expected 5, got %d\n", sz);
6427
6428     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6430
6431     /* URLUpdateInfo value exists */
6432     sz = MAX_PATH;
6433     lstrcpyA(buf, "apple");
6434     r = pMsiGetProductInfoExA(prodcode, NULL,
6435                               MSIINSTALLCONTEXT_MACHINE,
6436                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6438     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6439     ok(sz == 6, "Expected 6, got %d\n", sz);
6440
6441     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6443
6444     /* VersionMinor value exists */
6445     sz = MAX_PATH;
6446     lstrcpyA(buf, "apple");
6447     r = pMsiGetProductInfoExA(prodcode, NULL,
6448                               MSIINSTALLCONTEXT_MACHINE,
6449                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6451     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6452     ok(sz == 1, "Expected 1, got %d\n", sz);
6453
6454     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6456
6457     /* VersionMajor value exists */
6458     sz = MAX_PATH;
6459     lstrcpyA(buf, "apple");
6460     r = pMsiGetProductInfoExA(prodcode, NULL,
6461                               MSIINSTALLCONTEXT_MACHINE,
6462                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6464     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6465     ok(sz == 1, "Expected 1, got %d\n", sz);
6466
6467     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6469
6470     /* DisplayVersion value exists */
6471     sz = MAX_PATH;
6472     lstrcpyA(buf, "apple");
6473     r = pMsiGetProductInfoExA(prodcode, NULL,
6474                               MSIINSTALLCONTEXT_MACHINE,
6475                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6477     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6478     ok(sz == 5, "Expected 5, got %d\n", sz);
6479
6480     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6481     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6482
6483     /* ProductID value exists */
6484     sz = MAX_PATH;
6485     lstrcpyA(buf, "apple");
6486     r = pMsiGetProductInfoExA(prodcode, NULL,
6487                               MSIINSTALLCONTEXT_MACHINE,
6488                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6489     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6490     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6491     ok(sz == 2, "Expected 2, got %d\n", sz);
6492
6493     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6495
6496     /* RegCompany value exists */
6497     sz = MAX_PATH;
6498     lstrcpyA(buf, "apple");
6499     r = pMsiGetProductInfoExA(prodcode, NULL,
6500                               MSIINSTALLCONTEXT_MACHINE,
6501                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6502     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6503     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6504     ok(sz == 4, "Expected 4, got %d\n", sz);
6505
6506     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6508
6509     /* RegOwner value exists */
6510     sz = MAX_PATH;
6511     lstrcpyA(buf, "apple");
6512     r = pMsiGetProductInfoExA(prodcode, NULL,
6513                               MSIINSTALLCONTEXT_MACHINE,
6514                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6516     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6517     ok(sz == 5, "Expected 5, got %d\n", sz);
6518
6519     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6521
6522     /* Transforms value exists */
6523     sz = MAX_PATH;
6524     lstrcpyA(buf, "apple");
6525     r = pMsiGetProductInfoExA(prodcode, NULL,
6526                               MSIINSTALLCONTEXT_MACHINE,
6527                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6528     ok(r == ERROR_UNKNOWN_PRODUCT,
6529        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6530     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6531     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6532
6533     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6535
6536     /* Language value exists */
6537     sz = MAX_PATH;
6538     lstrcpyA(buf, "apple");
6539     r = pMsiGetProductInfoExA(prodcode, NULL,
6540                               MSIINSTALLCONTEXT_MACHINE,
6541                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6542     ok(r == ERROR_UNKNOWN_PRODUCT,
6543        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6544     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6545     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6546
6547     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6549
6550     /* ProductName value exists */
6551     sz = MAX_PATH;
6552     lstrcpyA(buf, "apple");
6553     r = pMsiGetProductInfoExA(prodcode, NULL,
6554                               MSIINSTALLCONTEXT_MACHINE,
6555                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6556     ok(r == ERROR_UNKNOWN_PRODUCT,
6557        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6558     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6559     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6560
6561     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6563
6564     /* FIXME */
6565
6566     /* AssignmentType value exists */
6567     sz = MAX_PATH;
6568     lstrcpyA(buf, "apple");
6569     r = pMsiGetProductInfoExA(prodcode, NULL,
6570                               MSIINSTALLCONTEXT_MACHINE,
6571                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6572     ok(r == ERROR_UNKNOWN_PRODUCT,
6573        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6574     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6575     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6576
6577     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6579
6580     /* PackageCode value exists */
6581     sz = MAX_PATH;
6582     lstrcpyA(buf, "apple");
6583     r = pMsiGetProductInfoExA(prodcode, NULL,
6584                               MSIINSTALLCONTEXT_MACHINE,
6585                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6586     ok(r == ERROR_UNKNOWN_PRODUCT,
6587        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6588     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6589     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6590
6591     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6593
6594     /* Version value exists */
6595     sz = MAX_PATH;
6596     lstrcpyA(buf, "apple");
6597     r = pMsiGetProductInfoExA(prodcode, NULL,
6598                               MSIINSTALLCONTEXT_MACHINE,
6599                               INSTALLPROPERTY_VERSION, buf, &sz);
6600     ok(r == ERROR_UNKNOWN_PRODUCT,
6601        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6602     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6603     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6604
6605     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6607
6608     /* ProductIcon value exists */
6609     sz = MAX_PATH;
6610     lstrcpyA(buf, "apple");
6611     r = pMsiGetProductInfoExA(prodcode, NULL,
6612                               MSIINSTALLCONTEXT_MACHINE,
6613                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6614     ok(r == ERROR_UNKNOWN_PRODUCT,
6615        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6616     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6617     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6618
6619     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6621
6622     /* PackageName value exists */
6623     sz = MAX_PATH;
6624     lstrcpyA(buf, "apple");
6625     r = pMsiGetProductInfoExA(prodcode, NULL,
6626                               MSIINSTALLCONTEXT_MACHINE,
6627                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6628     ok(r == ERROR_UNKNOWN_PRODUCT,
6629        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6630     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6631     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6632
6633     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6635
6636     /* AuthorizedLUAApp value exists */
6637     sz = MAX_PATH;
6638     lstrcpyA(buf, "apple");
6639     r = pMsiGetProductInfoExA(prodcode, NULL,
6640                               MSIINSTALLCONTEXT_MACHINE,
6641                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6642     ok(r == ERROR_UNKNOWN_PRODUCT,
6643        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6644     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6645     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6646
6647     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6648     RegDeleteValueA(propkey, "PackageName");
6649     RegDeleteValueA(propkey, "ProductIcon");
6650     RegDeleteValueA(propkey, "Version");
6651     RegDeleteValueA(propkey, "PackageCode");
6652     RegDeleteValueA(propkey, "AssignmentType");
6653     RegDeleteValueA(propkey, "ProductName");
6654     RegDeleteValueA(propkey, "Language");
6655     RegDeleteValueA(propkey, "Transforms");
6656     RegDeleteValueA(propkey, "RegOwner");
6657     RegDeleteValueA(propkey, "RegCompany");
6658     RegDeleteValueA(propkey, "ProductID");
6659     RegDeleteValueA(propkey, "DisplayVersion");
6660     RegDeleteValueA(propkey, "VersionMajor");
6661     RegDeleteValueA(propkey, "VersionMinor");
6662     RegDeleteValueA(propkey, "URLUpdateInfo");
6663     RegDeleteValueA(propkey, "URLInfoAbout");
6664     RegDeleteValueA(propkey, "Publisher");
6665     RegDeleteValueA(propkey, "LocalPackage");
6666     RegDeleteValueA(propkey, "InstallSource");
6667     RegDeleteValueA(propkey, "InstallLocation");
6668     RegDeleteValueA(propkey, "DisplayName");
6669     RegDeleteValueA(propkey, "InstallDate");
6670     RegDeleteValueA(propkey, "HelpTelephone");
6671     RegDeleteValueA(propkey, "HelpLink");
6672     RegDeleteValueA(propkey, "LocalPackage");
6673     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6674     RegCloseKey(propkey);
6675     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6676     RegCloseKey(localkey);
6677
6678     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6679     lstrcatA(keypath, prod_squashed);
6680
6681     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6683
6684     /* local classes product key exists */
6685     sz = MAX_PATH;
6686     lstrcpyA(buf, "apple");
6687     r = pMsiGetProductInfoExA(prodcode, NULL,
6688                               MSIINSTALLCONTEXT_MACHINE,
6689                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6691     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6692     ok(sz == 1, "Expected 1, got %d\n", sz);
6693
6694     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6696
6697     /* HelpLink value exists */
6698     sz = MAX_PATH;
6699     lstrcpyA(buf, "apple");
6700     r = pMsiGetProductInfoExA(prodcode, NULL,
6701                               MSIINSTALLCONTEXT_MACHINE,
6702                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6703     ok(r == ERROR_UNKNOWN_PROPERTY,
6704        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6705     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6706     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6707
6708     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6710
6711     /* HelpTelephone value exists */
6712     sz = MAX_PATH;
6713     lstrcpyA(buf, "apple");
6714     r = pMsiGetProductInfoExA(prodcode, NULL,
6715                               MSIINSTALLCONTEXT_MACHINE,
6716                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6717     ok(r == ERROR_UNKNOWN_PROPERTY,
6718        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6719     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6720     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6721
6722     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6723     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6724
6725     /* InstallDate value exists */
6726     sz = MAX_PATH;
6727     lstrcpyA(buf, "apple");
6728     r = pMsiGetProductInfoExA(prodcode, NULL,
6729                               MSIINSTALLCONTEXT_MACHINE,
6730                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6731     ok(r == ERROR_UNKNOWN_PROPERTY,
6732        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6733     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6734     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6735
6736     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6738
6739     /* DisplayName value exists */
6740     sz = MAX_PATH;
6741     lstrcpyA(buf, "apple");
6742     r = pMsiGetProductInfoExA(prodcode, NULL,
6743                               MSIINSTALLCONTEXT_MACHINE,
6744                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6745     ok(r == ERROR_UNKNOWN_PROPERTY,
6746        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6747     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6748     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6749
6750     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6752
6753     /* InstallLocation value exists */
6754     sz = MAX_PATH;
6755     lstrcpyA(buf, "apple");
6756     r = pMsiGetProductInfoExA(prodcode, NULL,
6757                               MSIINSTALLCONTEXT_MACHINE,
6758                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6759     ok(r == ERROR_UNKNOWN_PROPERTY,
6760        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6761     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6762     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6763
6764     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6766
6767     /* InstallSource value exists */
6768     sz = MAX_PATH;
6769     lstrcpyA(buf, "apple");
6770     r = pMsiGetProductInfoExA(prodcode, NULL,
6771                               MSIINSTALLCONTEXT_MACHINE,
6772                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6773     ok(r == ERROR_UNKNOWN_PROPERTY,
6774        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6775     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6776     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6777
6778     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6780
6781     /* LocalPackage value exists */
6782     sz = MAX_PATH;
6783     lstrcpyA(buf, "apple");
6784     r = pMsiGetProductInfoExA(prodcode, NULL,
6785                               MSIINSTALLCONTEXT_MACHINE,
6786                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6787     ok(r == ERROR_UNKNOWN_PROPERTY,
6788        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6789     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6790     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6791
6792     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6794
6795     /* Publisher value exists */
6796     sz = MAX_PATH;
6797     lstrcpyA(buf, "apple");
6798     r = pMsiGetProductInfoExA(prodcode, NULL,
6799                               MSIINSTALLCONTEXT_MACHINE,
6800                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6801     ok(r == ERROR_UNKNOWN_PROPERTY,
6802        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6803     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6804     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6805
6806     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6807     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6808
6809     /* URLInfoAbout value exists */
6810     sz = MAX_PATH;
6811     lstrcpyA(buf, "apple");
6812     r = pMsiGetProductInfoExA(prodcode, NULL,
6813                               MSIINSTALLCONTEXT_MACHINE,
6814                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6815     ok(r == ERROR_UNKNOWN_PROPERTY,
6816        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6817     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6818     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6819
6820     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6821     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6822
6823     /* URLUpdateInfo value exists */
6824     sz = MAX_PATH;
6825     lstrcpyA(buf, "apple");
6826     r = pMsiGetProductInfoExA(prodcode, NULL,
6827                               MSIINSTALLCONTEXT_MACHINE,
6828                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6829     ok(r == ERROR_UNKNOWN_PROPERTY,
6830        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6831     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6832     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6833
6834     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6835     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6836
6837     /* VersionMinor value exists */
6838     sz = MAX_PATH;
6839     lstrcpyA(buf, "apple");
6840     r = pMsiGetProductInfoExA(prodcode, NULL,
6841                               MSIINSTALLCONTEXT_MACHINE,
6842                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6843     ok(r == ERROR_UNKNOWN_PROPERTY,
6844        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6845     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6846     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6847
6848     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6850
6851     /* VersionMajor value exists */
6852     sz = MAX_PATH;
6853     lstrcpyA(buf, "apple");
6854     r = pMsiGetProductInfoExA(prodcode, NULL,
6855                               MSIINSTALLCONTEXT_MACHINE,
6856                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6857     ok(r == ERROR_UNKNOWN_PROPERTY,
6858        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6859     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6860     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6861
6862     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6864
6865     /* DisplayVersion value exists */
6866     sz = MAX_PATH;
6867     lstrcpyA(buf, "apple");
6868     r = pMsiGetProductInfoExA(prodcode, NULL,
6869                               MSIINSTALLCONTEXT_MACHINE,
6870                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6871     ok(r == ERROR_UNKNOWN_PROPERTY,
6872        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6873     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6874     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6875
6876     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6878
6879     /* ProductID value exists */
6880     sz = MAX_PATH;
6881     lstrcpyA(buf, "apple");
6882     r = pMsiGetProductInfoExA(prodcode, NULL,
6883                               MSIINSTALLCONTEXT_MACHINE,
6884                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6885     ok(r == ERROR_UNKNOWN_PROPERTY,
6886        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6887     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6888     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6889
6890     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6892
6893     /* RegCompany value exists */
6894     sz = MAX_PATH;
6895     lstrcpyA(buf, "apple");
6896     r = pMsiGetProductInfoExA(prodcode, NULL,
6897                               MSIINSTALLCONTEXT_MACHINE,
6898                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6899     ok(r == ERROR_UNKNOWN_PROPERTY,
6900        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6901     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6902     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6903
6904     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6906
6907     /* RegOwner value exists */
6908     sz = MAX_PATH;
6909     lstrcpyA(buf, "apple");
6910     r = pMsiGetProductInfoExA(prodcode, NULL,
6911                               MSIINSTALLCONTEXT_MACHINE,
6912                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6913     ok(r == ERROR_UNKNOWN_PROPERTY,
6914        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6915     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6916     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6917
6918     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6920
6921     /* Transforms value exists */
6922     sz = MAX_PATH;
6923     lstrcpyA(buf, "apple");
6924     r = pMsiGetProductInfoExA(prodcode, NULL,
6925                               MSIINSTALLCONTEXT_MACHINE,
6926                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6927     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6928     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6929     ok(sz == 5, "Expected 5, got %d\n", sz);
6930
6931     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6933
6934     /* Language value exists */
6935     sz = MAX_PATH;
6936     lstrcpyA(buf, "apple");
6937     r = pMsiGetProductInfoExA(prodcode, NULL,
6938                               MSIINSTALLCONTEXT_MACHINE,
6939                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6940     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6941     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6942     ok(sz == 4, "Expected 4, got %d\n", sz);
6943
6944     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6946
6947     /* ProductName value exists */
6948     sz = MAX_PATH;
6949     lstrcpyA(buf, "apple");
6950     r = pMsiGetProductInfoExA(prodcode, NULL,
6951                               MSIINSTALLCONTEXT_MACHINE,
6952                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6953     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6954     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6955     ok(sz == 4, "Expected 4, got %d\n", sz);
6956
6957     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6959
6960     /* FIXME */
6961
6962     /* AssignmentType value exists */
6963     sz = MAX_PATH;
6964     lstrcpyA(buf, "apple");
6965     r = pMsiGetProductInfoExA(prodcode, NULL,
6966                               MSIINSTALLCONTEXT_MACHINE,
6967                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6969     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6970     ok(sz == 0, "Expected 0, got %d\n", sz);
6971
6972     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6974
6975     /* FIXME */
6976
6977     /* PackageCode value exists */
6978     sz = MAX_PATH;
6979     lstrcpyA(buf, "apple");
6980     r = pMsiGetProductInfoExA(prodcode, NULL,
6981                               MSIINSTALLCONTEXT_MACHINE,
6982                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6983     todo_wine
6984     {
6985         ok(r == ERROR_BAD_CONFIGURATION,
6986            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6987         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6988         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6989     }
6990
6991     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6993
6994     /* Version value exists */
6995     sz = MAX_PATH;
6996     lstrcpyA(buf, "apple");
6997     r = pMsiGetProductInfoExA(prodcode, NULL,
6998                               MSIINSTALLCONTEXT_MACHINE,
6999                               INSTALLPROPERTY_VERSION, buf, &sz);
7000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7001     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7002     ok(sz == 3, "Expected 3, got %d\n", sz);
7003
7004     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7006
7007     /* ProductIcon value exists */
7008     sz = MAX_PATH;
7009     lstrcpyA(buf, "apple");
7010     r = pMsiGetProductInfoExA(prodcode, NULL,
7011                               MSIINSTALLCONTEXT_MACHINE,
7012                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7014     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7015     ok(sz == 4, "Expected 4, got %d\n", sz);
7016
7017     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7019
7020     /* PackageName value exists */
7021     sz = MAX_PATH;
7022     lstrcpyA(buf, "apple");
7023     r = pMsiGetProductInfoExA(prodcode, NULL,
7024                               MSIINSTALLCONTEXT_MACHINE,
7025                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7026     todo_wine
7027     {
7028         ok(r == ERROR_UNKNOWN_PRODUCT,
7029            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7030         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7031         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7032     }
7033
7034     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7036
7037     /* AuthorizedLUAApp value exists */
7038     sz = MAX_PATH;
7039     lstrcpyA(buf, "apple");
7040     r = pMsiGetProductInfoExA(prodcode, NULL,
7041                               MSIINSTALLCONTEXT_MACHINE,
7042                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7044     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7045     ok(sz == 4, "Expected 4, got %d\n", sz);
7046
7047     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7048     RegDeleteValueA(prodkey, "PackageName");
7049     RegDeleteValueA(prodkey, "ProductIcon");
7050     RegDeleteValueA(prodkey, "Version");
7051     RegDeleteValueA(prodkey, "PackageCode");
7052     RegDeleteValueA(prodkey, "AssignmentType");
7053     RegDeleteValueA(prodkey, "ProductName");
7054     RegDeleteValueA(prodkey, "Language");
7055     RegDeleteValueA(prodkey, "Transforms");
7056     RegDeleteValueA(prodkey, "RegOwner");
7057     RegDeleteValueA(prodkey, "RegCompany");
7058     RegDeleteValueA(prodkey, "ProductID");
7059     RegDeleteValueA(prodkey, "DisplayVersion");
7060     RegDeleteValueA(prodkey, "VersionMajor");
7061     RegDeleteValueA(prodkey, "VersionMinor");
7062     RegDeleteValueA(prodkey, "URLUpdateInfo");
7063     RegDeleteValueA(prodkey, "URLInfoAbout");
7064     RegDeleteValueA(prodkey, "Publisher");
7065     RegDeleteValueA(prodkey, "LocalPackage");
7066     RegDeleteValueA(prodkey, "InstallSource");
7067     RegDeleteValueA(prodkey, "InstallLocation");
7068     RegDeleteValueA(prodkey, "DisplayName");
7069     RegDeleteValueA(prodkey, "InstallDate");
7070     RegDeleteValueA(prodkey, "HelpTelephone");
7071     RegDeleteValueA(prodkey, "HelpLink");
7072     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7073     RegCloseKey(prodkey);
7074     LocalFree(usersid);
7075 }
7076
7077 #define INIT_USERINFO() \
7078     lstrcpyA(user, "apple"); \
7079     lstrcpyA(org, "orange"); \
7080     lstrcpyA(serial, "banana"); \
7081     usersz = orgsz = serialsz = MAX_PATH;
7082
7083 static void test_MsiGetUserInfo(void)
7084 {
7085     USERINFOSTATE state;
7086     CHAR user[MAX_PATH];
7087     CHAR org[MAX_PATH];
7088     CHAR serial[MAX_PATH];
7089     DWORD usersz, orgsz, serialsz;
7090     CHAR keypath[MAX_PATH * 2];
7091     CHAR prodcode[MAX_PATH];
7092     CHAR prod_squashed[MAX_PATH];
7093     HKEY prodkey, userprod, props;
7094     LPSTR usersid;
7095     LONG res;
7096     REGSAM access = KEY_ALL_ACCESS;
7097
7098     create_test_guid(prodcode, prod_squashed);
7099     get_user_sid(&usersid);
7100
7101     if (is_wow64)
7102         access |= KEY_WOW64_64KEY;
7103
7104     /* NULL szProduct */
7105     INIT_USERINFO();
7106     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
7107     ok(state == USERINFOSTATE_INVALIDARG,
7108        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7109     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7110     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7111     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7112     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7113     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7114     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7115
7116     /* empty szProductCode */
7117     INIT_USERINFO();
7118     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
7119     ok(state == USERINFOSTATE_INVALIDARG,
7120        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7121     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7122     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7123     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7124     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7125     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7126     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7127
7128     /* garbage szProductCode */
7129     INIT_USERINFO();
7130     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
7131     ok(state == USERINFOSTATE_INVALIDARG,
7132        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7133     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7134     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7135     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7136     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7137     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7138     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7139
7140     /* guid without brackets */
7141     INIT_USERINFO();
7142     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7143                             user, &usersz, org, &orgsz, serial, &serialsz);
7144     ok(state == USERINFOSTATE_INVALIDARG,
7145        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7146     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7147     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7148     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7149     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7150     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7151     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7152
7153     /* guid with brackets */
7154     INIT_USERINFO();
7155     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7156                             user, &usersz, org, &orgsz, serial, &serialsz);
7157     ok(state == USERINFOSTATE_UNKNOWN,
7158        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7159     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7160     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7161     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7162     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7163     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7164     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7165
7166     /* NULL lpUserNameBuf */
7167     INIT_USERINFO();
7168     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7169     ok(state == USERINFOSTATE_UNKNOWN,
7170        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7171     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7172     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7173     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7174     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7175     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7176
7177     /* NULL pcchUserNameBuf */
7178     INIT_USERINFO();
7179     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
7180     ok(state == USERINFOSTATE_INVALIDARG,
7181        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7182     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7183     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7184     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7185     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7186     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7187
7188     /* both lpUserNameBuf and pcchUserNameBuf NULL */
7189     INIT_USERINFO();
7190     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7191     ok(state == USERINFOSTATE_UNKNOWN,
7192        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7193     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7194     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7195     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7196     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7197
7198     /* NULL lpOrgNameBuf */
7199     INIT_USERINFO();
7200     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
7201     ok(state == USERINFOSTATE_UNKNOWN,
7202        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7203     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7204     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7205     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7206     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7207     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7208
7209     /* NULL pcchOrgNameBuf */
7210     INIT_USERINFO();
7211     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7212     ok(state == USERINFOSTATE_INVALIDARG,
7213        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7214     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7215     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7216     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7217     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7218     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7219
7220     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7221     INIT_USERINFO();
7222     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7223     ok(state == USERINFOSTATE_UNKNOWN,
7224        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7225     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7226     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7227     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7228     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7229
7230     /* NULL lpSerialBuf */
7231     INIT_USERINFO();
7232     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7233     ok(state == USERINFOSTATE_UNKNOWN,
7234        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7235     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7236     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7237     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7238     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7239     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7240
7241     /* NULL pcchSerialBuf */
7242     INIT_USERINFO();
7243     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7244     ok(state == USERINFOSTATE_INVALIDARG,
7245        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7246     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7247     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7248     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7249     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7250     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7251
7252     /* both lpSerialBuf and pcchSerialBuf NULL */
7253     INIT_USERINFO();
7254     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7255     ok(state == USERINFOSTATE_UNKNOWN,
7256        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7257     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7258     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7259     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7260     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7261
7262     /* MSIINSTALLCONTEXT_USERMANAGED */
7263
7264     /* create local system product key */
7265     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7266     lstrcatA(keypath, usersid);
7267     lstrcatA(keypath, "\\Installer\\Products\\");
7268     lstrcatA(keypath, prod_squashed);
7269
7270     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7271     if (res == ERROR_ACCESS_DENIED)
7272     {
7273         skip("Not enough rights to perform tests\n");
7274         LocalFree(usersid);
7275         return;
7276     }
7277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7278
7279     /* managed product key exists */
7280     INIT_USERINFO();
7281     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7282     ok(state == USERINFOSTATE_ABSENT,
7283        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7284     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7285     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7286     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7287     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7288     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7289     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7290
7291     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7292     lstrcatA(keypath, "Installer\\UserData\\");
7293     lstrcatA(keypath, usersid);
7294     lstrcatA(keypath, "\\Products\\");
7295     lstrcatA(keypath, prod_squashed);
7296
7297     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7299
7300     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7301     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7302
7303     /* InstallProperties key exists */
7304     INIT_USERINFO();
7305     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7306     ok(state == USERINFOSTATE_ABSENT,
7307        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7308     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7309     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7310     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7311     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7312     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7313     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7314
7315     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7316     INIT_USERINFO();
7317     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7318     ok(state == USERINFOSTATE_ABSENT,
7319        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7320     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7321     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7322     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7323     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7324
7325     /* RegOwner, RegCompany don't exist, out params are NULL */
7326     INIT_USERINFO();
7327     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7328     ok(state == USERINFOSTATE_ABSENT,
7329        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7330     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7331     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7332
7333     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7335
7336     /* RegOwner value exists */
7337     INIT_USERINFO();
7338     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7339     ok(state == USERINFOSTATE_ABSENT,
7340        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7341     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7342     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7343     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7344     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7345     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7346     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7347
7348     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7350
7351     /* RegCompany value exists */
7352     INIT_USERINFO();
7353     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7354     ok(state == USERINFOSTATE_ABSENT,
7355        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7356     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7357     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7358     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7359     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7360     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7361     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7362
7363     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7365
7366     /* ProductID value exists */
7367     INIT_USERINFO();
7368     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7369     ok(state == USERINFOSTATE_PRESENT,
7370        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7371     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7372     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7373     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7374     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7375     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7376     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7377
7378     /* pcchUserNameBuf is too small */
7379     INIT_USERINFO();
7380     usersz = 0;
7381     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7382     ok(state == USERINFOSTATE_MOREDATA,
7383        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7384     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7385     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7386     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7387     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7388     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7389     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7390
7391     /* pcchUserNameBuf has no room for NULL terminator */
7392     INIT_USERINFO();
7393     usersz = 5;
7394     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7395     ok(state == USERINFOSTATE_MOREDATA,
7396        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7397     todo_wine
7398     {
7399         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7400     }
7401     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7402     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7403     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7404     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7405     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7406
7407     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7408     INIT_USERINFO();
7409     usersz = 0;
7410     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7411     ok(state == USERINFOSTATE_PRESENT,
7412        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7413     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7414     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7415     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7416     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7417     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7418     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7419
7420     RegDeleteValueA(props, "ProductID");
7421     RegDeleteValueA(props, "RegCompany");
7422     RegDeleteValueA(props, "RegOwner");
7423     delete_key(props, "", access & KEY_WOW64_64KEY);
7424     RegCloseKey(props);
7425     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7426     RegCloseKey(userprod);
7427     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7428     RegCloseKey(prodkey);
7429
7430     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7431
7432     /* create local system product key */
7433     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7434     lstrcatA(keypath, prod_squashed);
7435
7436     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7438
7439     /* product key exists */
7440     INIT_USERINFO();
7441     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7442     ok(state == USERINFOSTATE_ABSENT,
7443        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7444     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7445     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7446     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7447     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7448     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7449     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7450
7451     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7452     lstrcatA(keypath, "Installer\\UserData\\");
7453     lstrcatA(keypath, usersid);
7454     lstrcatA(keypath, "\\Products\\");
7455     lstrcatA(keypath, prod_squashed);
7456
7457     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7459
7460     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7461     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7462
7463     /* InstallProperties key exists */
7464     INIT_USERINFO();
7465     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7466     ok(state == USERINFOSTATE_ABSENT,
7467        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7468     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7469     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7470     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7471     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7472     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7473     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7474
7475     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7476     INIT_USERINFO();
7477     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7478     ok(state == USERINFOSTATE_ABSENT,
7479        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7480     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7481     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7482     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7483     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7484
7485     /* RegOwner, RegCompany don't exist, out params are NULL */
7486     INIT_USERINFO();
7487     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7488     ok(state == USERINFOSTATE_ABSENT,
7489        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7490     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7491     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7492
7493     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7495
7496     /* RegOwner value exists */
7497     INIT_USERINFO();
7498     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7499     ok(state == USERINFOSTATE_ABSENT,
7500        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7501     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7502     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7503     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7504     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7505     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7506     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7507
7508     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7510
7511     /* RegCompany value exists */
7512     INIT_USERINFO();
7513     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7514     ok(state == USERINFOSTATE_ABSENT,
7515        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7516     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7517     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7518     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7519     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7520     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7521     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7522
7523     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7525
7526     /* ProductID value exists */
7527     INIT_USERINFO();
7528     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7529     ok(state == USERINFOSTATE_PRESENT,
7530        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7531     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7532     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7533     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7534     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7535     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7536     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7537
7538     RegDeleteValueA(props, "ProductID");
7539     RegDeleteValueA(props, "RegCompany");
7540     RegDeleteValueA(props, "RegOwner");
7541     delete_key(props, "", access & KEY_WOW64_64KEY);
7542     RegCloseKey(props);
7543     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7544     RegCloseKey(userprod);
7545     RegDeleteKeyA(prodkey, "");
7546     RegCloseKey(prodkey);
7547
7548     /* MSIINSTALLCONTEXT_MACHINE */
7549
7550     /* create local system product key */
7551     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7552     lstrcatA(keypath, prod_squashed);
7553
7554     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7556
7557     /* product key exists */
7558     INIT_USERINFO();
7559     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7560     ok(state == USERINFOSTATE_ABSENT,
7561        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7562     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7563     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7564     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7565     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7566     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7567     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7568
7569     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7570     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7571     lstrcatA(keypath, "\\Products\\");
7572     lstrcatA(keypath, prod_squashed);
7573
7574     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7576
7577     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7579
7580     /* InstallProperties key exists */
7581     INIT_USERINFO();
7582     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7583     ok(state == USERINFOSTATE_ABSENT,
7584        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7585     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7586     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7587     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7588     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7589     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7590     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7591
7592     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7593     INIT_USERINFO();
7594     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7595     ok(state == USERINFOSTATE_ABSENT,
7596        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7597     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7598     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7599     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7600     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7601
7602     /* RegOwner, RegCompany don't exist, out params are NULL */
7603     INIT_USERINFO();
7604     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7605     ok(state == USERINFOSTATE_ABSENT,
7606        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7607     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7608     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7609
7610     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7612
7613     /* RegOwner value exists */
7614     INIT_USERINFO();
7615     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7616     ok(state == USERINFOSTATE_ABSENT,
7617        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7618     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7619     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7620     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7621     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7622     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7623     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7624
7625     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7627
7628     /* RegCompany value exists */
7629     INIT_USERINFO();
7630     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7631     ok(state == USERINFOSTATE_ABSENT,
7632        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7633     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7634     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7635     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7636     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7637     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7638     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7639
7640     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7642
7643     /* ProductID value exists */
7644     INIT_USERINFO();
7645     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7646     ok(state == USERINFOSTATE_PRESENT,
7647        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7648     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7649     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7650     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7651     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7652     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7653     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7654
7655     RegDeleteValueA(props, "ProductID");
7656     RegDeleteValueA(props, "RegCompany");
7657     RegDeleteValueA(props, "RegOwner");
7658     delete_key(props, "", access & KEY_WOW64_64KEY);
7659     RegCloseKey(props);
7660     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7661     RegCloseKey(userprod);
7662     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7663     RegCloseKey(prodkey);
7664     LocalFree(usersid);
7665 }
7666
7667 static void test_MsiOpenProduct(void)
7668 {
7669     MSIHANDLE hprod, hdb;
7670     CHAR val[MAX_PATH];
7671     CHAR path[MAX_PATH];
7672     CHAR keypath[MAX_PATH*2];
7673     CHAR prodcode[MAX_PATH];
7674     CHAR prod_squashed[MAX_PATH];
7675     HKEY prodkey, userkey, props;
7676     LPSTR usersid;
7677     DWORD size;
7678     LONG res;
7679     UINT r;
7680     REGSAM access = KEY_ALL_ACCESS;
7681
7682     GetCurrentDirectoryA(MAX_PATH, path);
7683     lstrcatA(path, "\\");
7684
7685     create_test_guid(prodcode, prod_squashed);
7686     get_user_sid(&usersid);
7687
7688     if (is_wow64)
7689         access |= KEY_WOW64_64KEY;
7690
7691     hdb = create_package_db(prodcode);
7692     MsiCloseHandle(hdb);
7693
7694     /* NULL szProduct */
7695     hprod = 0xdeadbeef;
7696     r = MsiOpenProductA(NULL, &hprod);
7697     ok(r == ERROR_INVALID_PARAMETER,
7698        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7699     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7700
7701     /* empty szProduct */
7702     hprod = 0xdeadbeef;
7703     r = MsiOpenProductA("", &hprod);
7704     ok(r == ERROR_INVALID_PARAMETER,
7705        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7706     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7707
7708     /* garbage szProduct */
7709     hprod = 0xdeadbeef;
7710     r = MsiOpenProductA("garbage", &hprod);
7711     ok(r == ERROR_INVALID_PARAMETER,
7712        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7713     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7714
7715     /* guid without brackets */
7716     hprod = 0xdeadbeef;
7717     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7718     ok(r == ERROR_INVALID_PARAMETER,
7719        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7720     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7721
7722     /* guid with brackets */
7723     hprod = 0xdeadbeef;
7724     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7725     ok(r == ERROR_UNKNOWN_PRODUCT,
7726        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7727     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7728
7729     /* same length as guid, but random */
7730     hprod = 0xdeadbeef;
7731     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7732     ok(r == ERROR_INVALID_PARAMETER,
7733        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7734     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7735
7736     /* hProduct is NULL */
7737     hprod = 0xdeadbeef;
7738     r = MsiOpenProductA(prodcode, NULL);
7739     ok(r == ERROR_INVALID_PARAMETER,
7740        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7741     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7742
7743     /* MSIINSTALLCONTEXT_USERMANAGED */
7744
7745     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7746     lstrcatA(keypath, "Installer\\Managed\\");
7747     lstrcatA(keypath, usersid);
7748     lstrcatA(keypath, "\\Installer\\Products\\");
7749     lstrcatA(keypath, prod_squashed);
7750
7751     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7752     if (res == ERROR_ACCESS_DENIED)
7753     {
7754         skip("Not enough rights to perform tests\n");
7755         LocalFree(usersid);
7756         return;
7757     }
7758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7759
7760     /* managed product key exists */
7761     hprod = 0xdeadbeef;
7762     r = MsiOpenProductA(prodcode, &hprod);
7763     ok(r == ERROR_UNKNOWN_PRODUCT,
7764        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7765     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7766
7767     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7768     lstrcatA(keypath, "Installer\\UserData\\");
7769     lstrcatA(keypath, usersid);
7770     lstrcatA(keypath, "\\Products\\");
7771     lstrcatA(keypath, prod_squashed);
7772
7773     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7774     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7775
7776     /* user product key exists */
7777     hprod = 0xdeadbeef;
7778     r = MsiOpenProductA(prodcode, &hprod);
7779     ok(r == ERROR_UNKNOWN_PRODUCT,
7780        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7781     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7782
7783     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7785
7786     /* InstallProperties key exists */
7787     hprod = 0xdeadbeef;
7788     r = MsiOpenProductA(prodcode, &hprod);
7789     ok(r == ERROR_UNKNOWN_PRODUCT,
7790        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7791     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7792
7793     lstrcpyA(val, path);
7794     lstrcatA(val, "\\winetest.msi");
7795     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7796                          (const BYTE *)val, lstrlenA(val) + 1);
7797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7798
7799     /* ManagedLocalPackage value exists */
7800     hprod = 0xdeadbeef;
7801     r = MsiOpenProductA(prodcode, &hprod);
7802     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7803     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7804
7805     size = MAX_PATH;
7806     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7808     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7809     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7810
7811     MsiCloseHandle(hprod);
7812
7813     RegDeleteValueA(props, "ManagedLocalPackage");
7814     delete_key(props, "", access & KEY_WOW64_64KEY);
7815     RegCloseKey(props);
7816     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7817     RegCloseKey(userkey);
7818     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7819     RegCloseKey(prodkey);
7820
7821     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7822
7823     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7824     lstrcatA(keypath, prod_squashed);
7825
7826     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7827     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7828
7829     /* unmanaged product key exists */
7830     hprod = 0xdeadbeef;
7831     r = MsiOpenProductA(prodcode, &hprod);
7832     ok(r == ERROR_UNKNOWN_PRODUCT,
7833        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7834     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7835
7836     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7837     lstrcatA(keypath, "Installer\\UserData\\");
7838     lstrcatA(keypath, usersid);
7839     lstrcatA(keypath, "\\Products\\");
7840     lstrcatA(keypath, prod_squashed);
7841
7842     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7844
7845     /* user product key exists */
7846     hprod = 0xdeadbeef;
7847     r = MsiOpenProductA(prodcode, &hprod);
7848     ok(r == ERROR_UNKNOWN_PRODUCT,
7849        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7850     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7851
7852     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7854
7855     /* InstallProperties key exists */
7856     hprod = 0xdeadbeef;
7857     r = MsiOpenProductA(prodcode, &hprod);
7858     ok(r == ERROR_UNKNOWN_PRODUCT,
7859        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7860     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7861
7862     lstrcpyA(val, path);
7863     lstrcatA(val, "\\winetest.msi");
7864     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7865                          (const BYTE *)val, lstrlenA(val) + 1);
7866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7867
7868     /* LocalPackage value exists */
7869     hprod = 0xdeadbeef;
7870     r = MsiOpenProductA(prodcode, &hprod);
7871     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7872     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7873
7874     size = MAX_PATH;
7875     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7876     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7877     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7878     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7879
7880     MsiCloseHandle(hprod);
7881
7882     RegDeleteValueA(props, "LocalPackage");
7883     delete_key(props, "", access & KEY_WOW64_64KEY);
7884     RegCloseKey(props);
7885     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7886     RegCloseKey(userkey);
7887     RegDeleteKeyA(prodkey, "");
7888     RegCloseKey(prodkey);
7889
7890     /* MSIINSTALLCONTEXT_MACHINE */
7891
7892     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7893     lstrcatA(keypath, prod_squashed);
7894
7895     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7897
7898     /* managed product key exists */
7899     hprod = 0xdeadbeef;
7900     r = MsiOpenProductA(prodcode, &hprod);
7901     ok(r == ERROR_UNKNOWN_PRODUCT,
7902        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7903     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7904
7905     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7906     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7907     lstrcatA(keypath, prod_squashed);
7908
7909     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7911
7912     /* user product key exists */
7913     hprod = 0xdeadbeef;
7914     r = MsiOpenProductA(prodcode, &hprod);
7915     ok(r == ERROR_UNKNOWN_PRODUCT,
7916        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7917     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7918
7919     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7921
7922     /* InstallProperties key exists */
7923     hprod = 0xdeadbeef;
7924     r = MsiOpenProductA(prodcode, &hprod);
7925     ok(r == ERROR_UNKNOWN_PRODUCT,
7926        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7927     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7928
7929     lstrcpyA(val, path);
7930     lstrcatA(val, "\\winetest.msi");
7931     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7932                          (const BYTE *)val, lstrlenA(val) + 1);
7933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7934
7935     /* LocalPackage value exists */
7936     hprod = 0xdeadbeef;
7937     r = MsiOpenProductA(prodcode, &hprod);
7938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7939     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7940
7941     size = MAX_PATH;
7942     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7944     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7945     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7946
7947     MsiCloseHandle(hprod);
7948
7949     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7950                          (const BYTE *)"winetest.msi", 13);
7951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7952
7953     /* LocalPackage has just the package name */
7954     hprod = 0xdeadbeef;
7955     r = MsiOpenProductA(prodcode, &hprod);
7956     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7957     {
7958         skip("Not enough rights to perform tests\n");
7959         goto error;
7960     }
7961     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7962        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7963     if (r == ERROR_SUCCESS)
7964         MsiCloseHandle(hprod);
7965     else
7966         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7967
7968     lstrcpyA(val, path);
7969     lstrcatA(val, "\\winetest.msi");
7970     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7971                          (const BYTE *)val, lstrlenA(val) + 1);
7972     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7973
7974     DeleteFileA(msifile);
7975
7976     /* local package does not exist */
7977     hprod = 0xdeadbeef;
7978     r = MsiOpenProductA(prodcode, &hprod);
7979     ok(r == ERROR_UNKNOWN_PRODUCT,
7980        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7981     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7982
7983 error:
7984     RegDeleteValueA(props, "LocalPackage");
7985     delete_key(props, "", access & KEY_WOW64_64KEY);
7986     RegCloseKey(props);
7987     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7988     RegCloseKey(userkey);
7989     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7990     RegCloseKey(prodkey);
7991
7992     DeleteFileA(msifile);
7993     LocalFree(usersid);
7994 }
7995
7996 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7997 {
7998     MSIINSTALLCONTEXT context;
7999     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8000     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8001     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8002     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8003     HKEY prodkey, patches, udprod, udpatch, hpatch;
8004     DWORD size, data;
8005     LONG res;
8006     UINT r;
8007     REGSAM access = KEY_ALL_ACCESS;
8008
8009     create_test_guid(prodcode, prod_squashed);
8010     create_test_guid(patch, patch_squashed);
8011
8012     if (is_wow64)
8013         access |= KEY_WOW64_64KEY;
8014
8015     /* MSIPATCHSTATE_APPLIED */
8016
8017     lstrcpyA(patchcode, "apple");
8018     lstrcpyA(targetprod, "banana");
8019     context = 0xdeadbeef;
8020     lstrcpyA(targetsid, "kiwi");
8021     size = MAX_PATH;
8022     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8023                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8024                            &context, targetsid, &size);
8025     if (r == ERROR_ACCESS_DENIED)
8026     {
8027         skip("Not enough rights to perform tests\n");
8028         return;
8029     }
8030     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8031     ok(!lstrcmpA(patchcode, "apple"),
8032        "Expected patchcode to be unchanged, got %s\n", patchcode);
8033     ok(!lstrcmpA(targetprod, "banana"),
8034        "Expected targetprod to be unchanged, got %s\n", targetprod);
8035     ok(context == 0xdeadbeef,
8036        "Expected context to be unchanged, got %d\n", context);
8037     ok(!lstrcmpA(targetsid, "kiwi"),
8038        "Expected targetsid to be unchanged, got %s\n", targetsid);
8039     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8040
8041     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8042     lstrcatA(keypath, expectedsid);
8043     lstrcatA(keypath, "\\Installer\\Products\\");
8044     lstrcatA(keypath, prod_squashed);
8045
8046     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8047     if (res == ERROR_ACCESS_DENIED)
8048     {
8049         skip("Not enough rights to perform tests\n");
8050         return;
8051     }
8052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8053
8054     /* managed product key exists */
8055     lstrcpyA(patchcode, "apple");
8056     lstrcpyA(targetprod, "banana");
8057     context = 0xdeadbeef;
8058     lstrcpyA(targetsid, "kiwi");
8059     size = MAX_PATH;
8060     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8061                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8062                            &context, targetsid, &size);
8063     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8064     ok(!lstrcmpA(patchcode, "apple"),
8065        "Expected patchcode to be unchanged, got %s\n", patchcode);
8066     ok(!lstrcmpA(targetprod, "banana"),
8067        "Expected targetprod to be unchanged, got %s\n", targetprod);
8068     ok(context == 0xdeadbeef,
8069        "Expected context to be unchanged, got %d\n", context);
8070     ok(!lstrcmpA(targetsid, "kiwi"),
8071        "Expected targetsid to be unchanged, got %s\n", targetsid);
8072     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8073
8074     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8076
8077     /* patches key exists */
8078     lstrcpyA(patchcode, "apple");
8079     lstrcpyA(targetprod, "banana");
8080     context = 0xdeadbeef;
8081     lstrcpyA(targetsid, "kiwi");
8082     size = MAX_PATH;
8083     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8084                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8085                            &context, targetsid, &size);
8086     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8087     ok(!lstrcmpA(patchcode, "apple"),
8088        "Expected patchcode to be unchanged, got %s\n", patchcode);
8089     ok(!lstrcmpA(targetprod, "banana"),
8090        "Expected targetprod to be unchanged, got %s\n", targetprod);
8091     ok(context == 0xdeadbeef,
8092        "Expected context to be unchanged, got %d\n", context);
8093     ok(!lstrcmpA(targetsid, "kiwi"),
8094        "Expected targetsid to be unchanged, got %s\n", targetsid);
8095     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8096
8097     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8098                          (const BYTE *)patch_squashed,
8099                          lstrlenA(patch_squashed) + 1);
8100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8101
8102     /* Patches value exists, is not REG_MULTI_SZ */
8103     lstrcpyA(patchcode, "apple");
8104     lstrcpyA(targetprod, "banana");
8105     context = 0xdeadbeef;
8106     lstrcpyA(targetsid, "kiwi");
8107     size = MAX_PATH;
8108     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8109                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8110                            &context, targetsid, &size);
8111     ok(r == ERROR_BAD_CONFIGURATION,
8112        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8113     ok(!lstrcmpA(patchcode, "apple"),
8114        "Expected patchcode to be unchanged, got %s\n", patchcode);
8115     ok(!lstrcmpA(targetprod, "banana"),
8116        "Expected targetprod to be unchanged, got %s\n", targetprod);
8117     ok(context == 0xdeadbeef,
8118        "Expected context to be unchanged, got %d\n", context);
8119     ok(!lstrcmpA(targetsid, "kiwi"),
8120        "Expected targetsid to be unchanged, got %s\n", targetsid);
8121     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8122
8123     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8124                          (const BYTE *)"a\0b\0c\0\0", 7);
8125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8126
8127     /* Patches value exists, is not a squashed guid */
8128     lstrcpyA(patchcode, "apple");
8129     lstrcpyA(targetprod, "banana");
8130     context = 0xdeadbeef;
8131     lstrcpyA(targetsid, "kiwi");
8132     size = MAX_PATH;
8133     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8134                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8135                            &context, targetsid, &size);
8136     ok(r == ERROR_BAD_CONFIGURATION,
8137        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8138     ok(!lstrcmpA(patchcode, "apple"),
8139        "Expected patchcode to be unchanged, got %s\n", patchcode);
8140     ok(!lstrcmpA(targetprod, "banana"),
8141        "Expected targetprod to be unchanged, got %s\n", targetprod);
8142     ok(context == 0xdeadbeef,
8143        "Expected context to be unchanged, got %d\n", context);
8144     ok(!lstrcmpA(targetsid, "kiwi"),
8145        "Expected targetsid to be unchanged, got %s\n", targetsid);
8146     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8147
8148     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8149     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8150                          (const BYTE *)patch_squashed,
8151                          lstrlenA(patch_squashed) + 2);
8152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8153
8154     /* Patches value exists */
8155     lstrcpyA(patchcode, "apple");
8156     lstrcpyA(targetprod, "banana");
8157     context = 0xdeadbeef;
8158     lstrcpyA(targetsid, "kiwi");
8159     size = MAX_PATH;
8160     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8161                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8162                            &context, targetsid, &size);
8163     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8164     ok(!lstrcmpA(patchcode, "apple"),
8165        "Expected patchcode to be unchanged, got %s\n", patchcode);
8166     ok(!lstrcmpA(targetprod, "banana"),
8167        "Expected targetprod to be unchanged, got %s\n", targetprod);
8168     ok(context == 0xdeadbeef,
8169        "Expected context to be unchanged, got %d\n", context);
8170     ok(!lstrcmpA(targetsid, "kiwi"),
8171        "Expected targetsid to be unchanged, got %s\n", targetsid);
8172     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8173
8174     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8175                          (const BYTE *)"whatever", 9);
8176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8177
8178     /* patch squashed value exists */
8179     lstrcpyA(patchcode, "apple");
8180     lstrcpyA(targetprod, "banana");
8181     context = 0xdeadbeef;
8182     lstrcpyA(targetsid, "kiwi");
8183     size = MAX_PATH;
8184     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8185                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8186                            &context, targetsid, &size);
8187     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8188     ok(!lstrcmpA(patchcode, patch),
8189        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8190     ok(!lstrcmpA(targetprod, prodcode),
8191        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8192     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8193        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8194     ok(!lstrcmpA(targetsid, expectedsid),
8195        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8196     ok(size == lstrlenA(expectedsid),
8197        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8198
8199     /* increase the index */
8200     lstrcpyA(patchcode, "apple");
8201     lstrcpyA(targetprod, "banana");
8202     context = 0xdeadbeef;
8203     lstrcpyA(targetsid, "kiwi");
8204     size = MAX_PATH;
8205     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8206                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
8207                            &context, targetsid, &size);
8208     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8209     ok(!lstrcmpA(patchcode, "apple"),
8210        "Expected patchcode to be unchanged, got %s\n", patchcode);
8211     ok(!lstrcmpA(targetprod, "banana"),
8212        "Expected targetprod to be unchanged, got %s\n", targetprod);
8213     ok(context == 0xdeadbeef,
8214        "Expected context to be unchanged, got %d\n", context);
8215     ok(!lstrcmpA(targetsid, "kiwi"),
8216        "Expected targetsid to be unchanged, got %s\n", targetsid);
8217     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8218
8219     /* increase again */
8220     lstrcpyA(patchcode, "apple");
8221     lstrcpyA(targetprod, "banana");
8222     context = 0xdeadbeef;
8223     lstrcpyA(targetsid, "kiwi");
8224     size = MAX_PATH;
8225     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8226                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8227                            &context, targetsid, &size);
8228     ok(r == ERROR_INVALID_PARAMETER,
8229        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8230     ok(!lstrcmpA(patchcode, "apple"),
8231        "Expected patchcode to be unchanged, got %s\n", patchcode);
8232     ok(!lstrcmpA(targetprod, "banana"),
8233        "Expected targetprod to be unchanged, got %s\n", targetprod);
8234     ok(context == 0xdeadbeef,
8235        "Expected context to be unchanged, got %d\n", context);
8236     ok(!lstrcmpA(targetsid, "kiwi"),
8237        "Expected targetsid to be unchanged, got %s\n", targetsid);
8238     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8239
8240     /* szPatchCode is NULL */
8241     lstrcpyA(targetprod, "banana");
8242     context = 0xdeadbeef;
8243     lstrcpyA(targetsid, "kiwi");
8244     size = MAX_PATH;
8245     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8246                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8247                            &context, targetsid, &size);
8248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8249     ok(!lstrcmpA(targetprod, prodcode),
8250        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8251     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8252        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8253     ok(!lstrcmpA(targetsid, expectedsid),
8254        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8255     ok(size == lstrlenA(expectedsid),
8256        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8257
8258     /* szTargetProductCode is NULL */
8259     lstrcpyA(patchcode, "apple");
8260     context = 0xdeadbeef;
8261     lstrcpyA(targetsid, "kiwi");
8262     size = MAX_PATH;
8263     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8264                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8265                            &context, targetsid, &size);
8266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8267     ok(!lstrcmpA(patchcode, patch),
8268        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8269     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8270        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8271     ok(!lstrcmpA(targetsid, expectedsid),
8272        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8273     ok(size == lstrlenA(expectedsid),
8274        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8275
8276     /* pdwTargetProductContext is NULL */
8277     lstrcpyA(patchcode, "apple");
8278     lstrcpyA(targetprod, "banana");
8279     lstrcpyA(targetsid, "kiwi");
8280     size = MAX_PATH;
8281     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8282                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8283                            NULL, targetsid, &size);
8284     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8285     ok(!lstrcmpA(patchcode, patch),
8286        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8287     ok(!lstrcmpA(targetprod, prodcode),
8288        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8289     ok(!lstrcmpA(targetsid, expectedsid),
8290        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8291     ok(size == lstrlenA(expectedsid),
8292        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8293
8294     /* szTargetUserSid is NULL */
8295     lstrcpyA(patchcode, "apple");
8296     lstrcpyA(targetprod, "banana");
8297     context = 0xdeadbeef;
8298     size = MAX_PATH;
8299     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8300                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8301                            &context, NULL, &size);
8302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8303     ok(!lstrcmpA(patchcode, patch),
8304        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8305     ok(!lstrcmpA(targetprod, prodcode),
8306        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8307     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8308        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8309     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8310        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8311
8312     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8313     lstrcpyA(patchcode, "apple");
8314     lstrcpyA(targetprod, "banana");
8315     context = 0xdeadbeef;
8316     lstrcpyA(targetsid, "kiwi");
8317     size = lstrlenA(expectedsid);
8318     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8319                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8320                            &context, targetsid, &size);
8321     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8322     ok(!lstrcmpA(patchcode, patch),
8323        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8324     ok(!lstrcmpA(targetprod, prodcode),
8325        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8326     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8327        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8328     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8329        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8330     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8331        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8332
8333     /* pcchTargetUserSid has enough room for NULL terminator */
8334     lstrcpyA(patchcode, "apple");
8335     lstrcpyA(targetprod, "banana");
8336     context = 0xdeadbeef;
8337     lstrcpyA(targetsid, "kiwi");
8338     size = lstrlenA(expectedsid) + 1;
8339     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8340                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8341                            &context, targetsid, &size);
8342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8343     ok(!lstrcmpA(patchcode, patch),
8344        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8345     ok(!lstrcmpA(targetprod, prodcode),
8346        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8347     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8348        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8349     ok(!lstrcmpA(targetsid, expectedsid),
8350        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8351     ok(size == lstrlenA(expectedsid),
8352        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8353
8354     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8355     lstrcpyA(patchcode, "apple");
8356     lstrcpyA(targetprod, "banana");
8357     context = 0xdeadbeef;
8358     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8359                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8360                            &context, NULL, NULL);
8361     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8362     ok(!lstrcmpA(patchcode, patch),
8363        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8364     ok(!lstrcmpA(targetprod, prodcode),
8365        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8366     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8367        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8368
8369     /* MSIPATCHSTATE_SUPERSEDED */
8370
8371     lstrcpyA(patchcode, "apple");
8372     lstrcpyA(targetprod, "banana");
8373     context = 0xdeadbeef;
8374     lstrcpyA(targetsid, "kiwi");
8375     size = MAX_PATH;
8376     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8377                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8378                            &context, targetsid, &size);
8379     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8380     ok(!lstrcmpA(patchcode, "apple"),
8381        "Expected patchcode to be unchanged, got %s\n", patchcode);
8382     ok(!lstrcmpA(targetprod, "banana"),
8383        "Expected targetprod to be unchanged, got %s\n", targetprod);
8384     ok(context == 0xdeadbeef,
8385        "Expected context to be unchanged, got %d\n", context);
8386     ok(!lstrcmpA(targetsid, "kiwi"),
8387        "Expected targetsid to be unchanged, got %s\n", targetsid);
8388     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8389
8390     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8391     lstrcatA(keypath, expectedsid);
8392     lstrcatA(keypath, "\\Products\\");
8393     lstrcatA(keypath, prod_squashed);
8394
8395     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8397
8398     /* UserData product key exists */
8399     lstrcpyA(patchcode, "apple");
8400     lstrcpyA(targetprod, "banana");
8401     context = 0xdeadbeef;
8402     lstrcpyA(targetsid, "kiwi");
8403     size = MAX_PATH;
8404     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8405                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8406                            &context, targetsid, &size);
8407     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8408     ok(!lstrcmpA(patchcode, "apple"),
8409        "Expected patchcode to be unchanged, got %s\n", patchcode);
8410     ok(!lstrcmpA(targetprod, "banana"),
8411        "Expected targetprod to be unchanged, got %s\n", targetprod);
8412     ok(context == 0xdeadbeef,
8413        "Expected context to be unchanged, got %d\n", context);
8414     ok(!lstrcmpA(targetsid, "kiwi"),
8415        "Expected targetsid to be unchanged, got %s\n", targetsid);
8416     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8417
8418     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8420
8421     /* UserData patches key exists */
8422     lstrcpyA(patchcode, "apple");
8423     lstrcpyA(targetprod, "banana");
8424     context = 0xdeadbeef;
8425     lstrcpyA(targetsid, "kiwi");
8426     size = MAX_PATH;
8427     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8428                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8429                            &context, targetsid, &size);
8430     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8431     ok(!lstrcmpA(patchcode, "apple"),
8432        "Expected patchcode to be unchanged, got %s\n", patchcode);
8433     ok(!lstrcmpA(targetprod, "banana"),
8434        "Expected targetprod to be unchanged, got %s\n", targetprod);
8435     ok(context == 0xdeadbeef,
8436        "Expected context to be unchanged, got %d\n", context);
8437     ok(!lstrcmpA(targetsid, "kiwi"),
8438        "Expected targetsid to be unchanged, got %s\n", targetsid);
8439     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8440
8441     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8443
8444     /* specific UserData patch key exists */
8445     lstrcpyA(patchcode, "apple");
8446     lstrcpyA(targetprod, "banana");
8447     context = 0xdeadbeef;
8448     lstrcpyA(targetsid, "kiwi");
8449     size = MAX_PATH;
8450     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8451                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8452                            &context, targetsid, &size);
8453     ok(r == ERROR_BAD_CONFIGURATION,
8454        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8455     ok(!lstrcmpA(patchcode, "apple"),
8456        "Expected patchcode to be unchanged, got %s\n", patchcode);
8457     ok(!lstrcmpA(targetprod, "banana"),
8458        "Expected targetprod to be unchanged, got %s\n", targetprod);
8459     ok(context == 0xdeadbeef,
8460        "Expected context to be unchanged, got %d\n", context);
8461     ok(!lstrcmpA(targetsid, "kiwi"),
8462        "Expected targetsid to be unchanged, got %s\n", targetsid);
8463     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8464
8465     data = MSIPATCHSTATE_SUPERSEDED;
8466     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8467                          (const BYTE *)&data, sizeof(DWORD));
8468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8469
8470     /* State value exists */
8471     lstrcpyA(patchcode, "apple");
8472     lstrcpyA(targetprod, "banana");
8473     context = 0xdeadbeef;
8474     lstrcpyA(targetsid, "kiwi");
8475     size = MAX_PATH;
8476     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8477                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8478                            &context, targetsid, &size);
8479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8480     ok(!lstrcmpA(patchcode, patch),
8481        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8482     ok(!lstrcmpA(targetprod, prodcode),
8483        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8484     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8485        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8486     ok(!lstrcmpA(targetsid, expectedsid),
8487        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8488     ok(size == lstrlenA(expectedsid),
8489        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8490
8491     /* MSIPATCHSTATE_OBSOLETED */
8492
8493     lstrcpyA(patchcode, "apple");
8494     lstrcpyA(targetprod, "banana");
8495     context = 0xdeadbeef;
8496     lstrcpyA(targetsid, "kiwi");
8497     size = MAX_PATH;
8498     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8499                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8500                            &context, targetsid, &size);
8501     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8502     ok(!lstrcmpA(patchcode, "apple"),
8503        "Expected patchcode to be unchanged, got %s\n", patchcode);
8504     ok(!lstrcmpA(targetprod, "banana"),
8505        "Expected targetprod to be unchanged, got %s\n", targetprod);
8506     ok(context == 0xdeadbeef,
8507        "Expected context to be unchanged, got %d\n", context);
8508     ok(!lstrcmpA(targetsid, "kiwi"),
8509        "Expected targetsid to be unchanged, got %s\n", targetsid);
8510     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8511
8512     data = MSIPATCHSTATE_OBSOLETED;
8513     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8514                          (const BYTE *)&data, sizeof(DWORD));
8515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8516
8517     /* State value is obsoleted */
8518     lstrcpyA(patchcode, "apple");
8519     lstrcpyA(targetprod, "banana");
8520     context = 0xdeadbeef;
8521     lstrcpyA(targetsid, "kiwi");
8522     size = MAX_PATH;
8523     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8524                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8525                            &context, targetsid, &size);
8526     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8527     ok(!lstrcmpA(patchcode, patch),
8528        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8529     ok(!lstrcmpA(targetprod, prodcode),
8530        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8531     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8532        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8533     ok(!lstrcmpA(targetsid, expectedsid),
8534        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8535     ok(size == lstrlenA(expectedsid),
8536        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8537
8538     /* MSIPATCHSTATE_REGISTERED */
8539     /* FIXME */
8540
8541     /* MSIPATCHSTATE_ALL */
8542
8543     /* 1st */
8544     lstrcpyA(patchcode, "apple");
8545     lstrcpyA(targetprod, "banana");
8546     context = 0xdeadbeef;
8547     lstrcpyA(targetsid, "kiwi");
8548     size = MAX_PATH;
8549     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8550                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8551                            &context, targetsid, &size);
8552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8553     ok(!lstrcmpA(patchcode, patch),
8554        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8555     ok(!lstrcmpA(targetprod, prodcode),
8556        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8557     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8558        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8559     ok(!lstrcmpA(targetsid, expectedsid),
8560        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8561     ok(size == lstrlenA(expectedsid),
8562        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8563
8564     /* same patch in multiple places, only one is enumerated */
8565     lstrcpyA(patchcode, "apple");
8566     lstrcpyA(targetprod, "banana");
8567     context = 0xdeadbeef;
8568     lstrcpyA(targetsid, "kiwi");
8569     size = MAX_PATH;
8570     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8571                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8572                            &context, targetsid, &size);
8573     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8574     ok(!lstrcmpA(patchcode, "apple"),
8575        "Expected patchcode to be unchanged, got %s\n", patchcode);
8576     ok(!lstrcmpA(targetprod, "banana"),
8577        "Expected targetprod to be unchanged, got %s\n", targetprod);
8578     ok(context == 0xdeadbeef,
8579        "Expected context to be unchanged, got %d\n", context);
8580     ok(!lstrcmpA(targetsid, "kiwi"),
8581        "Expected targetsid to be unchanged, got %s\n", targetsid);
8582     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8583
8584     RegDeleteValueA(hpatch, "State");
8585     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8586     RegCloseKey(hpatch);
8587     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8588     RegCloseKey(udpatch);
8589     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8590     RegCloseKey(udprod);
8591     RegDeleteValueA(patches, "Patches");
8592     delete_key(patches, "", access & KEY_WOW64_64KEY);
8593     RegCloseKey(patches);
8594     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8595     RegCloseKey(prodkey);
8596 }
8597
8598 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8599 {
8600     MSIINSTALLCONTEXT context;
8601     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8602     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8603     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8604     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8605     HKEY prodkey, patches, udprod, udpatch;
8606     HKEY userkey, hpatch;
8607     DWORD size, data;
8608     LONG res;
8609     UINT r;
8610     REGSAM access = KEY_ALL_ACCESS;
8611
8612     create_test_guid(prodcode, prod_squashed);
8613     create_test_guid(patch, patch_squashed);
8614
8615     if (is_wow64)
8616         access |= KEY_WOW64_64KEY;
8617
8618     /* MSIPATCHSTATE_APPLIED */
8619
8620     lstrcpyA(patchcode, "apple");
8621     lstrcpyA(targetprod, "banana");
8622     context = 0xdeadbeef;
8623     lstrcpyA(targetsid, "kiwi");
8624     size = MAX_PATH;
8625     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8626                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8627                            &context, targetsid, &size);
8628     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8629     ok(!lstrcmpA(patchcode, "apple"),
8630        "Expected patchcode to be unchanged, got %s\n", patchcode);
8631     ok(!lstrcmpA(targetprod, "banana"),
8632        "Expected targetprod to be unchanged, got %s\n", targetprod);
8633     ok(context == 0xdeadbeef,
8634        "Expected context to be unchanged, got %d\n", context);
8635     ok(!lstrcmpA(targetsid, "kiwi"),
8636        "Expected targetsid to be unchanged, got %s\n", targetsid);
8637     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8638
8639     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8640     lstrcatA(keypath, prod_squashed);
8641
8642     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8644
8645     /* current user product key exists */
8646     lstrcpyA(patchcode, "apple");
8647     lstrcpyA(targetprod, "banana");
8648     context = 0xdeadbeef;
8649     lstrcpyA(targetsid, "kiwi");
8650     size = MAX_PATH;
8651     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8652                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8653                            &context, targetsid, &size);
8654     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8655     ok(!lstrcmpA(patchcode, "apple"),
8656        "Expected patchcode to be unchanged, got %s\n", patchcode);
8657     ok(!lstrcmpA(targetprod, "banana"),
8658        "Expected targetprod to be unchanged, got %s\n", targetprod);
8659     ok(context == 0xdeadbeef,
8660        "Expected context to be unchanged, got %d\n", context);
8661     ok(!lstrcmpA(targetsid, "kiwi"),
8662        "Expected targetsid to be unchanged, got %s\n", targetsid);
8663     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8664
8665     res = RegCreateKeyA(prodkey, "Patches", &patches);
8666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8667
8668     /* Patches key exists */
8669     lstrcpyA(patchcode, "apple");
8670     lstrcpyA(targetprod, "banana");
8671     context = 0xdeadbeef;
8672     lstrcpyA(targetsid, "kiwi");
8673     size = MAX_PATH;
8674     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8675                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8676                            &context, targetsid, &size);
8677     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8678     ok(!lstrcmpA(patchcode, "apple"),
8679        "Expected patchcode to be unchanged, got %s\n", patchcode);
8680     ok(!lstrcmpA(targetprod, "banana"),
8681        "Expected targetprod to be unchanged, got %s\n", targetprod);
8682     ok(context == 0xdeadbeef,
8683        "Expected context to be unchanged, got %d\n", context);
8684     ok(!lstrcmpA(targetsid, "kiwi"),
8685        "Expected targetsid to be unchanged, got %s\n", targetsid);
8686     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8687
8688     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8689                          (const BYTE *)patch_squashed,
8690                          lstrlenA(patch_squashed) + 1);
8691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8692
8693     /* Patches value exists, is not REG_MULTI_SZ */
8694     lstrcpyA(patchcode, "apple");
8695     lstrcpyA(targetprod, "banana");
8696     context = 0xdeadbeef;
8697     lstrcpyA(targetsid, "kiwi");
8698     size = MAX_PATH;
8699     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8700                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8701                            &context, targetsid, &size);
8702     ok(r == ERROR_BAD_CONFIGURATION,
8703        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8704     ok(!lstrcmpA(patchcode, "apple"),
8705        "Expected patchcode to be unchanged, got %s\n", patchcode);
8706     ok(!lstrcmpA(targetprod, "banana"),
8707        "Expected targetprod to be unchanged, got %s\n", targetprod);
8708     ok(context == 0xdeadbeef,
8709        "Expected context to be unchanged, got %d\n", context);
8710     ok(!lstrcmpA(targetsid, "kiwi"),
8711        "Expected targetsid to be unchanged, got %s\n", targetsid);
8712     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8713
8714     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8715                          (const BYTE *)"a\0b\0c\0\0", 7);
8716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8717
8718     /* Patches value exists, is not a squashed guid */
8719     lstrcpyA(patchcode, "apple");
8720     lstrcpyA(targetprod, "banana");
8721     context = 0xdeadbeef;
8722     lstrcpyA(targetsid, "kiwi");
8723     size = MAX_PATH;
8724     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8725                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8726                            &context, targetsid, &size);
8727     ok(r == ERROR_BAD_CONFIGURATION,
8728        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8729     ok(!lstrcmpA(patchcode, "apple"),
8730        "Expected patchcode to be unchanged, got %s\n", patchcode);
8731     ok(!lstrcmpA(targetprod, "banana"),
8732        "Expected targetprod to be unchanged, got %s\n", targetprod);
8733     ok(context == 0xdeadbeef,
8734        "Expected context to be unchanged, got %d\n", context);
8735     ok(!lstrcmpA(targetsid, "kiwi"),
8736        "Expected targetsid to be unchanged, got %s\n", targetsid);
8737     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8738
8739     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8740     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8741                          (const BYTE *)patch_squashed,
8742                          lstrlenA(patch_squashed) + 2);
8743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8744
8745     /* Patches value exists */
8746     lstrcpyA(patchcode, "apple");
8747     lstrcpyA(targetprod, "banana");
8748     context = 0xdeadbeef;
8749     lstrcpyA(targetsid, "kiwi");
8750     size = MAX_PATH;
8751     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8752                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8753                            &context, targetsid, &size);
8754     ok(r == ERROR_NO_MORE_ITEMS ||
8755        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8756        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8757     ok(!lstrcmpA(patchcode, "apple"),
8758        "Expected patchcode to be unchanged, got %s\n", patchcode);
8759     ok(!lstrcmpA(targetprod, "banana"),
8760        "Expected targetprod to be unchanged, got %s\n", targetprod);
8761     ok(context == 0xdeadbeef,
8762        "Expected context to be unchanged, got %d\n", context);
8763     ok(!lstrcmpA(targetsid, "kiwi"),
8764        "Expected targetsid to be unchanged, got %s\n", targetsid);
8765     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8766
8767     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8768                          (const BYTE *)"whatever", 9);
8769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8770
8771     /* patch code value exists */
8772     lstrcpyA(patchcode, "apple");
8773     lstrcpyA(targetprod, "banana");
8774     context = 0xdeadbeef;
8775     lstrcpyA(targetsid, "kiwi");
8776     size = MAX_PATH;
8777     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8778                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8779                            &context, targetsid, &size);
8780     ok(r == ERROR_NO_MORE_ITEMS ||
8781        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8782        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8783     ok(!lstrcmpA(patchcode, "apple"),
8784        "Expected patchcode to be unchanged, got %s\n", patchcode);
8785     ok(!lstrcmpA(targetprod, "banana"),
8786        "Expected targetprod to be unchanged, got %s\n", targetprod);
8787     ok(context == 0xdeadbeef,
8788        "Expected context to be unchanged, got %d\n", context);
8789     ok(!lstrcmpA(targetsid, "kiwi"),
8790        "Expected targetsid to be unchanged, got %s\n", targetsid);
8791     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8792
8793     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8794     lstrcatA(keypath, expectedsid);
8795     lstrcatA(keypath, "\\Patches\\");
8796     lstrcatA(keypath, patch_squashed);
8797
8798     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8799     if (res == ERROR_ACCESS_DENIED)
8800     {
8801         skip("Not enough rights to perform tests\n");
8802         goto error;
8803     }
8804     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8805
8806     /* userdata patch key exists */
8807     lstrcpyA(patchcode, "apple");
8808     lstrcpyA(targetprod, "banana");
8809     context = 0xdeadbeef;
8810     lstrcpyA(targetsid, "kiwi");
8811     size = MAX_PATH;
8812     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8813                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8814                            &context, targetsid, &size);
8815     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8816     ok(!lstrcmpA(patchcode, patch),
8817        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8818     ok(!lstrcmpA(targetprod, prodcode),
8819        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8820     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8821        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8822     ok(!lstrcmpA(targetsid, expectedsid),
8823        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8824     ok(size == lstrlenA(expectedsid),
8825        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8826
8827     /* MSIPATCHSTATE_SUPERSEDED */
8828
8829     lstrcpyA(patchcode, "apple");
8830     lstrcpyA(targetprod, "banana");
8831     context = 0xdeadbeef;
8832     lstrcpyA(targetsid, "kiwi");
8833     size = MAX_PATH;
8834     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8835                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8836                            &context, targetsid, &size);
8837     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8838     ok(!lstrcmpA(patchcode, "apple"),
8839        "Expected patchcode to be unchanged, got %s\n", patchcode);
8840     ok(!lstrcmpA(targetprod, "banana"),
8841        "Expected targetprod to be unchanged, got %s\n", targetprod);
8842     ok(context == 0xdeadbeef,
8843        "Expected context to be unchanged, got %d\n", context);
8844     ok(!lstrcmpA(targetsid, "kiwi"),
8845        "Expected targetsid to be unchanged, got %s\n", targetsid);
8846     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8847
8848     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8849     lstrcatA(keypath, expectedsid);
8850     lstrcatA(keypath, "\\Products\\");
8851     lstrcatA(keypath, prod_squashed);
8852
8853     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8854     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8855
8856     /* UserData product key exists */
8857     lstrcpyA(patchcode, "apple");
8858     lstrcpyA(targetprod, "banana");
8859     context = 0xdeadbeef;
8860     lstrcpyA(targetsid, "kiwi");
8861     size = MAX_PATH;
8862     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8863                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8864                            &context, targetsid, &size);
8865     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8866     ok(!lstrcmpA(patchcode, "apple"),
8867        "Expected patchcode to be unchanged, got %s\n", patchcode);
8868     ok(!lstrcmpA(targetprod, "banana"),
8869        "Expected targetprod to be unchanged, got %s\n", targetprod);
8870     ok(context == 0xdeadbeef,
8871        "Expected context to be unchanged, got %d\n", context);
8872     ok(!lstrcmpA(targetsid, "kiwi"),
8873        "Expected targetsid to be unchanged, got %s\n", targetsid);
8874     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8875
8876     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8878
8879     /* UserData patches key exists */
8880     lstrcpyA(patchcode, "apple");
8881     lstrcpyA(targetprod, "banana");
8882     context = 0xdeadbeef;
8883     lstrcpyA(targetsid, "kiwi");
8884     size = MAX_PATH;
8885     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8886                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8887                            &context, targetsid, &size);
8888     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8889     ok(!lstrcmpA(patchcode, "apple"),
8890        "Expected patchcode to be unchanged, got %s\n", patchcode);
8891     ok(!lstrcmpA(targetprod, "banana"),
8892        "Expected targetprod to be unchanged, got %s\n", targetprod);
8893     ok(context == 0xdeadbeef,
8894        "Expected context to be unchanged, got %d\n", context);
8895     ok(!lstrcmpA(targetsid, "kiwi"),
8896        "Expected targetsid to be unchanged, got %s\n", targetsid);
8897     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8898
8899     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8901
8902     /* specific UserData patch key exists */
8903     lstrcpyA(patchcode, "apple");
8904     lstrcpyA(targetprod, "banana");
8905     context = 0xdeadbeef;
8906     lstrcpyA(targetsid, "kiwi");
8907     size = MAX_PATH;
8908     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8909                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8910                            &context, targetsid, &size);
8911     ok(r == ERROR_BAD_CONFIGURATION,
8912        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8913     ok(!lstrcmpA(patchcode, "apple"),
8914        "Expected patchcode to be unchanged, got %s\n", patchcode);
8915     ok(!lstrcmpA(targetprod, "banana"),
8916        "Expected targetprod to be unchanged, got %s\n", targetprod);
8917     ok(context == 0xdeadbeef,
8918        "Expected context to be unchanged, got %d\n", context);
8919     ok(!lstrcmpA(targetsid, "kiwi"),
8920        "Expected targetsid to be unchanged, got %s\n", targetsid);
8921     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8922
8923     data = MSIPATCHSTATE_SUPERSEDED;
8924     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8925                          (const BYTE *)&data, sizeof(DWORD));
8926     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8927
8928     /* State value exists */
8929     lstrcpyA(patchcode, "apple");
8930     lstrcpyA(targetprod, "banana");
8931     context = 0xdeadbeef;
8932     lstrcpyA(targetsid, "kiwi");
8933     size = MAX_PATH;
8934     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8935                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8936                            &context, targetsid, &size);
8937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8938     ok(!lstrcmpA(patchcode, patch),
8939        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8940     ok(!lstrcmpA(targetprod, prodcode),
8941        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8942     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8943        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8944     ok(!lstrcmpA(targetsid, expectedsid),
8945        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8946     ok(size == lstrlenA(expectedsid),
8947        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8948
8949     /* MSIPATCHSTATE_OBSOLETED */
8950
8951     lstrcpyA(patchcode, "apple");
8952     lstrcpyA(targetprod, "banana");
8953     context = 0xdeadbeef;
8954     lstrcpyA(targetsid, "kiwi");
8955     size = MAX_PATH;
8956     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8957                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8958                            &context, targetsid, &size);
8959     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8960     ok(!lstrcmpA(patchcode, "apple"),
8961        "Expected patchcode to be unchanged, got %s\n", patchcode);
8962     ok(!lstrcmpA(targetprod, "banana"),
8963        "Expected targetprod to be unchanged, got %s\n", targetprod);
8964     ok(context == 0xdeadbeef,
8965        "Expected context to be unchanged, got %d\n", context);
8966     ok(!lstrcmpA(targetsid, "kiwi"),
8967        "Expected targetsid to be unchanged, got %s\n", targetsid);
8968     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8969
8970     data = MSIPATCHSTATE_OBSOLETED;
8971     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8972                          (const BYTE *)&data, sizeof(DWORD));
8973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8974
8975     /* State value is obsoleted */
8976     lstrcpyA(patchcode, "apple");
8977     lstrcpyA(targetprod, "banana");
8978     context = 0xdeadbeef;
8979     lstrcpyA(targetsid, "kiwi");
8980     size = MAX_PATH;
8981     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8982                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8983                            &context, targetsid, &size);
8984     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8985     ok(!lstrcmpA(patchcode, patch),
8986        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8987     ok(!lstrcmpA(targetprod, prodcode),
8988        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8989     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8990        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8991     ok(!lstrcmpA(targetsid, expectedsid),
8992        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8993     ok(size == lstrlenA(expectedsid),
8994        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8995
8996     /* MSIPATCHSTATE_REGISTERED */
8997     /* FIXME */
8998
8999     /* MSIPATCHSTATE_ALL */
9000
9001     /* 1st */
9002     lstrcpyA(patchcode, "apple");
9003     lstrcpyA(targetprod, "banana");
9004     context = 0xdeadbeef;
9005     lstrcpyA(targetsid, "kiwi");
9006     size = MAX_PATH;
9007     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9008                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9009                            &context, targetsid, &size);
9010     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9011     ok(!lstrcmpA(patchcode, patch),
9012        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9013     ok(!lstrcmpA(targetprod, prodcode),
9014        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9015     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9016        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9017     ok(!lstrcmpA(targetsid, expectedsid),
9018        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9019     ok(size == lstrlenA(expectedsid),
9020        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9021
9022     /* same patch in multiple places, only one is enumerated */
9023     lstrcpyA(patchcode, "apple");
9024     lstrcpyA(targetprod, "banana");
9025     context = 0xdeadbeef;
9026     lstrcpyA(targetsid, "kiwi");
9027     size = MAX_PATH;
9028     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9029                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9030                            &context, targetsid, &size);
9031     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9032     ok(!lstrcmpA(patchcode, "apple"),
9033        "Expected patchcode to be unchanged, got %s\n", patchcode);
9034     ok(!lstrcmpA(targetprod, "banana"),
9035        "Expected targetprod to be unchanged, got %s\n", targetprod);
9036     ok(context == 0xdeadbeef,
9037        "Expected context to be unchanged, got %d\n", context);
9038     ok(!lstrcmpA(targetsid, "kiwi"),
9039        "Expected targetsid to be unchanged, got %s\n", targetsid);
9040     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9041
9042     RegDeleteValueA(hpatch, "State");
9043     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9044     RegCloseKey(hpatch);
9045     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9046     RegCloseKey(udpatch);
9047     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9048     RegCloseKey(udprod);
9049     delete_key(userkey, "", access & KEY_WOW64_64KEY);
9050     RegCloseKey(userkey);
9051     RegDeleteValueA(patches, patch_squashed);
9052     RegDeleteValueA(patches, "Patches");
9053
9054 error:
9055     RegDeleteKeyA(patches, "");
9056     RegCloseKey(patches);
9057     RegDeleteKeyA(prodkey, "");
9058     RegCloseKey(prodkey);
9059 }
9060
9061 static void test_MsiEnumPatchesEx_machine(void)
9062 {
9063     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9064     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9065     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9066     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9067     HKEY prodkey, patches, udprod, udpatch;
9068     HKEY hpatch;
9069     MSIINSTALLCONTEXT context;
9070     DWORD size, data;
9071     LONG res;
9072     UINT r;
9073     REGSAM access = KEY_ALL_ACCESS;
9074
9075     create_test_guid(prodcode, prod_squashed);
9076     create_test_guid(patch, patch_squashed);
9077
9078     if (is_wow64)
9079         access |= KEY_WOW64_64KEY;
9080
9081     /* MSIPATCHSTATE_APPLIED */
9082
9083     lstrcpyA(patchcode, "apple");
9084     lstrcpyA(targetprod, "banana");
9085     context = 0xdeadbeef;
9086     lstrcpyA(targetsid, "kiwi");
9087     size = MAX_PATH;
9088     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9089                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9090                            &context, targetsid, &size);
9091     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9092     ok(!lstrcmpA(patchcode, "apple"),
9093        "Expected patchcode to be unchanged, got %s\n", patchcode);
9094     ok(!lstrcmpA(targetprod, "banana"),
9095        "Expected targetprod to be unchanged, got %s\n", targetprod);
9096     ok(context == 0xdeadbeef,
9097        "Expected context to be unchanged, got %d\n", context);
9098     ok(!lstrcmpA(targetsid, "kiwi"),
9099        "Expected targetsid to be unchanged, got %s\n", targetsid);
9100     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9101
9102     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9103     lstrcatA(keypath, prod_squashed);
9104
9105     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9106     if (res == ERROR_ACCESS_DENIED)
9107     {
9108         skip("Not enough rights to perform tests\n");
9109         return;
9110     }
9111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9112
9113     /* local product key exists */
9114     lstrcpyA(patchcode, "apple");
9115     lstrcpyA(targetprod, "banana");
9116     context = 0xdeadbeef;
9117     lstrcpyA(targetsid, "kiwi");
9118     size = MAX_PATH;
9119     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9120                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9121                            &context, targetsid, &size);
9122     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9123     ok(!lstrcmpA(patchcode, "apple"),
9124        "Expected patchcode to be unchanged, got %s\n", patchcode);
9125     ok(!lstrcmpA(targetprod, "banana"),
9126        "Expected targetprod to be unchanged, got %s\n", targetprod);
9127     ok(context == 0xdeadbeef,
9128        "Expected context to be unchanged, got %d\n", context);
9129     ok(!lstrcmpA(targetsid, "kiwi"),
9130        "Expected targetsid to be unchanged, got %s\n", targetsid);
9131     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9132
9133     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9135
9136     /* Patches key exists */
9137     lstrcpyA(patchcode, "apple");
9138     lstrcpyA(targetprod, "banana");
9139     context = 0xdeadbeef;
9140     lstrcpyA(targetsid, "kiwi");
9141     size = MAX_PATH;
9142     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9143                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9144                            &context, targetsid, &size);
9145     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9146     ok(!lstrcmpA(patchcode, "apple"),
9147        "Expected patchcode to be unchanged, got %s\n", patchcode);
9148     ok(!lstrcmpA(targetprod, "banana"),
9149        "Expected targetprod to be unchanged, got %s\n", targetprod);
9150     ok(context == 0xdeadbeef,
9151        "Expected context to be unchanged, got %d\n", context);
9152     ok(!lstrcmpA(targetsid, "kiwi"),
9153        "Expected targetsid to be unchanged, got %s\n", targetsid);
9154     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9155
9156     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9157                          (const BYTE *)patch_squashed,
9158                          lstrlenA(patch_squashed) + 1);
9159     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9160
9161     /* Patches value exists, is not REG_MULTI_SZ */
9162     lstrcpyA(patchcode, "apple");
9163     lstrcpyA(targetprod, "banana");
9164     context = 0xdeadbeef;
9165     lstrcpyA(targetsid, "kiwi");
9166     size = MAX_PATH;
9167     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9168                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9169                            &context, targetsid, &size);
9170     ok(r == ERROR_BAD_CONFIGURATION,
9171        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9172     ok(!lstrcmpA(patchcode, "apple"),
9173        "Expected patchcode to be unchanged, got %s\n", patchcode);
9174     ok(!lstrcmpA(targetprod, "banana"),
9175        "Expected targetprod to be unchanged, got %s\n", targetprod);
9176     ok(context == 0xdeadbeef,
9177        "Expected context to be unchanged, got %d\n", context);
9178     ok(!lstrcmpA(targetsid, "kiwi"),
9179        "Expected targetsid to be unchanged, got %s\n", targetsid);
9180     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9181
9182     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9183                          (const BYTE *)"a\0b\0c\0\0", 7);
9184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9185
9186     /* Patches value exists, is not a squashed guid */
9187     lstrcpyA(patchcode, "apple");
9188     lstrcpyA(targetprod, "banana");
9189     context = 0xdeadbeef;
9190     lstrcpyA(targetsid, "kiwi");
9191     size = MAX_PATH;
9192     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9193                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9194                            &context, targetsid, &size);
9195     ok(r == ERROR_BAD_CONFIGURATION,
9196        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9197     ok(!lstrcmpA(patchcode, "apple"),
9198        "Expected patchcode to be unchanged, got %s\n", patchcode);
9199     ok(!lstrcmpA(targetprod, "banana"),
9200        "Expected targetprod to be unchanged, got %s\n", targetprod);
9201     ok(context == 0xdeadbeef,
9202        "Expected context to be unchanged, got %d\n", context);
9203     ok(!lstrcmpA(targetsid, "kiwi"),
9204        "Expected targetsid to be unchanged, got %s\n", targetsid);
9205     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9206
9207     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9208     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9209                          (const BYTE *)patch_squashed,
9210                          lstrlenA(patch_squashed) + 2);
9211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9212
9213     /* Patches value exists */
9214     lstrcpyA(patchcode, "apple");
9215     lstrcpyA(targetprod, "banana");
9216     context = 0xdeadbeef;
9217     lstrcpyA(targetsid, "kiwi");
9218     size = MAX_PATH;
9219     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9220                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9221                            &context, targetsid, &size);
9222     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9223     ok(!lstrcmpA(patchcode, "apple"),
9224        "Expected patchcode to be unchanged, got %s\n", patchcode);
9225     ok(!lstrcmpA(targetprod, "banana"),
9226        "Expected targetprod to be unchanged, got %s\n", targetprod);
9227     ok(context == 0xdeadbeef,
9228        "Expected context to be unchanged, got %d\n", context);
9229     ok(!lstrcmpA(targetsid, "kiwi"),
9230        "Expected targetsid to be unchanged, got %s\n", targetsid);
9231     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9232
9233     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9234                          (const BYTE *)"whatever", 9);
9235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9236
9237     /* patch code value exists */
9238     lstrcpyA(patchcode, "apple");
9239     lstrcpyA(targetprod, "banana");
9240     context = 0xdeadbeef;
9241     lstrcpyA(targetsid, "kiwi");
9242     size = MAX_PATH;
9243     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9244                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9245                            &context, targetsid, &size);
9246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9247     ok(!lstrcmpA(patchcode, patch),
9248        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9249     ok(!lstrcmpA(targetprod, prodcode),
9250        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9251     ok(context == MSIINSTALLCONTEXT_MACHINE,
9252        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9253     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9254     ok(size == 0, "Expected 0, got %d\n", size);
9255
9256     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9257     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9258     lstrcatA(keypath, prod_squashed);
9259
9260     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9262
9263     /* local UserData product key exists */
9264     lstrcpyA(patchcode, "apple");
9265     lstrcpyA(targetprod, "banana");
9266     context = 0xdeadbeef;
9267     lstrcpyA(targetsid, "kiwi");
9268     size = MAX_PATH;
9269     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9270                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9271                            &context, targetsid, &size);
9272     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9273     ok(!lstrcmpA(patchcode, patch),
9274        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9275     ok(!lstrcmpA(targetprod, prodcode),
9276        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9277     ok(context == MSIINSTALLCONTEXT_MACHINE,
9278        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9279     ok(!lstrcmpA(targetsid, ""),
9280        "Expected \"\", got \"%s\"\n", targetsid);
9281     ok(size == 0, "Expected 0, got %d\n", size);
9282
9283     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9285
9286     /* local UserData Patches key exists */
9287     lstrcpyA(patchcode, "apple");
9288     lstrcpyA(targetprod, "banana");
9289     context = 0xdeadbeef;
9290     lstrcpyA(targetsid, "kiwi");
9291     size = MAX_PATH;
9292     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9293                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9294                            &context, targetsid, &size);
9295     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9296     ok(!lstrcmpA(patchcode, patch),
9297        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9298     ok(!lstrcmpA(targetprod, prodcode),
9299        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9300     ok(context == MSIINSTALLCONTEXT_MACHINE,
9301        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9302     ok(!lstrcmpA(targetsid, ""),
9303        "Expected \"\", got \"%s\"\n", targetsid);
9304     ok(size == 0, "Expected 0, got %d\n", size);
9305
9306     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9308
9309     /* local UserData Product patch key exists */
9310     lstrcpyA(patchcode, "apple");
9311     lstrcpyA(targetprod, "banana");
9312     context = 0xdeadbeef;
9313     lstrcpyA(targetsid, "kiwi");
9314     size = MAX_PATH;
9315     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9316                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9317                            &context, targetsid, &size);
9318     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9319     ok(!lstrcmpA(patchcode, "apple"),
9320        "Expected patchcode to be unchanged, got %s\n", patchcode);
9321     ok(!lstrcmpA(targetprod, "banana"),
9322        "Expected targetprod to be unchanged, got %s\n", targetprod);
9323     ok(context == 0xdeadbeef,
9324        "Expected context to be unchanged, got %d\n", context);
9325     ok(!lstrcmpA(targetsid, "kiwi"),
9326        "Expected targetsid to be unchanged, got %s\n", targetsid);
9327     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9328
9329     data = MSIPATCHSTATE_APPLIED;
9330     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9331                          (const BYTE *)&data, sizeof(DWORD));
9332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9333
9334     /* State value exists */
9335     lstrcpyA(patchcode, "apple");
9336     lstrcpyA(targetprod, "banana");
9337     context = 0xdeadbeef;
9338     lstrcpyA(targetsid, "kiwi");
9339     size = MAX_PATH;
9340     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9341                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9342                            &context, targetsid, &size);
9343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9344     ok(!lstrcmpA(patchcode, patch),
9345        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9346     ok(!lstrcmpA(targetprod, prodcode),
9347        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9348     ok(context == MSIINSTALLCONTEXT_MACHINE,
9349        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9350     ok(!lstrcmpA(targetsid, ""),
9351        "Expected \"\", got \"%s\"\n", targetsid);
9352     ok(size == 0, "Expected 0, got %d\n", size);
9353
9354     /* MSIPATCHSTATE_SUPERSEDED */
9355
9356     lstrcpyA(patchcode, "apple");
9357     lstrcpyA(targetprod, "banana");
9358     context = 0xdeadbeef;
9359     lstrcpyA(targetsid, "kiwi");
9360     size = MAX_PATH;
9361     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9362                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9363                            &context, targetsid, &size);
9364     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9365     ok(!lstrcmpA(patchcode, "apple"),
9366        "Expected patchcode to be unchanged, got %s\n", patchcode);
9367     ok(!lstrcmpA(targetprod, "banana"),
9368        "Expected targetprod to be unchanged, got %s\n", targetprod);
9369     ok(context == 0xdeadbeef,
9370        "Expected context to be unchanged, got %d\n", context);
9371     ok(!lstrcmpA(targetsid, "kiwi"),
9372        "Expected targetsid to be unchanged, got %s\n", targetsid);
9373     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9374
9375     data = MSIPATCHSTATE_SUPERSEDED;
9376     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9377                          (const BYTE *)&data, sizeof(DWORD));
9378     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9379
9380     /* State value is MSIPATCHSTATE_SUPERSEDED */
9381     lstrcpyA(patchcode, "apple");
9382     lstrcpyA(targetprod, "banana");
9383     context = 0xdeadbeef;
9384     lstrcpyA(targetsid, "kiwi");
9385     size = MAX_PATH;
9386     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9387                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9388                            &context, targetsid, &size);
9389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9390     ok(!lstrcmpA(patchcode, patch),
9391        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9392     ok(!lstrcmpA(targetprod, prodcode),
9393        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9394     ok(context == MSIINSTALLCONTEXT_MACHINE,
9395        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9396     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9397     ok(size == 0, "Expected 0, got %d\n", size);
9398
9399     /* MSIPATCHSTATE_OBSOLETED */
9400
9401     lstrcpyA(patchcode, "apple");
9402     lstrcpyA(targetprod, "banana");
9403     context = 0xdeadbeef;
9404     lstrcpyA(targetsid, "kiwi");
9405     size = MAX_PATH;
9406     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9407                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9408                            &context, targetsid, &size);
9409     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9410     ok(!lstrcmpA(patchcode, "apple"),
9411        "Expected patchcode to be unchanged, got %s\n", patchcode);
9412     ok(!lstrcmpA(targetprod, "banana"),
9413        "Expected targetprod to be unchanged, got %s\n", targetprod);
9414     ok(context == 0xdeadbeef,
9415        "Expected context to be unchanged, got %d\n", context);
9416     ok(!lstrcmpA(targetsid, "kiwi"),
9417        "Expected targetsid to be unchanged, got %s\n", targetsid);
9418     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9419
9420     data = MSIPATCHSTATE_OBSOLETED;
9421     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9422                          (const BYTE *)&data, sizeof(DWORD));
9423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9424
9425     /* State value is obsoleted */
9426     lstrcpyA(patchcode, "apple");
9427     lstrcpyA(targetprod, "banana");
9428     context = 0xdeadbeef;
9429     lstrcpyA(targetsid, "kiwi");
9430     size = MAX_PATH;
9431     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9432                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9433                            &context, targetsid, &size);
9434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9435     ok(!lstrcmpA(patchcode, patch),
9436        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9437     ok(!lstrcmpA(targetprod, prodcode),
9438        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9439     ok(context == MSIINSTALLCONTEXT_MACHINE,
9440        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9441     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9442     ok(size == 0, "Expected 0, got %d\n", size);
9443
9444     /* MSIPATCHSTATE_REGISTERED */
9445     /* FIXME */
9446
9447     /* MSIPATCHSTATE_ALL */
9448
9449     /* 1st */
9450     lstrcpyA(patchcode, "apple");
9451     lstrcpyA(targetprod, "banana");
9452     context = 0xdeadbeef;
9453     lstrcpyA(targetsid, "kiwi");
9454     size = MAX_PATH;
9455     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9456                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9457                            &context, targetsid, &size);
9458     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9459     ok(!lstrcmpA(patchcode, patch),
9460        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9461     ok(!lstrcmpA(targetprod, prodcode),
9462        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9463     ok(context == MSIINSTALLCONTEXT_MACHINE,
9464        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9465     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9466     ok(size == 0, "Expected 0, got %d\n", size);
9467
9468     /* same patch in multiple places, only one is enumerated */
9469     lstrcpyA(patchcode, "apple");
9470     lstrcpyA(targetprod, "banana");
9471     context = 0xdeadbeef;
9472     lstrcpyA(targetsid, "kiwi");
9473     size = MAX_PATH;
9474     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9475                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9476                            &context, targetsid, &size);
9477     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9478     ok(!lstrcmpA(patchcode, "apple"),
9479        "Expected patchcode to be unchanged, got %s\n", patchcode);
9480     ok(!lstrcmpA(targetprod, "banana"),
9481        "Expected targetprod to be unchanged, got %s\n", targetprod);
9482     ok(context == 0xdeadbeef,
9483        "Expected context to be unchanged, got %d\n", context);
9484     ok(!lstrcmpA(targetsid, "kiwi"),
9485        "Expected targetsid to be unchanged, got %s\n", targetsid);
9486     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9487
9488     RegDeleteValueA(patches, patch_squashed);
9489     RegDeleteValueA(patches, "Patches");
9490     delete_key(patches, "", access & KEY_WOW64_64KEY);
9491     RegCloseKey(patches);
9492     RegDeleteValueA(hpatch, "State");
9493     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9494     RegCloseKey(hpatch);
9495     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9496     RegCloseKey(udpatch);
9497     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9498     RegCloseKey(udprod);
9499     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9500     RegCloseKey(prodkey);
9501 }
9502
9503 static void test_MsiEnumPatchesEx(void)
9504 {
9505     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9506     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9507     CHAR patchcode[MAX_PATH];
9508     MSIINSTALLCONTEXT context;
9509     LPSTR usersid;
9510     DWORD size;
9511     UINT r;
9512
9513     if (!pMsiEnumPatchesExA)
9514     {
9515         win_skip("MsiEnumPatchesExA not implemented\n");
9516         return;
9517     }
9518
9519     create_test_guid(prodcode, prod_squashed);
9520     get_user_sid(&usersid);
9521
9522     /* empty szProductCode */
9523     lstrcpyA(patchcode, "apple");
9524     lstrcpyA(targetprod, "banana");
9525     context = 0xdeadbeef;
9526     lstrcpyA(targetsid, "kiwi");
9527     size = MAX_PATH;
9528     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9529                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9530                            targetsid, &size);
9531     ok(r == ERROR_INVALID_PARAMETER,
9532        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9533     ok(!lstrcmpA(patchcode, "apple"),
9534        "Expected patchcode to be unchanged, got %s\n", patchcode);
9535     ok(!lstrcmpA(targetprod, "banana"),
9536        "Expected targetprod to be unchanged, got %s\n", targetprod);
9537     ok(context == 0xdeadbeef,
9538        "Expected context to be unchanged, got %d\n", context);
9539     ok(!lstrcmpA(targetsid, "kiwi"),
9540        "Expected targetsid to be unchanged, got %s\n", targetsid);
9541     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9542
9543     /* garbage szProductCode */
9544     lstrcpyA(patchcode, "apple");
9545     lstrcpyA(targetprod, "banana");
9546     context = 0xdeadbeef;
9547     lstrcpyA(targetsid, "kiwi");
9548     size = MAX_PATH;
9549     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9550                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9551                            targetsid, &size);
9552     ok(r == ERROR_INVALID_PARAMETER,
9553        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9554     ok(!lstrcmpA(patchcode, "apple"),
9555        "Expected patchcode to be unchanged, got %s\n", patchcode);
9556     ok(!lstrcmpA(targetprod, "banana"),
9557        "Expected targetprod to be unchanged, got %s\n", targetprod);
9558     ok(context == 0xdeadbeef,
9559        "Expected context to be unchanged, got %d\n", context);
9560     ok(!lstrcmpA(targetsid, "kiwi"),
9561        "Expected targetsid to be unchanged, got %s\n", targetsid);
9562     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9563
9564     /* guid without brackets */
9565     lstrcpyA(patchcode, "apple");
9566     lstrcpyA(targetprod, "banana");
9567     context = 0xdeadbeef;
9568     lstrcpyA(targetsid, "kiwi");
9569     size = MAX_PATH;
9570     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9571                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9572                            0, patchcode, targetprod, &context,
9573                            targetsid, &size);
9574     ok(r == ERROR_INVALID_PARAMETER,
9575        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9576     ok(!lstrcmpA(patchcode, "apple"),
9577        "Expected patchcode to be unchanged, got %s\n", patchcode);
9578     ok(!lstrcmpA(targetprod, "banana"),
9579        "Expected targetprod to be unchanged, got %s\n", targetprod);
9580     ok(context == 0xdeadbeef,
9581        "Expected context to be unchanged, got %d\n", context);
9582     ok(!lstrcmpA(targetsid, "kiwi"),
9583        "Expected targetsid to be unchanged, got %s\n", targetsid);
9584     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9585
9586     /* guid with brackets */
9587     lstrcpyA(patchcode, "apple");
9588     lstrcpyA(targetprod, "banana");
9589     context = 0xdeadbeef;
9590     lstrcpyA(targetsid, "kiwi");
9591     size = MAX_PATH;
9592     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9593                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9594                            0, patchcode, targetprod, &context,
9595                            targetsid, &size);
9596     ok(r == ERROR_NO_MORE_ITEMS,
9597        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9598     ok(!lstrcmpA(patchcode, "apple"),
9599        "Expected patchcode to be unchanged, got %s\n", patchcode);
9600     ok(!lstrcmpA(targetprod, "banana"),
9601        "Expected targetprod to be unchanged, got %s\n", targetprod);
9602     ok(context == 0xdeadbeef,
9603        "Expected context to be unchanged, got %d\n", context);
9604     ok(!lstrcmpA(targetsid, "kiwi"),
9605        "Expected targetsid to be unchanged, got %s\n", targetsid);
9606     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9607
9608     /* szUserSid is S-1-5-18 */
9609     lstrcpyA(patchcode, "apple");
9610     lstrcpyA(targetprod, "banana");
9611     context = 0xdeadbeef;
9612     lstrcpyA(targetsid, "kiwi");
9613     size = MAX_PATH;
9614     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9615                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9616                            0, patchcode, targetprod, &context,
9617                            targetsid, &size);
9618     ok(r == ERROR_INVALID_PARAMETER,
9619        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9620     ok(!lstrcmpA(patchcode, "apple"),
9621        "Expected patchcode to be unchanged, got %s\n", patchcode);
9622     ok(!lstrcmpA(targetprod, "banana"),
9623        "Expected targetprod to be unchanged, got %s\n", targetprod);
9624     ok(context == 0xdeadbeef,
9625        "Expected context to be unchanged, got %d\n", context);
9626     ok(!lstrcmpA(targetsid, "kiwi"),
9627        "Expected targetsid to be unchanged, got %s\n", targetsid);
9628     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9629
9630     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9631     lstrcpyA(patchcode, "apple");
9632     lstrcpyA(targetprod, "banana");
9633     context = 0xdeadbeef;
9634     lstrcpyA(targetsid, "kiwi");
9635     size = MAX_PATH;
9636     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9637                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9638                            &context, targetsid, &size);
9639     ok(r == ERROR_INVALID_PARAMETER,
9640        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9641     ok(!lstrcmpA(patchcode, "apple"),
9642        "Expected patchcode to be unchanged, got %s\n", patchcode);
9643     ok(!lstrcmpA(targetprod, "banana"),
9644        "Expected targetprod to be unchanged, got %s\n", targetprod);
9645     ok(context == 0xdeadbeef,
9646        "Expected context to be unchanged, got %d\n", context);
9647     ok(!lstrcmpA(targetsid, "kiwi"),
9648        "Expected targetsid to be unchanged, got %s\n", targetsid);
9649     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9650
9651     /* dwContext is out of bounds */
9652     lstrcpyA(patchcode, "apple");
9653     lstrcpyA(targetprod, "banana");
9654     context = 0xdeadbeef;
9655     lstrcpyA(targetsid, "kiwi");
9656     size = MAX_PATH;
9657     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9658                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9659                            &context, targetsid, &size);
9660     ok(r == ERROR_INVALID_PARAMETER,
9661        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9662     ok(!lstrcmpA(patchcode, "apple"),
9663        "Expected patchcode to be unchanged, got %s\n", patchcode);
9664     ok(!lstrcmpA(targetprod, "banana"),
9665        "Expected targetprod to be unchanged, got %s\n", targetprod);
9666     ok(context == 0xdeadbeef,
9667        "Expected context to be unchanged, got %d\n", context);
9668     ok(!lstrcmpA(targetsid, "kiwi"),
9669        "Expected targetsid to be unchanged, got %s\n", targetsid);
9670     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9671
9672     /* dwContext is out of bounds */
9673     lstrcpyA(patchcode, "apple");
9674     lstrcpyA(targetprod, "banana");
9675     context = 0xdeadbeef;
9676     lstrcpyA(targetsid, "kiwi");
9677     size = MAX_PATH;
9678     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9679                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9680                            &context, targetsid, &size);
9681     ok(r == ERROR_INVALID_PARAMETER,
9682        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9683     ok(!lstrcmpA(patchcode, "apple"),
9684        "Expected patchcode to be unchanged, got %s\n", patchcode);
9685     ok(!lstrcmpA(targetprod, "banana"),
9686        "Expected targetprod to be unchanged, got %s\n", targetprod);
9687     ok(context == 0xdeadbeef,
9688        "Expected context to be unchanged, got %d\n", context);
9689     ok(!lstrcmpA(targetsid, "kiwi"),
9690        "Expected targetsid to be unchanged, got %s\n", targetsid);
9691     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9692
9693     /* dwFilter is out of bounds */
9694     lstrcpyA(patchcode, "apple");
9695     lstrcpyA(targetprod, "banana");
9696     context = 0xdeadbeef;
9697     lstrcpyA(targetsid, "kiwi");
9698     size = MAX_PATH;
9699     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9700                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9701                            &context, targetsid, &size);
9702     ok(r == ERROR_INVALID_PARAMETER,
9703        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9704     ok(!lstrcmpA(patchcode, "apple"),
9705        "Expected patchcode to be unchanged, got %s\n", patchcode);
9706     ok(!lstrcmpA(targetprod, "banana"),
9707        "Expected targetprod to be unchanged, got %s\n", targetprod);
9708     ok(context == 0xdeadbeef,
9709        "Expected context to be unchanged, got %d\n", context);
9710     ok(!lstrcmpA(targetsid, "kiwi"),
9711        "Expected targetsid to be unchanged, got %s\n", targetsid);
9712     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9713
9714     /* dwFilter is out of bounds */
9715     lstrcpyA(patchcode, "apple");
9716     lstrcpyA(targetprod, "banana");
9717     context = 0xdeadbeef;
9718     lstrcpyA(targetsid, "kiwi");
9719     size = MAX_PATH;
9720     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9721                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9722                            &context, targetsid, &size);
9723     ok(r == ERROR_INVALID_PARAMETER,
9724        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9725     ok(!lstrcmpA(patchcode, "apple"),
9726        "Expected patchcode to be unchanged, got %s\n", patchcode);
9727     ok(!lstrcmpA(targetprod, "banana"),
9728        "Expected targetprod to be unchanged, got %s\n", targetprod);
9729     ok(context == 0xdeadbeef,
9730        "Expected context to be unchanged, got %d\n", context);
9731     ok(!lstrcmpA(targetsid, "kiwi"),
9732        "Expected targetsid to be unchanged, got %s\n", targetsid);
9733     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9734
9735     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9736     lstrcpyA(patchcode, "apple");
9737     lstrcpyA(targetprod, "banana");
9738     context = 0xdeadbeef;
9739     lstrcpyA(targetsid, "kiwi");
9740     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9741                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9742                            &context, targetsid, NULL);
9743     ok(r == ERROR_INVALID_PARAMETER,
9744        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9745     ok(!lstrcmpA(patchcode, "apple"),
9746        "Expected patchcode to be unchanged, got %s\n", patchcode);
9747     ok(!lstrcmpA(targetprod, "banana"),
9748        "Expected targetprod to be unchanged, got %s\n", targetprod);
9749     ok(context == 0xdeadbeef,
9750        "Expected context to be unchanged, got %d\n", context);
9751     ok(!lstrcmpA(targetsid, "kiwi"),
9752        "Expected targetsid to be unchanged, got %s\n", targetsid);
9753
9754     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9755     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9756     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9757     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9758     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9759     /* FIXME: Successfully test userunmanaged with a different user */
9760     test_MsiEnumPatchesEx_machine();
9761     LocalFree(usersid);
9762 }
9763
9764 static void test_MsiEnumPatches(void)
9765 {
9766     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9767     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9768     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9769     CHAR transforms[MAX_PATH];
9770     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9771     HKEY prodkey, patches, udprod;
9772     HKEY userkey, hpatch, udpatch;
9773     DWORD size, data;
9774     LPSTR usersid;
9775     LONG res;
9776     UINT r;
9777     REGSAM access = KEY_ALL_ACCESS;
9778
9779     create_test_guid(prodcode, prod_squashed);
9780     create_test_guid(patchcode, patch_squashed);
9781     get_user_sid(&usersid);
9782
9783     if (is_wow64)
9784         access |= KEY_WOW64_64KEY;
9785
9786     /* NULL szProduct */
9787     size = MAX_PATH;
9788     lstrcpyA(patch, "apple");
9789     lstrcpyA(transforms, "banana");
9790     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9791     ok(r == ERROR_INVALID_PARAMETER,
9792        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9793     ok(!lstrcmpA(patch, "apple"),
9794        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9795     ok(!lstrcmpA(transforms, "banana"),
9796        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9797     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9798
9799     /* empty szProduct */
9800     size = MAX_PATH;
9801     lstrcpyA(patch, "apple");
9802     lstrcpyA(transforms, "banana");
9803     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9804     ok(r == ERROR_INVALID_PARAMETER,
9805        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9806     ok(!lstrcmpA(patch, "apple"),
9807        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9808     ok(!lstrcmpA(transforms, "banana"),
9809        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9810     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9811
9812     /* garbage szProduct */
9813     size = MAX_PATH;
9814     lstrcpyA(patch, "apple");
9815     lstrcpyA(transforms, "banana");
9816     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9817     ok(r == ERROR_INVALID_PARAMETER,
9818        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9819     ok(!lstrcmpA(patch, "apple"),
9820        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9821     ok(!lstrcmpA(transforms, "banana"),
9822        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9823     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9824
9825     /* guid without brackets */
9826     size = MAX_PATH;
9827     lstrcpyA(patch, "apple");
9828     lstrcpyA(transforms, "banana");
9829     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9830                         transforms, &size);
9831     ok(r == ERROR_INVALID_PARAMETER,
9832        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9833     ok(!lstrcmpA(patch, "apple"),
9834        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9835     ok(!lstrcmpA(transforms, "banana"),
9836        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9837     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9838
9839     /* guid with brackets */
9840     size = MAX_PATH;
9841     lstrcpyA(patch, "apple");
9842     lstrcpyA(transforms, "banana");
9843     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9844                         transforms, &size);
9845     ok(r == ERROR_UNKNOWN_PRODUCT,
9846        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9847     ok(!lstrcmpA(patch, "apple"),
9848        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9849     ok(!lstrcmpA(transforms, "banana"),
9850        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9851     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9852
9853     /* same length as guid, but random */
9854     size = MAX_PATH;
9855     lstrcpyA(patch, "apple");
9856     lstrcpyA(transforms, "banana");
9857     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9858                         transforms, &size);
9859     ok(r == ERROR_INVALID_PARAMETER,
9860        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9861     ok(!lstrcmpA(patch, "apple"),
9862        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9863     ok(!lstrcmpA(transforms, "banana"),
9864        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9865     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9866
9867     /* MSIINSTALLCONTEXT_USERMANAGED */
9868
9869     size = MAX_PATH;
9870     lstrcpyA(patch, "apple");
9871     lstrcpyA(transforms, "banana");
9872     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9873     ok(r == ERROR_UNKNOWN_PRODUCT,
9874        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9875     ok(!lstrcmpA(patch, "apple"),
9876        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9877     ok(!lstrcmpA(transforms, "banana"),
9878        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9879     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9880
9881     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9882     lstrcatA(keypath, usersid);
9883     lstrcatA(keypath, "\\Installer\\Products\\");
9884     lstrcatA(keypath, prod_squashed);
9885
9886     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9887     if (res == ERROR_ACCESS_DENIED)
9888     {
9889         skip("Not enough rights to perform tests\n");
9890         LocalFree(usersid);
9891         return;
9892     }
9893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9894
9895     /* managed product key exists */
9896     size = MAX_PATH;
9897     lstrcpyA(patch, "apple");
9898     lstrcpyA(transforms, "banana");
9899     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9900     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9901     ok(!lstrcmpA(patch, "apple"),
9902        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9903     ok(!lstrcmpA(transforms, "banana"),
9904        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9905     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9906
9907     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9909
9910     /* patches key exists */
9911     size = MAX_PATH;
9912     lstrcpyA(patch, "apple");
9913     lstrcpyA(transforms, "banana");
9914     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9915     ok(r == ERROR_NO_MORE_ITEMS ||
9916        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9917        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9918     ok(!lstrcmpA(patch, "apple"),
9919        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9920     ok(!lstrcmpA(transforms, "banana"),
9921        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9922     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9923
9924     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9925                          (const BYTE *)patch_squashed,
9926                          lstrlenA(patch_squashed) + 1);
9927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9928
9929     /* Patches value exists, is not REG_MULTI_SZ */
9930     size = MAX_PATH;
9931     lstrcpyA(patch, "apple");
9932     lstrcpyA(transforms, "banana");
9933     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9934     ok(r == ERROR_BAD_CONFIGURATION ||
9935        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9936        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9937     ok(!lstrcmpA(patch, "apple"),
9938        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9939     ok(!lstrcmpA(transforms, "banana"),
9940        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9941     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9942
9943     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9944                          (const BYTE *)"a\0b\0c\0\0", 7);
9945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9946
9947     /* Patches value exists, is not a squashed guid */
9948     size = MAX_PATH;
9949     lstrcpyA(patch, "apple");
9950     lstrcpyA(transforms, "banana");
9951     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9952     ok(r == ERROR_BAD_CONFIGURATION,
9953        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9954     ok(!lstrcmpA(patch, "apple"),
9955        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9956     ok(!lstrcmpA(transforms, "banana"),
9957        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9958     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9959
9960     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9961     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9962                          (const BYTE *)patch_squashed,
9963                          lstrlenA(patch_squashed) + 2);
9964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9965
9966     /* Patches value exists */
9967     size = MAX_PATH;
9968     lstrcpyA(patch, "apple");
9969     lstrcpyA(transforms, "banana");
9970     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9971     ok(r == ERROR_NO_MORE_ITEMS ||
9972        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9973        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9974     ok(!lstrcmpA(patch, "apple") ||
9975        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9976        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9977     ok(!lstrcmpA(transforms, "banana"),
9978        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9979     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9980
9981     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9982                          (const BYTE *)"whatever", 9);
9983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9984
9985     /* patch squashed value exists */
9986     size = MAX_PATH;
9987     lstrcpyA(patch, "apple");
9988     lstrcpyA(transforms, "banana");
9989     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9991     ok(!lstrcmpA(patch, patchcode),
9992        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9993     ok(!lstrcmpA(transforms, "whatever"),
9994        "Expected \"whatever\", got \"%s\"\n", transforms);
9995     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9996
9997     /* lpPatchBuf is NULL */
9998     size = MAX_PATH;
9999     lstrcpyA(transforms, "banana");
10000     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
10001     ok(r == ERROR_INVALID_PARAMETER,
10002        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10003     ok(!lstrcmpA(transforms, "banana"),
10004        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10005     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10006
10007     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
10008     size = MAX_PATH;
10009     lstrcpyA(patch, "apple");
10010     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
10011     ok(r == ERROR_INVALID_PARAMETER,
10012        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10013     ok(!lstrcmpA(patch, "apple"),
10014        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10015     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10016
10017     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
10018     lstrcpyA(patch, "apple");
10019     lstrcpyA(transforms, "banana");
10020     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
10021     ok(r == ERROR_INVALID_PARAMETER,
10022        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10023     ok(!lstrcmpA(patch, "apple"),
10024        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10025     ok(!lstrcmpA(transforms, "banana"),
10026        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10027
10028     /* pcchTransformsBuf is too small */
10029     size = 6;
10030     lstrcpyA(patch, "apple");
10031     lstrcpyA(transforms, "banana");
10032     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10033     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10034     ok(!lstrcmpA(patch, patchcode),
10035        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10036     ok(!lstrcmpA(transforms, "whate") ||
10037        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10038        "Expected \"whate\", got \"%s\"\n", transforms);
10039     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
10040
10041     /* increase the index */
10042     size = MAX_PATH;
10043     lstrcpyA(patch, "apple");
10044     lstrcpyA(transforms, "banana");
10045     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
10046     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10047     ok(!lstrcmpA(patch, "apple"),
10048        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10049     ok(!lstrcmpA(transforms, "banana"),
10050        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10051     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10052
10053     /* increase again */
10054     size = MAX_PATH;
10055     lstrcpyA(patch, "apple");
10056     lstrcpyA(transforms, "banana");
10057     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
10058     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10059     ok(!lstrcmpA(patch, "apple"),
10060        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10061     ok(!lstrcmpA(transforms, "banana"),
10062        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10063     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10064
10065     RegDeleteValueA(patches, "Patches");
10066     delete_key(patches, "", access & KEY_WOW64_64KEY);
10067     RegCloseKey(patches);
10068     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10069     RegCloseKey(prodkey);
10070
10071     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10072
10073     size = MAX_PATH;
10074     lstrcpyA(patch, "apple");
10075     lstrcpyA(transforms, "banana");
10076     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10077     ok(r == ERROR_UNKNOWN_PRODUCT,
10078        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10079     ok(!lstrcmpA(patch, "apple"),
10080        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10081     ok(!lstrcmpA(transforms, "banana"),
10082        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10083     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10084
10085     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10086     lstrcatA(keypath, prod_squashed);
10087
10088     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10090
10091     /* current user product key exists */
10092     size = MAX_PATH;
10093     lstrcpyA(patch, "apple");
10094     lstrcpyA(transforms, "banana");
10095     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10096     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10097     ok(!lstrcmpA(patch, "apple"),
10098        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10099     ok(!lstrcmpA(transforms, "banana"),
10100        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10101     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10102
10103     res = RegCreateKeyA(prodkey, "Patches", &patches);
10104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10105
10106     /* Patches key exists */
10107     size = MAX_PATH;
10108     lstrcpyA(patch, "apple");
10109     lstrcpyA(transforms, "banana");
10110     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10111     ok(r == ERROR_NO_MORE_ITEMS ||
10112        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10113        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10114     ok(!lstrcmpA(patch, "apple"),
10115        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10116     ok(!lstrcmpA(transforms, "banana"),
10117        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10118     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10119
10120     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10121                          (const BYTE *)patch_squashed,
10122                          lstrlenA(patch_squashed) + 1);
10123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10124
10125     /* Patches value exists, is not REG_MULTI_SZ */
10126     size = MAX_PATH;
10127     lstrcpyA(patch, "apple");
10128     lstrcpyA(transforms, "banana");
10129     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10130     ok(r == ERROR_BAD_CONFIGURATION ||
10131        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10132        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10133     ok(!lstrcmpA(patch, "apple"),
10134        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10135     ok(!lstrcmpA(transforms, "banana"),
10136        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10137     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10138
10139     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10140                          (const BYTE *)"a\0b\0c\0\0", 7);
10141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10142
10143     /* Patches value exists, is not a squashed guid */
10144     size = MAX_PATH;
10145     lstrcpyA(patch, "apple");
10146     lstrcpyA(transforms, "banana");
10147     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10148     ok(r == ERROR_BAD_CONFIGURATION,
10149        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10150     ok(!lstrcmpA(patch, "apple"),
10151        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10152     ok(!lstrcmpA(transforms, "banana"),
10153        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10154     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10155
10156     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10157     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10158                          (const BYTE *)patch_squashed,
10159                          lstrlenA(patch_squashed) + 2);
10160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10161
10162     /* Patches value exists */
10163     size = MAX_PATH;
10164     lstrcpyA(patch, "apple");
10165     lstrcpyA(transforms, "banana");
10166     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10167     ok(r == ERROR_NO_MORE_ITEMS ||
10168        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10169        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10170     ok(!lstrcmpA(patch, "apple") ||
10171        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10172        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10173     ok(!lstrcmpA(transforms, "banana"),
10174        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10175     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10176
10177     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10178                          (const BYTE *)"whatever", 9);
10179     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10180
10181     /* patch code value exists */
10182     size = MAX_PATH;
10183     lstrcpyA(patch, "apple");
10184     lstrcpyA(transforms, "banana");
10185     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10186     ok(r == ERROR_NO_MORE_ITEMS ||
10187        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10188        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10189     ok(!lstrcmpA(patch, "apple") ||
10190        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10191        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10192     ok(!lstrcmpA(transforms, "banana") ||
10193        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10194        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10195     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10196
10197     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10198     lstrcatA(keypath, usersid);
10199     lstrcatA(keypath, "\\Patches\\");
10200     lstrcatA(keypath, patch_squashed);
10201
10202     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10203     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10204
10205     /* userdata patch key exists */
10206     size = MAX_PATH;
10207     lstrcpyA(patch, "apple");
10208     lstrcpyA(transforms, "banana");
10209     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10211     ok(!lstrcmpA(patch, patchcode),
10212        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10213     ok(!lstrcmpA(transforms, "whatever"),
10214        "Expected \"whatever\", got \"%s\"\n", transforms);
10215     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10216
10217     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10218     RegCloseKey(userkey);
10219     RegDeleteValueA(patches, patch_squashed);
10220     RegDeleteValueA(patches, "Patches");
10221     RegDeleteKeyA(patches, "");
10222     RegCloseKey(patches);
10223     RegDeleteKeyA(prodkey, "");
10224     RegCloseKey(prodkey);
10225
10226     /* MSIINSTALLCONTEXT_MACHINE */
10227
10228     size = MAX_PATH;
10229     lstrcpyA(patch, "apple");
10230     lstrcpyA(transforms, "banana");
10231     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10232     ok(r == ERROR_UNKNOWN_PRODUCT,
10233        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10234     ok(!lstrcmpA(patch, "apple"),
10235        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10236     ok(!lstrcmpA(transforms, "banana"),
10237        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10238     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10239
10240     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10241     lstrcatA(keypath, prod_squashed);
10242
10243     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10245
10246     /* local product key exists */
10247     size = MAX_PATH;
10248     lstrcpyA(patch, "apple");
10249     lstrcpyA(transforms, "banana");
10250     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10251     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10252     ok(!lstrcmpA(patch, "apple"),
10253        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10254     ok(!lstrcmpA(transforms, "banana"),
10255        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10256     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10257
10258     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10260
10261     /* Patches key exists */
10262     size = MAX_PATH;
10263     lstrcpyA(patch, "apple");
10264     lstrcpyA(transforms, "banana");
10265     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10266     ok(r == ERROR_NO_MORE_ITEMS ||
10267        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10268        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10269     ok(!lstrcmpA(patch, "apple"),
10270        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10271     ok(!lstrcmpA(transforms, "banana"),
10272        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10273     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10274
10275     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10276                          (const BYTE *)patch_squashed,
10277                          lstrlenA(patch_squashed) + 1);
10278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10279
10280     /* Patches value exists, is not REG_MULTI_SZ */
10281     size = MAX_PATH;
10282     lstrcpyA(patch, "apple");
10283     lstrcpyA(transforms, "banana");
10284     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10285     ok(r == ERROR_BAD_CONFIGURATION ||
10286        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10287        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10288     ok(!lstrcmpA(patch, "apple"),
10289        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10290     ok(!lstrcmpA(transforms, "banana"),
10291        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10292     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10293
10294     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10295                          (const BYTE *)"a\0b\0c\0\0", 7);
10296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10297
10298     /* Patches value exists, is not a squashed guid */
10299     size = MAX_PATH;
10300     lstrcpyA(patch, "apple");
10301     lstrcpyA(transforms, "banana");
10302     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10303     ok(r == ERROR_BAD_CONFIGURATION,
10304        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10305     ok(!lstrcmpA(patch, "apple"),
10306        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10307     ok(!lstrcmpA(transforms, "banana"),
10308        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10309     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10310
10311     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10312     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10313                          (const BYTE *)patch_squashed,
10314                          lstrlenA(patch_squashed) + 2);
10315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10316
10317     /* Patches value exists */
10318     size = MAX_PATH;
10319     lstrcpyA(patch, "apple");
10320     lstrcpyA(transforms, "banana");
10321     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10322     ok(r == ERROR_NO_MORE_ITEMS ||
10323        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10324        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10325     ok(!lstrcmpA(patch, "apple") ||
10326        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10327        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10328     ok(!lstrcmpA(transforms, "banana"),
10329        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10330     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10331
10332     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10333                          (const BYTE *)"whatever", 9);
10334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10335
10336     /* patch code value exists */
10337     size = MAX_PATH;
10338     lstrcpyA(patch, "apple");
10339     lstrcpyA(transforms, "banana");
10340     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10341     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10342     ok(!lstrcmpA(patch, patchcode),
10343        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10344     ok(!lstrcmpA(transforms, "whatever"),
10345        "Expected \"whatever\", got \"%s\"\n", transforms);
10346     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10347
10348     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10349     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10350     lstrcatA(keypath, prod_squashed);
10351
10352     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10354
10355     /* local UserData product key exists */
10356     size = MAX_PATH;
10357     lstrcpyA(patch, "apple");
10358     lstrcpyA(transforms, "banana");
10359     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10361     ok(!lstrcmpA(patch, patchcode),
10362        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10363     ok(!lstrcmpA(transforms, "whatever"),
10364        "Expected \"whatever\", got \"%s\"\n", transforms);
10365     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10366
10367     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10369
10370     /* local UserData Patches key exists */
10371     size = MAX_PATH;
10372     lstrcpyA(patch, "apple");
10373     lstrcpyA(transforms, "banana");
10374     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10375     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10376     ok(!lstrcmpA(patch, patchcode),
10377        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10378     ok(!lstrcmpA(transforms, "whatever"),
10379        "Expected \"whatever\", got \"%s\"\n", transforms);
10380     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10381
10382     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10384
10385     /* local UserData Product patch key exists */
10386     size = MAX_PATH;
10387     lstrcpyA(patch, "apple");
10388     lstrcpyA(transforms, "banana");
10389     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10390     ok(r == ERROR_NO_MORE_ITEMS ||
10391        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10392        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10393     ok(!lstrcmpA(patch, "apple") ||
10394        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10395        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10396     ok(!lstrcmpA(transforms, "banana") ||
10397        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10398        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10399     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10400
10401     data = MSIPATCHSTATE_APPLIED;
10402     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10403                          (const BYTE *)&data, sizeof(DWORD));
10404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10405
10406     /* State value exists */
10407     size = MAX_PATH;
10408     lstrcpyA(patch, "apple");
10409     lstrcpyA(transforms, "banana");
10410     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10412     ok(!lstrcmpA(patch, patchcode),
10413        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10414     ok(!lstrcmpA(transforms, "whatever"),
10415        "Expected \"whatever\", got \"%s\"\n", transforms);
10416     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10417
10418     /* now duplicate some of the tests for the W version */
10419
10420     /* pcchTransformsBuf is too small */
10421     size = 6;
10422     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10423     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10424     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10425     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10426     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10427     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10428     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10429     ok(!lstrcmpA(patch, patchcode),
10430        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10431     ok(!lstrcmpA(transforms, "whate") ||
10432        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10433        "Expected \"whate\", got \"%s\"\n", transforms);
10434     ok(size == 8, "Expected 8, got %d\n", size);
10435
10436     /* patch code value exists */
10437     size = MAX_PATH;
10438     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10439     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10440     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10442     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10443     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10444     ok(!lstrcmpA(patch, patchcode),
10445        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10446     ok(!lstrcmpA(transforms, "whatever"),
10447        "Expected \"whatever\", got \"%s\"\n", transforms);
10448     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10449
10450     RegDeleteValueA(patches, patch_squashed);
10451     RegDeleteValueA(patches, "Patches");
10452     delete_key(patches, "", access & KEY_WOW64_64KEY);
10453     RegCloseKey(patches);
10454     RegDeleteValueA(hpatch, "State");
10455     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10456     RegCloseKey(hpatch);
10457     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10458     RegCloseKey(udpatch);
10459     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10460     RegCloseKey(udprod);
10461     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10462     RegCloseKey(prodkey);
10463     LocalFree(usersid);
10464 }
10465
10466 static void test_MsiGetPatchInfoEx(void)
10467 {
10468     CHAR keypath[MAX_PATH], val[MAX_PATH];
10469     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10470     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10471     HKEY prodkey, patches, udprod, props;
10472     HKEY hpatch, udpatch, prodpatches;
10473     LPSTR usersid;
10474     DWORD size;
10475     LONG res;
10476     UINT r;
10477     REGSAM access = KEY_ALL_ACCESS;
10478
10479     if (!pMsiGetPatchInfoExA)
10480     {
10481         win_skip("MsiGetPatchInfoEx not implemented\n");
10482         return;
10483     }
10484
10485     create_test_guid(prodcode, prod_squashed);
10486     create_test_guid(patchcode, patch_squashed);
10487     get_user_sid(&usersid);
10488
10489     if (is_wow64)
10490         access |= KEY_WOW64_64KEY;
10491
10492     /* NULL szPatchCode */
10493     lstrcpyA(val, "apple");
10494     size = MAX_PATH;
10495     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10496                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10497     ok(r == ERROR_INVALID_PARAMETER,
10498        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10499     ok(!lstrcmpA(val, "apple"),
10500        "Expected val to be unchanged, got \"%s\"\n", val);
10501     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10502
10503     /* empty szPatchCode */
10504     size = MAX_PATH;
10505     lstrcpyA(val, "apple");
10506     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10507                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10508     ok(r == ERROR_INVALID_PARAMETER,
10509        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10510     ok(!lstrcmpA(val, "apple"),
10511        "Expected val to be unchanged, got \"%s\"\n", val);
10512     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10513
10514     /* garbage szPatchCode */
10515     size = MAX_PATH;
10516     lstrcpyA(val, "apple");
10517     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10518                             MSIINSTALLCONTEXT_USERMANAGED,
10519                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10520     ok(r == ERROR_INVALID_PARAMETER,
10521        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10522     ok(!lstrcmpA(val, "apple"),
10523        "Expected val to be unchanged, got \"%s\"\n", val);
10524     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10525
10526     /* guid without brackets */
10527     size = MAX_PATH;
10528     lstrcpyA(val, "apple");
10529     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10530                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10531                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10532     ok(r == ERROR_INVALID_PARAMETER,
10533        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10534     ok(!lstrcmpA(val, "apple"),
10535        "Expected val to be unchanged, got \"%s\"\n", val);
10536     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10537
10538     /* guid with brackets */
10539     size = MAX_PATH;
10540     lstrcpyA(val, "apple");
10541     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10542                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10543                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10544     ok(r == ERROR_UNKNOWN_PRODUCT,
10545        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10546     ok(!lstrcmpA(val, "apple"),
10547        "Expected val to be unchanged, got \"%s\"\n", val);
10548     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10549
10550     /* same length as guid, but random */
10551     size = MAX_PATH;
10552     lstrcpyA(val, "apple");
10553     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10554                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10555                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10556     ok(r == ERROR_INVALID_PARAMETER,
10557        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10558     ok(!lstrcmpA(val, "apple"),
10559        "Expected val to be unchanged, got \"%s\"\n", val);
10560     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10561
10562     /* NULL szProductCode */
10563     lstrcpyA(val, "apple");
10564     size = MAX_PATH;
10565     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10566                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10567     ok(r == ERROR_INVALID_PARAMETER,
10568        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10569     ok(!lstrcmpA(val, "apple"),
10570        "Expected val to be unchanged, got \"%s\"\n", val);
10571     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10572
10573     /* empty szProductCode */
10574     size = MAX_PATH;
10575     lstrcpyA(val, "apple");
10576     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10577                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10578     ok(r == ERROR_INVALID_PARAMETER,
10579        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10580     ok(!lstrcmpA(val, "apple"),
10581        "Expected val to be unchanged, got \"%s\"\n", val);
10582     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10583
10584     /* garbage szProductCode */
10585     size = MAX_PATH;
10586     lstrcpyA(val, "apple");
10587     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10588                             MSIINSTALLCONTEXT_USERMANAGED,
10589                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10590     ok(r == ERROR_INVALID_PARAMETER,
10591        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10592     ok(!lstrcmpA(val, "apple"),
10593        "Expected val to be unchanged, got \"%s\"\n", val);
10594     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10595
10596     /* guid without brackets */
10597     size = MAX_PATH;
10598     lstrcpyA(val, "apple");
10599     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10600                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10601                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10602     ok(r == ERROR_INVALID_PARAMETER,
10603        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10604     ok(!lstrcmpA(val, "apple"),
10605        "Expected val to be unchanged, got \"%s\"\n", val);
10606     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10607
10608     /* guid with brackets */
10609     size = MAX_PATH;
10610     lstrcpyA(val, "apple");
10611     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10612                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10613                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10614     ok(r == ERROR_UNKNOWN_PRODUCT,
10615        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10616     ok(!lstrcmpA(val, "apple"),
10617        "Expected val to be unchanged, got \"%s\"\n", val);
10618     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10619
10620     /* same length as guid, but random */
10621     size = MAX_PATH;
10622     lstrcpyA(val, "apple");
10623     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10624                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10625                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10626     ok(r == ERROR_INVALID_PARAMETER,
10627        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10628     ok(!lstrcmpA(val, "apple"),
10629        "Expected val to be unchanged, got \"%s\"\n", val);
10630     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10631
10632     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10633     size = MAX_PATH;
10634     lstrcpyA(val, "apple");
10635     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10636                             MSIINSTALLCONTEXT_USERMANAGED,
10637                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10638     ok(r == ERROR_INVALID_PARAMETER,
10639        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10640     ok(!lstrcmpA(val, "apple"),
10641        "Expected val to be unchanged, got \"%s\"\n", val);
10642     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10643
10644     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10645     size = MAX_PATH;
10646     lstrcpyA(val, "apple");
10647     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10648                             MSIINSTALLCONTEXT_USERUNMANAGED,
10649                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10650     ok(r == ERROR_INVALID_PARAMETER,
10651        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10652     ok(!lstrcmpA(val, "apple"),
10653        "Expected val to be unchanged, got \"%s\"\n", val);
10654     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10655
10656     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10657     size = MAX_PATH;
10658     lstrcpyA(val, "apple");
10659     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10660                             MSIINSTALLCONTEXT_MACHINE,
10661                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10662     ok(r == ERROR_INVALID_PARAMETER,
10663        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10664     ok(!lstrcmpA(val, "apple"),
10665        "Expected val to be unchanged, got \"%s\"\n", val);
10666     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10667
10668     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10669     size = MAX_PATH;
10670     lstrcpyA(val, "apple");
10671     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10672                             MSIINSTALLCONTEXT_MACHINE,
10673                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10674     ok(r == ERROR_INVALID_PARAMETER,
10675        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10676     ok(!lstrcmpA(val, "apple"),
10677        "Expected val to be unchanged, got \"%s\"\n", val);
10678     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10679
10680     /* dwContext is out of range */
10681     size = MAX_PATH;
10682     lstrcpyA(val, "apple");
10683     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10684                             MSIINSTALLCONTEXT_NONE,
10685                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10686     ok(r == ERROR_INVALID_PARAMETER,
10687        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10688     ok(!lstrcmpA(val, "apple"),
10689        "Expected val to be unchanged, got \"%s\"\n", val);
10690     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10691
10692     /* dwContext is out of range */
10693     size = MAX_PATH;
10694     lstrcpyA(val, "apple");
10695     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10696                             MSIINSTALLCONTEXT_ALL,
10697                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10698     ok(r == ERROR_INVALID_PARAMETER,
10699        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10700     ok(!lstrcmpA(val, "apple"),
10701        "Expected val to be unchanged, got \"%s\"\n", val);
10702     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10703
10704     /* dwContext is invalid */
10705     size = MAX_PATH;
10706     lstrcpyA(val, "apple");
10707     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10708                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10709     ok(r == ERROR_INVALID_PARAMETER,
10710        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10711     ok(!lstrcmpA(val, "apple"),
10712        "Expected val to be unchanged, got \"%s\"\n", val);
10713     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10714
10715     /* MSIINSTALLCONTEXT_USERMANAGED */
10716
10717     size = MAX_PATH;
10718     lstrcpyA(val, "apple");
10719     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10720                             MSIINSTALLCONTEXT_USERMANAGED,
10721                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10722     ok(r == ERROR_UNKNOWN_PRODUCT,
10723        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10724     ok(!lstrcmpA(val, "apple"),
10725        "Expected val to be unchanged, got \"%s\"\n", val);
10726     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10727
10728     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10729     lstrcatA(keypath, usersid);
10730     lstrcatA(keypath, "\\Products\\");
10731     lstrcatA(keypath, prod_squashed);
10732
10733     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10734     if (res == ERROR_ACCESS_DENIED)
10735     {
10736         skip("Not enough rights to perform tests\n");
10737         LocalFree(usersid);
10738         return;
10739     }
10740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10741
10742     /* local UserData product key exists */
10743     size = MAX_PATH;
10744     lstrcpyA(val, "apple");
10745     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10746                             MSIINSTALLCONTEXT_USERMANAGED,
10747                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10748     ok(r == ERROR_UNKNOWN_PRODUCT,
10749        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10750     ok(!lstrcmpA(val, "apple"),
10751        "Expected val to be unchanged, got \"%s\"\n", val);
10752     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10753
10754     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10755     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10756
10757     /* InstallProperties key exists */
10758     size = MAX_PATH;
10759     lstrcpyA(val, "apple");
10760     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10761                             MSIINSTALLCONTEXT_USERMANAGED,
10762                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10763     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10764     ok(!lstrcmpA(val, "apple"),
10765        "Expected val to be unchanged, got \"%s\"\n", val);
10766     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10767
10768     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10770
10771     /* Patches key exists */
10772     size = MAX_PATH;
10773     lstrcpyA(val, "apple");
10774     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10775                             MSIINSTALLCONTEXT_USERMANAGED,
10776                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10777     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10778     ok(!lstrcmpA(val, "apple"),
10779        "Expected val to be unchanged, got \"%s\"\n", val);
10780     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10781
10782     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10784
10785     /* Patches key exists */
10786     size = MAX_PATH;
10787     lstrcpyA(val, "apple");
10788     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10789                             MSIINSTALLCONTEXT_USERMANAGED,
10790                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10791     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10792     ok(!lstrcmpA(val, "apple"),
10793        "Expected val to be unchanged, got \"%s\"\n", val);
10794     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10795
10796     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10797     lstrcatA(keypath, usersid);
10798     lstrcatA(keypath, "\\Installer\\Products\\");
10799     lstrcatA(keypath, prod_squashed);
10800
10801     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10803
10804     /* managed product key exists */
10805     size = MAX_PATH;
10806     lstrcpyA(val, "apple");
10807     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10808                             MSIINSTALLCONTEXT_USERMANAGED,
10809                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10810     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10811     ok(!lstrcmpA(val, "apple"),
10812        "Expected val to be unchanged, got \"%s\"\n", val);
10813     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10814
10815     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10816     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10817
10818     /* Patches key exists */
10819     size = MAX_PATH;
10820     lstrcpyA(val, "apple");
10821     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10822                             MSIINSTALLCONTEXT_USERMANAGED,
10823                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10824     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10825     ok(!lstrcmpA(val, "apple"),
10826        "Expected val to be unchanged, got \"%s\"\n", val);
10827     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10828
10829     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10830                          (const BYTE *)"transforms", 11);
10831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10832
10833     /* specific patch value exists */
10834     size = MAX_PATH;
10835     lstrcpyA(val, "apple");
10836     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10837                             MSIINSTALLCONTEXT_USERMANAGED,
10838                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10839     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10840     ok(!lstrcmpA(val, "apple"),
10841        "Expected val to be unchanged, got \"%s\"\n", val);
10842     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10843
10844     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10845     lstrcatA(keypath, usersid);
10846     lstrcatA(keypath, "\\Patches\\");
10847     lstrcatA(keypath, patch_squashed);
10848
10849     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10850     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10851
10852     /* UserData Patches key exists */
10853     size = MAX_PATH;
10854     lstrcpyA(val, "apple");
10855     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10856                             MSIINSTALLCONTEXT_USERMANAGED,
10857                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10858     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10859     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10860     ok(size == 0, "Expected 0, got %d\n", size);
10861
10862     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10863                          (const BYTE *)"pack", 5);
10864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10865
10866     /* ManagedLocalPatch value exists */
10867     size = MAX_PATH;
10868     lstrcpyA(val, "apple");
10869     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10870                             MSIINSTALLCONTEXT_USERMANAGED,
10871                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10872     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10873     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10874     ok(size == 4, "Expected 4, got %d\n", size);
10875
10876     size = MAX_PATH;
10877     lstrcpyA(val, "apple");
10878     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10879                             MSIINSTALLCONTEXT_USERMANAGED,
10880                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10881     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10882     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10883     ok(size == 10, "Expected 10, got %d\n", size);
10884
10885     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10886                          (const BYTE *)"mydate", 7);
10887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10888
10889     /* Installed value exists */
10890     size = MAX_PATH;
10891     lstrcpyA(val, "apple");
10892     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10893                             MSIINSTALLCONTEXT_USERMANAGED,
10894                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10895     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10896     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10897     ok(size == 6, "Expected 6, got %d\n", size);
10898
10899     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10900                          (const BYTE *)"yes", 4);
10901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10902
10903     /* Uninstallable value exists */
10904     size = MAX_PATH;
10905     lstrcpyA(val, "apple");
10906     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10907                             MSIINSTALLCONTEXT_USERMANAGED,
10908                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10910     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10911     ok(size == 3, "Expected 3, got %d\n", size);
10912
10913     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10914                          (const BYTE *)"good", 5);
10915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10916
10917     /* State value exists */
10918     size = MAX_PATH;
10919     lstrcpyA(val, "apple");
10920     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10921                             MSIINSTALLCONTEXT_USERMANAGED,
10922                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10924     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10925     ok(size == 4, "Expected 4, got %d\n", size);
10926
10927     size = 1;
10928     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10929                          (const BYTE *)&size, sizeof(DWORD));
10930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10931
10932     /* State value exists */
10933     size = MAX_PATH;
10934     lstrcpyA(val, "apple");
10935     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10936                             MSIINSTALLCONTEXT_USERMANAGED,
10937                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10939     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10940     ok(size == 1, "Expected 1, got %d\n", size);
10941
10942     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10943                          (const BYTE *)"display", 8);
10944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10945
10946     /* DisplayName value exists */
10947     size = MAX_PATH;
10948     lstrcpyA(val, "apple");
10949     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10950                             MSIINSTALLCONTEXT_USERMANAGED,
10951                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10953     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10954     ok(size == 7, "Expected 7, got %d\n", size);
10955
10956     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10957                          (const BYTE *)"moreinfo", 9);
10958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10959
10960     /* MoreInfoURL value exists */
10961     size = MAX_PATH;
10962     lstrcpyA(val, "apple");
10963     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10964                             MSIINSTALLCONTEXT_USERMANAGED,
10965                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10967     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10968     ok(size == 8, "Expected 8, got %d\n", size);
10969
10970     /* szProperty is invalid */
10971     size = MAX_PATH;
10972     lstrcpyA(val, "apple");
10973     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10974                             MSIINSTALLCONTEXT_USERMANAGED,
10975                             "IDontExist", val, &size);
10976     ok(r == ERROR_UNKNOWN_PROPERTY,
10977        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10978     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10979     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10980
10981     /* lpValue is NULL, while pcchValue is non-NULL */
10982     size = MAX_PATH;
10983     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10984                             MSIINSTALLCONTEXT_USERMANAGED,
10985                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10987     ok(size == 16, "Expected 16, got %d\n", size);
10988
10989     /* pcchValue is NULL, while lpValue is non-NULL */
10990     lstrcpyA(val, "apple");
10991     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10992                             MSIINSTALLCONTEXT_USERMANAGED,
10993                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10994     ok(r == ERROR_INVALID_PARAMETER,
10995        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10996     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10997
10998     /* both lpValue and pcchValue are NULL */
10999     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11000                             MSIINSTALLCONTEXT_USERMANAGED,
11001                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
11002     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11003
11004     /* pcchValue doesn't have enough room for NULL terminator */
11005     size = 8;
11006     lstrcpyA(val, "apple");
11007     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11008                             MSIINSTALLCONTEXT_USERMANAGED,
11009                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11010     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11011     ok(!lstrcmpA(val, "moreinf"),
11012        "Expected \"moreinf\", got \"%s\"\n", val);
11013     ok(size == 16, "Expected 16, got %d\n", size);
11014
11015     /* pcchValue has exactly enough room for NULL terminator */
11016     size = 9;
11017     lstrcpyA(val, "apple");
11018     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11019                             MSIINSTALLCONTEXT_USERMANAGED,
11020                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11022     ok(!lstrcmpA(val, "moreinfo"),
11023        "Expected \"moreinfo\", got \"%s\"\n", val);
11024     ok(size == 8, "Expected 8, got %d\n", size);
11025
11026     /* pcchValue is too small, lpValue is NULL */
11027     size = 0;
11028     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11029                             MSIINSTALLCONTEXT_USERMANAGED,
11030                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
11031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11032     ok(size == 16, "Expected 16, got %d\n", size);
11033
11034     RegDeleteValueA(prodpatches, patch_squashed);
11035     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11036     RegCloseKey(prodpatches);
11037     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11038     RegCloseKey(prodkey);
11039
11040     /* UserData is sufficient for all properties
11041      * except INSTALLPROPERTY_TRANSFORMS
11042      */
11043     size = MAX_PATH;
11044     lstrcpyA(val, "apple");
11045     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11046                             MSIINSTALLCONTEXT_USERMANAGED,
11047                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11049     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11050     ok(size == 4, "Expected 4, got %d\n", size);
11051
11052     /* UserData is sufficient for all properties
11053      * except INSTALLPROPERTY_TRANSFORMS
11054      */
11055     size = MAX_PATH;
11056     lstrcpyA(val, "apple");
11057     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11058                             MSIINSTALLCONTEXT_USERMANAGED,
11059                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11060     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11061     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11062     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11063
11064     RegDeleteValueA(hpatch, "MoreInfoURL");
11065     RegDeleteValueA(hpatch, "Display");
11066     RegDeleteValueA(hpatch, "State");
11067     RegDeleteValueA(hpatch, "Uninstallable");
11068     RegDeleteValueA(hpatch, "Installed");
11069     RegDeleteValueA(udpatch, "ManagedLocalPackage");
11070     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11071     RegCloseKey(udpatch);
11072     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11073     RegCloseKey(hpatch);
11074     delete_key(patches, "", access & KEY_WOW64_64KEY);
11075     RegCloseKey(patches);
11076     delete_key(props, "", access & KEY_WOW64_64KEY);
11077     RegCloseKey(props);
11078     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11079     RegCloseKey(udprod);
11080
11081     /* MSIINSTALLCONTEXT_USERUNMANAGED */
11082
11083     size = MAX_PATH;
11084     lstrcpyA(val, "apple");
11085     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11086                             MSIINSTALLCONTEXT_USERUNMANAGED,
11087                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11088     ok(r == ERROR_UNKNOWN_PRODUCT,
11089        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11090     ok(!lstrcmpA(val, "apple"),
11091        "Expected val to be unchanged, got \"%s\"\n", val);
11092     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11093
11094     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11095     lstrcatA(keypath, usersid);
11096     lstrcatA(keypath, "\\Products\\");
11097     lstrcatA(keypath, prod_squashed);
11098
11099     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11101
11102     /* local UserData product key exists */
11103     size = MAX_PATH;
11104     lstrcpyA(val, "apple");
11105     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11106                             MSIINSTALLCONTEXT_USERUNMANAGED,
11107                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11108     ok(r == ERROR_UNKNOWN_PRODUCT,
11109        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11110     ok(!lstrcmpA(val, "apple"),
11111        "Expected val to be unchanged, got \"%s\"\n", val);
11112     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11113
11114     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11115     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11116
11117     /* InstallProperties key exists */
11118     size = MAX_PATH;
11119     lstrcpyA(val, "apple");
11120     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11121                             MSIINSTALLCONTEXT_USERUNMANAGED,
11122                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11123     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11124     ok(!lstrcmpA(val, "apple"),
11125        "Expected val to be unchanged, got \"%s\"\n", val);
11126     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11127
11128     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11130
11131     /* Patches key exists */
11132     size = MAX_PATH;
11133     lstrcpyA(val, "apple");
11134     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11135                             MSIINSTALLCONTEXT_USERUNMANAGED,
11136                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11137     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11138     ok(!lstrcmpA(val, "apple"),
11139        "Expected val to be unchanged, got \"%s\"\n", val);
11140     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11141
11142     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11144
11145     /* Patches key exists */
11146     size = MAX_PATH;
11147     lstrcpyA(val, "apple");
11148     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11149                             MSIINSTALLCONTEXT_USERUNMANAGED,
11150                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11151     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11152     ok(!lstrcmpA(val, "apple"),
11153        "Expected val to be unchanged, got \"%s\"\n", val);
11154     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11155
11156     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11157     lstrcatA(keypath, prod_squashed);
11158
11159     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11161
11162     /* current user product key exists */
11163     size = MAX_PATH;
11164     lstrcpyA(val, "apple");
11165     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11166                             MSIINSTALLCONTEXT_USERUNMANAGED,
11167                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11168     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11169     ok(!lstrcmpA(val, "apple"),
11170        "Expected val to be unchanged, got \"%s\"\n", val);
11171     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11172
11173     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
11174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11175
11176     /* Patches key exists */
11177     size = MAX_PATH;
11178     lstrcpyA(val, "apple");
11179     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11180                             MSIINSTALLCONTEXT_USERUNMANAGED,
11181                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11182     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11183     ok(!lstrcmpA(val, "apple"),
11184        "Expected val to be unchanged, got \"%s\"\n", val);
11185     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11186
11187     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11188                          (const BYTE *)"transforms", 11);
11189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11190
11191     /* specific patch value exists */
11192     size = MAX_PATH;
11193     lstrcpyA(val, "apple");
11194     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11195                             MSIINSTALLCONTEXT_USERUNMANAGED,
11196                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11197     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11198     ok(!lstrcmpA(val, "apple"),
11199        "Expected val to be unchanged, got \"%s\"\n", val);
11200     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11201
11202     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11203     lstrcatA(keypath, usersid);
11204     lstrcatA(keypath, "\\Patches\\");
11205     lstrcatA(keypath, patch_squashed);
11206
11207     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11209
11210     /* UserData Patches key exists */
11211     size = MAX_PATH;
11212     lstrcpyA(val, "apple");
11213     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11214                             MSIINSTALLCONTEXT_USERUNMANAGED,
11215                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11217     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11218     ok(size == 0, "Expected 0, got %d\n", size);
11219
11220     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11221                          (const BYTE *)"pack", 5);
11222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11223
11224     /* LocalPatch value exists */
11225     size = MAX_PATH;
11226     lstrcpyA(val, "apple");
11227     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11228                             MSIINSTALLCONTEXT_USERUNMANAGED,
11229                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11230     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11231     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11232     ok(size == 4, "Expected 4, got %d\n", size);
11233
11234     size = MAX_PATH;
11235     lstrcpyA(val, "apple");
11236     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11237                             MSIINSTALLCONTEXT_USERUNMANAGED,
11238                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11240     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11241     ok(size == 10, "Expected 10, got %d\n", size);
11242
11243     RegDeleteValueA(prodpatches, patch_squashed);
11244     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11245     RegCloseKey(prodpatches);
11246     RegDeleteKeyA(prodkey, "");
11247     RegCloseKey(prodkey);
11248
11249     /* UserData is sufficient for all properties
11250      * except INSTALLPROPERTY_TRANSFORMS
11251      */
11252     size = MAX_PATH;
11253     lstrcpyA(val, "apple");
11254     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11255                             MSIINSTALLCONTEXT_USERUNMANAGED,
11256                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11257     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11258     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11259     ok(size == 4, "Expected 4, got %d\n", size);
11260
11261     /* UserData is sufficient for all properties
11262      * except INSTALLPROPERTY_TRANSFORMS
11263      */
11264     size = MAX_PATH;
11265     lstrcpyA(val, "apple");
11266     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11267                             MSIINSTALLCONTEXT_USERUNMANAGED,
11268                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11269     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11270     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11271     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11272
11273     RegDeleteValueA(udpatch, "LocalPackage");
11274     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11275     RegCloseKey(udpatch);
11276     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11277     RegCloseKey(hpatch);
11278     delete_key(patches, "", access & KEY_WOW64_64KEY);
11279     RegCloseKey(patches);
11280     delete_key(props, "", access & KEY_WOW64_64KEY);
11281     RegCloseKey(props);
11282     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11283     RegCloseKey(udprod);
11284
11285     /* MSIINSTALLCONTEXT_MACHINE */
11286
11287     size = MAX_PATH;
11288     lstrcpyA(val, "apple");
11289     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11290                             MSIINSTALLCONTEXT_MACHINE,
11291                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11292     ok(r == ERROR_UNKNOWN_PRODUCT,
11293        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11294     ok(!lstrcmpA(val, "apple"),
11295        "Expected val to be unchanged, got \"%s\"\n", val);
11296     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11297
11298     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11299     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11300     lstrcatA(keypath, prod_squashed);
11301
11302     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11304
11305     /* local UserData product key exists */
11306     size = MAX_PATH;
11307     lstrcpyA(val, "apple");
11308     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11309                             MSIINSTALLCONTEXT_MACHINE,
11310                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11311     ok(r == ERROR_UNKNOWN_PRODUCT,
11312        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11313     ok(!lstrcmpA(val, "apple"),
11314        "Expected val to be unchanged, got \"%s\"\n", val);
11315     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11316
11317     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11319
11320     /* InstallProperties key exists */
11321     size = MAX_PATH;
11322     lstrcpyA(val, "apple");
11323     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11324                             MSIINSTALLCONTEXT_MACHINE,
11325                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11326     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11327     ok(!lstrcmpA(val, "apple"),
11328        "Expected val to be unchanged, got \"%s\"\n", val);
11329     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11330
11331     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11333
11334     /* Patches key exists */
11335     size = MAX_PATH;
11336     lstrcpyA(val, "apple");
11337     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11338                             MSIINSTALLCONTEXT_MACHINE,
11339                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11340     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11341     ok(!lstrcmpA(val, "apple"),
11342        "Expected val to be unchanged, got \"%s\"\n", val);
11343     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11344
11345     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11347
11348     /* Patches key exists */
11349     size = MAX_PATH;
11350     lstrcpyA(val, "apple");
11351     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11352                             MSIINSTALLCONTEXT_MACHINE,
11353                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11354     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11355     ok(!lstrcmpA(val, "apple"),
11356        "Expected val to be unchanged, got \"%s\"\n", val);
11357     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11358
11359     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11360     lstrcatA(keypath, prod_squashed);
11361
11362     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11364
11365     /* local product key exists */
11366     size = MAX_PATH;
11367     lstrcpyA(val, "apple");
11368     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11369                             MSIINSTALLCONTEXT_MACHINE,
11370                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11371     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11372     ok(!lstrcmpA(val, "apple"),
11373        "Expected val to be unchanged, got \"%s\"\n", val);
11374     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11375
11376     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11378
11379     /* Patches key exists */
11380     size = MAX_PATH;
11381     lstrcpyA(val, "apple");
11382     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11383                             MSIINSTALLCONTEXT_MACHINE,
11384                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11385     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11386     ok(!lstrcmpA(val, "apple"),
11387        "Expected val to be unchanged, got \"%s\"\n", val);
11388     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11389
11390     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11391                          (const BYTE *)"transforms", 11);
11392     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11393
11394     /* specific patch value exists */
11395     size = MAX_PATH;
11396     lstrcpyA(val, "apple");
11397     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11398                             MSIINSTALLCONTEXT_MACHINE,
11399                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11400     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11401     ok(!lstrcmpA(val, "apple"),
11402        "Expected val to be unchanged, got \"%s\"\n", val);
11403     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11404
11405     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11406     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11407     lstrcatA(keypath, patch_squashed);
11408
11409     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11410     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11411
11412     /* UserData Patches key exists */
11413     size = MAX_PATH;
11414     lstrcpyA(val, "apple");
11415     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11416                             MSIINSTALLCONTEXT_MACHINE,
11417                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11418     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11419     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11420     ok(size == 0, "Expected 0, got %d\n", size);
11421
11422     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11423                          (const BYTE *)"pack", 5);
11424     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11425
11426     /* LocalPatch value exists */
11427     size = MAX_PATH;
11428     lstrcpyA(val, "apple");
11429     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11430                             MSIINSTALLCONTEXT_MACHINE,
11431                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11433     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11434     ok(size == 4, "Expected 4, got %d\n", size);
11435
11436     size = MAX_PATH;
11437     lstrcpyA(val, "apple");
11438     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11439                             MSIINSTALLCONTEXT_MACHINE,
11440                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11442     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11443     ok(size == 10, "Expected 10, got %d\n", size);
11444
11445     RegDeleteValueA(prodpatches, patch_squashed);
11446     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11447     RegCloseKey(prodpatches);
11448     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11449     RegCloseKey(prodkey);
11450
11451     /* UserData is sufficient for all properties
11452      * except INSTALLPROPERTY_TRANSFORMS
11453      */
11454     size = MAX_PATH;
11455     lstrcpyA(val, "apple");
11456     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11457                             MSIINSTALLCONTEXT_MACHINE,
11458                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11460     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11461     ok(size == 4, "Expected 4, got %d\n", size);
11462
11463     /* UserData is sufficient for all properties
11464      * except INSTALLPROPERTY_TRANSFORMS
11465      */
11466     size = MAX_PATH;
11467     lstrcpyA(val, "apple");
11468     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11469                             MSIINSTALLCONTEXT_MACHINE,
11470                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11471     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11472     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11473     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11474
11475     RegDeleteValueA(udpatch, "LocalPackage");
11476     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11477     RegCloseKey(udpatch);
11478     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11479     RegCloseKey(hpatch);
11480     delete_key(patches, "", access & KEY_WOW64_64KEY);
11481     RegCloseKey(patches);
11482     delete_key(props, "", access & KEY_WOW64_64KEY);
11483     RegCloseKey(props);
11484     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11485     RegCloseKey(udprod);
11486     LocalFree(usersid);
11487 }
11488
11489 static void test_MsiGetPatchInfo(void)
11490 {
11491     UINT r;
11492     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11493     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11494     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11495     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11496     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11497     DWORD size;
11498     LONG res;
11499     REGSAM access = KEY_ALL_ACCESS;
11500
11501     create_test_guid(patch_code, patch_squashed);
11502     create_test_guid(prod_code, prod_squashed);
11503     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11504
11505     if (is_wow64)
11506         access |= KEY_WOW64_64KEY;
11507
11508     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11509     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11510
11511     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11512     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11513
11514     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11515     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11516
11517     size = 0;
11518     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11519     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11520
11521     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11522     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11523
11524     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11525     lstrcatA(keypath, prod_squashed);
11526
11527     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11528     if (res == ERROR_ACCESS_DENIED)
11529     {
11530         skip("Not enough rights to perform tests\n");
11531         return;
11532     }
11533     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11534
11535     /* product key exists */
11536     size = MAX_PATH;
11537     lstrcpyA(val, "apple");
11538     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11539     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11540     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11541     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11542
11543     res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11544     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11545
11546     /* patches key exists */
11547     size = MAX_PATH;
11548     lstrcpyA(val, "apple");
11549     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11550     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11551     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11552     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11553
11554     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11555     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11556
11557     /* patch key exists */
11558     size = MAX_PATH;
11559     lstrcpyA(val, "apple");
11560     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11561     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11562     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11563     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11564
11565     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11566     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11567     lstrcatA(keypath, prod_squashed);
11568
11569     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11570     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11571
11572     /* UserData product key exists */
11573     size = MAX_PATH;
11574     lstrcpyA(val, "apple");
11575     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11576     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11577     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11578     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11579
11580     res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11581     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11582
11583     /* InstallProperties key exists */
11584     size = MAX_PATH;
11585     lstrcpyA(val, "apple");
11586     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11587     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11588     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11589     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11590
11591     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11592     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11593
11594     /* UserData Patches key exists */
11595     size = MAX_PATH;
11596     lstrcpyA(val, "apple");
11597     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11598     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11599     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11600     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11601
11602     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11603     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11604
11605     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11607
11608     /* UserData product patch key exists */
11609     size = MAX_PATH;
11610     lstrcpyA(val, "apple");
11611     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11612     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11613     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11614     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11615
11616     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11617     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11618     lstrcatA(keypath, patch_squashed);
11619
11620     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11621     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11622
11623     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11624     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11625
11626     /* UserData Patch key exists */
11627     size = 0;
11628     lstrcpyA(val, "apple");
11629     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11630     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11631     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11632     ok(size == 11, "expected 11 got %u\n", size);
11633
11634     size = MAX_PATH;
11635     lstrcpyA(val, "apple");
11636     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11637     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11638     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11639     ok(size == 11, "expected 11 got %u\n", size);
11640
11641     size = 0;
11642     valW[0] = 0;
11643     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11644     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11645     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11646     ok(size == 11, "expected 11 got %u\n", size);
11647
11648     size = MAX_PATH;
11649     valW[0] = 0;
11650     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11651     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11652     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11653     ok(size == 11, "expected 11 got %u\n", size);
11654
11655     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11656     RegCloseKey(hkey_udproductpatch);
11657     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11658     RegCloseKey(hkey_udproductpatches);
11659     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11660     RegCloseKey(hkey_udpatch);
11661     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11662     RegCloseKey(hkey_patches);
11663     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11664     RegCloseKey(hkey_product);
11665     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11666     RegCloseKey(hkey_patch);
11667     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11668     RegCloseKey(hkey_udpatches);
11669     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11670     RegCloseKey(hkey_udprops);
11671     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11672     RegCloseKey(hkey_udproduct);
11673 }
11674
11675 static void test_MsiEnumProducts(void)
11676 {
11677     UINT r;
11678     int found1, found2, found3;
11679     DWORD index;
11680     char product1[39], product2[39], product3[39], guid[39];
11681     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11682     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11683     char *usersid;
11684     HKEY key1, key2, key3;
11685     REGSAM access = KEY_ALL_ACCESS;
11686
11687     create_test_guid(product1, product_squashed1);
11688     create_test_guid(product2, product_squashed2);
11689     create_test_guid(product3, product_squashed3);
11690     get_user_sid(&usersid);
11691
11692     if (is_wow64)
11693         access |= KEY_WOW64_64KEY;
11694
11695     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11696     strcat(keypath1, product_squashed1);
11697
11698     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11699     if (r == ERROR_ACCESS_DENIED)
11700     {
11701         skip("Not enough rights to perform tests\n");
11702         LocalFree(usersid);
11703         return;
11704     }
11705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11706
11707     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11708     strcat(keypath2, usersid);
11709     strcat(keypath2, "\\Installer\\Products\\");
11710     strcat(keypath2, product_squashed2);
11711
11712     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11714
11715     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11716     strcat(keypath3, product_squashed3);
11717
11718     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11719     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11720
11721     index = 0;
11722     r = MsiEnumProductsA(index, guid);
11723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11724
11725     r = MsiEnumProductsA(index, NULL);
11726     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11727
11728     index = 2;
11729     r = MsiEnumProductsA(index, guid);
11730     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11731
11732     index = 0;
11733     r = MsiEnumProductsA(index, guid);
11734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11735
11736     found1 = found2 = found3 = 0;
11737     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11738     {
11739         if (!strcmp(product1, guid)) found1 = 1;
11740         if (!strcmp(product2, guid)) found2 = 1;
11741         if (!strcmp(product3, guid)) found3 = 1;
11742         index++;
11743     }
11744     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11745     ok(found1, "product1 not found\n");
11746     ok(found2, "product2 not found\n");
11747     ok(found3, "product3 not found\n");
11748
11749     delete_key(key1, "", access & KEY_WOW64_64KEY);
11750     delete_key(key2, "", access & KEY_WOW64_64KEY);
11751     RegDeleteKeyA(key3, "");
11752     RegCloseKey(key1);
11753     RegCloseKey(key2);
11754     RegCloseKey(key3);
11755     LocalFree(usersid);
11756 }
11757
11758 START_TEST(msi)
11759 {
11760     init_functionpointers();
11761
11762     if (pIsWow64Process)
11763         pIsWow64Process(GetCurrentProcess(), &is_wow64);
11764
11765     test_usefeature();
11766     test_null();
11767     test_getcomponentpath();
11768     test_MsiGetFileHash();
11769
11770     if (!pConvertSidToStringSidA)
11771         win_skip("ConvertSidToStringSidA not implemented\n");
11772     else
11773     {
11774         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11775         test_MsiQueryProductState();
11776         test_MsiQueryFeatureState();
11777         test_MsiQueryComponentState();
11778         test_MsiGetComponentPath();
11779         test_MsiGetProductCode();
11780         test_MsiEnumClients();
11781         test_MsiGetProductInfo();
11782         test_MsiGetProductInfoEx();
11783         test_MsiGetUserInfo();
11784         test_MsiOpenProduct();
11785         test_MsiEnumPatchesEx();
11786         test_MsiEnumPatches();
11787         test_MsiGetPatchInfoEx();
11788         test_MsiGetPatchInfo();
11789         test_MsiEnumProducts();
11790     }
11791
11792     test_MsiGetFileVersion();
11793 }