mshtml: COM cleanup for the IHTMLDOMNode iface.
[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, "Expected ERROR_SUCCESS, got %d\n", r);
5004     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5005     ok(sz == 1, "Expected 1, got %d\n", sz);
5006
5007     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5009
5010     /* HelpLink value exists */
5011     sz = MAX_PATH;
5012     lstrcpyA(buf, "apple");
5013     r = pMsiGetProductInfoExA(prodcode, usersid,
5014                               MSIINSTALLCONTEXT_USERUNMANAGED,
5015                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5016     ok(r == ERROR_UNKNOWN_PROPERTY,
5017        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5018     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5019     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5020
5021     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5023
5024     /* HelpTelephone value exists */
5025     sz = MAX_PATH;
5026     lstrcpyA(buf, "apple");
5027     r = pMsiGetProductInfoExA(prodcode, usersid,
5028                               MSIINSTALLCONTEXT_USERUNMANAGED,
5029                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5030     ok(r == ERROR_UNKNOWN_PROPERTY,
5031        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5032     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5033     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5034
5035     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5036     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5037
5038     /* InstallDate value exists */
5039     sz = MAX_PATH;
5040     lstrcpyA(buf, "apple");
5041     r = pMsiGetProductInfoExA(prodcode, usersid,
5042                               MSIINSTALLCONTEXT_USERUNMANAGED,
5043                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5044     ok(r == ERROR_UNKNOWN_PROPERTY,
5045        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5046     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5047     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5048
5049     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5051
5052     /* DisplayName value exists */
5053     sz = MAX_PATH;
5054     lstrcpyA(buf, "apple");
5055     r = pMsiGetProductInfoExA(prodcode, usersid,
5056                               MSIINSTALLCONTEXT_USERUNMANAGED,
5057                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5058     ok(r == ERROR_UNKNOWN_PROPERTY,
5059        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5060     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5061     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5062
5063     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5065
5066     /* InstallLocation value exists */
5067     sz = MAX_PATH;
5068     lstrcpyA(buf, "apple");
5069     r = pMsiGetProductInfoExA(prodcode, usersid,
5070                               MSIINSTALLCONTEXT_USERUNMANAGED,
5071                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5072     ok(r == ERROR_UNKNOWN_PROPERTY,
5073        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5074     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5075     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5076
5077     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5079
5080     /* InstallSource value exists */
5081     sz = MAX_PATH;
5082     lstrcpyA(buf, "apple");
5083     r = pMsiGetProductInfoExA(prodcode, usersid,
5084                               MSIINSTALLCONTEXT_USERUNMANAGED,
5085                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5086     ok(r == ERROR_UNKNOWN_PROPERTY,
5087        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5088     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5089     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5090
5091     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5093
5094     /* LocalPackage value exists */
5095     sz = MAX_PATH;
5096     lstrcpyA(buf, "apple");
5097     r = pMsiGetProductInfoExA(prodcode, usersid,
5098                               MSIINSTALLCONTEXT_USERUNMANAGED,
5099                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5100     ok(r == ERROR_UNKNOWN_PROPERTY,
5101        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5102     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5103     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5104
5105     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5107
5108     /* Publisher value exists */
5109     sz = MAX_PATH;
5110     lstrcpyA(buf, "apple");
5111     r = pMsiGetProductInfoExA(prodcode, usersid,
5112                               MSIINSTALLCONTEXT_USERUNMANAGED,
5113                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5114     ok(r == ERROR_UNKNOWN_PROPERTY,
5115        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5116     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5117     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5118
5119     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5121
5122     /* URLInfoAbout value exists */
5123     sz = MAX_PATH;
5124     lstrcpyA(buf, "apple");
5125     r = pMsiGetProductInfoExA(prodcode, usersid,
5126                               MSIINSTALLCONTEXT_USERUNMANAGED,
5127                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5128     ok(r == ERROR_UNKNOWN_PROPERTY,
5129        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5130     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5131     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5132
5133     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5135
5136     /* URLUpdateInfo value exists */
5137     sz = MAX_PATH;
5138     lstrcpyA(buf, "apple");
5139     r = pMsiGetProductInfoExA(prodcode, usersid,
5140                               MSIINSTALLCONTEXT_USERUNMANAGED,
5141                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5142     ok(r == ERROR_UNKNOWN_PROPERTY,
5143        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5144     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5145     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5146
5147     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5149
5150     /* VersionMinor value exists */
5151     sz = MAX_PATH;
5152     lstrcpyA(buf, "apple");
5153     r = pMsiGetProductInfoExA(prodcode, usersid,
5154                               MSIINSTALLCONTEXT_USERUNMANAGED,
5155                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5156     ok(r == ERROR_UNKNOWN_PROPERTY,
5157        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5158     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5159     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5160
5161     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5163
5164     /* VersionMajor value exists */
5165     sz = MAX_PATH;
5166     lstrcpyA(buf, "apple");
5167     r = pMsiGetProductInfoExA(prodcode, usersid,
5168                               MSIINSTALLCONTEXT_USERUNMANAGED,
5169                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5170     ok(r == ERROR_UNKNOWN_PROPERTY,
5171        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5172     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5173     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5174
5175     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5177
5178     /* DisplayVersion value exists */
5179     sz = MAX_PATH;
5180     lstrcpyA(buf, "apple");
5181     r = pMsiGetProductInfoExA(prodcode, usersid,
5182                               MSIINSTALLCONTEXT_USERUNMANAGED,
5183                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5184     ok(r == ERROR_UNKNOWN_PROPERTY,
5185        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5186     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5187     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5188
5189     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5190     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5191
5192     /* ProductID value exists */
5193     sz = MAX_PATH;
5194     lstrcpyA(buf, "apple");
5195     r = pMsiGetProductInfoExA(prodcode, usersid,
5196                               MSIINSTALLCONTEXT_USERUNMANAGED,
5197                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5198     ok(r == ERROR_UNKNOWN_PROPERTY,
5199        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5200     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5201     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5202
5203     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5205
5206     /* RegCompany value exists */
5207     sz = MAX_PATH;
5208     lstrcpyA(buf, "apple");
5209     r = pMsiGetProductInfoExA(prodcode, usersid,
5210                               MSIINSTALLCONTEXT_USERUNMANAGED,
5211                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5212     ok(r == ERROR_UNKNOWN_PROPERTY,
5213        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5214     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5215     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5216
5217     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5218     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5219
5220     /* RegOwner value exists */
5221     sz = MAX_PATH;
5222     lstrcpyA(buf, "apple");
5223     r = pMsiGetProductInfoExA(prodcode, usersid,
5224                               MSIINSTALLCONTEXT_USERUNMANAGED,
5225                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5226     ok(r == ERROR_UNKNOWN_PROPERTY,
5227        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5228     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5229     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5230
5231     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5233
5234     /* Transforms value exists */
5235     sz = MAX_PATH;
5236     lstrcpyA(buf, "apple");
5237     r = pMsiGetProductInfoExA(prodcode, usersid,
5238                               MSIINSTALLCONTEXT_USERUNMANAGED,
5239                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5241     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5242     ok(sz == 5, "Expected 5, got %d\n", sz);
5243
5244     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5245     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5246
5247     /* Language value exists */
5248     sz = MAX_PATH;
5249     lstrcpyA(buf, "apple");
5250     r = pMsiGetProductInfoExA(prodcode, usersid,
5251                               MSIINSTALLCONTEXT_USERUNMANAGED,
5252                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5253     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5254     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5255     ok(sz == 4, "Expected 4, got %d\n", sz);
5256
5257     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5259
5260     /* ProductName value exists */
5261     sz = MAX_PATH;
5262     lstrcpyA(buf, "apple");
5263     r = pMsiGetProductInfoExA(prodcode, usersid,
5264                               MSIINSTALLCONTEXT_USERUNMANAGED,
5265                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5267     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5268     ok(sz == 4, "Expected 4, got %d\n", sz);
5269
5270     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5272
5273     /* FIXME */
5274
5275     /* AssignmentType value exists */
5276     sz = MAX_PATH;
5277     lstrcpyA(buf, "apple");
5278     r = pMsiGetProductInfoExA(prodcode, usersid,
5279                               MSIINSTALLCONTEXT_USERUNMANAGED,
5280                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5281     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5282     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5283     ok(sz == 0, "Expected 0, got %d\n", sz);
5284
5285     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5286     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5287
5288     /* FIXME */
5289
5290     /* PackageCode value exists */
5291     sz = MAX_PATH;
5292     lstrcpyA(buf, "apple");
5293     r = pMsiGetProductInfoExA(prodcode, usersid,
5294                               MSIINSTALLCONTEXT_USERUNMANAGED,
5295                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5296     todo_wine
5297     {
5298         ok(r == ERROR_BAD_CONFIGURATION,
5299            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5300         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5301         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5302     }
5303
5304     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5306
5307     /* Version value exists */
5308     sz = MAX_PATH;
5309     lstrcpyA(buf, "apple");
5310     r = pMsiGetProductInfoExA(prodcode, usersid,
5311                               MSIINSTALLCONTEXT_USERUNMANAGED,
5312                               INSTALLPROPERTY_VERSION, buf, &sz);
5313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5314     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5315     ok(sz == 3, "Expected 3, got %d\n", sz);
5316
5317     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5319
5320     /* ProductIcon value exists */
5321     sz = MAX_PATH;
5322     lstrcpyA(buf, "apple");
5323     r = pMsiGetProductInfoExA(prodcode, usersid,
5324                               MSIINSTALLCONTEXT_USERUNMANAGED,
5325                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5326     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5327     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5328     ok(sz == 4, "Expected 4, got %d\n", sz);
5329
5330     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5332
5333     /* PackageName value exists */
5334     sz = MAX_PATH;
5335     lstrcpyA(buf, "apple");
5336     r = pMsiGetProductInfoExA(prodcode, usersid,
5337                               MSIINSTALLCONTEXT_USERUNMANAGED,
5338                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5339     todo_wine
5340     {
5341         ok(r == ERROR_UNKNOWN_PRODUCT,
5342            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5343         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5344         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5345     }
5346
5347     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5349
5350     /* AuthorizedLUAApp value exists */
5351     sz = MAX_PATH;
5352     lstrcpyA(buf, "apple");
5353     r = pMsiGetProductInfoExA(prodcode, usersid,
5354                               MSIINSTALLCONTEXT_USERUNMANAGED,
5355                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5357     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5358     ok(sz == 4, "Expected 4, got %d\n", sz);
5359
5360     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5361     RegDeleteValueA(prodkey, "PackageName");
5362     RegDeleteValueA(prodkey, "ProductIcon");
5363     RegDeleteValueA(prodkey, "Version");
5364     RegDeleteValueA(prodkey, "PackageCode");
5365     RegDeleteValueA(prodkey, "AssignmentType");
5366     RegDeleteValueA(prodkey, "ProductName");
5367     RegDeleteValueA(prodkey, "Language");
5368     RegDeleteValueA(prodkey, "Transforms");
5369     RegDeleteValueA(prodkey, "RegOwner");
5370     RegDeleteValueA(prodkey, "RegCompany");
5371     RegDeleteValueA(prodkey, "ProductID");
5372     RegDeleteValueA(prodkey, "DisplayVersion");
5373     RegDeleteValueA(prodkey, "VersionMajor");
5374     RegDeleteValueA(prodkey, "VersionMinor");
5375     RegDeleteValueA(prodkey, "URLUpdateInfo");
5376     RegDeleteValueA(prodkey, "URLInfoAbout");
5377     RegDeleteValueA(prodkey, "Publisher");
5378     RegDeleteValueA(prodkey, "LocalPackage");
5379     RegDeleteValueA(prodkey, "InstallSource");
5380     RegDeleteValueA(prodkey, "InstallLocation");
5381     RegDeleteValueA(prodkey, "DisplayName");
5382     RegDeleteValueA(prodkey, "InstallDate");
5383     RegDeleteValueA(prodkey, "HelpTelephone");
5384     RegDeleteValueA(prodkey, "HelpLink");
5385     RegDeleteValueA(prodkey, "LocalPackage");
5386     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5387     RegCloseKey(prodkey);
5388
5389     /* MSIINSTALLCONTEXT_USERMANAGED */
5390
5391     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5392     lstrcatA(keypath, usersid);
5393     lstrcatA(keypath, "\\Products\\");
5394     lstrcatA(keypath, prod_squashed);
5395
5396     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5397     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5398
5399     /* local user product key exists */
5400     sz = MAX_PATH;
5401     lstrcpyA(buf, "apple");
5402     r = pMsiGetProductInfoExA(prodcode, usersid,
5403                               MSIINSTALLCONTEXT_USERMANAGED,
5404                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5405     ok(r == ERROR_UNKNOWN_PRODUCT,
5406        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5407     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5408     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5409
5410     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5412
5413     /* InstallProperties key exists */
5414     sz = MAX_PATH;
5415     lstrcpyA(buf, "apple");
5416     r = pMsiGetProductInfoExA(prodcode, usersid,
5417                               MSIINSTALLCONTEXT_USERMANAGED,
5418                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5419     ok(r == ERROR_UNKNOWN_PRODUCT,
5420        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5421     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5422     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5423
5424     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5426
5427     /* ManagedLocalPackage value exists */
5428     sz = MAX_PATH;
5429     lstrcpyA(buf, "apple");
5430     r = pMsiGetProductInfoExA(prodcode, usersid,
5431                               MSIINSTALLCONTEXT_USERMANAGED,
5432                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5434     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5435     ok(sz == 1, "Expected 1, got %d\n", sz);
5436
5437     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5439
5440     /* HelpLink value exists */
5441     sz = MAX_PATH;
5442     lstrcpyA(buf, "apple");
5443     r = pMsiGetProductInfoExA(prodcode, usersid,
5444                               MSIINSTALLCONTEXT_USERMANAGED,
5445                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5447     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5448     ok(sz == 4, "Expected 4, got %d\n", sz);
5449
5450     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5452
5453     /* HelpTelephone value exists */
5454     sz = MAX_PATH;
5455     lstrcpyA(buf, "apple");
5456     r = pMsiGetProductInfoExA(prodcode, usersid,
5457                               MSIINSTALLCONTEXT_USERMANAGED,
5458                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5460     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5461     ok(sz == 5, "Expected 5, got %d\n", sz);
5462
5463     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5464     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5465
5466     /* InstallDate value exists */
5467     sz = MAX_PATH;
5468     lstrcpyA(buf, "apple");
5469     r = pMsiGetProductInfoExA(prodcode, usersid,
5470                               MSIINSTALLCONTEXT_USERMANAGED,
5471                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5473     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5474     ok(sz == 4, "Expected 4, got %d\n", sz);
5475
5476     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5478
5479     /* DisplayName value exists */
5480     sz = MAX_PATH;
5481     lstrcpyA(buf, "apple");
5482     r = pMsiGetProductInfoExA(prodcode, usersid,
5483                               MSIINSTALLCONTEXT_USERMANAGED,
5484                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5485     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5486     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5487     ok(sz == 4, "Expected 4, got %d\n", sz);
5488
5489     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5491
5492     /* InstallLocation value exists */
5493     sz = MAX_PATH;
5494     lstrcpyA(buf, "apple");
5495     r = pMsiGetProductInfoExA(prodcode, usersid,
5496                               MSIINSTALLCONTEXT_USERMANAGED,
5497                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5499     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5500     ok(sz == 3, "Expected 3, got %d\n", sz);
5501
5502     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5504
5505     /* InstallSource value exists */
5506     sz = MAX_PATH;
5507     lstrcpyA(buf, "apple");
5508     r = pMsiGetProductInfoExA(prodcode, usersid,
5509                               MSIINSTALLCONTEXT_USERMANAGED,
5510                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5512     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5513     ok(sz == 6, "Expected 6, got %d\n", sz);
5514
5515     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5516     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5517
5518     /* LocalPackage value exists */
5519     sz = MAX_PATH;
5520     lstrcpyA(buf, "apple");
5521     r = pMsiGetProductInfoExA(prodcode, usersid,
5522                               MSIINSTALLCONTEXT_USERMANAGED,
5523                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5525     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5526     ok(sz == 5, "Expected 5, got %d\n", sz);
5527
5528     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5530
5531     /* Publisher value exists */
5532     sz = MAX_PATH;
5533     lstrcpyA(buf, "apple");
5534     r = pMsiGetProductInfoExA(prodcode, usersid,
5535                               MSIINSTALLCONTEXT_USERMANAGED,
5536                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5537     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5538     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5539     ok(sz == 3, "Expected 3, got %d\n", sz);
5540
5541     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5543
5544     /* URLInfoAbout value exists */
5545     sz = MAX_PATH;
5546     lstrcpyA(buf, "apple");
5547     r = pMsiGetProductInfoExA(prodcode, usersid,
5548                               MSIINSTALLCONTEXT_USERMANAGED,
5549                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5551     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5552     ok(sz == 5, "Expected 5, got %d\n", sz);
5553
5554     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5556
5557     /* URLUpdateInfo value exists */
5558     sz = MAX_PATH;
5559     lstrcpyA(buf, "apple");
5560     r = pMsiGetProductInfoExA(prodcode, usersid,
5561                               MSIINSTALLCONTEXT_USERMANAGED,
5562                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5564     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5565     ok(sz == 6, "Expected 6, got %d\n", sz);
5566
5567     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5569
5570     /* VersionMinor value exists */
5571     sz = MAX_PATH;
5572     lstrcpyA(buf, "apple");
5573     r = pMsiGetProductInfoExA(prodcode, usersid,
5574                               MSIINSTALLCONTEXT_USERMANAGED,
5575                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5577     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5578     ok(sz == 1, "Expected 1, got %d\n", sz);
5579
5580     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5582
5583     /* VersionMajor value exists */
5584     sz = MAX_PATH;
5585     lstrcpyA(buf, "apple");
5586     r = pMsiGetProductInfoExA(prodcode, usersid,
5587                               MSIINSTALLCONTEXT_USERMANAGED,
5588                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5589     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5590     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5591     ok(sz == 1, "Expected 1, got %d\n", sz);
5592
5593     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5594     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5595
5596     /* DisplayVersion value exists */
5597     sz = MAX_PATH;
5598     lstrcpyA(buf, "apple");
5599     r = pMsiGetProductInfoExA(prodcode, usersid,
5600                               MSIINSTALLCONTEXT_USERMANAGED,
5601                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5603     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5604     ok(sz == 5, "Expected 5, got %d\n", sz);
5605
5606     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5608
5609     /* ProductID value exists */
5610     sz = MAX_PATH;
5611     lstrcpyA(buf, "apple");
5612     r = pMsiGetProductInfoExA(prodcode, usersid,
5613                               MSIINSTALLCONTEXT_USERMANAGED,
5614                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5615     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5616     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5617     ok(sz == 2, "Expected 2, got %d\n", sz);
5618
5619     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5621
5622     /* RegCompany value exists */
5623     sz = MAX_PATH;
5624     lstrcpyA(buf, "apple");
5625     r = pMsiGetProductInfoExA(prodcode, usersid,
5626                               MSIINSTALLCONTEXT_USERMANAGED,
5627                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5628     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5629     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5630     ok(sz == 4, "Expected 4, got %d\n", sz);
5631
5632     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5633     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5634
5635     /* RegOwner value exists */
5636     sz = MAX_PATH;
5637     lstrcpyA(buf, "apple");
5638     r = pMsiGetProductInfoExA(prodcode, usersid,
5639                               MSIINSTALLCONTEXT_USERMANAGED,
5640                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5641     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5642     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5643     ok(sz == 5, "Expected 5, got %d\n", sz);
5644
5645     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5647
5648     /* Transforms value exists */
5649     sz = MAX_PATH;
5650     lstrcpyA(buf, "apple");
5651     r = pMsiGetProductInfoExA(prodcode, usersid,
5652                               MSIINSTALLCONTEXT_USERMANAGED,
5653                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5654     ok(r == ERROR_UNKNOWN_PRODUCT,
5655        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5656     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5657     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5658
5659     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5661
5662     /* Language value exists */
5663     sz = MAX_PATH;
5664     lstrcpyA(buf, "apple");
5665     r = pMsiGetProductInfoExA(prodcode, usersid,
5666                               MSIINSTALLCONTEXT_USERMANAGED,
5667                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5668     ok(r == ERROR_UNKNOWN_PRODUCT,
5669        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5670     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5671     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5672
5673     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5675
5676     /* ProductName value exists */
5677     sz = MAX_PATH;
5678     lstrcpyA(buf, "apple");
5679     r = pMsiGetProductInfoExA(prodcode, usersid,
5680                               MSIINSTALLCONTEXT_USERMANAGED,
5681                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5682     ok(r == ERROR_UNKNOWN_PRODUCT,
5683        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5684     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5685     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5686
5687     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5688     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5689
5690     /* FIXME */
5691
5692     /* AssignmentType value exists */
5693     sz = MAX_PATH;
5694     lstrcpyA(buf, "apple");
5695     r = pMsiGetProductInfoExA(prodcode, usersid,
5696                               MSIINSTALLCONTEXT_USERMANAGED,
5697                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5698     ok(r == ERROR_UNKNOWN_PRODUCT,
5699        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5700     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5701     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5702
5703     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5704     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5705
5706     /* PackageCode value exists */
5707     sz = MAX_PATH;
5708     lstrcpyA(buf, "apple");
5709     r = pMsiGetProductInfoExA(prodcode, usersid,
5710                               MSIINSTALLCONTEXT_USERMANAGED,
5711                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5712     ok(r == ERROR_UNKNOWN_PRODUCT,
5713        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5714     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5715     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5716
5717     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5719
5720     /* Version value exists */
5721     sz = MAX_PATH;
5722     lstrcpyA(buf, "apple");
5723     r = pMsiGetProductInfoExA(prodcode, usersid,
5724                               MSIINSTALLCONTEXT_USERMANAGED,
5725                               INSTALLPROPERTY_VERSION, buf, &sz);
5726     ok(r == ERROR_UNKNOWN_PRODUCT,
5727        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5728     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5729     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5730
5731     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5732     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5733
5734     /* ProductIcon value exists */
5735     sz = MAX_PATH;
5736     lstrcpyA(buf, "apple");
5737     r = pMsiGetProductInfoExA(prodcode, usersid,
5738                               MSIINSTALLCONTEXT_USERMANAGED,
5739                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5740     ok(r == ERROR_UNKNOWN_PRODUCT,
5741        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5742     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5743     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5744
5745     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5747
5748     /* PackageName value exists */
5749     sz = MAX_PATH;
5750     lstrcpyA(buf, "apple");
5751     r = pMsiGetProductInfoExA(prodcode, usersid,
5752                               MSIINSTALLCONTEXT_USERMANAGED,
5753                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5754     ok(r == ERROR_UNKNOWN_PRODUCT,
5755        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5756     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5757     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5758
5759     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5761
5762     /* AuthorizedLUAApp value exists */
5763     sz = MAX_PATH;
5764     lstrcpyA(buf, "apple");
5765     r = pMsiGetProductInfoExA(prodcode, usersid,
5766                               MSIINSTALLCONTEXT_USERMANAGED,
5767                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5768     ok(r == ERROR_UNKNOWN_PRODUCT,
5769        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5770     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5771     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5772
5773     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5774     RegDeleteValueA(propkey, "PackageName");
5775     RegDeleteValueA(propkey, "ProductIcon");
5776     RegDeleteValueA(propkey, "Version");
5777     RegDeleteValueA(propkey, "PackageCode");
5778     RegDeleteValueA(propkey, "AssignmentType");
5779     RegDeleteValueA(propkey, "ProductName");
5780     RegDeleteValueA(propkey, "Language");
5781     RegDeleteValueA(propkey, "Transforms");
5782     RegDeleteValueA(propkey, "RegOwner");
5783     RegDeleteValueA(propkey, "RegCompany");
5784     RegDeleteValueA(propkey, "ProductID");
5785     RegDeleteValueA(propkey, "DisplayVersion");
5786     RegDeleteValueA(propkey, "VersionMajor");
5787     RegDeleteValueA(propkey, "VersionMinor");
5788     RegDeleteValueA(propkey, "URLUpdateInfo");
5789     RegDeleteValueA(propkey, "URLInfoAbout");
5790     RegDeleteValueA(propkey, "Publisher");
5791     RegDeleteValueA(propkey, "LocalPackage");
5792     RegDeleteValueA(propkey, "InstallSource");
5793     RegDeleteValueA(propkey, "InstallLocation");
5794     RegDeleteValueA(propkey, "DisplayName");
5795     RegDeleteValueA(propkey, "InstallDate");
5796     RegDeleteValueA(propkey, "HelpTelephone");
5797     RegDeleteValueA(propkey, "HelpLink");
5798     RegDeleteValueA(propkey, "ManagedLocalPackage");
5799     delete_key(propkey, "", access & KEY_WOW64_64KEY);
5800     RegCloseKey(propkey);
5801     delete_key(localkey, "", access & KEY_WOW64_64KEY);
5802     RegCloseKey(localkey);
5803
5804     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5805     lstrcatA(keypath, usersid);
5806     lstrcatA(keypath, "\\Installer\\Products\\");
5807     lstrcatA(keypath, prod_squashed);
5808
5809     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5811
5812     /* user product key exists */
5813     sz = MAX_PATH;
5814     lstrcpyA(buf, "apple");
5815     r = pMsiGetProductInfoExA(prodcode, usersid,
5816                               MSIINSTALLCONTEXT_USERMANAGED,
5817                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5818     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5819     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5820     ok(sz == 1, "Expected 1, got %d\n", sz);
5821
5822     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5823     RegCloseKey(userkey);
5824
5825     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5826     lstrcatA(keypath, prod_squashed);
5827
5828     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5830
5831     /* current user product key exists */
5832     sz = MAX_PATH;
5833     lstrcpyA(buf, "apple");
5834     r = pMsiGetProductInfoExA(prodcode, usersid,
5835                               MSIINSTALLCONTEXT_USERMANAGED,
5836                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5837     ok(r == ERROR_UNKNOWN_PRODUCT,
5838        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5839     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5840     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5841
5842     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5844
5845     /* HelpLink value exists, user product key does not exist */
5846     sz = MAX_PATH;
5847     lstrcpyA(buf, "apple");
5848     r = pMsiGetProductInfoExA(prodcode, usersid,
5849                               MSIINSTALLCONTEXT_USERMANAGED,
5850                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5851     ok(r == ERROR_UNKNOWN_PRODUCT,
5852        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5853     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5854     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5855
5856     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5857     lstrcatA(keypath, usersid);
5858     lstrcatA(keypath, "\\Installer\\Products\\");
5859     lstrcatA(keypath, prod_squashed);
5860
5861     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5863
5864     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5865     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5866
5867     /* HelpLink value exists, user product key does exist */
5868     sz = MAX_PATH;
5869     lstrcpyA(buf, "apple");
5870     r = pMsiGetProductInfoExA(prodcode, usersid,
5871                               MSIINSTALLCONTEXT_USERMANAGED,
5872                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5873     ok(r == ERROR_UNKNOWN_PROPERTY,
5874        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5875     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5876     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5877
5878     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5880
5881     /* HelpTelephone value exists */
5882     sz = MAX_PATH;
5883     lstrcpyA(buf, "apple");
5884     r = pMsiGetProductInfoExA(prodcode, usersid,
5885                               MSIINSTALLCONTEXT_USERMANAGED,
5886                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5887     ok(r == ERROR_UNKNOWN_PROPERTY,
5888        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5889     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5890     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5891
5892     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5894
5895     /* InstallDate value exists */
5896     sz = MAX_PATH;
5897     lstrcpyA(buf, "apple");
5898     r = pMsiGetProductInfoExA(prodcode, usersid,
5899                               MSIINSTALLCONTEXT_USERMANAGED,
5900                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5901     ok(r == ERROR_UNKNOWN_PROPERTY,
5902        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5903     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5904     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5905
5906     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5908
5909     /* DisplayName value exists */
5910     sz = MAX_PATH;
5911     lstrcpyA(buf, "apple");
5912     r = pMsiGetProductInfoExA(prodcode, usersid,
5913                               MSIINSTALLCONTEXT_USERMANAGED,
5914                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5915     ok(r == ERROR_UNKNOWN_PROPERTY,
5916        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5917     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5918     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5919
5920     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5922
5923     /* InstallLocation value exists */
5924     sz = MAX_PATH;
5925     lstrcpyA(buf, "apple");
5926     r = pMsiGetProductInfoExA(prodcode, usersid,
5927                               MSIINSTALLCONTEXT_USERMANAGED,
5928                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5929     ok(r == ERROR_UNKNOWN_PROPERTY,
5930        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5931     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5932     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5933
5934     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5936
5937     /* InstallSource value exists */
5938     sz = MAX_PATH;
5939     lstrcpyA(buf, "apple");
5940     r = pMsiGetProductInfoExA(prodcode, usersid,
5941                               MSIINSTALLCONTEXT_USERMANAGED,
5942                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5943     ok(r == ERROR_UNKNOWN_PROPERTY,
5944        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5945     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5946     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5947
5948     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5950
5951     /* LocalPackage value exists */
5952     sz = MAX_PATH;
5953     lstrcpyA(buf, "apple");
5954     r = pMsiGetProductInfoExA(prodcode, usersid,
5955                               MSIINSTALLCONTEXT_USERMANAGED,
5956                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5957     ok(r == ERROR_UNKNOWN_PROPERTY,
5958        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5959     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5960     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5961
5962     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5964
5965     /* Publisher value exists */
5966     sz = MAX_PATH;
5967     lstrcpyA(buf, "apple");
5968     r = pMsiGetProductInfoExA(prodcode, usersid,
5969                               MSIINSTALLCONTEXT_USERMANAGED,
5970                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5971     ok(r == ERROR_UNKNOWN_PROPERTY,
5972        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5973     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5974     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5975
5976     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5978
5979     /* URLInfoAbout value exists */
5980     sz = MAX_PATH;
5981     lstrcpyA(buf, "apple");
5982     r = pMsiGetProductInfoExA(prodcode, usersid,
5983                               MSIINSTALLCONTEXT_USERMANAGED,
5984                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5985     ok(r == ERROR_UNKNOWN_PROPERTY,
5986        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5987     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5988     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5989
5990     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5992
5993     /* URLUpdateInfo value exists */
5994     sz = MAX_PATH;
5995     lstrcpyA(buf, "apple");
5996     r = pMsiGetProductInfoExA(prodcode, usersid,
5997                               MSIINSTALLCONTEXT_USERMANAGED,
5998                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5999     ok(r == ERROR_UNKNOWN_PROPERTY,
6000        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6001     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6002     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6003
6004     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6006
6007     /* VersionMinor value exists */
6008     sz = MAX_PATH;
6009     lstrcpyA(buf, "apple");
6010     r = pMsiGetProductInfoExA(prodcode, usersid,
6011                               MSIINSTALLCONTEXT_USERMANAGED,
6012                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6013     ok(r == ERROR_UNKNOWN_PROPERTY,
6014        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6015     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6016     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6017
6018     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6020
6021     /* VersionMajor value exists */
6022     sz = MAX_PATH;
6023     lstrcpyA(buf, "apple");
6024     r = pMsiGetProductInfoExA(prodcode, usersid,
6025                               MSIINSTALLCONTEXT_USERMANAGED,
6026                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6027     ok(r == ERROR_UNKNOWN_PROPERTY,
6028        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6029     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6030     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6031
6032     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6034
6035     /* DisplayVersion value exists */
6036     sz = MAX_PATH;
6037     lstrcpyA(buf, "apple");
6038     r = pMsiGetProductInfoExA(prodcode, usersid,
6039                               MSIINSTALLCONTEXT_USERMANAGED,
6040                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6041     ok(r == ERROR_UNKNOWN_PROPERTY,
6042        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6043     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6044     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6045
6046     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6048
6049     /* ProductID value exists */
6050     sz = MAX_PATH;
6051     lstrcpyA(buf, "apple");
6052     r = pMsiGetProductInfoExA(prodcode, usersid,
6053                               MSIINSTALLCONTEXT_USERMANAGED,
6054                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6055     ok(r == ERROR_UNKNOWN_PROPERTY,
6056        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6057     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6058     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6059
6060     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6062
6063     /* RegCompany value exists */
6064     sz = MAX_PATH;
6065     lstrcpyA(buf, "apple");
6066     r = pMsiGetProductInfoExA(prodcode, usersid,
6067                               MSIINSTALLCONTEXT_USERMANAGED,
6068                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6069     ok(r == ERROR_UNKNOWN_PROPERTY,
6070        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6071     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6072     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6073
6074     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6076
6077     /* RegOwner value exists */
6078     sz = MAX_PATH;
6079     lstrcpyA(buf, "apple");
6080     r = pMsiGetProductInfoExA(prodcode, usersid,
6081                               MSIINSTALLCONTEXT_USERMANAGED,
6082                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6083     ok(r == ERROR_UNKNOWN_PROPERTY,
6084        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6085     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6086     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6087
6088     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6090
6091     /* Transforms value exists */
6092     sz = MAX_PATH;
6093     lstrcpyA(buf, "apple");
6094     r = pMsiGetProductInfoExA(prodcode, usersid,
6095                               MSIINSTALLCONTEXT_USERMANAGED,
6096                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6097     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6098     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6099     ok(sz == 5, "Expected 5, got %d\n", sz);
6100
6101     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6103
6104     /* Language value exists */
6105     sz = MAX_PATH;
6106     lstrcpyA(buf, "apple");
6107     r = pMsiGetProductInfoExA(prodcode, usersid,
6108                               MSIINSTALLCONTEXT_USERMANAGED,
6109                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6110     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6111     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6112     ok(sz == 4, "Expected 4, got %d\n", sz);
6113
6114     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6115     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6116
6117     /* ProductName value exists */
6118     sz = MAX_PATH;
6119     lstrcpyA(buf, "apple");
6120     r = pMsiGetProductInfoExA(prodcode, usersid,
6121                               MSIINSTALLCONTEXT_USERMANAGED,
6122                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6124     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6125     ok(sz == 4, "Expected 4, got %d\n", sz);
6126
6127     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6129
6130     /* FIXME */
6131
6132     /* AssignmentType value exists */
6133     sz = MAX_PATH;
6134     lstrcpyA(buf, "apple");
6135     r = pMsiGetProductInfoExA(prodcode, usersid,
6136                               MSIINSTALLCONTEXT_USERMANAGED,
6137                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6139     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6140     ok(sz == 0, "Expected 0, got %d\n", sz);
6141
6142     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6144
6145     /* FIXME */
6146
6147     /* PackageCode value exists */
6148     sz = MAX_PATH;
6149     lstrcpyA(buf, "apple");
6150     r = pMsiGetProductInfoExA(prodcode, usersid,
6151                               MSIINSTALLCONTEXT_USERMANAGED,
6152                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6153     todo_wine
6154     {
6155         ok(r == ERROR_BAD_CONFIGURATION,
6156            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6157         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6158         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6159     }
6160
6161     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6163
6164     /* Version value exists */
6165     sz = MAX_PATH;
6166     lstrcpyA(buf, "apple");
6167     r = pMsiGetProductInfoExA(prodcode, usersid,
6168                               MSIINSTALLCONTEXT_USERMANAGED,
6169                               INSTALLPROPERTY_VERSION, buf, &sz);
6170     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6171     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6172     ok(sz == 3, "Expected 3, got %d\n", sz);
6173
6174     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6175     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6176
6177     /* ProductIcon value exists */
6178     sz = MAX_PATH;
6179     lstrcpyA(buf, "apple");
6180     r = pMsiGetProductInfoExA(prodcode, usersid,
6181                               MSIINSTALLCONTEXT_USERMANAGED,
6182                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6183     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6184     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6185     ok(sz == 4, "Expected 4, got %d\n", sz);
6186
6187     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6189
6190     /* PackageName value exists */
6191     sz = MAX_PATH;
6192     lstrcpyA(buf, "apple");
6193     r = pMsiGetProductInfoExA(prodcode, usersid,
6194                               MSIINSTALLCONTEXT_USERMANAGED,
6195                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6196     todo_wine
6197     {
6198         ok(r == ERROR_UNKNOWN_PRODUCT,
6199            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6200         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6201         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6202     }
6203
6204     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6206
6207     /* AuthorizedLUAApp value exists */
6208     sz = MAX_PATH;
6209     lstrcpyA(buf, "apple");
6210     r = pMsiGetProductInfoExA(prodcode, usersid,
6211                               MSIINSTALLCONTEXT_USERMANAGED,
6212                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6214     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6215     ok(sz == 4, "Expected 4, got %d\n", sz);
6216
6217     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6218     RegDeleteValueA(userkey, "PackageName");
6219     RegDeleteValueA(userkey, "ProductIcon");
6220     RegDeleteValueA(userkey, "Version");
6221     RegDeleteValueA(userkey, "PackageCode");
6222     RegDeleteValueA(userkey, "AssignmentType");
6223     RegDeleteValueA(userkey, "ProductName");
6224     RegDeleteValueA(userkey, "Language");
6225     RegDeleteValueA(userkey, "Transforms");
6226     RegDeleteValueA(userkey, "RegOwner");
6227     RegDeleteValueA(userkey, "RegCompany");
6228     RegDeleteValueA(userkey, "ProductID");
6229     RegDeleteValueA(userkey, "DisplayVersion");
6230     RegDeleteValueA(userkey, "VersionMajor");
6231     RegDeleteValueA(userkey, "VersionMinor");
6232     RegDeleteValueA(userkey, "URLUpdateInfo");
6233     RegDeleteValueA(userkey, "URLInfoAbout");
6234     RegDeleteValueA(userkey, "Publisher");
6235     RegDeleteValueA(userkey, "LocalPackage");
6236     RegDeleteValueA(userkey, "InstallSource");
6237     RegDeleteValueA(userkey, "InstallLocation");
6238     RegDeleteValueA(userkey, "DisplayName");
6239     RegDeleteValueA(userkey, "InstallDate");
6240     RegDeleteValueA(userkey, "HelpTelephone");
6241     RegDeleteValueA(userkey, "HelpLink");
6242     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6243     RegCloseKey(userkey);
6244     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6245     RegCloseKey(prodkey);
6246
6247     /* MSIINSTALLCONTEXT_MACHINE */
6248
6249     /* szUserSid is non-NULL */
6250     sz = MAX_PATH;
6251     lstrcpyA(buf, "apple");
6252     r = pMsiGetProductInfoExA(prodcode, usersid,
6253                               MSIINSTALLCONTEXT_MACHINE,
6254                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6255     ok(r == ERROR_INVALID_PARAMETER,
6256        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6257     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6258     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6259
6260     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6261     lstrcatA(keypath, prod_squashed);
6262
6263     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6264     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6265
6266     /* local system product key exists */
6267     sz = MAX_PATH;
6268     lstrcpyA(buf, "apple");
6269     r = pMsiGetProductInfoExA(prodcode, NULL,
6270                               MSIINSTALLCONTEXT_MACHINE,
6271                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6272     ok(r == ERROR_UNKNOWN_PRODUCT,
6273        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6274     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6275     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6276
6277     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6279
6280     /* InstallProperties key exists */
6281     sz = MAX_PATH;
6282     lstrcpyA(buf, "apple");
6283     r = pMsiGetProductInfoExA(prodcode, NULL,
6284                               MSIINSTALLCONTEXT_MACHINE,
6285                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6286     ok(r == ERROR_UNKNOWN_PRODUCT,
6287        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6288     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6289     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6290
6291     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6292     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6293
6294     /* LocalPackage value exists */
6295     sz = MAX_PATH;
6296     lstrcpyA(buf, "apple");
6297     r = pMsiGetProductInfoExA(prodcode, NULL,
6298                               MSIINSTALLCONTEXT_MACHINE,
6299                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6300     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6301     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6302     ok(sz == 1, "Expected 1, got %d\n", sz);
6303
6304     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6306
6307     /* HelpLink value exists */
6308     sz = MAX_PATH;
6309     lstrcpyA(buf, "apple");
6310     r = pMsiGetProductInfoExA(prodcode, NULL,
6311                               MSIINSTALLCONTEXT_MACHINE,
6312                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6314     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6315     ok(sz == 4, "Expected 4, got %d\n", sz);
6316
6317     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6319
6320     /* HelpTelephone value exists */
6321     sz = MAX_PATH;
6322     lstrcpyA(buf, "apple");
6323     r = pMsiGetProductInfoExA(prodcode, NULL,
6324                               MSIINSTALLCONTEXT_MACHINE,
6325                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6326     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6327     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6328     ok(sz == 5, "Expected 5, got %d\n", sz);
6329
6330     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6332
6333     /* InstallDate value exists */
6334     sz = MAX_PATH;
6335     lstrcpyA(buf, "apple");
6336     r = pMsiGetProductInfoExA(prodcode, NULL,
6337                               MSIINSTALLCONTEXT_MACHINE,
6338                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6339     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6340     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6341     ok(sz == 4, "Expected 4, got %d\n", sz);
6342
6343     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6345
6346     /* DisplayName value exists */
6347     sz = MAX_PATH;
6348     lstrcpyA(buf, "apple");
6349     r = pMsiGetProductInfoExA(prodcode, NULL,
6350                               MSIINSTALLCONTEXT_MACHINE,
6351                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6352     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6353     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6354     ok(sz == 4, "Expected 4, got %d\n", sz);
6355
6356     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6358
6359     /* InstallLocation value exists */
6360     sz = MAX_PATH;
6361     lstrcpyA(buf, "apple");
6362     r = pMsiGetProductInfoExA(prodcode, NULL,
6363                               MSIINSTALLCONTEXT_MACHINE,
6364                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6366     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6367     ok(sz == 3, "Expected 3, got %d\n", sz);
6368
6369     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6371
6372     /* InstallSource value exists */
6373     sz = MAX_PATH;
6374     lstrcpyA(buf, "apple");
6375     r = pMsiGetProductInfoExA(prodcode, NULL,
6376                               MSIINSTALLCONTEXT_MACHINE,
6377                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6378     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6379     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6380     ok(sz == 6, "Expected 6, got %d\n", sz);
6381
6382     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6384
6385     /* LocalPackage value exists */
6386     sz = MAX_PATH;
6387     lstrcpyA(buf, "apple");
6388     r = pMsiGetProductInfoExA(prodcode, NULL,
6389                               MSIINSTALLCONTEXT_MACHINE,
6390                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6391     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6392     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6393     ok(sz == 5, "Expected 5, got %d\n", sz);
6394
6395     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6397
6398     /* Publisher value exists */
6399     sz = MAX_PATH;
6400     lstrcpyA(buf, "apple");
6401     r = pMsiGetProductInfoExA(prodcode, NULL,
6402                               MSIINSTALLCONTEXT_MACHINE,
6403                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6405     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6406     ok(sz == 3, "Expected 3, got %d\n", sz);
6407
6408     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6410
6411     /* URLInfoAbout value exists */
6412     sz = MAX_PATH;
6413     lstrcpyA(buf, "apple");
6414     r = pMsiGetProductInfoExA(prodcode, NULL,
6415                               MSIINSTALLCONTEXT_MACHINE,
6416                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6418     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6419     ok(sz == 5, "Expected 5, got %d\n", sz);
6420
6421     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6423
6424     /* URLUpdateInfo value exists */
6425     sz = MAX_PATH;
6426     lstrcpyA(buf, "apple");
6427     r = pMsiGetProductInfoExA(prodcode, NULL,
6428                               MSIINSTALLCONTEXT_MACHINE,
6429                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6431     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6432     ok(sz == 6, "Expected 6, got %d\n", sz);
6433
6434     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6436
6437     /* VersionMinor value exists */
6438     sz = MAX_PATH;
6439     lstrcpyA(buf, "apple");
6440     r = pMsiGetProductInfoExA(prodcode, NULL,
6441                               MSIINSTALLCONTEXT_MACHINE,
6442                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6444     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6445     ok(sz == 1, "Expected 1, got %d\n", sz);
6446
6447     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6449
6450     /* VersionMajor value exists */
6451     sz = MAX_PATH;
6452     lstrcpyA(buf, "apple");
6453     r = pMsiGetProductInfoExA(prodcode, NULL,
6454                               MSIINSTALLCONTEXT_MACHINE,
6455                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6457     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6458     ok(sz == 1, "Expected 1, got %d\n", sz);
6459
6460     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6461     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6462
6463     /* DisplayVersion value exists */
6464     sz = MAX_PATH;
6465     lstrcpyA(buf, "apple");
6466     r = pMsiGetProductInfoExA(prodcode, NULL,
6467                               MSIINSTALLCONTEXT_MACHINE,
6468                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6470     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6471     ok(sz == 5, "Expected 5, got %d\n", sz);
6472
6473     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6474     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6475
6476     /* ProductID value exists */
6477     sz = MAX_PATH;
6478     lstrcpyA(buf, "apple");
6479     r = pMsiGetProductInfoExA(prodcode, NULL,
6480                               MSIINSTALLCONTEXT_MACHINE,
6481                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6483     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6484     ok(sz == 2, "Expected 2, got %d\n", sz);
6485
6486     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6488
6489     /* RegCompany value exists */
6490     sz = MAX_PATH;
6491     lstrcpyA(buf, "apple");
6492     r = pMsiGetProductInfoExA(prodcode, NULL,
6493                               MSIINSTALLCONTEXT_MACHINE,
6494                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6495     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6496     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6497     ok(sz == 4, "Expected 4, got %d\n", sz);
6498
6499     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6501
6502     /* RegOwner value exists */
6503     sz = MAX_PATH;
6504     lstrcpyA(buf, "apple");
6505     r = pMsiGetProductInfoExA(prodcode, NULL,
6506                               MSIINSTALLCONTEXT_MACHINE,
6507                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6508     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6509     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6510     ok(sz == 5, "Expected 5, got %d\n", sz);
6511
6512     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6513     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6514
6515     /* Transforms value exists */
6516     sz = MAX_PATH;
6517     lstrcpyA(buf, "apple");
6518     r = pMsiGetProductInfoExA(prodcode, NULL,
6519                               MSIINSTALLCONTEXT_MACHINE,
6520                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6521     ok(r == ERROR_UNKNOWN_PRODUCT,
6522        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6523     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6524     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6525
6526     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6528
6529     /* Language value exists */
6530     sz = MAX_PATH;
6531     lstrcpyA(buf, "apple");
6532     r = pMsiGetProductInfoExA(prodcode, NULL,
6533                               MSIINSTALLCONTEXT_MACHINE,
6534                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6535     ok(r == ERROR_UNKNOWN_PRODUCT,
6536        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6537     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6538     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6539
6540     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6541     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6542
6543     /* ProductName value exists */
6544     sz = MAX_PATH;
6545     lstrcpyA(buf, "apple");
6546     r = pMsiGetProductInfoExA(prodcode, NULL,
6547                               MSIINSTALLCONTEXT_MACHINE,
6548                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6549     ok(r == ERROR_UNKNOWN_PRODUCT,
6550        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6551     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6552     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6553
6554     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6556
6557     /* FIXME */
6558
6559     /* AssignmentType value exists */
6560     sz = MAX_PATH;
6561     lstrcpyA(buf, "apple");
6562     r = pMsiGetProductInfoExA(prodcode, NULL,
6563                               MSIINSTALLCONTEXT_MACHINE,
6564                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6565     ok(r == ERROR_UNKNOWN_PRODUCT,
6566        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6567     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6568     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6569
6570     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6572
6573     /* PackageCode value exists */
6574     sz = MAX_PATH;
6575     lstrcpyA(buf, "apple");
6576     r = pMsiGetProductInfoExA(prodcode, NULL,
6577                               MSIINSTALLCONTEXT_MACHINE,
6578                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6579     ok(r == ERROR_UNKNOWN_PRODUCT,
6580        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6581     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6582     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6583
6584     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6586
6587     /* Version value exists */
6588     sz = MAX_PATH;
6589     lstrcpyA(buf, "apple");
6590     r = pMsiGetProductInfoExA(prodcode, NULL,
6591                               MSIINSTALLCONTEXT_MACHINE,
6592                               INSTALLPROPERTY_VERSION, buf, &sz);
6593     ok(r == ERROR_UNKNOWN_PRODUCT,
6594        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6595     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6596     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6597
6598     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6600
6601     /* ProductIcon value exists */
6602     sz = MAX_PATH;
6603     lstrcpyA(buf, "apple");
6604     r = pMsiGetProductInfoExA(prodcode, NULL,
6605                               MSIINSTALLCONTEXT_MACHINE,
6606                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6607     ok(r == ERROR_UNKNOWN_PRODUCT,
6608        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6609     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6610     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6611
6612     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6614
6615     /* PackageName value exists */
6616     sz = MAX_PATH;
6617     lstrcpyA(buf, "apple");
6618     r = pMsiGetProductInfoExA(prodcode, NULL,
6619                               MSIINSTALLCONTEXT_MACHINE,
6620                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6621     ok(r == ERROR_UNKNOWN_PRODUCT,
6622        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6623     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6624     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6625
6626     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6628
6629     /* AuthorizedLUAApp value exists */
6630     sz = MAX_PATH;
6631     lstrcpyA(buf, "apple");
6632     r = pMsiGetProductInfoExA(prodcode, NULL,
6633                               MSIINSTALLCONTEXT_MACHINE,
6634                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6635     ok(r == ERROR_UNKNOWN_PRODUCT,
6636        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6637     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6638     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6639
6640     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6641     RegDeleteValueA(propkey, "PackageName");
6642     RegDeleteValueA(propkey, "ProductIcon");
6643     RegDeleteValueA(propkey, "Version");
6644     RegDeleteValueA(propkey, "PackageCode");
6645     RegDeleteValueA(propkey, "AssignmentType");
6646     RegDeleteValueA(propkey, "ProductName");
6647     RegDeleteValueA(propkey, "Language");
6648     RegDeleteValueA(propkey, "Transforms");
6649     RegDeleteValueA(propkey, "RegOwner");
6650     RegDeleteValueA(propkey, "RegCompany");
6651     RegDeleteValueA(propkey, "ProductID");
6652     RegDeleteValueA(propkey, "DisplayVersion");
6653     RegDeleteValueA(propkey, "VersionMajor");
6654     RegDeleteValueA(propkey, "VersionMinor");
6655     RegDeleteValueA(propkey, "URLUpdateInfo");
6656     RegDeleteValueA(propkey, "URLInfoAbout");
6657     RegDeleteValueA(propkey, "Publisher");
6658     RegDeleteValueA(propkey, "LocalPackage");
6659     RegDeleteValueA(propkey, "InstallSource");
6660     RegDeleteValueA(propkey, "InstallLocation");
6661     RegDeleteValueA(propkey, "DisplayName");
6662     RegDeleteValueA(propkey, "InstallDate");
6663     RegDeleteValueA(propkey, "HelpTelephone");
6664     RegDeleteValueA(propkey, "HelpLink");
6665     RegDeleteValueA(propkey, "LocalPackage");
6666     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6667     RegCloseKey(propkey);
6668     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6669     RegCloseKey(localkey);
6670
6671     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6672     lstrcatA(keypath, prod_squashed);
6673
6674     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6676
6677     /* local classes product key exists */
6678     sz = MAX_PATH;
6679     lstrcpyA(buf, "apple");
6680     r = pMsiGetProductInfoExA(prodcode, NULL,
6681                               MSIINSTALLCONTEXT_MACHINE,
6682                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6684     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6685     ok(sz == 1, "Expected 1, got %d\n", sz);
6686
6687     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6688     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6689
6690     /* HelpLink value exists */
6691     sz = MAX_PATH;
6692     lstrcpyA(buf, "apple");
6693     r = pMsiGetProductInfoExA(prodcode, NULL,
6694                               MSIINSTALLCONTEXT_MACHINE,
6695                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6696     ok(r == ERROR_UNKNOWN_PROPERTY,
6697        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6698     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6699     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6700
6701     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6703
6704     /* HelpTelephone value exists */
6705     sz = MAX_PATH;
6706     lstrcpyA(buf, "apple");
6707     r = pMsiGetProductInfoExA(prodcode, NULL,
6708                               MSIINSTALLCONTEXT_MACHINE,
6709                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6710     ok(r == ERROR_UNKNOWN_PROPERTY,
6711        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6712     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6713     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6714
6715     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6717
6718     /* InstallDate value exists */
6719     sz = MAX_PATH;
6720     lstrcpyA(buf, "apple");
6721     r = pMsiGetProductInfoExA(prodcode, NULL,
6722                               MSIINSTALLCONTEXT_MACHINE,
6723                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6724     ok(r == ERROR_UNKNOWN_PROPERTY,
6725        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6726     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6727     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6728
6729     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6731
6732     /* DisplayName value exists */
6733     sz = MAX_PATH;
6734     lstrcpyA(buf, "apple");
6735     r = pMsiGetProductInfoExA(prodcode, NULL,
6736                               MSIINSTALLCONTEXT_MACHINE,
6737                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6738     ok(r == ERROR_UNKNOWN_PROPERTY,
6739        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6740     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6741     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6742
6743     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6744     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6745
6746     /* InstallLocation value exists */
6747     sz = MAX_PATH;
6748     lstrcpyA(buf, "apple");
6749     r = pMsiGetProductInfoExA(prodcode, NULL,
6750                               MSIINSTALLCONTEXT_MACHINE,
6751                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6752     ok(r == ERROR_UNKNOWN_PROPERTY,
6753        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6754     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6755     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6756
6757     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6759
6760     /* InstallSource value exists */
6761     sz = MAX_PATH;
6762     lstrcpyA(buf, "apple");
6763     r = pMsiGetProductInfoExA(prodcode, NULL,
6764                               MSIINSTALLCONTEXT_MACHINE,
6765                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6766     ok(r == ERROR_UNKNOWN_PROPERTY,
6767        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6768     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6769     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6770
6771     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6773
6774     /* LocalPackage value exists */
6775     sz = MAX_PATH;
6776     lstrcpyA(buf, "apple");
6777     r = pMsiGetProductInfoExA(prodcode, NULL,
6778                               MSIINSTALLCONTEXT_MACHINE,
6779                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6780     ok(r == ERROR_UNKNOWN_PROPERTY,
6781        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6782     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6783     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6784
6785     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6787
6788     /* Publisher value exists */
6789     sz = MAX_PATH;
6790     lstrcpyA(buf, "apple");
6791     r = pMsiGetProductInfoExA(prodcode, NULL,
6792                               MSIINSTALLCONTEXT_MACHINE,
6793                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6794     ok(r == ERROR_UNKNOWN_PROPERTY,
6795        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6796     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6797     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6798
6799     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6801
6802     /* URLInfoAbout value exists */
6803     sz = MAX_PATH;
6804     lstrcpyA(buf, "apple");
6805     r = pMsiGetProductInfoExA(prodcode, NULL,
6806                               MSIINSTALLCONTEXT_MACHINE,
6807                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6808     ok(r == ERROR_UNKNOWN_PROPERTY,
6809        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6810     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6811     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6812
6813     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6815
6816     /* URLUpdateInfo value exists */
6817     sz = MAX_PATH;
6818     lstrcpyA(buf, "apple");
6819     r = pMsiGetProductInfoExA(prodcode, NULL,
6820                               MSIINSTALLCONTEXT_MACHINE,
6821                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6822     ok(r == ERROR_UNKNOWN_PROPERTY,
6823        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6824     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6825     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6826
6827     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6828     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6829
6830     /* VersionMinor value exists */
6831     sz = MAX_PATH;
6832     lstrcpyA(buf, "apple");
6833     r = pMsiGetProductInfoExA(prodcode, NULL,
6834                               MSIINSTALLCONTEXT_MACHINE,
6835                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6836     ok(r == ERROR_UNKNOWN_PROPERTY,
6837        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6838     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6839     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6840
6841     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6842     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6843
6844     /* VersionMajor value exists */
6845     sz = MAX_PATH;
6846     lstrcpyA(buf, "apple");
6847     r = pMsiGetProductInfoExA(prodcode, NULL,
6848                               MSIINSTALLCONTEXT_MACHINE,
6849                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6850     ok(r == ERROR_UNKNOWN_PROPERTY,
6851        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6852     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6853     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6854
6855     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6856     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6857
6858     /* DisplayVersion value exists */
6859     sz = MAX_PATH;
6860     lstrcpyA(buf, "apple");
6861     r = pMsiGetProductInfoExA(prodcode, NULL,
6862                               MSIINSTALLCONTEXT_MACHINE,
6863                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6864     ok(r == ERROR_UNKNOWN_PROPERTY,
6865        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6866     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6867     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6868
6869     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6871
6872     /* ProductID value exists */
6873     sz = MAX_PATH;
6874     lstrcpyA(buf, "apple");
6875     r = pMsiGetProductInfoExA(prodcode, NULL,
6876                               MSIINSTALLCONTEXT_MACHINE,
6877                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6878     ok(r == ERROR_UNKNOWN_PROPERTY,
6879        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6880     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6881     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6882
6883     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6884     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6885
6886     /* RegCompany value exists */
6887     sz = MAX_PATH;
6888     lstrcpyA(buf, "apple");
6889     r = pMsiGetProductInfoExA(prodcode, NULL,
6890                               MSIINSTALLCONTEXT_MACHINE,
6891                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6892     ok(r == ERROR_UNKNOWN_PROPERTY,
6893        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6894     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6895     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6896
6897     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6899
6900     /* RegOwner value exists */
6901     sz = MAX_PATH;
6902     lstrcpyA(buf, "apple");
6903     r = pMsiGetProductInfoExA(prodcode, NULL,
6904                               MSIINSTALLCONTEXT_MACHINE,
6905                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6906     ok(r == ERROR_UNKNOWN_PROPERTY,
6907        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6908     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6909     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6910
6911     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6913
6914     /* Transforms value exists */
6915     sz = MAX_PATH;
6916     lstrcpyA(buf, "apple");
6917     r = pMsiGetProductInfoExA(prodcode, NULL,
6918                               MSIINSTALLCONTEXT_MACHINE,
6919                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6920     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6921     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6922     ok(sz == 5, "Expected 5, got %d\n", sz);
6923
6924     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6926
6927     /* Language value exists */
6928     sz = MAX_PATH;
6929     lstrcpyA(buf, "apple");
6930     r = pMsiGetProductInfoExA(prodcode, NULL,
6931                               MSIINSTALLCONTEXT_MACHINE,
6932                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6933     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6934     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6935     ok(sz == 4, "Expected 4, got %d\n", sz);
6936
6937     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6939
6940     /* ProductName value exists */
6941     sz = MAX_PATH;
6942     lstrcpyA(buf, "apple");
6943     r = pMsiGetProductInfoExA(prodcode, NULL,
6944                               MSIINSTALLCONTEXT_MACHINE,
6945                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6947     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6948     ok(sz == 4, "Expected 4, got %d\n", sz);
6949
6950     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6952
6953     /* FIXME */
6954
6955     /* AssignmentType value exists */
6956     sz = MAX_PATH;
6957     lstrcpyA(buf, "apple");
6958     r = pMsiGetProductInfoExA(prodcode, NULL,
6959                               MSIINSTALLCONTEXT_MACHINE,
6960                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6961     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6962     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6963     ok(sz == 0, "Expected 0, got %d\n", sz);
6964
6965     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6967
6968     /* FIXME */
6969
6970     /* PackageCode value exists */
6971     sz = MAX_PATH;
6972     lstrcpyA(buf, "apple");
6973     r = pMsiGetProductInfoExA(prodcode, NULL,
6974                               MSIINSTALLCONTEXT_MACHINE,
6975                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6976     todo_wine
6977     {
6978         ok(r == ERROR_BAD_CONFIGURATION,
6979            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6980         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6981         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6982     }
6983
6984     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6986
6987     /* Version value exists */
6988     sz = MAX_PATH;
6989     lstrcpyA(buf, "apple");
6990     r = pMsiGetProductInfoExA(prodcode, NULL,
6991                               MSIINSTALLCONTEXT_MACHINE,
6992                               INSTALLPROPERTY_VERSION, buf, &sz);
6993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6994     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6995     ok(sz == 3, "Expected 3, got %d\n", sz);
6996
6997     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6999
7000     /* ProductIcon value exists */
7001     sz = MAX_PATH;
7002     lstrcpyA(buf, "apple");
7003     r = pMsiGetProductInfoExA(prodcode, NULL,
7004                               MSIINSTALLCONTEXT_MACHINE,
7005                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7006     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7007     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7008     ok(sz == 4, "Expected 4, got %d\n", sz);
7009
7010     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7012
7013     /* PackageName value exists */
7014     sz = MAX_PATH;
7015     lstrcpyA(buf, "apple");
7016     r = pMsiGetProductInfoExA(prodcode, NULL,
7017                               MSIINSTALLCONTEXT_MACHINE,
7018                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7019     todo_wine
7020     {
7021         ok(r == ERROR_UNKNOWN_PRODUCT,
7022            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7023         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7024         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7025     }
7026
7027     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7029
7030     /* AuthorizedLUAApp value exists */
7031     sz = MAX_PATH;
7032     lstrcpyA(buf, "apple");
7033     r = pMsiGetProductInfoExA(prodcode, NULL,
7034                               MSIINSTALLCONTEXT_MACHINE,
7035                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7037     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7038     ok(sz == 4, "Expected 4, got %d\n", sz);
7039
7040     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7041     RegDeleteValueA(prodkey, "PackageName");
7042     RegDeleteValueA(prodkey, "ProductIcon");
7043     RegDeleteValueA(prodkey, "Version");
7044     RegDeleteValueA(prodkey, "PackageCode");
7045     RegDeleteValueA(prodkey, "AssignmentType");
7046     RegDeleteValueA(prodkey, "ProductName");
7047     RegDeleteValueA(prodkey, "Language");
7048     RegDeleteValueA(prodkey, "Transforms");
7049     RegDeleteValueA(prodkey, "RegOwner");
7050     RegDeleteValueA(prodkey, "RegCompany");
7051     RegDeleteValueA(prodkey, "ProductID");
7052     RegDeleteValueA(prodkey, "DisplayVersion");
7053     RegDeleteValueA(prodkey, "VersionMajor");
7054     RegDeleteValueA(prodkey, "VersionMinor");
7055     RegDeleteValueA(prodkey, "URLUpdateInfo");
7056     RegDeleteValueA(prodkey, "URLInfoAbout");
7057     RegDeleteValueA(prodkey, "Publisher");
7058     RegDeleteValueA(prodkey, "LocalPackage");
7059     RegDeleteValueA(prodkey, "InstallSource");
7060     RegDeleteValueA(prodkey, "InstallLocation");
7061     RegDeleteValueA(prodkey, "DisplayName");
7062     RegDeleteValueA(prodkey, "InstallDate");
7063     RegDeleteValueA(prodkey, "HelpTelephone");
7064     RegDeleteValueA(prodkey, "HelpLink");
7065     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7066     RegCloseKey(prodkey);
7067     LocalFree(usersid);
7068 }
7069
7070 #define INIT_USERINFO() \
7071     lstrcpyA(user, "apple"); \
7072     lstrcpyA(org, "orange"); \
7073     lstrcpyA(serial, "banana"); \
7074     usersz = orgsz = serialsz = MAX_PATH;
7075
7076 static void test_MsiGetUserInfo(void)
7077 {
7078     USERINFOSTATE state;
7079     CHAR user[MAX_PATH];
7080     CHAR org[MAX_PATH];
7081     CHAR serial[MAX_PATH];
7082     DWORD usersz, orgsz, serialsz;
7083     CHAR keypath[MAX_PATH * 2];
7084     CHAR prodcode[MAX_PATH];
7085     CHAR prod_squashed[MAX_PATH];
7086     HKEY prodkey, userprod, props;
7087     LPSTR usersid;
7088     LONG res;
7089     REGSAM access = KEY_ALL_ACCESS;
7090
7091     create_test_guid(prodcode, prod_squashed);
7092     get_user_sid(&usersid);
7093
7094     if (is_wow64)
7095         access |= KEY_WOW64_64KEY;
7096
7097     /* NULL szProduct */
7098     INIT_USERINFO();
7099     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
7100     ok(state == USERINFOSTATE_INVALIDARG,
7101        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7102     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7103     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7104     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7105     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7106     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7107     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7108
7109     /* empty szProductCode */
7110     INIT_USERINFO();
7111     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
7112     ok(state == USERINFOSTATE_INVALIDARG,
7113        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7114     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7115     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7116     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7117     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7118     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7119     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7120
7121     /* garbage szProductCode */
7122     INIT_USERINFO();
7123     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
7124     ok(state == USERINFOSTATE_INVALIDARG,
7125        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7126     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7127     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7128     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7129     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7130     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7131     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7132
7133     /* guid without brackets */
7134     INIT_USERINFO();
7135     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7136                             user, &usersz, org, &orgsz, serial, &serialsz);
7137     ok(state == USERINFOSTATE_INVALIDARG,
7138        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7139     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7140     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7141     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7142     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7143     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7144     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7145
7146     /* guid with brackets */
7147     INIT_USERINFO();
7148     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7149                             user, &usersz, org, &orgsz, serial, &serialsz);
7150     ok(state == USERINFOSTATE_UNKNOWN,
7151        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7152     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7153     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7154     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7155     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7156     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7157     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7158
7159     /* NULL lpUserNameBuf */
7160     INIT_USERINFO();
7161     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7162     ok(state == USERINFOSTATE_UNKNOWN,
7163        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7164     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7165     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7166     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7167     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7168     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7169
7170     /* NULL pcchUserNameBuf */
7171     INIT_USERINFO();
7172     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
7173     ok(state == USERINFOSTATE_INVALIDARG,
7174        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7175     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7176     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7177     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7178     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7179     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7180
7181     /* both lpUserNameBuf and pcchUserNameBuf NULL */
7182     INIT_USERINFO();
7183     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7184     ok(state == USERINFOSTATE_UNKNOWN,
7185        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7186     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7187     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7188     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7189     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7190
7191     /* NULL lpOrgNameBuf */
7192     INIT_USERINFO();
7193     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
7194     ok(state == USERINFOSTATE_UNKNOWN,
7195        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7196     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7197     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7198     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7199     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7200     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7201
7202     /* NULL pcchOrgNameBuf */
7203     INIT_USERINFO();
7204     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7205     ok(state == USERINFOSTATE_INVALIDARG,
7206        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7207     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7208     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7209     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7210     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7211     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7212
7213     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7214     INIT_USERINFO();
7215     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7216     ok(state == USERINFOSTATE_UNKNOWN,
7217        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7218     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7219     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7220     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7221     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7222
7223     /* NULL lpSerialBuf */
7224     INIT_USERINFO();
7225     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7226     ok(state == USERINFOSTATE_UNKNOWN,
7227        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7228     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7229     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7230     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7231     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7232     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7233
7234     /* NULL pcchSerialBuf */
7235     INIT_USERINFO();
7236     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7237     ok(state == USERINFOSTATE_INVALIDARG,
7238        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7239     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7240     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7241     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7242     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7243     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7244
7245     /* both lpSerialBuf and pcchSerialBuf NULL */
7246     INIT_USERINFO();
7247     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7248     ok(state == USERINFOSTATE_UNKNOWN,
7249        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7250     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7251     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7252     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7253     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7254
7255     /* MSIINSTALLCONTEXT_USERMANAGED */
7256
7257     /* create local system product key */
7258     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7259     lstrcatA(keypath, usersid);
7260     lstrcatA(keypath, "\\Installer\\Products\\");
7261     lstrcatA(keypath, prod_squashed);
7262
7263     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7264     if (res == ERROR_ACCESS_DENIED)
7265     {
7266         skip("Not enough rights to perform tests\n");
7267         LocalFree(usersid);
7268         return;
7269     }
7270     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7271
7272     /* managed product key exists */
7273     INIT_USERINFO();
7274     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7275     ok(state == USERINFOSTATE_ABSENT,
7276        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7277     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7278     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7279     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7280     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7281     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7282     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7283
7284     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7285     lstrcatA(keypath, "Installer\\UserData\\");
7286     lstrcatA(keypath, usersid);
7287     lstrcatA(keypath, "\\Products\\");
7288     lstrcatA(keypath, prod_squashed);
7289
7290     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7292
7293     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7295
7296     /* InstallProperties key exists */
7297     INIT_USERINFO();
7298     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7299     ok(state == USERINFOSTATE_ABSENT,
7300        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7301     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7302     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7303     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7304     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7305     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7306     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7307
7308     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7309     INIT_USERINFO();
7310     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7311     ok(state == USERINFOSTATE_ABSENT,
7312        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7313     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7314     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7315     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7316     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7317
7318     /* RegOwner, RegCompany don't exist, out params are NULL */
7319     INIT_USERINFO();
7320     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7321     ok(state == USERINFOSTATE_ABSENT,
7322        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7323     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7324     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7325
7326     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7327     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7328
7329     /* RegOwner value exists */
7330     INIT_USERINFO();
7331     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7332     ok(state == USERINFOSTATE_ABSENT,
7333        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7334     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7335     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7336     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7337     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7338     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7339     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7340
7341     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7343
7344     /* RegCompany value exists */
7345     INIT_USERINFO();
7346     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7347     ok(state == USERINFOSTATE_ABSENT,
7348        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7349     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7350     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7351     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7352     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7353     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7354     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7355
7356     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7358
7359     /* ProductID value exists */
7360     INIT_USERINFO();
7361     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7362     ok(state == USERINFOSTATE_PRESENT,
7363        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7364     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7365     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7366     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7367     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7368     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7369     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7370
7371     /* pcchUserNameBuf is too small */
7372     INIT_USERINFO();
7373     usersz = 0;
7374     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7375     ok(state == USERINFOSTATE_MOREDATA,
7376        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7377     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7378     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7379     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7380     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7381     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7382     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7383
7384     /* pcchUserNameBuf has no room for NULL terminator */
7385     INIT_USERINFO();
7386     usersz = 5;
7387     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7388     ok(state == USERINFOSTATE_MOREDATA,
7389        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7390     todo_wine
7391     {
7392         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7393     }
7394     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7395     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7396     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7397     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7398     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7399
7400     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7401     INIT_USERINFO();
7402     usersz = 0;
7403     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7404     ok(state == USERINFOSTATE_PRESENT,
7405        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7406     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7407     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7408     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7409     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7410     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7411     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7412
7413     RegDeleteValueA(props, "ProductID");
7414     RegDeleteValueA(props, "RegCompany");
7415     RegDeleteValueA(props, "RegOwner");
7416     delete_key(props, "", access & KEY_WOW64_64KEY);
7417     RegCloseKey(props);
7418     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7419     RegCloseKey(userprod);
7420     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7421     RegCloseKey(prodkey);
7422
7423     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7424
7425     /* create local system product key */
7426     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7427     lstrcatA(keypath, prod_squashed);
7428
7429     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7431
7432     /* product key exists */
7433     INIT_USERINFO();
7434     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7435     ok(state == USERINFOSTATE_ABSENT,
7436        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7437     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7438     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7439     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7440     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7441     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7442     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7443
7444     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7445     lstrcatA(keypath, "Installer\\UserData\\");
7446     lstrcatA(keypath, usersid);
7447     lstrcatA(keypath, "\\Products\\");
7448     lstrcatA(keypath, prod_squashed);
7449
7450     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7452
7453     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7454     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7455
7456     /* InstallProperties key exists */
7457     INIT_USERINFO();
7458     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7459     ok(state == USERINFOSTATE_ABSENT,
7460        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7461     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7462     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7463     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7464     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7465     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7466     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7467
7468     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7469     INIT_USERINFO();
7470     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7471     ok(state == USERINFOSTATE_ABSENT,
7472        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7473     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7474     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7475     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7476     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7477
7478     /* RegOwner, RegCompany don't exist, out params are NULL */
7479     INIT_USERINFO();
7480     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7481     ok(state == USERINFOSTATE_ABSENT,
7482        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7483     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7484     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7485
7486     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7488
7489     /* RegOwner value exists */
7490     INIT_USERINFO();
7491     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7492     ok(state == USERINFOSTATE_ABSENT,
7493        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7494     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7495     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7496     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7497     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7498     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7499     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7500
7501     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7502     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7503
7504     /* RegCompany value exists */
7505     INIT_USERINFO();
7506     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7507     ok(state == USERINFOSTATE_ABSENT,
7508        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7509     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7510     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7511     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7512     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7513     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7514     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7515
7516     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7518
7519     /* ProductID value exists */
7520     INIT_USERINFO();
7521     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7522     ok(state == USERINFOSTATE_PRESENT,
7523        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7524     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7525     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7526     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7527     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7528     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7529     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7530
7531     RegDeleteValueA(props, "ProductID");
7532     RegDeleteValueA(props, "RegCompany");
7533     RegDeleteValueA(props, "RegOwner");
7534     delete_key(props, "", access & KEY_WOW64_64KEY);
7535     RegCloseKey(props);
7536     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7537     RegCloseKey(userprod);
7538     RegDeleteKeyA(prodkey, "");
7539     RegCloseKey(prodkey);
7540
7541     /* MSIINSTALLCONTEXT_MACHINE */
7542
7543     /* create local system product key */
7544     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7545     lstrcatA(keypath, prod_squashed);
7546
7547     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7549
7550     /* product key exists */
7551     INIT_USERINFO();
7552     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7553     ok(state == USERINFOSTATE_ABSENT,
7554        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7555     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7556     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7557     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7558     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7559     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7560     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7561
7562     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7563     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7564     lstrcatA(keypath, "\\Products\\");
7565     lstrcatA(keypath, prod_squashed);
7566
7567     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7569
7570     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7572
7573     /* InstallProperties key exists */
7574     INIT_USERINFO();
7575     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7576     ok(state == USERINFOSTATE_ABSENT,
7577        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7578     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7579     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7580     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7581     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7582     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7583     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7584
7585     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7586     INIT_USERINFO();
7587     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7588     ok(state == USERINFOSTATE_ABSENT,
7589        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7590     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7591     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7592     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7593     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7594
7595     /* RegOwner, RegCompany don't exist, out params are NULL */
7596     INIT_USERINFO();
7597     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7598     ok(state == USERINFOSTATE_ABSENT,
7599        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7600     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7601     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7602
7603     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7605
7606     /* RegOwner value exists */
7607     INIT_USERINFO();
7608     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7609     ok(state == USERINFOSTATE_ABSENT,
7610        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7611     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7612     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7613     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7614     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7615     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7616     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7617
7618     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7620
7621     /* RegCompany value exists */
7622     INIT_USERINFO();
7623     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7624     ok(state == USERINFOSTATE_ABSENT,
7625        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7626     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7627     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7628     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7629     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7630     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7631     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7632
7633     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7635
7636     /* ProductID value exists */
7637     INIT_USERINFO();
7638     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7639     ok(state == USERINFOSTATE_PRESENT,
7640        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7641     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7642     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7643     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7644     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7645     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7646     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7647
7648     RegDeleteValueA(props, "ProductID");
7649     RegDeleteValueA(props, "RegCompany");
7650     RegDeleteValueA(props, "RegOwner");
7651     delete_key(props, "", access & KEY_WOW64_64KEY);
7652     RegCloseKey(props);
7653     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7654     RegCloseKey(userprod);
7655     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7656     RegCloseKey(prodkey);
7657     LocalFree(usersid);
7658 }
7659
7660 static void test_MsiOpenProduct(void)
7661 {
7662     MSIHANDLE hprod, hdb;
7663     CHAR val[MAX_PATH];
7664     CHAR path[MAX_PATH];
7665     CHAR keypath[MAX_PATH*2];
7666     CHAR prodcode[MAX_PATH];
7667     CHAR prod_squashed[MAX_PATH];
7668     HKEY prodkey, userkey, props;
7669     LPSTR usersid;
7670     DWORD size;
7671     LONG res;
7672     UINT r;
7673     REGSAM access = KEY_ALL_ACCESS;
7674
7675     GetCurrentDirectoryA(MAX_PATH, path);
7676     lstrcatA(path, "\\");
7677
7678     create_test_guid(prodcode, prod_squashed);
7679     get_user_sid(&usersid);
7680
7681     if (is_wow64)
7682         access |= KEY_WOW64_64KEY;
7683
7684     hdb = create_package_db(prodcode);
7685     MsiCloseHandle(hdb);
7686
7687     /* NULL szProduct */
7688     hprod = 0xdeadbeef;
7689     r = MsiOpenProductA(NULL, &hprod);
7690     ok(r == ERROR_INVALID_PARAMETER,
7691        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7692     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7693
7694     /* empty szProduct */
7695     hprod = 0xdeadbeef;
7696     r = MsiOpenProductA("", &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     /* garbage szProduct */
7702     hprod = 0xdeadbeef;
7703     r = MsiOpenProductA("garbage", &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     /* guid without brackets */
7709     hprod = 0xdeadbeef;
7710     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &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 with brackets */
7716     hprod = 0xdeadbeef;
7717     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7718     ok(r == ERROR_UNKNOWN_PRODUCT,
7719        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7720     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7721
7722     /* same length as guid, but random */
7723     hprod = 0xdeadbeef;
7724     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7725     ok(r == ERROR_INVALID_PARAMETER,
7726        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7727     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7728
7729     /* hProduct is NULL */
7730     hprod = 0xdeadbeef;
7731     r = MsiOpenProductA(prodcode, NULL);
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     /* MSIINSTALLCONTEXT_USERMANAGED */
7737
7738     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7739     lstrcatA(keypath, "Installer\\Managed\\");
7740     lstrcatA(keypath, usersid);
7741     lstrcatA(keypath, "\\Installer\\Products\\");
7742     lstrcatA(keypath, prod_squashed);
7743
7744     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7745     if (res == ERROR_ACCESS_DENIED)
7746     {
7747         skip("Not enough rights to perform tests\n");
7748         LocalFree(usersid);
7749         return;
7750     }
7751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7752
7753     /* managed product key exists */
7754     hprod = 0xdeadbeef;
7755     r = MsiOpenProductA(prodcode, &hprod);
7756     ok(r == ERROR_UNKNOWN_PRODUCT,
7757        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7758     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7759
7760     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7761     lstrcatA(keypath, "Installer\\UserData\\");
7762     lstrcatA(keypath, usersid);
7763     lstrcatA(keypath, "\\Products\\");
7764     lstrcatA(keypath, prod_squashed);
7765
7766     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7768
7769     /* user product key exists */
7770     hprod = 0xdeadbeef;
7771     r = MsiOpenProductA(prodcode, &hprod);
7772     ok(r == ERROR_UNKNOWN_PRODUCT,
7773        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7774     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7775
7776     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7778
7779     /* InstallProperties key exists */
7780     hprod = 0xdeadbeef;
7781     r = MsiOpenProductA(prodcode, &hprod);
7782     ok(r == ERROR_UNKNOWN_PRODUCT,
7783        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7784     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7785
7786     lstrcpyA(val, path);
7787     lstrcatA(val, "\\winetest.msi");
7788     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7789                          (const BYTE *)val, lstrlenA(val) + 1);
7790     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7791
7792     /* ManagedLocalPackage value exists */
7793     hprod = 0xdeadbeef;
7794     r = MsiOpenProductA(prodcode, &hprod);
7795     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7796     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7797
7798     size = MAX_PATH;
7799     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7801     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7802     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7803
7804     MsiCloseHandle(hprod);
7805
7806     RegDeleteValueA(props, "ManagedLocalPackage");
7807     delete_key(props, "", access & KEY_WOW64_64KEY);
7808     RegCloseKey(props);
7809     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7810     RegCloseKey(userkey);
7811     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7812     RegCloseKey(prodkey);
7813
7814     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7815
7816     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7817     lstrcatA(keypath, prod_squashed);
7818
7819     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7821
7822     /* unmanaged product key exists */
7823     hprod = 0xdeadbeef;
7824     r = MsiOpenProductA(prodcode, &hprod);
7825     ok(r == ERROR_UNKNOWN_PRODUCT,
7826        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7827     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7828
7829     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7830     lstrcatA(keypath, "Installer\\UserData\\");
7831     lstrcatA(keypath, usersid);
7832     lstrcatA(keypath, "\\Products\\");
7833     lstrcatA(keypath, prod_squashed);
7834
7835     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7837
7838     /* user product key exists */
7839     hprod = 0xdeadbeef;
7840     r = MsiOpenProductA(prodcode, &hprod);
7841     ok(r == ERROR_UNKNOWN_PRODUCT,
7842        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7843     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7844
7845     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7846     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7847
7848     /* InstallProperties key exists */
7849     hprod = 0xdeadbeef;
7850     r = MsiOpenProductA(prodcode, &hprod);
7851     ok(r == ERROR_UNKNOWN_PRODUCT,
7852        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7853     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7854
7855     lstrcpyA(val, path);
7856     lstrcatA(val, "\\winetest.msi");
7857     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7858                          (const BYTE *)val, lstrlenA(val) + 1);
7859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7860
7861     /* LocalPackage value exists */
7862     hprod = 0xdeadbeef;
7863     r = MsiOpenProductA(prodcode, &hprod);
7864     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7865     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7866
7867     size = MAX_PATH;
7868     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7870     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7871     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7872
7873     MsiCloseHandle(hprod);
7874
7875     RegDeleteValueA(props, "LocalPackage");
7876     delete_key(props, "", access & KEY_WOW64_64KEY);
7877     RegCloseKey(props);
7878     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7879     RegCloseKey(userkey);
7880     RegDeleteKeyA(prodkey, "");
7881     RegCloseKey(prodkey);
7882
7883     /* MSIINSTALLCONTEXT_MACHINE */
7884
7885     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7886     lstrcatA(keypath, prod_squashed);
7887
7888     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7890
7891     /* managed product key exists */
7892     hprod = 0xdeadbeef;
7893     r = MsiOpenProductA(prodcode, &hprod);
7894     ok(r == ERROR_UNKNOWN_PRODUCT,
7895        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7896     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7897
7898     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7899     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7900     lstrcatA(keypath, prod_squashed);
7901
7902     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7903     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7904
7905     /* user product key exists */
7906     hprod = 0xdeadbeef;
7907     r = MsiOpenProductA(prodcode, &hprod);
7908     ok(r == ERROR_UNKNOWN_PRODUCT,
7909        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7910     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7911
7912     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7914
7915     /* InstallProperties key exists */
7916     hprod = 0xdeadbeef;
7917     r = MsiOpenProductA(prodcode, &hprod);
7918     ok(r == ERROR_UNKNOWN_PRODUCT,
7919        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7920     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7921
7922     lstrcpyA(val, path);
7923     lstrcatA(val, "\\winetest.msi");
7924     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7925                          (const BYTE *)val, lstrlenA(val) + 1);
7926     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7927
7928     /* LocalPackage value exists */
7929     hprod = 0xdeadbeef;
7930     r = MsiOpenProductA(prodcode, &hprod);
7931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7932     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7933
7934     size = MAX_PATH;
7935     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7937     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7938     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7939
7940     MsiCloseHandle(hprod);
7941
7942     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7943                          (const BYTE *)"winetest.msi", 13);
7944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7945
7946     /* LocalPackage has just the package name */
7947     hprod = 0xdeadbeef;
7948     r = MsiOpenProductA(prodcode, &hprod);
7949     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7950     {
7951         skip("Not enough rights to perform tests\n");
7952         goto error;
7953     }
7954     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7955        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7956     if (r == ERROR_SUCCESS)
7957         MsiCloseHandle(hprod);
7958     else
7959         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7960
7961     lstrcpyA(val, path);
7962     lstrcatA(val, "\\winetest.msi");
7963     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7964                          (const BYTE *)val, lstrlenA(val) + 1);
7965     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7966
7967     DeleteFileA(msifile);
7968
7969     /* local package does not exist */
7970     hprod = 0xdeadbeef;
7971     r = MsiOpenProductA(prodcode, &hprod);
7972     ok(r == ERROR_UNKNOWN_PRODUCT,
7973        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7974     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7975
7976 error:
7977     RegDeleteValueA(props, "LocalPackage");
7978     delete_key(props, "", access & KEY_WOW64_64KEY);
7979     RegCloseKey(props);
7980     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7981     RegCloseKey(userkey);
7982     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7983     RegCloseKey(prodkey);
7984
7985     DeleteFileA(msifile);
7986     LocalFree(usersid);
7987 }
7988
7989 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7990 {
7991     MSIINSTALLCONTEXT context;
7992     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7993     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7994     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7995     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7996     HKEY prodkey, patches, udprod, udpatch, hpatch;
7997     DWORD size, data;
7998     LONG res;
7999     UINT r;
8000     REGSAM access = KEY_ALL_ACCESS;
8001
8002     create_test_guid(prodcode, prod_squashed);
8003     create_test_guid(patch, patch_squashed);
8004
8005     if (is_wow64)
8006         access |= KEY_WOW64_64KEY;
8007
8008     /* MSIPATCHSTATE_APPLIED */
8009
8010     lstrcpyA(patchcode, "apple");
8011     lstrcpyA(targetprod, "banana");
8012     context = 0xdeadbeef;
8013     lstrcpyA(targetsid, "kiwi");
8014     size = MAX_PATH;
8015     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8016                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8017                            &context, targetsid, &size);
8018     if (r == ERROR_ACCESS_DENIED)
8019     {
8020         skip("Not enough rights to perform tests\n");
8021         return;
8022     }
8023     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8024     ok(!lstrcmpA(patchcode, "apple"),
8025        "Expected patchcode to be unchanged, got %s\n", patchcode);
8026     ok(!lstrcmpA(targetprod, "banana"),
8027        "Expected targetprod to be unchanged, got %s\n", targetprod);
8028     ok(context == 0xdeadbeef,
8029        "Expected context to be unchanged, got %d\n", context);
8030     ok(!lstrcmpA(targetsid, "kiwi"),
8031        "Expected targetsid to be unchanged, got %s\n", targetsid);
8032     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8033
8034     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8035     lstrcatA(keypath, expectedsid);
8036     lstrcatA(keypath, "\\Installer\\Products\\");
8037     lstrcatA(keypath, prod_squashed);
8038
8039     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8040     if (res == ERROR_ACCESS_DENIED)
8041     {
8042         skip("Not enough rights to perform tests\n");
8043         return;
8044     }
8045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8046
8047     /* managed product key exists */
8048     lstrcpyA(patchcode, "apple");
8049     lstrcpyA(targetprod, "banana");
8050     context = 0xdeadbeef;
8051     lstrcpyA(targetsid, "kiwi");
8052     size = MAX_PATH;
8053     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8054                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8055                            &context, targetsid, &size);
8056     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8057     ok(!lstrcmpA(patchcode, "apple"),
8058        "Expected patchcode to be unchanged, got %s\n", patchcode);
8059     ok(!lstrcmpA(targetprod, "banana"),
8060        "Expected targetprod to be unchanged, got %s\n", targetprod);
8061     ok(context == 0xdeadbeef,
8062        "Expected context to be unchanged, got %d\n", context);
8063     ok(!lstrcmpA(targetsid, "kiwi"),
8064        "Expected targetsid to be unchanged, got %s\n", targetsid);
8065     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8066
8067     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8069
8070     /* patches key exists */
8071     lstrcpyA(patchcode, "apple");
8072     lstrcpyA(targetprod, "banana");
8073     context = 0xdeadbeef;
8074     lstrcpyA(targetsid, "kiwi");
8075     size = MAX_PATH;
8076     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8077                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8078                            &context, targetsid, &size);
8079     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8080     ok(!lstrcmpA(patchcode, "apple"),
8081        "Expected patchcode to be unchanged, got %s\n", patchcode);
8082     ok(!lstrcmpA(targetprod, "banana"),
8083        "Expected targetprod to be unchanged, got %s\n", targetprod);
8084     ok(context == 0xdeadbeef,
8085        "Expected context to be unchanged, got %d\n", context);
8086     ok(!lstrcmpA(targetsid, "kiwi"),
8087        "Expected targetsid to be unchanged, got %s\n", targetsid);
8088     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8089
8090     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8091                          (const BYTE *)patch_squashed,
8092                          lstrlenA(patch_squashed) + 1);
8093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8094
8095     /* Patches value exists, is not REG_MULTI_SZ */
8096     lstrcpyA(patchcode, "apple");
8097     lstrcpyA(targetprod, "banana");
8098     context = 0xdeadbeef;
8099     lstrcpyA(targetsid, "kiwi");
8100     size = MAX_PATH;
8101     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8102                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8103                            &context, targetsid, &size);
8104     ok(r == ERROR_BAD_CONFIGURATION,
8105        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8106     ok(!lstrcmpA(patchcode, "apple"),
8107        "Expected patchcode to be unchanged, got %s\n", patchcode);
8108     ok(!lstrcmpA(targetprod, "banana"),
8109        "Expected targetprod to be unchanged, got %s\n", targetprod);
8110     ok(context == 0xdeadbeef,
8111        "Expected context to be unchanged, got %d\n", context);
8112     ok(!lstrcmpA(targetsid, "kiwi"),
8113        "Expected targetsid to be unchanged, got %s\n", targetsid);
8114     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8115
8116     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8117                          (const BYTE *)"a\0b\0c\0\0", 7);
8118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8119
8120     /* Patches value exists, is not a squashed guid */
8121     lstrcpyA(patchcode, "apple");
8122     lstrcpyA(targetprod, "banana");
8123     context = 0xdeadbeef;
8124     lstrcpyA(targetsid, "kiwi");
8125     size = MAX_PATH;
8126     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8127                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8128                            &context, targetsid, &size);
8129     ok(r == ERROR_BAD_CONFIGURATION,
8130        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8131     ok(!lstrcmpA(patchcode, "apple"),
8132        "Expected patchcode to be unchanged, got %s\n", patchcode);
8133     ok(!lstrcmpA(targetprod, "banana"),
8134        "Expected targetprod to be unchanged, got %s\n", targetprod);
8135     ok(context == 0xdeadbeef,
8136        "Expected context to be unchanged, got %d\n", context);
8137     ok(!lstrcmpA(targetsid, "kiwi"),
8138        "Expected targetsid to be unchanged, got %s\n", targetsid);
8139     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8140
8141     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8142     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8143                          (const BYTE *)patch_squashed,
8144                          lstrlenA(patch_squashed) + 2);
8145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8146
8147     /* Patches value exists */
8148     lstrcpyA(patchcode, "apple");
8149     lstrcpyA(targetprod, "banana");
8150     context = 0xdeadbeef;
8151     lstrcpyA(targetsid, "kiwi");
8152     size = MAX_PATH;
8153     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8154                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8155                            &context, targetsid, &size);
8156     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8157     ok(!lstrcmpA(patchcode, "apple"),
8158        "Expected patchcode to be unchanged, got %s\n", patchcode);
8159     ok(!lstrcmpA(targetprod, "banana"),
8160        "Expected targetprod to be unchanged, got %s\n", targetprod);
8161     ok(context == 0xdeadbeef,
8162        "Expected context to be unchanged, got %d\n", context);
8163     ok(!lstrcmpA(targetsid, "kiwi"),
8164        "Expected targetsid to be unchanged, got %s\n", targetsid);
8165     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8166
8167     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8168                          (const BYTE *)"whatever", 9);
8169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8170
8171     /* patch squashed value exists */
8172     lstrcpyA(patchcode, "apple");
8173     lstrcpyA(targetprod, "banana");
8174     context = 0xdeadbeef;
8175     lstrcpyA(targetsid, "kiwi");
8176     size = MAX_PATH;
8177     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8178                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8179                            &context, targetsid, &size);
8180     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8181     ok(!lstrcmpA(patchcode, patch),
8182        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8183     ok(!lstrcmpA(targetprod, prodcode),
8184        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8185     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8186        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8187     ok(!lstrcmpA(targetsid, expectedsid),
8188        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8189     ok(size == lstrlenA(expectedsid),
8190        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8191
8192     /* increase the index */
8193     lstrcpyA(patchcode, "apple");
8194     lstrcpyA(targetprod, "banana");
8195     context = 0xdeadbeef;
8196     lstrcpyA(targetsid, "kiwi");
8197     size = MAX_PATH;
8198     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8199                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
8200                            &context, targetsid, &size);
8201     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8202     ok(!lstrcmpA(patchcode, "apple"),
8203        "Expected patchcode to be unchanged, got %s\n", patchcode);
8204     ok(!lstrcmpA(targetprod, "banana"),
8205        "Expected targetprod to be unchanged, got %s\n", targetprod);
8206     ok(context == 0xdeadbeef,
8207        "Expected context to be unchanged, got %d\n", context);
8208     ok(!lstrcmpA(targetsid, "kiwi"),
8209        "Expected targetsid to be unchanged, got %s\n", targetsid);
8210     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8211
8212     /* increase again */
8213     lstrcpyA(patchcode, "apple");
8214     lstrcpyA(targetprod, "banana");
8215     context = 0xdeadbeef;
8216     lstrcpyA(targetsid, "kiwi");
8217     size = MAX_PATH;
8218     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8219                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8220                            &context, targetsid, &size);
8221     ok(r == ERROR_INVALID_PARAMETER,
8222        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8223     ok(!lstrcmpA(patchcode, "apple"),
8224        "Expected patchcode to be unchanged, got %s\n", patchcode);
8225     ok(!lstrcmpA(targetprod, "banana"),
8226        "Expected targetprod to be unchanged, got %s\n", targetprod);
8227     ok(context == 0xdeadbeef,
8228        "Expected context to be unchanged, got %d\n", context);
8229     ok(!lstrcmpA(targetsid, "kiwi"),
8230        "Expected targetsid to be unchanged, got %s\n", targetsid);
8231     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8232
8233     /* szPatchCode is NULL */
8234     lstrcpyA(targetprod, "banana");
8235     context = 0xdeadbeef;
8236     lstrcpyA(targetsid, "kiwi");
8237     size = MAX_PATH;
8238     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8239                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8240                            &context, targetsid, &size);
8241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8242     ok(!lstrcmpA(targetprod, prodcode),
8243        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8244     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8245        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8246     ok(!lstrcmpA(targetsid, expectedsid),
8247        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8248     ok(size == lstrlenA(expectedsid),
8249        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8250
8251     /* szTargetProductCode is NULL */
8252     lstrcpyA(patchcode, "apple");
8253     context = 0xdeadbeef;
8254     lstrcpyA(targetsid, "kiwi");
8255     size = MAX_PATH;
8256     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8257                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8258                            &context, targetsid, &size);
8259     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8260     ok(!lstrcmpA(patchcode, patch),
8261        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8262     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8263        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8264     ok(!lstrcmpA(targetsid, expectedsid),
8265        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8266     ok(size == lstrlenA(expectedsid),
8267        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8268
8269     /* pdwTargetProductContext is NULL */
8270     lstrcpyA(patchcode, "apple");
8271     lstrcpyA(targetprod, "banana");
8272     lstrcpyA(targetsid, "kiwi");
8273     size = MAX_PATH;
8274     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8275                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8276                            NULL, targetsid, &size);
8277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8278     ok(!lstrcmpA(patchcode, patch),
8279        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8280     ok(!lstrcmpA(targetprod, prodcode),
8281        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8282     ok(!lstrcmpA(targetsid, expectedsid),
8283        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8284     ok(size == lstrlenA(expectedsid),
8285        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8286
8287     /* szTargetUserSid is NULL */
8288     lstrcpyA(patchcode, "apple");
8289     lstrcpyA(targetprod, "banana");
8290     context = 0xdeadbeef;
8291     size = MAX_PATH;
8292     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8293                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8294                            &context, NULL, &size);
8295     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8296     ok(!lstrcmpA(patchcode, patch),
8297        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8298     ok(!lstrcmpA(targetprod, prodcode),
8299        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8300     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8301        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8302     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8303        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8304
8305     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8306     lstrcpyA(patchcode, "apple");
8307     lstrcpyA(targetprod, "banana");
8308     context = 0xdeadbeef;
8309     lstrcpyA(targetsid, "kiwi");
8310     size = lstrlenA(expectedsid);
8311     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8312                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8313                            &context, targetsid, &size);
8314     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8315     ok(!lstrcmpA(patchcode, patch),
8316        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8317     ok(!lstrcmpA(targetprod, prodcode),
8318        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8319     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8320        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8321     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8322        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8323     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8324        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8325
8326     /* pcchTargetUserSid has enough room for NULL terminator */
8327     lstrcpyA(patchcode, "apple");
8328     lstrcpyA(targetprod, "banana");
8329     context = 0xdeadbeef;
8330     lstrcpyA(targetsid, "kiwi");
8331     size = lstrlenA(expectedsid) + 1;
8332     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8333                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8334                            &context, targetsid, &size);
8335     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8336     ok(!lstrcmpA(patchcode, patch),
8337        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8338     ok(!lstrcmpA(targetprod, prodcode),
8339        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8340     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8341        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8342     ok(!lstrcmpA(targetsid, expectedsid),
8343        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8344     ok(size == lstrlenA(expectedsid),
8345        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8346
8347     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8348     lstrcpyA(patchcode, "apple");
8349     lstrcpyA(targetprod, "banana");
8350     context = 0xdeadbeef;
8351     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8352                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8353                            &context, NULL, NULL);
8354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8355     ok(!lstrcmpA(patchcode, patch),
8356        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8357     ok(!lstrcmpA(targetprod, prodcode),
8358        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8359     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8360        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8361
8362     /* MSIPATCHSTATE_SUPERSEDED */
8363
8364     lstrcpyA(patchcode, "apple");
8365     lstrcpyA(targetprod, "banana");
8366     context = 0xdeadbeef;
8367     lstrcpyA(targetsid, "kiwi");
8368     size = MAX_PATH;
8369     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8370                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8371                            &context, targetsid, &size);
8372     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8373     ok(!lstrcmpA(patchcode, "apple"),
8374        "Expected patchcode to be unchanged, got %s\n", patchcode);
8375     ok(!lstrcmpA(targetprod, "banana"),
8376        "Expected targetprod to be unchanged, got %s\n", targetprod);
8377     ok(context == 0xdeadbeef,
8378        "Expected context to be unchanged, got %d\n", context);
8379     ok(!lstrcmpA(targetsid, "kiwi"),
8380        "Expected targetsid to be unchanged, got %s\n", targetsid);
8381     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8382
8383     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8384     lstrcatA(keypath, expectedsid);
8385     lstrcatA(keypath, "\\Products\\");
8386     lstrcatA(keypath, prod_squashed);
8387
8388     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8390
8391     /* UserData product key exists */
8392     lstrcpyA(patchcode, "apple");
8393     lstrcpyA(targetprod, "banana");
8394     context = 0xdeadbeef;
8395     lstrcpyA(targetsid, "kiwi");
8396     size = MAX_PATH;
8397     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8398                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8399                            &context, targetsid, &size);
8400     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8401     ok(!lstrcmpA(patchcode, "apple"),
8402        "Expected patchcode to be unchanged, got %s\n", patchcode);
8403     ok(!lstrcmpA(targetprod, "banana"),
8404        "Expected targetprod to be unchanged, got %s\n", targetprod);
8405     ok(context == 0xdeadbeef,
8406        "Expected context to be unchanged, got %d\n", context);
8407     ok(!lstrcmpA(targetsid, "kiwi"),
8408        "Expected targetsid to be unchanged, got %s\n", targetsid);
8409     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8410
8411     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8412     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8413
8414     /* UserData patches key exists */
8415     lstrcpyA(patchcode, "apple");
8416     lstrcpyA(targetprod, "banana");
8417     context = 0xdeadbeef;
8418     lstrcpyA(targetsid, "kiwi");
8419     size = MAX_PATH;
8420     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8421                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8422                            &context, targetsid, &size);
8423     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8424     ok(!lstrcmpA(patchcode, "apple"),
8425        "Expected patchcode to be unchanged, got %s\n", patchcode);
8426     ok(!lstrcmpA(targetprod, "banana"),
8427        "Expected targetprod to be unchanged, got %s\n", targetprod);
8428     ok(context == 0xdeadbeef,
8429        "Expected context to be unchanged, got %d\n", context);
8430     ok(!lstrcmpA(targetsid, "kiwi"),
8431        "Expected targetsid to be unchanged, got %s\n", targetsid);
8432     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8433
8434     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8436
8437     /* specific UserData patch key exists */
8438     lstrcpyA(patchcode, "apple");
8439     lstrcpyA(targetprod, "banana");
8440     context = 0xdeadbeef;
8441     lstrcpyA(targetsid, "kiwi");
8442     size = MAX_PATH;
8443     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8444                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8445                            &context, targetsid, &size);
8446     ok(r == ERROR_BAD_CONFIGURATION,
8447        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8448     ok(!lstrcmpA(patchcode, "apple"),
8449        "Expected patchcode to be unchanged, got %s\n", patchcode);
8450     ok(!lstrcmpA(targetprod, "banana"),
8451        "Expected targetprod to be unchanged, got %s\n", targetprod);
8452     ok(context == 0xdeadbeef,
8453        "Expected context to be unchanged, got %d\n", context);
8454     ok(!lstrcmpA(targetsid, "kiwi"),
8455        "Expected targetsid to be unchanged, got %s\n", targetsid);
8456     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8457
8458     data = MSIPATCHSTATE_SUPERSEDED;
8459     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8460                          (const BYTE *)&data, sizeof(DWORD));
8461     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8462
8463     /* State value exists */
8464     lstrcpyA(patchcode, "apple");
8465     lstrcpyA(targetprod, "banana");
8466     context = 0xdeadbeef;
8467     lstrcpyA(targetsid, "kiwi");
8468     size = MAX_PATH;
8469     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8470                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8471                            &context, targetsid, &size);
8472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8473     ok(!lstrcmpA(patchcode, patch),
8474        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8475     ok(!lstrcmpA(targetprod, prodcode),
8476        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8477     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8478        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8479     ok(!lstrcmpA(targetsid, expectedsid),
8480        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8481     ok(size == lstrlenA(expectedsid),
8482        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8483
8484     /* MSIPATCHSTATE_OBSOLETED */
8485
8486     lstrcpyA(patchcode, "apple");
8487     lstrcpyA(targetprod, "banana");
8488     context = 0xdeadbeef;
8489     lstrcpyA(targetsid, "kiwi");
8490     size = MAX_PATH;
8491     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8492                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8493                            &context, targetsid, &size);
8494     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8495     ok(!lstrcmpA(patchcode, "apple"),
8496        "Expected patchcode to be unchanged, got %s\n", patchcode);
8497     ok(!lstrcmpA(targetprod, "banana"),
8498        "Expected targetprod to be unchanged, got %s\n", targetprod);
8499     ok(context == 0xdeadbeef,
8500        "Expected context to be unchanged, got %d\n", context);
8501     ok(!lstrcmpA(targetsid, "kiwi"),
8502        "Expected targetsid to be unchanged, got %s\n", targetsid);
8503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8504
8505     data = MSIPATCHSTATE_OBSOLETED;
8506     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8507                          (const BYTE *)&data, sizeof(DWORD));
8508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8509
8510     /* State value is obsoleted */
8511     lstrcpyA(patchcode, "apple");
8512     lstrcpyA(targetprod, "banana");
8513     context = 0xdeadbeef;
8514     lstrcpyA(targetsid, "kiwi");
8515     size = MAX_PATH;
8516     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8517                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8518                            &context, targetsid, &size);
8519     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8520     ok(!lstrcmpA(patchcode, patch),
8521        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8522     ok(!lstrcmpA(targetprod, prodcode),
8523        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8524     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8525        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8526     ok(!lstrcmpA(targetsid, expectedsid),
8527        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8528     ok(size == lstrlenA(expectedsid),
8529        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8530
8531     /* MSIPATCHSTATE_REGISTERED */
8532     /* FIXME */
8533
8534     /* MSIPATCHSTATE_ALL */
8535
8536     /* 1st */
8537     lstrcpyA(patchcode, "apple");
8538     lstrcpyA(targetprod, "banana");
8539     context = 0xdeadbeef;
8540     lstrcpyA(targetsid, "kiwi");
8541     size = MAX_PATH;
8542     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8543                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8544                            &context, targetsid, &size);
8545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8546     ok(!lstrcmpA(patchcode, patch),
8547        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8548     ok(!lstrcmpA(targetprod, prodcode),
8549        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8550     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8551        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8552     ok(!lstrcmpA(targetsid, expectedsid),
8553        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8554     ok(size == lstrlenA(expectedsid),
8555        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8556
8557     /* same patch in multiple places, only one is enumerated */
8558     lstrcpyA(patchcode, "apple");
8559     lstrcpyA(targetprod, "banana");
8560     context = 0xdeadbeef;
8561     lstrcpyA(targetsid, "kiwi");
8562     size = MAX_PATH;
8563     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8564                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8565                            &context, targetsid, &size);
8566     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8567     ok(!lstrcmpA(patchcode, "apple"),
8568        "Expected patchcode to be unchanged, got %s\n", patchcode);
8569     ok(!lstrcmpA(targetprod, "banana"),
8570        "Expected targetprod to be unchanged, got %s\n", targetprod);
8571     ok(context == 0xdeadbeef,
8572        "Expected context to be unchanged, got %d\n", context);
8573     ok(!lstrcmpA(targetsid, "kiwi"),
8574        "Expected targetsid to be unchanged, got %s\n", targetsid);
8575     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8576
8577     RegDeleteValueA(hpatch, "State");
8578     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8579     RegCloseKey(hpatch);
8580     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8581     RegCloseKey(udpatch);
8582     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8583     RegCloseKey(udprod);
8584     RegDeleteValueA(patches, "Patches");
8585     delete_key(patches, "", access & KEY_WOW64_64KEY);
8586     RegCloseKey(patches);
8587     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8588     RegCloseKey(prodkey);
8589 }
8590
8591 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8592 {
8593     MSIINSTALLCONTEXT context;
8594     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8595     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8596     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8597     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8598     HKEY prodkey, patches, udprod, udpatch;
8599     HKEY userkey, hpatch;
8600     DWORD size, data;
8601     LONG res;
8602     UINT r;
8603     REGSAM access = KEY_ALL_ACCESS;
8604
8605     create_test_guid(prodcode, prod_squashed);
8606     create_test_guid(patch, patch_squashed);
8607
8608     if (is_wow64)
8609         access |= KEY_WOW64_64KEY;
8610
8611     /* MSIPATCHSTATE_APPLIED */
8612
8613     lstrcpyA(patchcode, "apple");
8614     lstrcpyA(targetprod, "banana");
8615     context = 0xdeadbeef;
8616     lstrcpyA(targetsid, "kiwi");
8617     size = MAX_PATH;
8618     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8619                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8620                            &context, targetsid, &size);
8621     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8622     ok(!lstrcmpA(patchcode, "apple"),
8623        "Expected patchcode to be unchanged, got %s\n", patchcode);
8624     ok(!lstrcmpA(targetprod, "banana"),
8625        "Expected targetprod to be unchanged, got %s\n", targetprod);
8626     ok(context == 0xdeadbeef,
8627        "Expected context to be unchanged, got %d\n", context);
8628     ok(!lstrcmpA(targetsid, "kiwi"),
8629        "Expected targetsid to be unchanged, got %s\n", targetsid);
8630     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8631
8632     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8633     lstrcatA(keypath, prod_squashed);
8634
8635     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8637
8638     /* current user product key exists */
8639     lstrcpyA(patchcode, "apple");
8640     lstrcpyA(targetprod, "banana");
8641     context = 0xdeadbeef;
8642     lstrcpyA(targetsid, "kiwi");
8643     size = MAX_PATH;
8644     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8645                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8646                            &context, targetsid, &size);
8647     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8648     ok(!lstrcmpA(patchcode, "apple"),
8649        "Expected patchcode to be unchanged, got %s\n", patchcode);
8650     ok(!lstrcmpA(targetprod, "banana"),
8651        "Expected targetprod to be unchanged, got %s\n", targetprod);
8652     ok(context == 0xdeadbeef,
8653        "Expected context to be unchanged, got %d\n", context);
8654     ok(!lstrcmpA(targetsid, "kiwi"),
8655        "Expected targetsid to be unchanged, got %s\n", targetsid);
8656     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8657
8658     res = RegCreateKeyA(prodkey, "Patches", &patches);
8659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8660
8661     /* Patches key exists */
8662     lstrcpyA(patchcode, "apple");
8663     lstrcpyA(targetprod, "banana");
8664     context = 0xdeadbeef;
8665     lstrcpyA(targetsid, "kiwi");
8666     size = MAX_PATH;
8667     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8668                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8669                            &context, targetsid, &size);
8670     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8671     ok(!lstrcmpA(patchcode, "apple"),
8672        "Expected patchcode to be unchanged, got %s\n", patchcode);
8673     ok(!lstrcmpA(targetprod, "banana"),
8674        "Expected targetprod to be unchanged, got %s\n", targetprod);
8675     ok(context == 0xdeadbeef,
8676        "Expected context to be unchanged, got %d\n", context);
8677     ok(!lstrcmpA(targetsid, "kiwi"),
8678        "Expected targetsid to be unchanged, got %s\n", targetsid);
8679     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8680
8681     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8682                          (const BYTE *)patch_squashed,
8683                          lstrlenA(patch_squashed) + 1);
8684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8685
8686     /* Patches value exists, is not REG_MULTI_SZ */
8687     lstrcpyA(patchcode, "apple");
8688     lstrcpyA(targetprod, "banana");
8689     context = 0xdeadbeef;
8690     lstrcpyA(targetsid, "kiwi");
8691     size = MAX_PATH;
8692     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8693                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8694                            &context, targetsid, &size);
8695     ok(r == ERROR_BAD_CONFIGURATION,
8696        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8697     ok(!lstrcmpA(patchcode, "apple"),
8698        "Expected patchcode to be unchanged, got %s\n", patchcode);
8699     ok(!lstrcmpA(targetprod, "banana"),
8700        "Expected targetprod to be unchanged, got %s\n", targetprod);
8701     ok(context == 0xdeadbeef,
8702        "Expected context to be unchanged, got %d\n", context);
8703     ok(!lstrcmpA(targetsid, "kiwi"),
8704        "Expected targetsid to be unchanged, got %s\n", targetsid);
8705     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8706
8707     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8708                          (const BYTE *)"a\0b\0c\0\0", 7);
8709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8710
8711     /* Patches value exists, is not a squashed guid */
8712     lstrcpyA(patchcode, "apple");
8713     lstrcpyA(targetprod, "banana");
8714     context = 0xdeadbeef;
8715     lstrcpyA(targetsid, "kiwi");
8716     size = MAX_PATH;
8717     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8718                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8719                            &context, targetsid, &size);
8720     ok(r == ERROR_BAD_CONFIGURATION,
8721        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8722     ok(!lstrcmpA(patchcode, "apple"),
8723        "Expected patchcode to be unchanged, got %s\n", patchcode);
8724     ok(!lstrcmpA(targetprod, "banana"),
8725        "Expected targetprod to be unchanged, got %s\n", targetprod);
8726     ok(context == 0xdeadbeef,
8727        "Expected context to be unchanged, got %d\n", context);
8728     ok(!lstrcmpA(targetsid, "kiwi"),
8729        "Expected targetsid to be unchanged, got %s\n", targetsid);
8730     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8731
8732     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8733     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8734                          (const BYTE *)patch_squashed,
8735                          lstrlenA(patch_squashed) + 2);
8736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8737
8738     /* Patches value exists */
8739     lstrcpyA(patchcode, "apple");
8740     lstrcpyA(targetprod, "banana");
8741     context = 0xdeadbeef;
8742     lstrcpyA(targetsid, "kiwi");
8743     size = MAX_PATH;
8744     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8745                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8746                            &context, targetsid, &size);
8747     ok(r == ERROR_NO_MORE_ITEMS ||
8748        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8749        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8750     ok(!lstrcmpA(patchcode, "apple"),
8751        "Expected patchcode to be unchanged, got %s\n", patchcode);
8752     ok(!lstrcmpA(targetprod, "banana"),
8753        "Expected targetprod to be unchanged, got %s\n", targetprod);
8754     ok(context == 0xdeadbeef,
8755        "Expected context to be unchanged, got %d\n", context);
8756     ok(!lstrcmpA(targetsid, "kiwi"),
8757        "Expected targetsid to be unchanged, got %s\n", targetsid);
8758     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8759
8760     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8761                          (const BYTE *)"whatever", 9);
8762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8763
8764     /* patch code value exists */
8765     lstrcpyA(patchcode, "apple");
8766     lstrcpyA(targetprod, "banana");
8767     context = 0xdeadbeef;
8768     lstrcpyA(targetsid, "kiwi");
8769     size = MAX_PATH;
8770     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8771                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8772                            &context, targetsid, &size);
8773     ok(r == ERROR_NO_MORE_ITEMS ||
8774        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8775        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8776     ok(!lstrcmpA(patchcode, "apple"),
8777        "Expected patchcode to be unchanged, got %s\n", patchcode);
8778     ok(!lstrcmpA(targetprod, "banana"),
8779        "Expected targetprod to be unchanged, got %s\n", targetprod);
8780     ok(context == 0xdeadbeef,
8781        "Expected context to be unchanged, got %d\n", context);
8782     ok(!lstrcmpA(targetsid, "kiwi"),
8783        "Expected targetsid to be unchanged, got %s\n", targetsid);
8784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8785
8786     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8787     lstrcatA(keypath, expectedsid);
8788     lstrcatA(keypath, "\\Patches\\");
8789     lstrcatA(keypath, patch_squashed);
8790
8791     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8792     if (res == ERROR_ACCESS_DENIED)
8793     {
8794         skip("Not enough rights to perform tests\n");
8795         goto error;
8796     }
8797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8798
8799     /* userdata patch key exists */
8800     lstrcpyA(patchcode, "apple");
8801     lstrcpyA(targetprod, "banana");
8802     context = 0xdeadbeef;
8803     lstrcpyA(targetsid, "kiwi");
8804     size = MAX_PATH;
8805     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8806                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8807                            &context, targetsid, &size);
8808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8809     ok(!lstrcmpA(patchcode, patch),
8810        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8811     ok(!lstrcmpA(targetprod, prodcode),
8812        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8813     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8814        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8815     ok(!lstrcmpA(targetsid, expectedsid),
8816        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8817     ok(size == lstrlenA(expectedsid),
8818        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8819
8820     /* MSIPATCHSTATE_SUPERSEDED */
8821
8822     lstrcpyA(patchcode, "apple");
8823     lstrcpyA(targetprod, "banana");
8824     context = 0xdeadbeef;
8825     lstrcpyA(targetsid, "kiwi");
8826     size = MAX_PATH;
8827     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8828                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8829                            &context, targetsid, &size);
8830     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8831     ok(!lstrcmpA(patchcode, "apple"),
8832        "Expected patchcode to be unchanged, got %s\n", patchcode);
8833     ok(!lstrcmpA(targetprod, "banana"),
8834        "Expected targetprod to be unchanged, got %s\n", targetprod);
8835     ok(context == 0xdeadbeef,
8836        "Expected context to be unchanged, got %d\n", context);
8837     ok(!lstrcmpA(targetsid, "kiwi"),
8838        "Expected targetsid to be unchanged, got %s\n", targetsid);
8839     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8840
8841     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8842     lstrcatA(keypath, expectedsid);
8843     lstrcatA(keypath, "\\Products\\");
8844     lstrcatA(keypath, prod_squashed);
8845
8846     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8847     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8848
8849     /* UserData product key exists */
8850     lstrcpyA(patchcode, "apple");
8851     lstrcpyA(targetprod, "banana");
8852     context = 0xdeadbeef;
8853     lstrcpyA(targetsid, "kiwi");
8854     size = MAX_PATH;
8855     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8856                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8857                            &context, targetsid, &size);
8858     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8859     ok(!lstrcmpA(patchcode, "apple"),
8860        "Expected patchcode to be unchanged, got %s\n", patchcode);
8861     ok(!lstrcmpA(targetprod, "banana"),
8862        "Expected targetprod to be unchanged, got %s\n", targetprod);
8863     ok(context == 0xdeadbeef,
8864        "Expected context to be unchanged, got %d\n", context);
8865     ok(!lstrcmpA(targetsid, "kiwi"),
8866        "Expected targetsid to be unchanged, got %s\n", targetsid);
8867     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8868
8869     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8871
8872     /* UserData patches key exists */
8873     lstrcpyA(patchcode, "apple");
8874     lstrcpyA(targetprod, "banana");
8875     context = 0xdeadbeef;
8876     lstrcpyA(targetsid, "kiwi");
8877     size = MAX_PATH;
8878     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8879                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8880                            &context, targetsid, &size);
8881     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8882     ok(!lstrcmpA(patchcode, "apple"),
8883        "Expected patchcode to be unchanged, got %s\n", patchcode);
8884     ok(!lstrcmpA(targetprod, "banana"),
8885        "Expected targetprod to be unchanged, got %s\n", targetprod);
8886     ok(context == 0xdeadbeef,
8887        "Expected context to be unchanged, got %d\n", context);
8888     ok(!lstrcmpA(targetsid, "kiwi"),
8889        "Expected targetsid to be unchanged, got %s\n", targetsid);
8890     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8891
8892     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8894
8895     /* specific UserData patch key exists */
8896     lstrcpyA(patchcode, "apple");
8897     lstrcpyA(targetprod, "banana");
8898     context = 0xdeadbeef;
8899     lstrcpyA(targetsid, "kiwi");
8900     size = MAX_PATH;
8901     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8902                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8903                            &context, targetsid, &size);
8904     ok(r == ERROR_BAD_CONFIGURATION,
8905        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8906     ok(!lstrcmpA(patchcode, "apple"),
8907        "Expected patchcode to be unchanged, got %s\n", patchcode);
8908     ok(!lstrcmpA(targetprod, "banana"),
8909        "Expected targetprod to be unchanged, got %s\n", targetprod);
8910     ok(context == 0xdeadbeef,
8911        "Expected context to be unchanged, got %d\n", context);
8912     ok(!lstrcmpA(targetsid, "kiwi"),
8913        "Expected targetsid to be unchanged, got %s\n", targetsid);
8914     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8915
8916     data = MSIPATCHSTATE_SUPERSEDED;
8917     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8918                          (const BYTE *)&data, sizeof(DWORD));
8919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8920
8921     /* State value exists */
8922     lstrcpyA(patchcode, "apple");
8923     lstrcpyA(targetprod, "banana");
8924     context = 0xdeadbeef;
8925     lstrcpyA(targetsid, "kiwi");
8926     size = MAX_PATH;
8927     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8928                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8929                            &context, targetsid, &size);
8930     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8931     ok(!lstrcmpA(patchcode, patch),
8932        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8933     ok(!lstrcmpA(targetprod, prodcode),
8934        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8935     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8936        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8937     ok(!lstrcmpA(targetsid, expectedsid),
8938        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8939     ok(size == lstrlenA(expectedsid),
8940        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8941
8942     /* MSIPATCHSTATE_OBSOLETED */
8943
8944     lstrcpyA(patchcode, "apple");
8945     lstrcpyA(targetprod, "banana");
8946     context = 0xdeadbeef;
8947     lstrcpyA(targetsid, "kiwi");
8948     size = MAX_PATH;
8949     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8950                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8951                            &context, targetsid, &size);
8952     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8953     ok(!lstrcmpA(patchcode, "apple"),
8954        "Expected patchcode to be unchanged, got %s\n", patchcode);
8955     ok(!lstrcmpA(targetprod, "banana"),
8956        "Expected targetprod to be unchanged, got %s\n", targetprod);
8957     ok(context == 0xdeadbeef,
8958        "Expected context to be unchanged, got %d\n", context);
8959     ok(!lstrcmpA(targetsid, "kiwi"),
8960        "Expected targetsid to be unchanged, got %s\n", targetsid);
8961     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8962
8963     data = MSIPATCHSTATE_OBSOLETED;
8964     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8965                          (const BYTE *)&data, sizeof(DWORD));
8966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8967
8968     /* State value is obsoleted */
8969     lstrcpyA(patchcode, "apple");
8970     lstrcpyA(targetprod, "banana");
8971     context = 0xdeadbeef;
8972     lstrcpyA(targetsid, "kiwi");
8973     size = MAX_PATH;
8974     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8975                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8976                            &context, targetsid, &size);
8977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8978     ok(!lstrcmpA(patchcode, patch),
8979        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8980     ok(!lstrcmpA(targetprod, prodcode),
8981        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8982     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8983        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8984     ok(!lstrcmpA(targetsid, expectedsid),
8985        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8986     ok(size == lstrlenA(expectedsid),
8987        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8988
8989     /* MSIPATCHSTATE_REGISTERED */
8990     /* FIXME */
8991
8992     /* MSIPATCHSTATE_ALL */
8993
8994     /* 1st */
8995     lstrcpyA(patchcode, "apple");
8996     lstrcpyA(targetprod, "banana");
8997     context = 0xdeadbeef;
8998     lstrcpyA(targetsid, "kiwi");
8999     size = MAX_PATH;
9000     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9001                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9002                            &context, targetsid, &size);
9003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9004     ok(!lstrcmpA(patchcode, patch),
9005        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9006     ok(!lstrcmpA(targetprod, prodcode),
9007        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9008     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9009        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9010     ok(!lstrcmpA(targetsid, expectedsid),
9011        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9012     ok(size == lstrlenA(expectedsid),
9013        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9014
9015     /* same patch in multiple places, only one is enumerated */
9016     lstrcpyA(patchcode, "apple");
9017     lstrcpyA(targetprod, "banana");
9018     context = 0xdeadbeef;
9019     lstrcpyA(targetsid, "kiwi");
9020     size = MAX_PATH;
9021     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9022                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9023                            &context, targetsid, &size);
9024     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9025     ok(!lstrcmpA(patchcode, "apple"),
9026        "Expected patchcode to be unchanged, got %s\n", patchcode);
9027     ok(!lstrcmpA(targetprod, "banana"),
9028        "Expected targetprod to be unchanged, got %s\n", targetprod);
9029     ok(context == 0xdeadbeef,
9030        "Expected context to be unchanged, got %d\n", context);
9031     ok(!lstrcmpA(targetsid, "kiwi"),
9032        "Expected targetsid to be unchanged, got %s\n", targetsid);
9033     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9034
9035     RegDeleteValueA(hpatch, "State");
9036     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9037     RegCloseKey(hpatch);
9038     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9039     RegCloseKey(udpatch);
9040     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9041     RegCloseKey(udprod);
9042     delete_key(userkey, "", access & KEY_WOW64_64KEY);
9043     RegCloseKey(userkey);
9044     RegDeleteValueA(patches, patch_squashed);
9045     RegDeleteValueA(patches, "Patches");
9046
9047 error:
9048     RegDeleteKeyA(patches, "");
9049     RegCloseKey(patches);
9050     RegDeleteKeyA(prodkey, "");
9051     RegCloseKey(prodkey);
9052 }
9053
9054 static void test_MsiEnumPatchesEx_machine(void)
9055 {
9056     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9057     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9058     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9059     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9060     HKEY prodkey, patches, udprod, udpatch;
9061     HKEY hpatch;
9062     MSIINSTALLCONTEXT context;
9063     DWORD size, data;
9064     LONG res;
9065     UINT r;
9066     REGSAM access = KEY_ALL_ACCESS;
9067
9068     create_test_guid(prodcode, prod_squashed);
9069     create_test_guid(patch, patch_squashed);
9070
9071     if (is_wow64)
9072         access |= KEY_WOW64_64KEY;
9073
9074     /* MSIPATCHSTATE_APPLIED */
9075
9076     lstrcpyA(patchcode, "apple");
9077     lstrcpyA(targetprod, "banana");
9078     context = 0xdeadbeef;
9079     lstrcpyA(targetsid, "kiwi");
9080     size = MAX_PATH;
9081     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9082                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9083                            &context, targetsid, &size);
9084     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9085     ok(!lstrcmpA(patchcode, "apple"),
9086        "Expected patchcode to be unchanged, got %s\n", patchcode);
9087     ok(!lstrcmpA(targetprod, "banana"),
9088        "Expected targetprod to be unchanged, got %s\n", targetprod);
9089     ok(context == 0xdeadbeef,
9090        "Expected context to be unchanged, got %d\n", context);
9091     ok(!lstrcmpA(targetsid, "kiwi"),
9092        "Expected targetsid to be unchanged, got %s\n", targetsid);
9093     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9094
9095     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9096     lstrcatA(keypath, prod_squashed);
9097
9098     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9099     if (res == ERROR_ACCESS_DENIED)
9100     {
9101         skip("Not enough rights to perform tests\n");
9102         return;
9103     }
9104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9105
9106     /* local product key exists */
9107     lstrcpyA(patchcode, "apple");
9108     lstrcpyA(targetprod, "banana");
9109     context = 0xdeadbeef;
9110     lstrcpyA(targetsid, "kiwi");
9111     size = MAX_PATH;
9112     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9113                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9114                            &context, targetsid, &size);
9115     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9116     ok(!lstrcmpA(patchcode, "apple"),
9117        "Expected patchcode to be unchanged, got %s\n", patchcode);
9118     ok(!lstrcmpA(targetprod, "banana"),
9119        "Expected targetprod to be unchanged, got %s\n", targetprod);
9120     ok(context == 0xdeadbeef,
9121        "Expected context to be unchanged, got %d\n", context);
9122     ok(!lstrcmpA(targetsid, "kiwi"),
9123        "Expected targetsid to be unchanged, got %s\n", targetsid);
9124     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9125
9126     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9128
9129     /* Patches key exists */
9130     lstrcpyA(patchcode, "apple");
9131     lstrcpyA(targetprod, "banana");
9132     context = 0xdeadbeef;
9133     lstrcpyA(targetsid, "kiwi");
9134     size = MAX_PATH;
9135     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9136                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9137                            &context, targetsid, &size);
9138     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9139     ok(!lstrcmpA(patchcode, "apple"),
9140        "Expected patchcode to be unchanged, got %s\n", patchcode);
9141     ok(!lstrcmpA(targetprod, "banana"),
9142        "Expected targetprod to be unchanged, got %s\n", targetprod);
9143     ok(context == 0xdeadbeef,
9144        "Expected context to be unchanged, got %d\n", context);
9145     ok(!lstrcmpA(targetsid, "kiwi"),
9146        "Expected targetsid to be unchanged, got %s\n", targetsid);
9147     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9148
9149     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9150                          (const BYTE *)patch_squashed,
9151                          lstrlenA(patch_squashed) + 1);
9152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9153
9154     /* Patches value exists, is not REG_MULTI_SZ */
9155     lstrcpyA(patchcode, "apple");
9156     lstrcpyA(targetprod, "banana");
9157     context = 0xdeadbeef;
9158     lstrcpyA(targetsid, "kiwi");
9159     size = MAX_PATH;
9160     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9161                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9162                            &context, targetsid, &size);
9163     ok(r == ERROR_BAD_CONFIGURATION,
9164        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9165     ok(!lstrcmpA(patchcode, "apple"),
9166        "Expected patchcode to be unchanged, got %s\n", patchcode);
9167     ok(!lstrcmpA(targetprod, "banana"),
9168        "Expected targetprod to be unchanged, got %s\n", targetprod);
9169     ok(context == 0xdeadbeef,
9170        "Expected context to be unchanged, got %d\n", context);
9171     ok(!lstrcmpA(targetsid, "kiwi"),
9172        "Expected targetsid to be unchanged, got %s\n", targetsid);
9173     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9174
9175     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9176                          (const BYTE *)"a\0b\0c\0\0", 7);
9177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9178
9179     /* Patches value exists, is not a squashed guid */
9180     lstrcpyA(patchcode, "apple");
9181     lstrcpyA(targetprod, "banana");
9182     context = 0xdeadbeef;
9183     lstrcpyA(targetsid, "kiwi");
9184     size = MAX_PATH;
9185     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9186                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9187                            &context, targetsid, &size);
9188     ok(r == ERROR_BAD_CONFIGURATION,
9189        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9190     ok(!lstrcmpA(patchcode, "apple"),
9191        "Expected patchcode to be unchanged, got %s\n", patchcode);
9192     ok(!lstrcmpA(targetprod, "banana"),
9193        "Expected targetprod to be unchanged, got %s\n", targetprod);
9194     ok(context == 0xdeadbeef,
9195        "Expected context to be unchanged, got %d\n", context);
9196     ok(!lstrcmpA(targetsid, "kiwi"),
9197        "Expected targetsid to be unchanged, got %s\n", targetsid);
9198     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9199
9200     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9201     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9202                          (const BYTE *)patch_squashed,
9203                          lstrlenA(patch_squashed) + 2);
9204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9205
9206     /* Patches value exists */
9207     lstrcpyA(patchcode, "apple");
9208     lstrcpyA(targetprod, "banana");
9209     context = 0xdeadbeef;
9210     lstrcpyA(targetsid, "kiwi");
9211     size = MAX_PATH;
9212     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9213                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9214                            &context, targetsid, &size);
9215     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9216     ok(!lstrcmpA(patchcode, "apple"),
9217        "Expected patchcode to be unchanged, got %s\n", patchcode);
9218     ok(!lstrcmpA(targetprod, "banana"),
9219        "Expected targetprod to be unchanged, got %s\n", targetprod);
9220     ok(context == 0xdeadbeef,
9221        "Expected context to be unchanged, got %d\n", context);
9222     ok(!lstrcmpA(targetsid, "kiwi"),
9223        "Expected targetsid to be unchanged, got %s\n", targetsid);
9224     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9225
9226     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9227                          (const BYTE *)"whatever", 9);
9228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9229
9230     /* patch code value exists */
9231     lstrcpyA(patchcode, "apple");
9232     lstrcpyA(targetprod, "banana");
9233     context = 0xdeadbeef;
9234     lstrcpyA(targetsid, "kiwi");
9235     size = MAX_PATH;
9236     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9237                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9238                            &context, targetsid, &size);
9239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9240     ok(!lstrcmpA(patchcode, patch),
9241        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9242     ok(!lstrcmpA(targetprod, prodcode),
9243        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9244     ok(context == MSIINSTALLCONTEXT_MACHINE,
9245        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9246     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9247     ok(size == 0, "Expected 0, got %d\n", size);
9248
9249     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9250     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9251     lstrcatA(keypath, prod_squashed);
9252
9253     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9255
9256     /* local UserData product key exists */
9257     lstrcpyA(patchcode, "apple");
9258     lstrcpyA(targetprod, "banana");
9259     context = 0xdeadbeef;
9260     lstrcpyA(targetsid, "kiwi");
9261     size = MAX_PATH;
9262     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9263                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9264                            &context, targetsid, &size);
9265     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9266     ok(!lstrcmpA(patchcode, patch),
9267        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9268     ok(!lstrcmpA(targetprod, prodcode),
9269        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9270     ok(context == MSIINSTALLCONTEXT_MACHINE,
9271        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9272     ok(!lstrcmpA(targetsid, ""),
9273        "Expected \"\", got \"%s\"\n", targetsid);
9274     ok(size == 0, "Expected 0, got %d\n", size);
9275
9276     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9278
9279     /* local UserData Patches key exists */
9280     lstrcpyA(patchcode, "apple");
9281     lstrcpyA(targetprod, "banana");
9282     context = 0xdeadbeef;
9283     lstrcpyA(targetsid, "kiwi");
9284     size = MAX_PATH;
9285     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9286                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9287                            &context, targetsid, &size);
9288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9289     ok(!lstrcmpA(patchcode, patch),
9290        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9291     ok(!lstrcmpA(targetprod, prodcode),
9292        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9293     ok(context == MSIINSTALLCONTEXT_MACHINE,
9294        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9295     ok(!lstrcmpA(targetsid, ""),
9296        "Expected \"\", got \"%s\"\n", targetsid);
9297     ok(size == 0, "Expected 0, got %d\n", size);
9298
9299     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9301
9302     /* local UserData Product patch key exists */
9303     lstrcpyA(patchcode, "apple");
9304     lstrcpyA(targetprod, "banana");
9305     context = 0xdeadbeef;
9306     lstrcpyA(targetsid, "kiwi");
9307     size = MAX_PATH;
9308     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9309                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9310                            &context, targetsid, &size);
9311     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9312     ok(!lstrcmpA(patchcode, "apple"),
9313        "Expected patchcode to be unchanged, got %s\n", patchcode);
9314     ok(!lstrcmpA(targetprod, "banana"),
9315        "Expected targetprod to be unchanged, got %s\n", targetprod);
9316     ok(context == 0xdeadbeef,
9317        "Expected context to be unchanged, got %d\n", context);
9318     ok(!lstrcmpA(targetsid, "kiwi"),
9319        "Expected targetsid to be unchanged, got %s\n", targetsid);
9320     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9321
9322     data = MSIPATCHSTATE_APPLIED;
9323     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9324                          (const BYTE *)&data, sizeof(DWORD));
9325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9326
9327     /* State value exists */
9328     lstrcpyA(patchcode, "apple");
9329     lstrcpyA(targetprod, "banana");
9330     context = 0xdeadbeef;
9331     lstrcpyA(targetsid, "kiwi");
9332     size = MAX_PATH;
9333     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9334                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9335                            &context, targetsid, &size);
9336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9337     ok(!lstrcmpA(patchcode, patch),
9338        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9339     ok(!lstrcmpA(targetprod, prodcode),
9340        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9341     ok(context == MSIINSTALLCONTEXT_MACHINE,
9342        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9343     ok(!lstrcmpA(targetsid, ""),
9344        "Expected \"\", got \"%s\"\n", targetsid);
9345     ok(size == 0, "Expected 0, got %d\n", size);
9346
9347     /* MSIPATCHSTATE_SUPERSEDED */
9348
9349     lstrcpyA(patchcode, "apple");
9350     lstrcpyA(targetprod, "banana");
9351     context = 0xdeadbeef;
9352     lstrcpyA(targetsid, "kiwi");
9353     size = MAX_PATH;
9354     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9355                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9356                            &context, targetsid, &size);
9357     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9358     ok(!lstrcmpA(patchcode, "apple"),
9359        "Expected patchcode to be unchanged, got %s\n", patchcode);
9360     ok(!lstrcmpA(targetprod, "banana"),
9361        "Expected targetprod to be unchanged, got %s\n", targetprod);
9362     ok(context == 0xdeadbeef,
9363        "Expected context to be unchanged, got %d\n", context);
9364     ok(!lstrcmpA(targetsid, "kiwi"),
9365        "Expected targetsid to be unchanged, got %s\n", targetsid);
9366     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9367
9368     data = MSIPATCHSTATE_SUPERSEDED;
9369     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9370                          (const BYTE *)&data, sizeof(DWORD));
9371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9372
9373     /* State value is MSIPATCHSTATE_SUPERSEDED */
9374     lstrcpyA(patchcode, "apple");
9375     lstrcpyA(targetprod, "banana");
9376     context = 0xdeadbeef;
9377     lstrcpyA(targetsid, "kiwi");
9378     size = MAX_PATH;
9379     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9380                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9381                            &context, targetsid, &size);
9382     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9383     ok(!lstrcmpA(patchcode, patch),
9384        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9385     ok(!lstrcmpA(targetprod, prodcode),
9386        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9387     ok(context == MSIINSTALLCONTEXT_MACHINE,
9388        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9389     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9390     ok(size == 0, "Expected 0, got %d\n", size);
9391
9392     /* MSIPATCHSTATE_OBSOLETED */
9393
9394     lstrcpyA(patchcode, "apple");
9395     lstrcpyA(targetprod, "banana");
9396     context = 0xdeadbeef;
9397     lstrcpyA(targetsid, "kiwi");
9398     size = MAX_PATH;
9399     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9400                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9401                            &context, targetsid, &size);
9402     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9403     ok(!lstrcmpA(patchcode, "apple"),
9404        "Expected patchcode to be unchanged, got %s\n", patchcode);
9405     ok(!lstrcmpA(targetprod, "banana"),
9406        "Expected targetprod to be unchanged, got %s\n", targetprod);
9407     ok(context == 0xdeadbeef,
9408        "Expected context to be unchanged, got %d\n", context);
9409     ok(!lstrcmpA(targetsid, "kiwi"),
9410        "Expected targetsid to be unchanged, got %s\n", targetsid);
9411     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9412
9413     data = MSIPATCHSTATE_OBSOLETED;
9414     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9415                          (const BYTE *)&data, sizeof(DWORD));
9416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9417
9418     /* State value is obsoleted */
9419     lstrcpyA(patchcode, "apple");
9420     lstrcpyA(targetprod, "banana");
9421     context = 0xdeadbeef;
9422     lstrcpyA(targetsid, "kiwi");
9423     size = MAX_PATH;
9424     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9425                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9426                            &context, targetsid, &size);
9427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9428     ok(!lstrcmpA(patchcode, patch),
9429        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9430     ok(!lstrcmpA(targetprod, prodcode),
9431        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9432     ok(context == MSIINSTALLCONTEXT_MACHINE,
9433        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9434     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9435     ok(size == 0, "Expected 0, got %d\n", size);
9436
9437     /* MSIPATCHSTATE_REGISTERED */
9438     /* FIXME */
9439
9440     /* MSIPATCHSTATE_ALL */
9441
9442     /* 1st */
9443     lstrcpyA(patchcode, "apple");
9444     lstrcpyA(targetprod, "banana");
9445     context = 0xdeadbeef;
9446     lstrcpyA(targetsid, "kiwi");
9447     size = MAX_PATH;
9448     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9449                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9450                            &context, targetsid, &size);
9451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9452     ok(!lstrcmpA(patchcode, patch),
9453        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9454     ok(!lstrcmpA(targetprod, prodcode),
9455        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9456     ok(context == MSIINSTALLCONTEXT_MACHINE,
9457        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9458     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9459     ok(size == 0, "Expected 0, got %d\n", size);
9460
9461     /* same patch in multiple places, only one is enumerated */
9462     lstrcpyA(patchcode, "apple");
9463     lstrcpyA(targetprod, "banana");
9464     context = 0xdeadbeef;
9465     lstrcpyA(targetsid, "kiwi");
9466     size = MAX_PATH;
9467     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9468                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9469                            &context, targetsid, &size);
9470     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9471     ok(!lstrcmpA(patchcode, "apple"),
9472        "Expected patchcode to be unchanged, got %s\n", patchcode);
9473     ok(!lstrcmpA(targetprod, "banana"),
9474        "Expected targetprod to be unchanged, got %s\n", targetprod);
9475     ok(context == 0xdeadbeef,
9476        "Expected context to be unchanged, got %d\n", context);
9477     ok(!lstrcmpA(targetsid, "kiwi"),
9478        "Expected targetsid to be unchanged, got %s\n", targetsid);
9479     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9480
9481     RegDeleteValueA(patches, patch_squashed);
9482     RegDeleteValueA(patches, "Patches");
9483     delete_key(patches, "", access & KEY_WOW64_64KEY);
9484     RegCloseKey(patches);
9485     RegDeleteValueA(hpatch, "State");
9486     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9487     RegCloseKey(hpatch);
9488     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9489     RegCloseKey(udpatch);
9490     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9491     RegCloseKey(udprod);
9492     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9493     RegCloseKey(prodkey);
9494 }
9495
9496 static void test_MsiEnumPatchesEx(void)
9497 {
9498     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9499     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9500     CHAR patchcode[MAX_PATH];
9501     MSIINSTALLCONTEXT context;
9502     LPSTR usersid;
9503     DWORD size;
9504     UINT r;
9505
9506     if (!pMsiEnumPatchesExA)
9507     {
9508         win_skip("MsiEnumPatchesExA not implemented\n");
9509         return;
9510     }
9511
9512     create_test_guid(prodcode, prod_squashed);
9513     get_user_sid(&usersid);
9514
9515     /* empty szProductCode */
9516     lstrcpyA(patchcode, "apple");
9517     lstrcpyA(targetprod, "banana");
9518     context = 0xdeadbeef;
9519     lstrcpyA(targetsid, "kiwi");
9520     size = MAX_PATH;
9521     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9522                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9523                            targetsid, &size);
9524     ok(r == ERROR_INVALID_PARAMETER,
9525        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9526     ok(!lstrcmpA(patchcode, "apple"),
9527        "Expected patchcode to be unchanged, got %s\n", patchcode);
9528     ok(!lstrcmpA(targetprod, "banana"),
9529        "Expected targetprod to be unchanged, got %s\n", targetprod);
9530     ok(context == 0xdeadbeef,
9531        "Expected context to be unchanged, got %d\n", context);
9532     ok(!lstrcmpA(targetsid, "kiwi"),
9533        "Expected targetsid to be unchanged, got %s\n", targetsid);
9534     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9535
9536     /* garbage szProductCode */
9537     lstrcpyA(patchcode, "apple");
9538     lstrcpyA(targetprod, "banana");
9539     context = 0xdeadbeef;
9540     lstrcpyA(targetsid, "kiwi");
9541     size = MAX_PATH;
9542     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9543                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9544                            targetsid, &size);
9545     ok(r == ERROR_INVALID_PARAMETER,
9546        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9547     ok(!lstrcmpA(patchcode, "apple"),
9548        "Expected patchcode to be unchanged, got %s\n", patchcode);
9549     ok(!lstrcmpA(targetprod, "banana"),
9550        "Expected targetprod to be unchanged, got %s\n", targetprod);
9551     ok(context == 0xdeadbeef,
9552        "Expected context to be unchanged, got %d\n", context);
9553     ok(!lstrcmpA(targetsid, "kiwi"),
9554        "Expected targetsid to be unchanged, got %s\n", targetsid);
9555     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9556
9557     /* guid without brackets */
9558     lstrcpyA(patchcode, "apple");
9559     lstrcpyA(targetprod, "banana");
9560     context = 0xdeadbeef;
9561     lstrcpyA(targetsid, "kiwi");
9562     size = MAX_PATH;
9563     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9564                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9565                            0, patchcode, targetprod, &context,
9566                            targetsid, &size);
9567     ok(r == ERROR_INVALID_PARAMETER,
9568        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9569     ok(!lstrcmpA(patchcode, "apple"),
9570        "Expected patchcode to be unchanged, got %s\n", patchcode);
9571     ok(!lstrcmpA(targetprod, "banana"),
9572        "Expected targetprod to be unchanged, got %s\n", targetprod);
9573     ok(context == 0xdeadbeef,
9574        "Expected context to be unchanged, got %d\n", context);
9575     ok(!lstrcmpA(targetsid, "kiwi"),
9576        "Expected targetsid to be unchanged, got %s\n", targetsid);
9577     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9578
9579     /* guid with brackets */
9580     lstrcpyA(patchcode, "apple");
9581     lstrcpyA(targetprod, "banana");
9582     context = 0xdeadbeef;
9583     lstrcpyA(targetsid, "kiwi");
9584     size = MAX_PATH;
9585     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9586                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9587                            0, patchcode, targetprod, &context,
9588                            targetsid, &size);
9589     ok(r == ERROR_NO_MORE_ITEMS,
9590        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9591     ok(!lstrcmpA(patchcode, "apple"),
9592        "Expected patchcode to be unchanged, got %s\n", patchcode);
9593     ok(!lstrcmpA(targetprod, "banana"),
9594        "Expected targetprod to be unchanged, got %s\n", targetprod);
9595     ok(context == 0xdeadbeef,
9596        "Expected context to be unchanged, got %d\n", context);
9597     ok(!lstrcmpA(targetsid, "kiwi"),
9598        "Expected targetsid to be unchanged, got %s\n", targetsid);
9599     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9600
9601     /* szUserSid is S-1-5-18 */
9602     lstrcpyA(patchcode, "apple");
9603     lstrcpyA(targetprod, "banana");
9604     context = 0xdeadbeef;
9605     lstrcpyA(targetsid, "kiwi");
9606     size = MAX_PATH;
9607     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9608                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9609                            0, patchcode, targetprod, &context,
9610                            targetsid, &size);
9611     ok(r == ERROR_INVALID_PARAMETER,
9612        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9613     ok(!lstrcmpA(patchcode, "apple"),
9614        "Expected patchcode to be unchanged, got %s\n", patchcode);
9615     ok(!lstrcmpA(targetprod, "banana"),
9616        "Expected targetprod to be unchanged, got %s\n", targetprod);
9617     ok(context == 0xdeadbeef,
9618        "Expected context to be unchanged, got %d\n", context);
9619     ok(!lstrcmpA(targetsid, "kiwi"),
9620        "Expected targetsid to be unchanged, got %s\n", targetsid);
9621     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9622
9623     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9624     lstrcpyA(patchcode, "apple");
9625     lstrcpyA(targetprod, "banana");
9626     context = 0xdeadbeef;
9627     lstrcpyA(targetsid, "kiwi");
9628     size = MAX_PATH;
9629     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9630                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9631                            &context, targetsid, &size);
9632     ok(r == ERROR_INVALID_PARAMETER,
9633        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9634     ok(!lstrcmpA(patchcode, "apple"),
9635        "Expected patchcode to be unchanged, got %s\n", patchcode);
9636     ok(!lstrcmpA(targetprod, "banana"),
9637        "Expected targetprod to be unchanged, got %s\n", targetprod);
9638     ok(context == 0xdeadbeef,
9639        "Expected context to be unchanged, got %d\n", context);
9640     ok(!lstrcmpA(targetsid, "kiwi"),
9641        "Expected targetsid to be unchanged, got %s\n", targetsid);
9642     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9643
9644     /* dwContext is out of bounds */
9645     lstrcpyA(patchcode, "apple");
9646     lstrcpyA(targetprod, "banana");
9647     context = 0xdeadbeef;
9648     lstrcpyA(targetsid, "kiwi");
9649     size = MAX_PATH;
9650     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9651                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9652                            &context, targetsid, &size);
9653     ok(r == ERROR_INVALID_PARAMETER,
9654        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9655     ok(!lstrcmpA(patchcode, "apple"),
9656        "Expected patchcode to be unchanged, got %s\n", patchcode);
9657     ok(!lstrcmpA(targetprod, "banana"),
9658        "Expected targetprod to be unchanged, got %s\n", targetprod);
9659     ok(context == 0xdeadbeef,
9660        "Expected context to be unchanged, got %d\n", context);
9661     ok(!lstrcmpA(targetsid, "kiwi"),
9662        "Expected targetsid to be unchanged, got %s\n", targetsid);
9663     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9664
9665     /* dwContext is out of bounds */
9666     lstrcpyA(patchcode, "apple");
9667     lstrcpyA(targetprod, "banana");
9668     context = 0xdeadbeef;
9669     lstrcpyA(targetsid, "kiwi");
9670     size = MAX_PATH;
9671     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9672                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9673                            &context, targetsid, &size);
9674     ok(r == ERROR_INVALID_PARAMETER,
9675        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9676     ok(!lstrcmpA(patchcode, "apple"),
9677        "Expected patchcode to be unchanged, got %s\n", patchcode);
9678     ok(!lstrcmpA(targetprod, "banana"),
9679        "Expected targetprod to be unchanged, got %s\n", targetprod);
9680     ok(context == 0xdeadbeef,
9681        "Expected context to be unchanged, got %d\n", context);
9682     ok(!lstrcmpA(targetsid, "kiwi"),
9683        "Expected targetsid to be unchanged, got %s\n", targetsid);
9684     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9685
9686     /* dwFilter is out of bounds */
9687     lstrcpyA(patchcode, "apple");
9688     lstrcpyA(targetprod, "banana");
9689     context = 0xdeadbeef;
9690     lstrcpyA(targetsid, "kiwi");
9691     size = MAX_PATH;
9692     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9693                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9694                            &context, targetsid, &size);
9695     ok(r == ERROR_INVALID_PARAMETER,
9696        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9697     ok(!lstrcmpA(patchcode, "apple"),
9698        "Expected patchcode to be unchanged, got %s\n", patchcode);
9699     ok(!lstrcmpA(targetprod, "banana"),
9700        "Expected targetprod to be unchanged, got %s\n", targetprod);
9701     ok(context == 0xdeadbeef,
9702        "Expected context to be unchanged, got %d\n", context);
9703     ok(!lstrcmpA(targetsid, "kiwi"),
9704        "Expected targetsid to be unchanged, got %s\n", targetsid);
9705     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9706
9707     /* dwFilter is out of bounds */
9708     lstrcpyA(patchcode, "apple");
9709     lstrcpyA(targetprod, "banana");
9710     context = 0xdeadbeef;
9711     lstrcpyA(targetsid, "kiwi");
9712     size = MAX_PATH;
9713     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9714                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9715                            &context, targetsid, &size);
9716     ok(r == ERROR_INVALID_PARAMETER,
9717        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9718     ok(!lstrcmpA(patchcode, "apple"),
9719        "Expected patchcode to be unchanged, got %s\n", patchcode);
9720     ok(!lstrcmpA(targetprod, "banana"),
9721        "Expected targetprod to be unchanged, got %s\n", targetprod);
9722     ok(context == 0xdeadbeef,
9723        "Expected context to be unchanged, got %d\n", context);
9724     ok(!lstrcmpA(targetsid, "kiwi"),
9725        "Expected targetsid to be unchanged, got %s\n", targetsid);
9726     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9727
9728     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9729     lstrcpyA(patchcode, "apple");
9730     lstrcpyA(targetprod, "banana");
9731     context = 0xdeadbeef;
9732     lstrcpyA(targetsid, "kiwi");
9733     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9734                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9735                            &context, targetsid, NULL);
9736     ok(r == ERROR_INVALID_PARAMETER,
9737        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9738     ok(!lstrcmpA(patchcode, "apple"),
9739        "Expected patchcode to be unchanged, got %s\n", patchcode);
9740     ok(!lstrcmpA(targetprod, "banana"),
9741        "Expected targetprod to be unchanged, got %s\n", targetprod);
9742     ok(context == 0xdeadbeef,
9743        "Expected context to be unchanged, got %d\n", context);
9744     ok(!lstrcmpA(targetsid, "kiwi"),
9745        "Expected targetsid to be unchanged, got %s\n", targetsid);
9746
9747     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9748     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9749     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9750     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9751     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9752     /* FIXME: Successfully test userunmanaged with a different user */
9753     test_MsiEnumPatchesEx_machine();
9754     LocalFree(usersid);
9755 }
9756
9757 static void test_MsiEnumPatches(void)
9758 {
9759     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9760     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9761     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9762     CHAR transforms[MAX_PATH];
9763     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9764     HKEY prodkey, patches, udprod;
9765     HKEY userkey, hpatch, udpatch;
9766     DWORD size, data;
9767     LPSTR usersid;
9768     LONG res;
9769     UINT r;
9770     REGSAM access = KEY_ALL_ACCESS;
9771
9772     create_test_guid(prodcode, prod_squashed);
9773     create_test_guid(patchcode, patch_squashed);
9774     get_user_sid(&usersid);
9775
9776     if (is_wow64)
9777         access |= KEY_WOW64_64KEY;
9778
9779     /* NULL szProduct */
9780     size = MAX_PATH;
9781     lstrcpyA(patch, "apple");
9782     lstrcpyA(transforms, "banana");
9783     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9784     ok(r == ERROR_INVALID_PARAMETER,
9785        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9786     ok(!lstrcmpA(patch, "apple"),
9787        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9788     ok(!lstrcmpA(transforms, "banana"),
9789        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9790     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9791
9792     /* empty szProduct */
9793     size = MAX_PATH;
9794     lstrcpyA(patch, "apple");
9795     lstrcpyA(transforms, "banana");
9796     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9797     ok(r == ERROR_INVALID_PARAMETER,
9798        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9799     ok(!lstrcmpA(patch, "apple"),
9800        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9801     ok(!lstrcmpA(transforms, "banana"),
9802        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9803     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9804
9805     /* garbage szProduct */
9806     size = MAX_PATH;
9807     lstrcpyA(patch, "apple");
9808     lstrcpyA(transforms, "banana");
9809     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9810     ok(r == ERROR_INVALID_PARAMETER,
9811        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9812     ok(!lstrcmpA(patch, "apple"),
9813        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9814     ok(!lstrcmpA(transforms, "banana"),
9815        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9816     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9817
9818     /* guid without brackets */
9819     size = MAX_PATH;
9820     lstrcpyA(patch, "apple");
9821     lstrcpyA(transforms, "banana");
9822     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9823                         transforms, &size);
9824     ok(r == ERROR_INVALID_PARAMETER,
9825        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9826     ok(!lstrcmpA(patch, "apple"),
9827        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9828     ok(!lstrcmpA(transforms, "banana"),
9829        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9830     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9831
9832     /* guid with brackets */
9833     size = MAX_PATH;
9834     lstrcpyA(patch, "apple");
9835     lstrcpyA(transforms, "banana");
9836     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9837                         transforms, &size);
9838     ok(r == ERROR_UNKNOWN_PRODUCT,
9839        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9840     ok(!lstrcmpA(patch, "apple"),
9841        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9842     ok(!lstrcmpA(transforms, "banana"),
9843        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9844     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9845
9846     /* same length as guid, but random */
9847     size = MAX_PATH;
9848     lstrcpyA(patch, "apple");
9849     lstrcpyA(transforms, "banana");
9850     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9851                         transforms, &size);
9852     ok(r == ERROR_INVALID_PARAMETER,
9853        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9854     ok(!lstrcmpA(patch, "apple"),
9855        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9856     ok(!lstrcmpA(transforms, "banana"),
9857        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9858     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9859
9860     /* MSIINSTALLCONTEXT_USERMANAGED */
9861
9862     size = MAX_PATH;
9863     lstrcpyA(patch, "apple");
9864     lstrcpyA(transforms, "banana");
9865     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9866     ok(r == ERROR_UNKNOWN_PRODUCT,
9867        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9868     ok(!lstrcmpA(patch, "apple"),
9869        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9870     ok(!lstrcmpA(transforms, "banana"),
9871        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9872     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9873
9874     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9875     lstrcatA(keypath, usersid);
9876     lstrcatA(keypath, "\\Installer\\Products\\");
9877     lstrcatA(keypath, prod_squashed);
9878
9879     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9880     if (res == ERROR_ACCESS_DENIED)
9881     {
9882         skip("Not enough rights to perform tests\n");
9883         LocalFree(usersid);
9884         return;
9885     }
9886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9887
9888     /* managed product key exists */
9889     size = MAX_PATH;
9890     lstrcpyA(patch, "apple");
9891     lstrcpyA(transforms, "banana");
9892     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9893     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9894     ok(!lstrcmpA(patch, "apple"),
9895        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9896     ok(!lstrcmpA(transforms, "banana"),
9897        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9898     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9899
9900     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9902
9903     /* patches key exists */
9904     size = MAX_PATH;
9905     lstrcpyA(patch, "apple");
9906     lstrcpyA(transforms, "banana");
9907     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9908     ok(r == ERROR_NO_MORE_ITEMS ||
9909        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9910        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9911     ok(!lstrcmpA(patch, "apple"),
9912        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9913     ok(!lstrcmpA(transforms, "banana"),
9914        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9915     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9916
9917     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9918                          (const BYTE *)patch_squashed,
9919                          lstrlenA(patch_squashed) + 1);
9920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9921
9922     /* Patches value exists, is not REG_MULTI_SZ */
9923     size = MAX_PATH;
9924     lstrcpyA(patch, "apple");
9925     lstrcpyA(transforms, "banana");
9926     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9927     ok(r == ERROR_BAD_CONFIGURATION ||
9928        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9929        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9930     ok(!lstrcmpA(patch, "apple"),
9931        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9932     ok(!lstrcmpA(transforms, "banana"),
9933        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9934     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9935
9936     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9937                          (const BYTE *)"a\0b\0c\0\0", 7);
9938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9939
9940     /* Patches value exists, is not a squashed guid */
9941     size = MAX_PATH;
9942     lstrcpyA(patch, "apple");
9943     lstrcpyA(transforms, "banana");
9944     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9945     ok(r == ERROR_BAD_CONFIGURATION,
9946        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9947     ok(!lstrcmpA(patch, "apple"),
9948        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9949     ok(!lstrcmpA(transforms, "banana"),
9950        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9951     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9952
9953     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9954     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9955                          (const BYTE *)patch_squashed,
9956                          lstrlenA(patch_squashed) + 2);
9957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9958
9959     /* Patches value exists */
9960     size = MAX_PATH;
9961     lstrcpyA(patch, "apple");
9962     lstrcpyA(transforms, "banana");
9963     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9964     ok(r == ERROR_NO_MORE_ITEMS ||
9965        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9966        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9967     ok(!lstrcmpA(patch, "apple") ||
9968        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9969        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9970     ok(!lstrcmpA(transforms, "banana"),
9971        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9972     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9973
9974     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9975                          (const BYTE *)"whatever", 9);
9976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9977
9978     /* patch squashed value exists */
9979     size = MAX_PATH;
9980     lstrcpyA(patch, "apple");
9981     lstrcpyA(transforms, "banana");
9982     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9984     ok(!lstrcmpA(patch, patchcode),
9985        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9986     ok(!lstrcmpA(transforms, "whatever"),
9987        "Expected \"whatever\", got \"%s\"\n", transforms);
9988     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9989
9990     /* lpPatchBuf is NULL */
9991     size = MAX_PATH;
9992     lstrcpyA(transforms, "banana");
9993     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9994     ok(r == ERROR_INVALID_PARAMETER,
9995        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9996     ok(!lstrcmpA(transforms, "banana"),
9997        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9998     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9999
10000     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
10001     size = MAX_PATH;
10002     lstrcpyA(patch, "apple");
10003     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
10004     ok(r == ERROR_INVALID_PARAMETER,
10005        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10006     ok(!lstrcmpA(patch, "apple"),
10007        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10008     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10009
10010     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
10011     lstrcpyA(patch, "apple");
10012     lstrcpyA(transforms, "banana");
10013     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
10014     ok(r == ERROR_INVALID_PARAMETER,
10015        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10016     ok(!lstrcmpA(patch, "apple"),
10017        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10018     ok(!lstrcmpA(transforms, "banana"),
10019        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10020
10021     /* pcchTransformsBuf is too small */
10022     size = 6;
10023     lstrcpyA(patch, "apple");
10024     lstrcpyA(transforms, "banana");
10025     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10026     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10027     ok(!lstrcmpA(patch, patchcode),
10028        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10029     ok(!lstrcmpA(transforms, "whate") ||
10030        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10031        "Expected \"whate\", got \"%s\"\n", transforms);
10032     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
10033
10034     /* increase the index */
10035     size = MAX_PATH;
10036     lstrcpyA(patch, "apple");
10037     lstrcpyA(transforms, "banana");
10038     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
10039     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10040     ok(!lstrcmpA(patch, "apple"),
10041        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10042     ok(!lstrcmpA(transforms, "banana"),
10043        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10044     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10045
10046     /* increase again */
10047     size = MAX_PATH;
10048     lstrcpyA(patch, "apple");
10049     lstrcpyA(transforms, "banana");
10050     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
10051     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10052     ok(!lstrcmpA(patch, "apple"),
10053        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10054     ok(!lstrcmpA(transforms, "banana"),
10055        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10056     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10057
10058     RegDeleteValueA(patches, "Patches");
10059     delete_key(patches, "", access & KEY_WOW64_64KEY);
10060     RegCloseKey(patches);
10061     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10062     RegCloseKey(prodkey);
10063
10064     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10065
10066     size = MAX_PATH;
10067     lstrcpyA(patch, "apple");
10068     lstrcpyA(transforms, "banana");
10069     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10070     ok(r == ERROR_UNKNOWN_PRODUCT,
10071        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10072     ok(!lstrcmpA(patch, "apple"),
10073        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10074     ok(!lstrcmpA(transforms, "banana"),
10075        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10076     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10077
10078     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10079     lstrcatA(keypath, prod_squashed);
10080
10081     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10083
10084     /* current user product key exists */
10085     size = MAX_PATH;
10086     lstrcpyA(patch, "apple");
10087     lstrcpyA(transforms, "banana");
10088     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10089     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10090     ok(!lstrcmpA(patch, "apple"),
10091        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10092     ok(!lstrcmpA(transforms, "banana"),
10093        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10094     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10095
10096     res = RegCreateKeyA(prodkey, "Patches", &patches);
10097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10098
10099     /* Patches key exists */
10100     size = MAX_PATH;
10101     lstrcpyA(patch, "apple");
10102     lstrcpyA(transforms, "banana");
10103     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10104     ok(r == ERROR_NO_MORE_ITEMS ||
10105        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10106        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10107     ok(!lstrcmpA(patch, "apple"),
10108        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10109     ok(!lstrcmpA(transforms, "banana"),
10110        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10111     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10112
10113     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10114                          (const BYTE *)patch_squashed,
10115                          lstrlenA(patch_squashed) + 1);
10116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10117
10118     /* Patches value exists, is not REG_MULTI_SZ */
10119     size = MAX_PATH;
10120     lstrcpyA(patch, "apple");
10121     lstrcpyA(transforms, "banana");
10122     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10123     ok(r == ERROR_BAD_CONFIGURATION ||
10124        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10125        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10126     ok(!lstrcmpA(patch, "apple"),
10127        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10128     ok(!lstrcmpA(transforms, "banana"),
10129        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10130     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10131
10132     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10133                          (const BYTE *)"a\0b\0c\0\0", 7);
10134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10135
10136     /* Patches value exists, is not a squashed guid */
10137     size = MAX_PATH;
10138     lstrcpyA(patch, "apple");
10139     lstrcpyA(transforms, "banana");
10140     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10141     ok(r == ERROR_BAD_CONFIGURATION,
10142        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10143     ok(!lstrcmpA(patch, "apple"),
10144        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10145     ok(!lstrcmpA(transforms, "banana"),
10146        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10147     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10148
10149     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10150     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10151                          (const BYTE *)patch_squashed,
10152                          lstrlenA(patch_squashed) + 2);
10153     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10154
10155     /* Patches value exists */
10156     size = MAX_PATH;
10157     lstrcpyA(patch, "apple");
10158     lstrcpyA(transforms, "banana");
10159     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10160     ok(r == ERROR_NO_MORE_ITEMS ||
10161        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10162        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10163     ok(!lstrcmpA(patch, "apple") ||
10164        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10165        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10166     ok(!lstrcmpA(transforms, "banana"),
10167        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10168     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10169
10170     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10171                          (const BYTE *)"whatever", 9);
10172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10173
10174     /* patch code value exists */
10175     size = MAX_PATH;
10176     lstrcpyA(patch, "apple");
10177     lstrcpyA(transforms, "banana");
10178     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10179     ok(r == ERROR_NO_MORE_ITEMS ||
10180        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10181        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10182     ok(!lstrcmpA(patch, "apple") ||
10183        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10184        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10185     ok(!lstrcmpA(transforms, "banana") ||
10186        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10187        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10188     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10189
10190     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10191     lstrcatA(keypath, usersid);
10192     lstrcatA(keypath, "\\Patches\\");
10193     lstrcatA(keypath, patch_squashed);
10194
10195     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10197
10198     /* userdata patch key exists */
10199     size = MAX_PATH;
10200     lstrcpyA(patch, "apple");
10201     lstrcpyA(transforms, "banana");
10202     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10204     ok(!lstrcmpA(patch, patchcode),
10205        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10206     ok(!lstrcmpA(transforms, "whatever"),
10207        "Expected \"whatever\", got \"%s\"\n", transforms);
10208     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10209
10210     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10211     RegCloseKey(userkey);
10212     RegDeleteValueA(patches, patch_squashed);
10213     RegDeleteValueA(patches, "Patches");
10214     RegDeleteKeyA(patches, "");
10215     RegCloseKey(patches);
10216     RegDeleteKeyA(prodkey, "");
10217     RegCloseKey(prodkey);
10218
10219     /* MSIINSTALLCONTEXT_MACHINE */
10220
10221     size = MAX_PATH;
10222     lstrcpyA(patch, "apple");
10223     lstrcpyA(transforms, "banana");
10224     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10225     ok(r == ERROR_UNKNOWN_PRODUCT,
10226        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10227     ok(!lstrcmpA(patch, "apple"),
10228        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10229     ok(!lstrcmpA(transforms, "banana"),
10230        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10231     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10232
10233     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10234     lstrcatA(keypath, prod_squashed);
10235
10236     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10238
10239     /* local product key exists */
10240     size = MAX_PATH;
10241     lstrcpyA(patch, "apple");
10242     lstrcpyA(transforms, "banana");
10243     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10244     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10245     ok(!lstrcmpA(patch, "apple"),
10246        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10247     ok(!lstrcmpA(transforms, "banana"),
10248        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10249     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10250
10251     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10253
10254     /* Patches key exists */
10255     size = MAX_PATH;
10256     lstrcpyA(patch, "apple");
10257     lstrcpyA(transforms, "banana");
10258     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10259     ok(r == ERROR_NO_MORE_ITEMS ||
10260        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10261        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10262     ok(!lstrcmpA(patch, "apple"),
10263        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10264     ok(!lstrcmpA(transforms, "banana"),
10265        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10266     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10267
10268     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10269                          (const BYTE *)patch_squashed,
10270                          lstrlenA(patch_squashed) + 1);
10271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10272
10273     /* Patches value exists, is not REG_MULTI_SZ */
10274     size = MAX_PATH;
10275     lstrcpyA(patch, "apple");
10276     lstrcpyA(transforms, "banana");
10277     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10278     ok(r == ERROR_BAD_CONFIGURATION ||
10279        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10280        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10281     ok(!lstrcmpA(patch, "apple"),
10282        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10283     ok(!lstrcmpA(transforms, "banana"),
10284        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10285     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10286
10287     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10288                          (const BYTE *)"a\0b\0c\0\0", 7);
10289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10290
10291     /* Patches value exists, is not a squashed guid */
10292     size = MAX_PATH;
10293     lstrcpyA(patch, "apple");
10294     lstrcpyA(transforms, "banana");
10295     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10296     ok(r == ERROR_BAD_CONFIGURATION,
10297        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10298     ok(!lstrcmpA(patch, "apple"),
10299        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10300     ok(!lstrcmpA(transforms, "banana"),
10301        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10302     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10303
10304     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10305     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10306                          (const BYTE *)patch_squashed,
10307                          lstrlenA(patch_squashed) + 2);
10308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10309
10310     /* Patches value exists */
10311     size = MAX_PATH;
10312     lstrcpyA(patch, "apple");
10313     lstrcpyA(transforms, "banana");
10314     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10315     ok(r == ERROR_NO_MORE_ITEMS ||
10316        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10317        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10318     ok(!lstrcmpA(patch, "apple") ||
10319        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10320        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10321     ok(!lstrcmpA(transforms, "banana"),
10322        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10323     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10324
10325     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10326                          (const BYTE *)"whatever", 9);
10327     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10328
10329     /* patch code value exists */
10330     size = MAX_PATH;
10331     lstrcpyA(patch, "apple");
10332     lstrcpyA(transforms, "banana");
10333     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10334     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10335     ok(!lstrcmpA(patch, patchcode),
10336        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10337     ok(!lstrcmpA(transforms, "whatever"),
10338        "Expected \"whatever\", got \"%s\"\n", transforms);
10339     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10340
10341     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10342     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10343     lstrcatA(keypath, prod_squashed);
10344
10345     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10347
10348     /* local UserData product key exists */
10349     size = MAX_PATH;
10350     lstrcpyA(patch, "apple");
10351     lstrcpyA(transforms, "banana");
10352     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10353     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10354     ok(!lstrcmpA(patch, patchcode),
10355        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10356     ok(!lstrcmpA(transforms, "whatever"),
10357        "Expected \"whatever\", got \"%s\"\n", transforms);
10358     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10359
10360     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10362
10363     /* local UserData Patches key exists */
10364     size = MAX_PATH;
10365     lstrcpyA(patch, "apple");
10366     lstrcpyA(transforms, "banana");
10367     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10369     ok(!lstrcmpA(patch, patchcode),
10370        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10371     ok(!lstrcmpA(transforms, "whatever"),
10372        "Expected \"whatever\", got \"%s\"\n", transforms);
10373     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10374
10375     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10377
10378     /* local UserData Product patch key exists */
10379     size = MAX_PATH;
10380     lstrcpyA(patch, "apple");
10381     lstrcpyA(transforms, "banana");
10382     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10383     ok(r == ERROR_NO_MORE_ITEMS ||
10384        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10385        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10386     ok(!lstrcmpA(patch, "apple") ||
10387        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10388        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10389     ok(!lstrcmpA(transforms, "banana") ||
10390        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10391        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10392     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10393
10394     data = MSIPATCHSTATE_APPLIED;
10395     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10396                          (const BYTE *)&data, sizeof(DWORD));
10397     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10398
10399     /* State value exists */
10400     size = MAX_PATH;
10401     lstrcpyA(patch, "apple");
10402     lstrcpyA(transforms, "banana");
10403     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10405     ok(!lstrcmpA(patch, patchcode),
10406        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10407     ok(!lstrcmpA(transforms, "whatever"),
10408        "Expected \"whatever\", got \"%s\"\n", transforms);
10409     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10410
10411     /* now duplicate some of the tests for the W version */
10412
10413     /* pcchTransformsBuf is too small */
10414     size = 6;
10415     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10416     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10417     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10418     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10419     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10420     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10421     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10422     ok(!lstrcmpA(patch, patchcode),
10423        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10424     ok(!lstrcmpA(transforms, "whate") ||
10425        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10426        "Expected \"whate\", got \"%s\"\n", transforms);
10427     ok(size == 8, "Expected 8, got %d\n", size);
10428
10429     /* patch code value exists */
10430     size = MAX_PATH;
10431     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10432     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10433     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10435     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10436     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10437     ok(!lstrcmpA(patch, patchcode),
10438        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10439     ok(!lstrcmpA(transforms, "whatever"),
10440        "Expected \"whatever\", got \"%s\"\n", transforms);
10441     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10442
10443     RegDeleteValueA(patches, patch_squashed);
10444     RegDeleteValueA(patches, "Patches");
10445     delete_key(patches, "", access & KEY_WOW64_64KEY);
10446     RegCloseKey(patches);
10447     RegDeleteValueA(hpatch, "State");
10448     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10449     RegCloseKey(hpatch);
10450     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10451     RegCloseKey(udpatch);
10452     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10453     RegCloseKey(udprod);
10454     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10455     RegCloseKey(prodkey);
10456     LocalFree(usersid);
10457 }
10458
10459 static void test_MsiGetPatchInfoEx(void)
10460 {
10461     CHAR keypath[MAX_PATH], val[MAX_PATH];
10462     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10463     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10464     HKEY prodkey, patches, udprod, props;
10465     HKEY hpatch, udpatch, prodpatches;
10466     LPSTR usersid;
10467     DWORD size;
10468     LONG res;
10469     UINT r;
10470     REGSAM access = KEY_ALL_ACCESS;
10471
10472     if (!pMsiGetPatchInfoExA)
10473     {
10474         win_skip("MsiGetPatchInfoEx not implemented\n");
10475         return;
10476     }
10477
10478     create_test_guid(prodcode, prod_squashed);
10479     create_test_guid(patchcode, patch_squashed);
10480     get_user_sid(&usersid);
10481
10482     if (is_wow64)
10483         access |= KEY_WOW64_64KEY;
10484
10485     /* NULL szPatchCode */
10486     lstrcpyA(val, "apple");
10487     size = MAX_PATH;
10488     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10489                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10490     ok(r == ERROR_INVALID_PARAMETER,
10491        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10492     ok(!lstrcmpA(val, "apple"),
10493        "Expected val to be unchanged, got \"%s\"\n", val);
10494     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10495
10496     /* empty szPatchCode */
10497     size = MAX_PATH;
10498     lstrcpyA(val, "apple");
10499     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10500                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10501     ok(r == ERROR_INVALID_PARAMETER,
10502        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10503     ok(!lstrcmpA(val, "apple"),
10504        "Expected val to be unchanged, got \"%s\"\n", val);
10505     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10506
10507     /* garbage szPatchCode */
10508     size = MAX_PATH;
10509     lstrcpyA(val, "apple");
10510     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10511                             MSIINSTALLCONTEXT_USERMANAGED,
10512                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10513     ok(r == ERROR_INVALID_PARAMETER,
10514        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10515     ok(!lstrcmpA(val, "apple"),
10516        "Expected val to be unchanged, got \"%s\"\n", val);
10517     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10518
10519     /* guid without brackets */
10520     size = MAX_PATH;
10521     lstrcpyA(val, "apple");
10522     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10523                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10524                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10525     ok(r == ERROR_INVALID_PARAMETER,
10526        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10527     ok(!lstrcmpA(val, "apple"),
10528        "Expected val to be unchanged, got \"%s\"\n", val);
10529     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10530
10531     /* guid with brackets */
10532     size = MAX_PATH;
10533     lstrcpyA(val, "apple");
10534     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10535                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10536                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10537     ok(r == ERROR_UNKNOWN_PRODUCT,
10538        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10539     ok(!lstrcmpA(val, "apple"),
10540        "Expected val to be unchanged, got \"%s\"\n", val);
10541     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10542
10543     /* same length as guid, but random */
10544     size = MAX_PATH;
10545     lstrcpyA(val, "apple");
10546     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10547                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10548                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10549     ok(r == ERROR_INVALID_PARAMETER,
10550        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10551     ok(!lstrcmpA(val, "apple"),
10552        "Expected val to be unchanged, got \"%s\"\n", val);
10553     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10554
10555     /* NULL szProductCode */
10556     lstrcpyA(val, "apple");
10557     size = MAX_PATH;
10558     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10559                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10560     ok(r == ERROR_INVALID_PARAMETER,
10561        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10562     ok(!lstrcmpA(val, "apple"),
10563        "Expected val to be unchanged, got \"%s\"\n", val);
10564     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10565
10566     /* empty szProductCode */
10567     size = MAX_PATH;
10568     lstrcpyA(val, "apple");
10569     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10570                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10571     ok(r == ERROR_INVALID_PARAMETER,
10572        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10573     ok(!lstrcmpA(val, "apple"),
10574        "Expected val to be unchanged, got \"%s\"\n", val);
10575     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10576
10577     /* garbage szProductCode */
10578     size = MAX_PATH;
10579     lstrcpyA(val, "apple");
10580     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10581                             MSIINSTALLCONTEXT_USERMANAGED,
10582                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10583     ok(r == ERROR_INVALID_PARAMETER,
10584        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10585     ok(!lstrcmpA(val, "apple"),
10586        "Expected val to be unchanged, got \"%s\"\n", val);
10587     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10588
10589     /* guid without brackets */
10590     size = MAX_PATH;
10591     lstrcpyA(val, "apple");
10592     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10593                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10594                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10595     ok(r == ERROR_INVALID_PARAMETER,
10596        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10597     ok(!lstrcmpA(val, "apple"),
10598        "Expected val to be unchanged, got \"%s\"\n", val);
10599     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10600
10601     /* guid with brackets */
10602     size = MAX_PATH;
10603     lstrcpyA(val, "apple");
10604     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10605                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10606                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10607     ok(r == ERROR_UNKNOWN_PRODUCT,
10608        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10609     ok(!lstrcmpA(val, "apple"),
10610        "Expected val to be unchanged, got \"%s\"\n", val);
10611     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10612
10613     /* same length as guid, but random */
10614     size = MAX_PATH;
10615     lstrcpyA(val, "apple");
10616     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10617                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10618                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10619     ok(r == ERROR_INVALID_PARAMETER,
10620        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10621     ok(!lstrcmpA(val, "apple"),
10622        "Expected val to be unchanged, got \"%s\"\n", val);
10623     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10624
10625     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10626     size = MAX_PATH;
10627     lstrcpyA(val, "apple");
10628     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10629                             MSIINSTALLCONTEXT_USERMANAGED,
10630                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10631     ok(r == ERROR_INVALID_PARAMETER,
10632        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10633     ok(!lstrcmpA(val, "apple"),
10634        "Expected val to be unchanged, got \"%s\"\n", val);
10635     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10636
10637     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10638     size = MAX_PATH;
10639     lstrcpyA(val, "apple");
10640     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10641                             MSIINSTALLCONTEXT_USERUNMANAGED,
10642                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10643     ok(r == ERROR_INVALID_PARAMETER,
10644        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10645     ok(!lstrcmpA(val, "apple"),
10646        "Expected val to be unchanged, got \"%s\"\n", val);
10647     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10648
10649     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10650     size = MAX_PATH;
10651     lstrcpyA(val, "apple");
10652     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10653                             MSIINSTALLCONTEXT_MACHINE,
10654                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10655     ok(r == ERROR_INVALID_PARAMETER,
10656        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10657     ok(!lstrcmpA(val, "apple"),
10658        "Expected val to be unchanged, got \"%s\"\n", val);
10659     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10660
10661     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10662     size = MAX_PATH;
10663     lstrcpyA(val, "apple");
10664     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10665                             MSIINSTALLCONTEXT_MACHINE,
10666                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10667     ok(r == ERROR_INVALID_PARAMETER,
10668        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10669     ok(!lstrcmpA(val, "apple"),
10670        "Expected val to be unchanged, got \"%s\"\n", val);
10671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10672
10673     /* dwContext is out of range */
10674     size = MAX_PATH;
10675     lstrcpyA(val, "apple");
10676     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10677                             MSIINSTALLCONTEXT_NONE,
10678                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10679     ok(r == ERROR_INVALID_PARAMETER,
10680        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10681     ok(!lstrcmpA(val, "apple"),
10682        "Expected val to be unchanged, got \"%s\"\n", val);
10683     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10684
10685     /* dwContext is out of range */
10686     size = MAX_PATH;
10687     lstrcpyA(val, "apple");
10688     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10689                             MSIINSTALLCONTEXT_ALL,
10690                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10691     ok(r == ERROR_INVALID_PARAMETER,
10692        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10693     ok(!lstrcmpA(val, "apple"),
10694        "Expected val to be unchanged, got \"%s\"\n", val);
10695     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10696
10697     /* dwContext is invalid */
10698     size = MAX_PATH;
10699     lstrcpyA(val, "apple");
10700     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10701                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10702     ok(r == ERROR_INVALID_PARAMETER,
10703        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10704     ok(!lstrcmpA(val, "apple"),
10705        "Expected val to be unchanged, got \"%s\"\n", val);
10706     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10707
10708     /* MSIINSTALLCONTEXT_USERMANAGED */
10709
10710     size = MAX_PATH;
10711     lstrcpyA(val, "apple");
10712     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10713                             MSIINSTALLCONTEXT_USERMANAGED,
10714                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10715     ok(r == ERROR_UNKNOWN_PRODUCT,
10716        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10717     ok(!lstrcmpA(val, "apple"),
10718        "Expected val to be unchanged, got \"%s\"\n", val);
10719     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10720
10721     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10722     lstrcatA(keypath, usersid);
10723     lstrcatA(keypath, "\\Products\\");
10724     lstrcatA(keypath, prod_squashed);
10725
10726     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10727     if (res == ERROR_ACCESS_DENIED)
10728     {
10729         skip("Not enough rights to perform tests\n");
10730         LocalFree(usersid);
10731         return;
10732     }
10733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10734
10735     /* local UserData product key exists */
10736     size = MAX_PATH;
10737     lstrcpyA(val, "apple");
10738     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10739                             MSIINSTALLCONTEXT_USERMANAGED,
10740                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10741     ok(r == ERROR_UNKNOWN_PRODUCT,
10742        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10743     ok(!lstrcmpA(val, "apple"),
10744        "Expected val to be unchanged, got \"%s\"\n", val);
10745     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10746
10747     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10748     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10749
10750     /* InstallProperties key exists */
10751     size = MAX_PATH;
10752     lstrcpyA(val, "apple");
10753     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10754                             MSIINSTALLCONTEXT_USERMANAGED,
10755                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10756     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10757     ok(!lstrcmpA(val, "apple"),
10758        "Expected val to be unchanged, got \"%s\"\n", val);
10759     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10760
10761     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10763
10764     /* Patches key exists */
10765     size = MAX_PATH;
10766     lstrcpyA(val, "apple");
10767     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10768                             MSIINSTALLCONTEXT_USERMANAGED,
10769                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10770     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10771     ok(!lstrcmpA(val, "apple"),
10772        "Expected val to be unchanged, got \"%s\"\n", val);
10773     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10774
10775     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10777
10778     /* Patches key exists */
10779     size = MAX_PATH;
10780     lstrcpyA(val, "apple");
10781     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10782                             MSIINSTALLCONTEXT_USERMANAGED,
10783                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10784     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10785     ok(!lstrcmpA(val, "apple"),
10786        "Expected val to be unchanged, got \"%s\"\n", val);
10787     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10788
10789     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10790     lstrcatA(keypath, usersid);
10791     lstrcatA(keypath, "\\Installer\\Products\\");
10792     lstrcatA(keypath, prod_squashed);
10793
10794     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10796
10797     /* managed product key exists */
10798     size = MAX_PATH;
10799     lstrcpyA(val, "apple");
10800     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10801                             MSIINSTALLCONTEXT_USERMANAGED,
10802                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10803     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10804     ok(!lstrcmpA(val, "apple"),
10805        "Expected val to be unchanged, got \"%s\"\n", val);
10806     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10807
10808     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10809     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10810
10811     /* Patches key exists */
10812     size = MAX_PATH;
10813     lstrcpyA(val, "apple");
10814     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10815                             MSIINSTALLCONTEXT_USERMANAGED,
10816                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10817     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10818     ok(!lstrcmpA(val, "apple"),
10819        "Expected val to be unchanged, got \"%s\"\n", val);
10820     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10821
10822     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10823                          (const BYTE *)"transforms", 11);
10824     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10825
10826     /* specific patch value exists */
10827     size = MAX_PATH;
10828     lstrcpyA(val, "apple");
10829     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10830                             MSIINSTALLCONTEXT_USERMANAGED,
10831                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10832     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10833     ok(!lstrcmpA(val, "apple"),
10834        "Expected val to be unchanged, got \"%s\"\n", val);
10835     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10836
10837     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10838     lstrcatA(keypath, usersid);
10839     lstrcatA(keypath, "\\Patches\\");
10840     lstrcatA(keypath, patch_squashed);
10841
10842     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10844
10845     /* UserData Patches key exists */
10846     size = MAX_PATH;
10847     lstrcpyA(val, "apple");
10848     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10849                             MSIINSTALLCONTEXT_USERMANAGED,
10850                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10851     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10852     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10853     ok(size == 0, "Expected 0, got %d\n", size);
10854
10855     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10856                          (const BYTE *)"pack", 5);
10857     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10858
10859     /* ManagedLocalPatch value exists */
10860     size = MAX_PATH;
10861     lstrcpyA(val, "apple");
10862     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10863                             MSIINSTALLCONTEXT_USERMANAGED,
10864                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10865     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10866     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10867     ok(size == 4, "Expected 4, got %d\n", size);
10868
10869     size = MAX_PATH;
10870     lstrcpyA(val, "apple");
10871     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10872                             MSIINSTALLCONTEXT_USERMANAGED,
10873                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10875     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10876     ok(size == 10, "Expected 10, got %d\n", size);
10877
10878     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10879                          (const BYTE *)"mydate", 7);
10880     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10881
10882     /* Installed value exists */
10883     size = MAX_PATH;
10884     lstrcpyA(val, "apple");
10885     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10886                             MSIINSTALLCONTEXT_USERMANAGED,
10887                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10889     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10890     ok(size == 6, "Expected 6, got %d\n", size);
10891
10892     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10893                          (const BYTE *)"yes", 4);
10894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10895
10896     /* Uninstallable value exists */
10897     size = MAX_PATH;
10898     lstrcpyA(val, "apple");
10899     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10900                             MSIINSTALLCONTEXT_USERMANAGED,
10901                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10903     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10904     ok(size == 3, "Expected 3, got %d\n", size);
10905
10906     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10907                          (const BYTE *)"good", 5);
10908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10909
10910     /* State value exists */
10911     size = MAX_PATH;
10912     lstrcpyA(val, "apple");
10913     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10914                             MSIINSTALLCONTEXT_USERMANAGED,
10915                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10916     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10917     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10918     ok(size == 4, "Expected 4, got %d\n", size);
10919
10920     size = 1;
10921     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10922                          (const BYTE *)&size, sizeof(DWORD));
10923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10924
10925     /* State value exists */
10926     size = MAX_PATH;
10927     lstrcpyA(val, "apple");
10928     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10929                             MSIINSTALLCONTEXT_USERMANAGED,
10930                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10932     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10933     ok(size == 1, "Expected 1, got %d\n", size);
10934
10935     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10936                          (const BYTE *)"display", 8);
10937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10938
10939     /* DisplayName value exists */
10940     size = MAX_PATH;
10941     lstrcpyA(val, "apple");
10942     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10943                             MSIINSTALLCONTEXT_USERMANAGED,
10944                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10945     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10946     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10947     ok(size == 7, "Expected 7, got %d\n", size);
10948
10949     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10950                          (const BYTE *)"moreinfo", 9);
10951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10952
10953     /* MoreInfoURL value exists */
10954     size = MAX_PATH;
10955     lstrcpyA(val, "apple");
10956     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10957                             MSIINSTALLCONTEXT_USERMANAGED,
10958                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10959     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10960     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10961     ok(size == 8, "Expected 8, got %d\n", size);
10962
10963     /* szProperty is invalid */
10964     size = MAX_PATH;
10965     lstrcpyA(val, "apple");
10966     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10967                             MSIINSTALLCONTEXT_USERMANAGED,
10968                             "IDontExist", val, &size);
10969     ok(r == ERROR_UNKNOWN_PROPERTY,
10970        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10971     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10972     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10973
10974     /* lpValue is NULL, while pcchValue is non-NULL */
10975     size = MAX_PATH;
10976     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10977                             MSIINSTALLCONTEXT_USERMANAGED,
10978                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10980     ok(size == 16, "Expected 16, got %d\n", size);
10981
10982     /* pcchValue is NULL, while lpValue is non-NULL */
10983     lstrcpyA(val, "apple");
10984     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10985                             MSIINSTALLCONTEXT_USERMANAGED,
10986                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10987     ok(r == ERROR_INVALID_PARAMETER,
10988        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10989     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10990
10991     /* both lpValue and pcchValue are NULL */
10992     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10993                             MSIINSTALLCONTEXT_USERMANAGED,
10994                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10995     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10996
10997     /* pcchValue doesn't have enough room for NULL terminator */
10998     size = 8;
10999     lstrcpyA(val, "apple");
11000     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11001                             MSIINSTALLCONTEXT_USERMANAGED,
11002                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11003     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11004     ok(!lstrcmpA(val, "moreinf"),
11005        "Expected \"moreinf\", got \"%s\"\n", val);
11006     ok(size == 16, "Expected 16, got %d\n", size);
11007
11008     /* pcchValue has exactly enough room for NULL terminator */
11009     size = 9;
11010     lstrcpyA(val, "apple");
11011     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11012                             MSIINSTALLCONTEXT_USERMANAGED,
11013                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11015     ok(!lstrcmpA(val, "moreinfo"),
11016        "Expected \"moreinfo\", got \"%s\"\n", val);
11017     ok(size == 8, "Expected 8, got %d\n", size);
11018
11019     /* pcchValue is too small, lpValue is NULL */
11020     size = 0;
11021     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11022                             MSIINSTALLCONTEXT_USERMANAGED,
11023                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
11024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11025     ok(size == 16, "Expected 16, got %d\n", size);
11026
11027     RegDeleteValueA(prodpatches, patch_squashed);
11028     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11029     RegCloseKey(prodpatches);
11030     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11031     RegCloseKey(prodkey);
11032
11033     /* UserData is sufficient for all properties
11034      * except INSTALLPROPERTY_TRANSFORMS
11035      */
11036     size = MAX_PATH;
11037     lstrcpyA(val, "apple");
11038     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11039                             MSIINSTALLCONTEXT_USERMANAGED,
11040                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11042     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11043     ok(size == 4, "Expected 4, got %d\n", size);
11044
11045     /* UserData is sufficient for all properties
11046      * except INSTALLPROPERTY_TRANSFORMS
11047      */
11048     size = MAX_PATH;
11049     lstrcpyA(val, "apple");
11050     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11051                             MSIINSTALLCONTEXT_USERMANAGED,
11052                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11053     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11054     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11055     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11056
11057     RegDeleteValueA(hpatch, "MoreInfoURL");
11058     RegDeleteValueA(hpatch, "Display");
11059     RegDeleteValueA(hpatch, "State");
11060     RegDeleteValueA(hpatch, "Uninstallable");
11061     RegDeleteValueA(hpatch, "Installed");
11062     RegDeleteValueA(udpatch, "ManagedLocalPackage");
11063     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11064     RegCloseKey(udpatch);
11065     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11066     RegCloseKey(hpatch);
11067     delete_key(patches, "", access & KEY_WOW64_64KEY);
11068     RegCloseKey(patches);
11069     delete_key(props, "", access & KEY_WOW64_64KEY);
11070     RegCloseKey(props);
11071     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11072     RegCloseKey(udprod);
11073
11074     /* MSIINSTALLCONTEXT_USERUNMANAGED */
11075
11076     size = MAX_PATH;
11077     lstrcpyA(val, "apple");
11078     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11079                             MSIINSTALLCONTEXT_USERUNMANAGED,
11080                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11081     ok(r == ERROR_UNKNOWN_PRODUCT,
11082        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11083     ok(!lstrcmpA(val, "apple"),
11084        "Expected val to be unchanged, got \"%s\"\n", val);
11085     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11086
11087     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11088     lstrcatA(keypath, usersid);
11089     lstrcatA(keypath, "\\Products\\");
11090     lstrcatA(keypath, prod_squashed);
11091
11092     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11094
11095     /* local UserData product key exists */
11096     size = MAX_PATH;
11097     lstrcpyA(val, "apple");
11098     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11099                             MSIINSTALLCONTEXT_USERUNMANAGED,
11100                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11101     ok(r == ERROR_UNKNOWN_PRODUCT,
11102        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11103     ok(!lstrcmpA(val, "apple"),
11104        "Expected val to be unchanged, got \"%s\"\n", val);
11105     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11106
11107     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11109
11110     /* InstallProperties key exists */
11111     size = MAX_PATH;
11112     lstrcpyA(val, "apple");
11113     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11114                             MSIINSTALLCONTEXT_USERUNMANAGED,
11115                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11116     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11117     ok(!lstrcmpA(val, "apple"),
11118        "Expected val to be unchanged, got \"%s\"\n", val);
11119     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11120
11121     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11123
11124     /* Patches key exists */
11125     size = MAX_PATH;
11126     lstrcpyA(val, "apple");
11127     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11128                             MSIINSTALLCONTEXT_USERUNMANAGED,
11129                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11130     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11131     ok(!lstrcmpA(val, "apple"),
11132        "Expected val to be unchanged, got \"%s\"\n", val);
11133     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11134
11135     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11137
11138     /* Patches key exists */
11139     size = MAX_PATH;
11140     lstrcpyA(val, "apple");
11141     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11142                             MSIINSTALLCONTEXT_USERUNMANAGED,
11143                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11144     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11145     ok(!lstrcmpA(val, "apple"),
11146        "Expected val to be unchanged, got \"%s\"\n", val);
11147     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11148
11149     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11150     lstrcatA(keypath, prod_squashed);
11151
11152     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11153     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11154
11155     /* current user product key exists */
11156     size = MAX_PATH;
11157     lstrcpyA(val, "apple");
11158     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11159                             MSIINSTALLCONTEXT_USERUNMANAGED,
11160                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11161     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11162     ok(!lstrcmpA(val, "apple"),
11163        "Expected val to be unchanged, got \"%s\"\n", val);
11164     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11165
11166     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
11167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11168
11169     /* Patches key exists */
11170     size = MAX_PATH;
11171     lstrcpyA(val, "apple");
11172     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11173                             MSIINSTALLCONTEXT_USERUNMANAGED,
11174                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11175     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11176     ok(!lstrcmpA(val, "apple"),
11177        "Expected val to be unchanged, got \"%s\"\n", val);
11178     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11179
11180     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11181                          (const BYTE *)"transforms", 11);
11182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11183
11184     /* specific patch value exists */
11185     size = MAX_PATH;
11186     lstrcpyA(val, "apple");
11187     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11188                             MSIINSTALLCONTEXT_USERUNMANAGED,
11189                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11190     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11191     ok(!lstrcmpA(val, "apple"),
11192        "Expected val to be unchanged, got \"%s\"\n", val);
11193     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11194
11195     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11196     lstrcatA(keypath, usersid);
11197     lstrcatA(keypath, "\\Patches\\");
11198     lstrcatA(keypath, patch_squashed);
11199
11200     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11202
11203     /* UserData Patches key exists */
11204     size = MAX_PATH;
11205     lstrcpyA(val, "apple");
11206     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11207                             MSIINSTALLCONTEXT_USERUNMANAGED,
11208                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11209     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11210     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11211     ok(size == 0, "Expected 0, got %d\n", size);
11212
11213     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11214                          (const BYTE *)"pack", 5);
11215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11216
11217     /* LocalPatch value exists */
11218     size = MAX_PATH;
11219     lstrcpyA(val, "apple");
11220     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11221                             MSIINSTALLCONTEXT_USERUNMANAGED,
11222                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11224     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11225     ok(size == 4, "Expected 4, got %d\n", size);
11226
11227     size = MAX_PATH;
11228     lstrcpyA(val, "apple");
11229     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11230                             MSIINSTALLCONTEXT_USERUNMANAGED,
11231                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11232     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11233     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11234     ok(size == 10, "Expected 10, got %d\n", size);
11235
11236     RegDeleteValueA(prodpatches, patch_squashed);
11237     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11238     RegCloseKey(prodpatches);
11239     RegDeleteKeyA(prodkey, "");
11240     RegCloseKey(prodkey);
11241
11242     /* UserData is sufficient for all properties
11243      * except INSTALLPROPERTY_TRANSFORMS
11244      */
11245     size = MAX_PATH;
11246     lstrcpyA(val, "apple");
11247     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11248                             MSIINSTALLCONTEXT_USERUNMANAGED,
11249                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11251     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11252     ok(size == 4, "Expected 4, got %d\n", size);
11253
11254     /* UserData is sufficient for all properties
11255      * except INSTALLPROPERTY_TRANSFORMS
11256      */
11257     size = MAX_PATH;
11258     lstrcpyA(val, "apple");
11259     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11260                             MSIINSTALLCONTEXT_USERUNMANAGED,
11261                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11262     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11263     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11264     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11265
11266     RegDeleteValueA(udpatch, "LocalPackage");
11267     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11268     RegCloseKey(udpatch);
11269     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11270     RegCloseKey(hpatch);
11271     delete_key(patches, "", access & KEY_WOW64_64KEY);
11272     RegCloseKey(patches);
11273     delete_key(props, "", access & KEY_WOW64_64KEY);
11274     RegCloseKey(props);
11275     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11276     RegCloseKey(udprod);
11277
11278     /* MSIINSTALLCONTEXT_MACHINE */
11279
11280     size = MAX_PATH;
11281     lstrcpyA(val, "apple");
11282     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11283                             MSIINSTALLCONTEXT_MACHINE,
11284                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11285     ok(r == ERROR_UNKNOWN_PRODUCT,
11286        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11287     ok(!lstrcmpA(val, "apple"),
11288        "Expected val to be unchanged, got \"%s\"\n", val);
11289     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11290
11291     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11292     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11293     lstrcatA(keypath, prod_squashed);
11294
11295     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11297
11298     /* local UserData product key exists */
11299     size = MAX_PATH;
11300     lstrcpyA(val, "apple");
11301     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11302                             MSIINSTALLCONTEXT_MACHINE,
11303                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11304     ok(r == ERROR_UNKNOWN_PRODUCT,
11305        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11306     ok(!lstrcmpA(val, "apple"),
11307        "Expected val to be unchanged, got \"%s\"\n", val);
11308     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11309
11310     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11311     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11312
11313     /* InstallProperties key exists */
11314     size = MAX_PATH;
11315     lstrcpyA(val, "apple");
11316     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11317                             MSIINSTALLCONTEXT_MACHINE,
11318                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11319     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11320     ok(!lstrcmpA(val, "apple"),
11321        "Expected val to be unchanged, got \"%s\"\n", val);
11322     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11323
11324     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11326
11327     /* Patches key exists */
11328     size = MAX_PATH;
11329     lstrcpyA(val, "apple");
11330     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11331                             MSIINSTALLCONTEXT_MACHINE,
11332                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11333     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11334     ok(!lstrcmpA(val, "apple"),
11335        "Expected val to be unchanged, got \"%s\"\n", val);
11336     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11337
11338     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11340
11341     /* Patches key exists */
11342     size = MAX_PATH;
11343     lstrcpyA(val, "apple");
11344     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11345                             MSIINSTALLCONTEXT_MACHINE,
11346                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11347     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11348     ok(!lstrcmpA(val, "apple"),
11349        "Expected val to be unchanged, got \"%s\"\n", val);
11350     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11351
11352     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11353     lstrcatA(keypath, prod_squashed);
11354
11355     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11357
11358     /* local product key exists */
11359     size = MAX_PATH;
11360     lstrcpyA(val, "apple");
11361     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11362                             MSIINSTALLCONTEXT_MACHINE,
11363                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11364     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11365     ok(!lstrcmpA(val, "apple"),
11366        "Expected val to be unchanged, got \"%s\"\n", val);
11367     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11368
11369     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11371
11372     /* Patches key exists */
11373     size = MAX_PATH;
11374     lstrcpyA(val, "apple");
11375     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11376                             MSIINSTALLCONTEXT_MACHINE,
11377                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11378     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11379     ok(!lstrcmpA(val, "apple"),
11380        "Expected val to be unchanged, got \"%s\"\n", val);
11381     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11382
11383     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11384                          (const BYTE *)"transforms", 11);
11385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11386
11387     /* specific patch value exists */
11388     size = MAX_PATH;
11389     lstrcpyA(val, "apple");
11390     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11391                             MSIINSTALLCONTEXT_MACHINE,
11392                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11393     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11394     ok(!lstrcmpA(val, "apple"),
11395        "Expected val to be unchanged, got \"%s\"\n", val);
11396     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11397
11398     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11399     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11400     lstrcatA(keypath, patch_squashed);
11401
11402     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11404
11405     /* UserData Patches key exists */
11406     size = MAX_PATH;
11407     lstrcpyA(val, "apple");
11408     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11409                             MSIINSTALLCONTEXT_MACHINE,
11410                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11412     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11413     ok(size == 0, "Expected 0, got %d\n", size);
11414
11415     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11416                          (const BYTE *)"pack", 5);
11417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11418
11419     /* LocalPatch value exists */
11420     size = MAX_PATH;
11421     lstrcpyA(val, "apple");
11422     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11423                             MSIINSTALLCONTEXT_MACHINE,
11424                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11425     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11426     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11427     ok(size == 4, "Expected 4, got %d\n", size);
11428
11429     size = MAX_PATH;
11430     lstrcpyA(val, "apple");
11431     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11432                             MSIINSTALLCONTEXT_MACHINE,
11433                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11435     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11436     ok(size == 10, "Expected 10, got %d\n", size);
11437
11438     RegDeleteValueA(prodpatches, patch_squashed);
11439     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11440     RegCloseKey(prodpatches);
11441     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11442     RegCloseKey(prodkey);
11443
11444     /* UserData is sufficient for all properties
11445      * except INSTALLPROPERTY_TRANSFORMS
11446      */
11447     size = MAX_PATH;
11448     lstrcpyA(val, "apple");
11449     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11450                             MSIINSTALLCONTEXT_MACHINE,
11451                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11453     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11454     ok(size == 4, "Expected 4, got %d\n", size);
11455
11456     /* UserData is sufficient for all properties
11457      * except INSTALLPROPERTY_TRANSFORMS
11458      */
11459     size = MAX_PATH;
11460     lstrcpyA(val, "apple");
11461     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11462                             MSIINSTALLCONTEXT_MACHINE,
11463                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11464     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11465     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11466     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11467
11468     RegDeleteValueA(udpatch, "LocalPackage");
11469     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11470     RegCloseKey(udpatch);
11471     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11472     RegCloseKey(hpatch);
11473     delete_key(patches, "", access & KEY_WOW64_64KEY);
11474     RegCloseKey(patches);
11475     delete_key(props, "", access & KEY_WOW64_64KEY);
11476     RegCloseKey(props);
11477     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11478     RegCloseKey(udprod);
11479     LocalFree(usersid);
11480 }
11481
11482 static void test_MsiGetPatchInfo(void)
11483 {
11484     UINT r;
11485     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11486     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11487     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11488     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11489     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11490     DWORD size;
11491     LONG res;
11492     REGSAM access = KEY_ALL_ACCESS;
11493
11494     create_test_guid(patch_code, patch_squashed);
11495     create_test_guid(prod_code, prod_squashed);
11496     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11497
11498     if (is_wow64)
11499         access |= KEY_WOW64_64KEY;
11500
11501     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11502     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11503
11504     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11505     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11506
11507     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11508     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11509
11510     size = 0;
11511     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11512     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11513
11514     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11515     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11516
11517     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11518     lstrcatA(keypath, prod_squashed);
11519
11520     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11521     if (res == ERROR_ACCESS_DENIED)
11522     {
11523         skip("Not enough rights to perform tests\n");
11524         return;
11525     }
11526     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11527
11528     /* product key exists */
11529     size = MAX_PATH;
11530     lstrcpyA(val, "apple");
11531     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11532     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11533     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11534     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11535
11536     res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11537     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11538
11539     /* patches key exists */
11540     size = MAX_PATH;
11541     lstrcpyA(val, "apple");
11542     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11543     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11544     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11545     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11546
11547     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11548     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11549
11550     /* patch key exists */
11551     size = MAX_PATH;
11552     lstrcpyA(val, "apple");
11553     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11554     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11555     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11556     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11557
11558     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11559     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11560     lstrcatA(keypath, prod_squashed);
11561
11562     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11564
11565     /* UserData product key exists */
11566     size = MAX_PATH;
11567     lstrcpyA(val, "apple");
11568     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11569     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11570     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11571     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11572
11573     res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11574     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11575
11576     /* InstallProperties key exists */
11577     size = MAX_PATH;
11578     lstrcpyA(val, "apple");
11579     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11580     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11581     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11582     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11583
11584     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11585     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11586
11587     /* UserData Patches key exists */
11588     size = MAX_PATH;
11589     lstrcpyA(val, "apple");
11590     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11591     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11592     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11593     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11594
11595     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11597
11598     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11600
11601     /* UserData product patch key exists */
11602     size = MAX_PATH;
11603     lstrcpyA(val, "apple");
11604     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11605     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11606     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11607     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11608
11609     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11610     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11611     lstrcatA(keypath, patch_squashed);
11612
11613     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11614     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11615
11616     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11617     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11618
11619     /* UserData Patch key exists */
11620     size = 0;
11621     lstrcpyA(val, "apple");
11622     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11623     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11624     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11625     ok(size == 11, "expected 11 got %u\n", size);
11626
11627     size = MAX_PATH;
11628     lstrcpyA(val, "apple");
11629     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11630     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11631     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11632     ok(size == 11, "expected 11 got %u\n", size);
11633
11634     size = 0;
11635     valW[0] = 0;
11636     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11637     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11638     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11639     ok(size == 11, "expected 11 got %u\n", size);
11640
11641     size = MAX_PATH;
11642     valW[0] = 0;
11643     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11644     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS 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     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11649     RegCloseKey(hkey_udproductpatch);
11650     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11651     RegCloseKey(hkey_udproductpatches);
11652     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11653     RegCloseKey(hkey_udpatch);
11654     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11655     RegCloseKey(hkey_patches);
11656     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11657     RegCloseKey(hkey_product);
11658     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11659     RegCloseKey(hkey_patch);
11660     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11661     RegCloseKey(hkey_udpatches);
11662     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11663     RegCloseKey(hkey_udprops);
11664     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11665     RegCloseKey(hkey_udproduct);
11666 }
11667
11668 static void test_MsiEnumProducts(void)
11669 {
11670     UINT r;
11671     int found1, found2, found3;
11672     DWORD index;
11673     char product1[39], product2[39], product3[39], guid[39];
11674     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11675     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11676     char *usersid;
11677     HKEY key1, key2, key3;
11678     REGSAM access = KEY_ALL_ACCESS;
11679
11680     create_test_guid(product1, product_squashed1);
11681     create_test_guid(product2, product_squashed2);
11682     create_test_guid(product3, product_squashed3);
11683     get_user_sid(&usersid);
11684
11685     if (is_wow64)
11686         access |= KEY_WOW64_64KEY;
11687
11688     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11689     strcat(keypath1, product_squashed1);
11690
11691     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11692     if (r == ERROR_ACCESS_DENIED)
11693     {
11694         skip("Not enough rights to perform tests\n");
11695         LocalFree(usersid);
11696         return;
11697     }
11698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11699
11700     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11701     strcat(keypath2, usersid);
11702     strcat(keypath2, "\\Installer\\Products\\");
11703     strcat(keypath2, product_squashed2);
11704
11705     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11706     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11707
11708     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11709     strcat(keypath3, product_squashed3);
11710
11711     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11712     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11713
11714     index = 0;
11715     r = MsiEnumProductsA(index, guid);
11716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11717
11718     r = MsiEnumProductsA(index, NULL);
11719     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11720
11721     index = 2;
11722     r = MsiEnumProductsA(index, guid);
11723     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11724
11725     index = 0;
11726     r = MsiEnumProductsA(index, guid);
11727     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11728
11729     found1 = found2 = found3 = 0;
11730     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11731     {
11732         if (!strcmp(product1, guid)) found1 = 1;
11733         if (!strcmp(product2, guid)) found2 = 1;
11734         if (!strcmp(product3, guid)) found3 = 1;
11735         index++;
11736     }
11737     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11738     ok(found1, "product1 not found\n");
11739     ok(found2, "product2 not found\n");
11740     ok(found3, "product3 not found\n");
11741
11742     delete_key(key1, "", access & KEY_WOW64_64KEY);
11743     delete_key(key2, "", access & KEY_WOW64_64KEY);
11744     RegDeleteKeyA(key3, "");
11745     RegCloseKey(key1);
11746     RegCloseKey(key2);
11747     RegCloseKey(key3);
11748     LocalFree(usersid);
11749 }
11750
11751 START_TEST(msi)
11752 {
11753     init_functionpointers();
11754
11755     if (pIsWow64Process)
11756         pIsWow64Process(GetCurrentProcess(), &is_wow64);
11757
11758     test_usefeature();
11759     test_null();
11760     test_getcomponentpath();
11761     test_MsiGetFileHash();
11762
11763     if (!pConvertSidToStringSidA)
11764         win_skip("ConvertSidToStringSidA not implemented\n");
11765     else
11766     {
11767         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11768         test_MsiQueryProductState();
11769         test_MsiQueryFeatureState();
11770         test_MsiQueryComponentState();
11771         test_MsiGetComponentPath();
11772         test_MsiGetProductCode();
11773         test_MsiEnumClients();
11774         test_MsiGetProductInfo();
11775         test_MsiGetProductInfoEx();
11776         test_MsiGetUserInfo();
11777         test_MsiOpenProduct();
11778         test_MsiEnumPatchesEx();
11779         test_MsiEnumPatches();
11780         test_MsiGetPatchInfoEx();
11781         test_MsiGetPatchInfo();
11782         test_MsiEnumProducts();
11783     }
11784
11785     test_MsiGetFileVersion();
11786 }