d3drm: Fix leakage of pData2 on error.
[wine] / dlls / msi / tests / msi.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static BOOL is_wow64;
33 static const char msifile[] = "winetest.msi";
34
35 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
36 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
37 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
38
39 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
40     (LPCSTR, LPCSTR, LPSTR, DWORD*);
41 static UINT (WINAPI *pMsiGetFileHashA)
42     (LPCSTR, DWORD, PMSIFILEHASHINFO);
43 static UINT (WINAPI *pMsiGetProductInfoExA)
44     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
45 static UINT (WINAPI *pMsiOpenPackageExA)
46     (LPCSTR, DWORD, MSIHANDLE*);
47 static UINT (WINAPI *pMsiOpenPackageExW)
48     (LPCWSTR, DWORD, MSIHANDLE*);
49 static UINT (WINAPI *pMsiEnumPatchesExA)
50     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
51     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
52 static UINT (WINAPI *pMsiQueryComponentStateA)
53     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
54 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
55     (LPCSTR, LPCSTR ,DWORD, DWORD);
56 static UINT (WINAPI *pMsiGetPatchInfoExA)
57     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
58 static UINT (WINAPI *pMsiEnumProductsExA)
59     (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
60
61 static void init_functionpointers(void)
62 {
63     HMODULE hmsi = GetModuleHandleA("msi.dll");
64     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
65     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
66
67 #define GET_PROC(dll, func) \
68     p ## func = (void *)GetProcAddress(dll, #func); \
69     if(!p ## func) \
70       trace("GetProcAddress(%s) failed\n", #func);
71
72     GET_PROC(hmsi, MsiGetComponentPathA)
73     GET_PROC(hmsi, MsiGetFileHashA)
74     GET_PROC(hmsi, MsiGetProductInfoExA)
75     GET_PROC(hmsi, MsiOpenPackageExA)
76     GET_PROC(hmsi, MsiOpenPackageExW)
77     GET_PROC(hmsi, MsiEnumPatchesExA)
78     GET_PROC(hmsi, MsiQueryComponentStateA)
79     GET_PROC(hmsi, MsiUseFeatureExA)
80     GET_PROC(hmsi, MsiGetPatchInfoExA)
81     GET_PROC(hmsi, MsiEnumProductsExA)
82
83     GET_PROC(hadvapi32, ConvertSidToStringSidA)
84     GET_PROC(hadvapi32, RegDeleteKeyExA)
85     GET_PROC(hkernel32, IsWow64Process)
86
87 #undef GET_PROC
88 }
89
90 static UINT run_query(MSIHANDLE hdb, const char *query)
91 {
92     MSIHANDLE hview = 0;
93     UINT r;
94
95     r = MsiDatabaseOpenView(hdb, query, &hview);
96     if (r != ERROR_SUCCESS)
97         return r;
98
99     r = MsiViewExecute(hview, 0);
100     if (r == ERROR_SUCCESS)
101         r = MsiViewClose(hview);
102     MsiCloseHandle(hview);
103     return r;
104 }
105
106 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
107 {
108     UINT res;
109     MSIHANDLE suminfo;
110
111     /* build summary info */
112     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
113     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
114
115     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
116                                     "Installation Database");
117     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
118
119     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
120                                     "Installation Database");
121     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
122
123     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
124                                     "Wine Hackers");
125     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
126
127     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
128                                     ";1033");
129     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
130
131     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
132                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
133     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
134
135     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
136     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
137
138     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
139     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
140
141     res = MsiSummaryInfoPersist(suminfo);
142     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
143
144     res = MsiCloseHandle(suminfo);
145     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
146
147     return res;
148 }
149
150 static MSIHANDLE create_package_db(LPSTR prodcode)
151 {
152     MSIHANDLE hdb = 0;
153     CHAR query[MAX_PATH];
154     UINT res;
155
156     DeleteFile(msifile);
157
158     /* create an empty database */
159     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
160     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
161     if (res != ERROR_SUCCESS)
162         return hdb;
163
164     res = MsiDatabaseCommit(hdb);
165     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
166
167     set_summary_info(hdb, prodcode);
168
169     res = run_query(hdb,
170             "CREATE TABLE `Directory` ( "
171             "`Directory` CHAR(255) NOT NULL, "
172             "`Directory_Parent` CHAR(255), "
173             "`DefaultDir` CHAR(255) NOT NULL "
174             "PRIMARY KEY `Directory`)");
175     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
176
177     res = run_query(hdb,
178             "CREATE TABLE `Property` ( "
179             "`Property` CHAR(72) NOT NULL, "
180             "`Value` CHAR(255) "
181             "PRIMARY KEY `Property`)");
182     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
183
184     sprintf(query, "INSERT INTO `Property` "
185             "(`Property`, `Value`) "
186             "VALUES( 'ProductCode', '%s' )", prodcode);
187     res = run_query(hdb, query);
188     ok(res == ERROR_SUCCESS , "Failed\n");
189
190     res = MsiDatabaseCommit(hdb);
191     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
192
193     return hdb;
194 }
195
196 static void test_usefeature(void)
197 {
198     INSTALLSTATE r;
199
200     if (!pMsiUseFeatureExA)
201     {
202         win_skip("MsiUseFeatureExA not implemented\n");
203         return;
204     }
205
206     r = MsiQueryFeatureState(NULL,NULL);
207     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
208
209     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
210     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
211
212     r = pMsiUseFeatureExA(NULL,NULL,0,0);
213     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
214
215     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
216     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
217
218     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
219                          NULL, -2, 0 );
220     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
221
222     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
223                          "WORDVIEWFiles", -2, 0 );
224     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
225
226     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
227                          "WORDVIEWFiles", -2, 0 );
228     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
229
230     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
231                          "WORDVIEWFiles", -2, 1 );
232     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
233 }
234
235 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
236 {
237     if (pRegDeleteKeyExA)
238         return pRegDeleteKeyExA( key, subkey, access, 0 );
239     return RegDeleteKeyA( key, subkey );
240 }
241
242 static void test_null(void)
243 {
244     MSIHANDLE hpkg;
245     UINT r;
246     HKEY hkey;
247     DWORD dwType, cbData;
248     LPBYTE lpData = NULL;
249     INSTALLSTATE state;
250     REGSAM access = KEY_ALL_ACCESS;
251
252     if (is_wow64)
253         access |= KEY_WOW64_64KEY;
254
255     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
256     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
257
258     state = MsiQueryProductStateW(NULL);
259     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
260
261     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
262     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
263
264     r = MsiConfigureFeatureW(NULL, NULL, 0);
265     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
266
267     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
268     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
269
270     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
271     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
272
273     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
274     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
275
276     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
277      * necessary registry values */
278
279     /* empty product string */
280     r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
281     if (r == ERROR_ACCESS_DENIED)
282     {
283         skip("Not enough rights to perform tests\n");
284         return;
285     }
286     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
287
288     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
289     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
290     if ( r == ERROR_SUCCESS )
291     {
292         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
293         if (!lpData)
294             skip("Out of memory\n");
295         else
296         {
297             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
298             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
299         }
300     }
301
302     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
303     if (r == ERROR_ACCESS_DENIED)
304     {
305         skip("Not enough rights to perform tests\n");
306         HeapFree(GetProcessHeap(), 0, lpData);
307         RegCloseKey(hkey);
308         return;
309     }
310     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
311
312     r = MsiGetProductInfoA("", "", NULL, NULL);
313     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
314
315     if (lpData)
316     {
317         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
318         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
319
320         HeapFree(GetProcessHeap(), 0, lpData);
321     }
322     else
323     {
324         r = RegDeleteValueA(hkey, NULL);
325         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
326     }
327
328     r = RegCloseKey(hkey);
329     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
330
331     /* empty attribute */
332     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
333                         0, NULL, 0, access, NULL, &hkey, NULL);
334     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
335
336     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
337     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
338
339     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
340     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
341
342     r = RegCloseKey(hkey);
343     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
344
345     r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
346                    access & KEY_WOW64_64KEY);
347     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
348 }
349
350 static void test_getcomponentpath(void)
351 {
352     INSTALLSTATE r;
353     char buffer[0x100];
354     DWORD sz;
355
356     if(!pMsiGetComponentPathA)
357         return;
358
359     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
360     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
361
362     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
363     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
364
365     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
366     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
367
368     sz = sizeof buffer;
369     buffer[0]=0;
370     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
371     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
372
373     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
374         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
375     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
376
377     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
378         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
379     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
380
381     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
382         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
383     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
384
385     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
386                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
387     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
388 }
389
390 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
391 {
392     HANDLE file;
393     DWORD written;
394
395     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
396     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
397     WriteFile(file, data, strlen(data), &written, NULL);
398
399     if (size)
400     {
401         SetFilePointer(file, size, NULL, FILE_BEGIN);
402         SetEndOfFile(file);
403     }
404
405     CloseHandle(file);
406 }
407
408 #define HASHSIZE sizeof(MSIFILEHASHINFO)
409
410 static const struct
411 {
412     LPCSTR data;
413     DWORD size;
414     MSIFILEHASHINFO hash;
415 } hash_data[] =
416 {
417     { "abc", 0,
418       { HASHSIZE,
419         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
420       },
421     },
422
423     { "C:\\Program Files\\msitest\\caesar\n", 0,
424       { HASHSIZE,
425         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
426       },
427     },
428
429     { "C:\\Program Files\\msitest\\caesar\n", 500,
430       { HASHSIZE,
431         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
432       },
433     },
434 };
435
436 static void test_MsiGetFileHash(void)
437 {
438     const char name[] = "msitest.bin";
439     UINT r;
440     MSIFILEHASHINFO hash;
441     DWORD i;
442
443     if (!pMsiGetFileHashA)
444     {
445         win_skip("MsiGetFileHash not implemented\n");
446         return;
447     }
448
449     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
450
451     /* szFilePath is NULL */
452     r = pMsiGetFileHashA(NULL, 0, &hash);
453     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
454
455     /* szFilePath is empty */
456     r = pMsiGetFileHashA("", 0, &hash);
457     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
458        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
459
460     /* szFilePath is nonexistent */
461     r = pMsiGetFileHashA(name, 0, &hash);
462     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
463
464     /* dwOptions is non-zero */
465     r = pMsiGetFileHashA(name, 1, &hash);
466     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
467
468     /* pHash.dwFileHashInfoSize is not correct */
469     hash.dwFileHashInfoSize = 0;
470     r = pMsiGetFileHashA(name, 0, &hash);
471     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
472
473     /* pHash is NULL */
474     r = pMsiGetFileHashA(name, 0, NULL);
475     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
476
477     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
478     {
479         int ret;
480
481         create_file(name, hash_data[i].data, hash_data[i].size);
482
483         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
484         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
485
486         r = pMsiGetFileHashA(name, 0, &hash);
487         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
488
489         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
490         ok(!ret, "Hash incorrect\n");
491
492         DeleteFile(name);
493     }
494 }
495
496 /* copied from dlls/msi/registry.c */
497 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
498 {
499     DWORD i,n=1;
500     GUID guid;
501
502     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
503         return FALSE;
504
505     for(i=0; i<8; i++)
506         out[7-i] = in[n++];
507     n++;
508     for(i=0; i<4; i++)
509         out[11-i] = in[n++];
510     n++;
511     for(i=0; i<4; i++)
512         out[15-i] = in[n++];
513     n++;
514     for(i=0; i<2; i++)
515     {
516         out[17+i*2] = in[n++];
517         out[16+i*2] = in[n++];
518     }
519     n++;
520     for( ; i<8; i++)
521     {
522         out[17+i*2] = in[n++];
523         out[16+i*2] = in[n++];
524     }
525     out[32]=0;
526     return TRUE;
527 }
528
529 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
530 {
531     WCHAR guidW[MAX_PATH];
532     WCHAR squashedW[MAX_PATH];
533     GUID guid;
534     HRESULT hr;
535     int size;
536
537     hr = CoCreateGuid(&guid);
538     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
539
540     size = StringFromGUID2(&guid, guidW, MAX_PATH);
541     ok(size == 39, "Expected 39, got %d\n", hr);
542
543     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
544     if (squashed)
545     {
546         squash_guid(guidW, squashedW);
547         WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
548     }
549 }
550
551 static char *get_user_sid(void)
552 {
553     HANDLE token;
554     DWORD size = 0;
555     TOKEN_USER *user;
556     char *usersid = NULL;
557
558     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
559     GetTokenInformation(token, TokenUser, NULL, size, &size);
560
561     user = HeapAlloc(GetProcessHeap(), 0, size);
562     GetTokenInformation(token, TokenUser, user, size, &size);
563     pConvertSidToStringSidA(user->User.Sid, &usersid);
564     HeapFree(GetProcessHeap(), 0, user);
565
566     CloseHandle(token);
567     return usersid;
568 }
569
570 static void test_MsiQueryProductState(void)
571 {
572     CHAR prodcode[MAX_PATH];
573     CHAR prod_squashed[MAX_PATH];
574     CHAR keypath[MAX_PATH*2];
575     LPSTR usersid;
576     INSTALLSTATE state;
577     LONG res;
578     HKEY userkey, localkey, props;
579     HKEY prodkey;
580     DWORD data, error;
581     REGSAM access = KEY_ALL_ACCESS;
582
583     create_test_guid(prodcode, prod_squashed);
584     usersid = get_user_sid();
585
586     if (is_wow64)
587         access |= KEY_WOW64_64KEY;
588
589     /* NULL prodcode */
590     SetLastError(0xdeadbeef);
591     state = MsiQueryProductStateA(NULL);
592     error = GetLastError();
593     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
594     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
595
596     /* empty prodcode */
597     SetLastError(0xdeadbeef);
598     state = MsiQueryProductStateA("");
599     error = GetLastError();
600     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
601     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
602
603     /* garbage prodcode */
604     SetLastError(0xdeadbeef);
605     state = MsiQueryProductStateA("garbage");
606     error = GetLastError();
607     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
608     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
609
610     /* guid without brackets */
611     SetLastError(0xdeadbeef);
612     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
613     error = GetLastError();
614     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
615     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
616
617     /* guid with brackets */
618     SetLastError(0xdeadbeef);
619     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
620     error = GetLastError();
621     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
622     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
623        "expected ERROR_SUCCESS, got %u\n", error);
624
625     /* same length as guid, but random */
626     SetLastError(0xdeadbeef);
627     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
628     error = GetLastError();
629     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
630     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
631
632     /* MSIINSTALLCONTEXT_USERUNMANAGED */
633
634     SetLastError(0xdeadbeef);
635     state = MsiQueryProductStateA(prodcode);
636     error = GetLastError();
637     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
638     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
639        "expected ERROR_SUCCESS, got %u\n", error);
640
641     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
642     lstrcatA(keypath, prod_squashed);
643
644     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
646
647     /* user product key exists */
648     SetLastError(0xdeadbeef);
649     state = MsiQueryProductStateA(prodcode);
650     error = GetLastError();
651     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
652     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
653        "expected ERROR_SUCCESS, got %u\n", error);
654
655     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
656     lstrcatA(keypath, prodcode);
657
658     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
659     if (res == ERROR_ACCESS_DENIED)
660     {
661         skip("Not enough rights to perform tests\n");
662         RegDeleteKeyA(userkey, "");
663         LocalFree(usersid);
664         return;
665     }
666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
667
668     /* local uninstall key exists */
669     SetLastError(0xdeadbeef);
670     state = MsiQueryProductStateA(prodcode);
671     error = GetLastError();
672     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
673     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
674        "expected ERROR_SUCCESS, got %u\n", error);
675
676     data = 1;
677     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
679
680     /* WindowsInstaller value exists */
681     SetLastError(0xdeadbeef);
682     state = MsiQueryProductStateA(prodcode);
683     error = GetLastError();
684     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
685     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
686        "expected ERROR_SUCCESS, got %u\n", error);
687
688     RegDeleteValueA(localkey, "WindowsInstaller");
689     delete_key(localkey, "", access & KEY_WOW64_64KEY);
690
691     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
692     lstrcatA(keypath, usersid);
693     lstrcatA(keypath, "\\Products\\");
694     lstrcatA(keypath, prod_squashed);
695
696     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
697     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
698
699     /* local product key exists */
700     SetLastError(0xdeadbeef);
701     state = MsiQueryProductStateA(prodcode);
702     error = GetLastError();
703     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
704     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
705        "expected ERROR_SUCCESS, got %u\n", error);
706
707     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
709
710     /* install properties key exists */
711     SetLastError(0xdeadbeef);
712     state = MsiQueryProductStateA(prodcode);
713     error = GetLastError();
714     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
715     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
716        "expected ERROR_SUCCESS, got %u\n", error);
717
718     data = 1;
719     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
721
722     /* WindowsInstaller value exists */
723     SetLastError(0xdeadbeef);
724     state = MsiQueryProductStateA(prodcode);
725     error = GetLastError();
726     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
727     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
728        "expected ERROR_SUCCESS, got %u\n", error);
729
730     data = 2;
731     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
732     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
733
734     /* WindowsInstaller value is not 1 */
735     SetLastError(0xdeadbeef);
736     state = MsiQueryProductStateA(prodcode);
737     error = GetLastError();
738     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
739     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
740        "expected ERROR_SUCCESS, got %u\n", error);
741
742     RegDeleteKeyA(userkey, "");
743
744     /* user product key does not exist */
745     SetLastError(0xdeadbeef);
746     state = MsiQueryProductStateA(prodcode);
747     error = GetLastError();
748     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
749     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
750        "expected ERROR_SUCCESS, got %u\n", error);
751
752     RegDeleteValueA(props, "WindowsInstaller");
753     delete_key(props, "", access & KEY_WOW64_64KEY);
754     RegCloseKey(props);
755     delete_key(localkey, "", access & KEY_WOW64_64KEY);
756     RegCloseKey(localkey);
757     RegDeleteKeyA(userkey, "");
758     RegCloseKey(userkey);
759
760     /* MSIINSTALLCONTEXT_USERMANAGED */
761
762     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
763     lstrcatA(keypath, usersid);
764     lstrcatA(keypath, "\\Installer\\Products\\");
765     lstrcatA(keypath, prod_squashed);
766
767     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
769
770     state = MsiQueryProductStateA(prodcode);
771     ok(state == INSTALLSTATE_ADVERTISED,
772        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
773
774     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
775     lstrcatA(keypath, usersid);
776     lstrcatA(keypath, "\\Products\\");
777     lstrcatA(keypath, prod_squashed);
778
779     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
780     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
781
782     state = MsiQueryProductStateA(prodcode);
783     ok(state == INSTALLSTATE_ADVERTISED,
784        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
785
786     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
788
789     state = MsiQueryProductStateA(prodcode);
790     ok(state == INSTALLSTATE_ADVERTISED,
791        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
792
793     data = 1;
794     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
796
797     /* WindowsInstaller value exists */
798     state = MsiQueryProductStateA(prodcode);
799     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
800
801     RegDeleteValueA(props, "WindowsInstaller");
802     delete_key(props, "", access & KEY_WOW64_64KEY);
803     RegCloseKey(props);
804     delete_key(localkey, "", access & KEY_WOW64_64KEY);
805     RegCloseKey(localkey);
806     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
807     RegCloseKey(prodkey);
808
809     /* MSIINSTALLCONTEXT_MACHINE */
810
811     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
812     lstrcatA(keypath, prod_squashed);
813
814     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
815     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
816
817     state = MsiQueryProductStateA(prodcode);
818     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
819
820     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
821     lstrcatA(keypath, "S-1-5-18\\Products\\");
822     lstrcatA(keypath, prod_squashed);
823
824     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
826
827     state = MsiQueryProductStateA(prodcode);
828     ok(state == INSTALLSTATE_ADVERTISED,
829        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
830
831     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
832     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
833
834     state = MsiQueryProductStateA(prodcode);
835     ok(state == INSTALLSTATE_ADVERTISED,
836        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
837
838     data = 1;
839     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
841
842     /* WindowsInstaller value exists */
843     state = MsiQueryProductStateA(prodcode);
844     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
845
846     RegDeleteValueA(props, "WindowsInstaller");
847     delete_key(props, "", access & KEY_WOW64_64KEY);
848     RegCloseKey(props);
849     delete_key(localkey, "", access & KEY_WOW64_64KEY);
850     RegCloseKey(localkey);
851     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
852     RegCloseKey(prodkey);
853
854     LocalFree(usersid);
855 }
856
857 static const char table_enc85[] =
858 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
859 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
860 "yz{}~";
861
862 /*
863  *  Encodes a base85 guid given a GUID pointer
864  *  Caller should provide a 21 character buffer for the encoded string.
865  */
866 static void encode_base85_guid( GUID *guid, LPWSTR str )
867 {
868     unsigned int x, *p, i;
869
870     p = (unsigned int*) guid;
871     for( i=0; i<4; i++ )
872     {
873         x = p[i];
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         x = x/85;
880         *str++ = table_enc85[x%85];
881         x = x/85;
882         *str++ = table_enc85[x%85];
883     }
884     *str = 0;
885 }
886
887 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
888 {
889     WCHAR guidW[MAX_PATH];
890     WCHAR base85W[MAX_PATH];
891     WCHAR squashedW[MAX_PATH];
892     GUID guid;
893     HRESULT hr;
894     int size;
895
896     hr = CoCreateGuid(&guid);
897     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
898
899     size = StringFromGUID2(&guid, guidW, MAX_PATH);
900     ok(size == 39, "Expected 39, got %d\n", hr);
901
902     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
903     encode_base85_guid(&guid, base85W);
904     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
905     squash_guid(guidW, squashedW);
906     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
907 }
908
909 static void test_MsiQueryFeatureState(void)
910 {
911     HKEY userkey, localkey, compkey, compkey2;
912     CHAR prodcode[MAX_PATH];
913     CHAR prod_squashed[MAX_PATH];
914     CHAR component[MAX_PATH];
915     CHAR comp_base85[MAX_PATH];
916     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
917     CHAR keypath[MAX_PATH*2];
918     INSTALLSTATE state;
919     LPSTR usersid;
920     LONG res;
921     REGSAM access = KEY_ALL_ACCESS;
922     DWORD error;
923
924     create_test_guid(prodcode, prod_squashed);
925     compose_base85_guid(component, comp_base85, comp_squashed);
926     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
927     usersid = get_user_sid();
928
929     if (is_wow64)
930         access |= KEY_WOW64_64KEY;
931
932     /* NULL prodcode */
933     SetLastError(0xdeadbeef);
934     state = MsiQueryFeatureStateA(NULL, "feature");
935     error = GetLastError();
936     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
937     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
938
939     /* empty prodcode */
940     SetLastError(0xdeadbeef);
941     state = MsiQueryFeatureStateA("", "feature");
942     error = GetLastError();
943     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
944     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
945
946     /* garbage prodcode */
947     SetLastError(0xdeadbeef);
948     state = MsiQueryFeatureStateA("garbage", "feature");
949     error = GetLastError();
950     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
951     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
952
953     /* guid without brackets */
954     SetLastError(0xdeadbeef);
955     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
956     error = GetLastError();
957     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
958     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
959
960     /* guid with brackets */
961     SetLastError(0xdeadbeef);
962     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
963     error = GetLastError();
964     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
965     ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
966        "expected ERROR_SUCCESS, got %u\n", error);
967
968     /* same length as guid, but random */
969     SetLastError(0xdeadbeef);
970     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
971     error = GetLastError();
972     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
973     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
974
975     /* NULL szFeature */
976     SetLastError(0xdeadbeef);
977     state = MsiQueryFeatureStateA(prodcode, NULL);
978     error = GetLastError();
979     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
980     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
981
982     /* empty szFeature */
983     SetLastError(0xdeadbeef);
984     state = MsiQueryFeatureStateA(prodcode, "");
985     error = GetLastError();
986     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
987     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
988        "expected ERROR_SUCCESS, got %u\n", error);
989
990     /* feature key does not exist yet */
991     SetLastError(0xdeadbeef);
992     state = MsiQueryFeatureStateA(prodcode, "feature");
993     error = GetLastError();
994     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
995     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
996        "expected ERROR_SUCCESS, got %u\n", error);
997
998     /* MSIINSTALLCONTEXT_USERUNMANAGED */
999
1000     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
1001     lstrcatA(keypath, prod_squashed);
1002
1003     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1005
1006     /* feature key exists */
1007     SetLastError(0xdeadbeef);
1008     state = MsiQueryFeatureStateA(prodcode, "feature");
1009     error = GetLastError();
1010     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1011     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1012        "expected ERROR_SUCCESS, got %u\n", error);
1013
1014     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1015     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1016
1017     /* feature value exists */
1018     SetLastError(0xdeadbeef);
1019     state = MsiQueryFeatureStateA(prodcode, "feature");
1020     error = GetLastError();
1021     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1022     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1023        "expected ERROR_SUCCESS, got %u\n", error);
1024
1025     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1026     lstrcatA(keypath, usersid);
1027     lstrcatA(keypath, "\\Products\\");
1028     lstrcatA(keypath, prod_squashed);
1029     lstrcatA(keypath, "\\Features");
1030
1031     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1032     if (res == ERROR_ACCESS_DENIED)
1033     {
1034         skip("Not enough rights to perform tests\n");
1035         RegDeleteKeyA(userkey, "");
1036         RegCloseKey(userkey);
1037         LocalFree(usersid);
1038         return;
1039     }
1040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1041
1042     /* userdata features key exists */
1043     SetLastError(0xdeadbeef);
1044     state = MsiQueryFeatureStateA(prodcode, "feature");
1045     error = GetLastError();
1046     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1047     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1048        "expected ERROR_SUCCESS, got %u\n", error);
1049
1050     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1051     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1052
1053     SetLastError(0xdeadbeef);
1054     state = MsiQueryFeatureStateA(prodcode, "feature");
1055     error = GetLastError();
1056     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1057     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1058        "expected ERROR_SUCCESS, got %u\n", error);
1059
1060     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1062
1063     SetLastError(0xdeadbeef);
1064     state = MsiQueryFeatureStateA(prodcode, "feature");
1065     error = GetLastError();
1066     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1067     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1068        "expected ERROR_SUCCESS, got %u\n", error);
1069
1070     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1072
1073     SetLastError(0xdeadbeef);
1074     state = MsiQueryFeatureStateA(prodcode, "feature");
1075     error = GetLastError();
1076     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1077     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1078        "expected ERROR_SUCCESS, got %u\n", error);
1079
1080     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1082
1083     SetLastError(0xdeadbeef);
1084     state = MsiQueryFeatureStateA(prodcode, "feature");
1085     error = GetLastError();
1086     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1087     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1088        "expected ERROR_SUCCESS, got %u\n", error);
1089
1090     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1091     lstrcatA(keypath, usersid);
1092     lstrcatA(keypath, "\\Components\\");
1093     lstrcatA(keypath, comp_squashed);
1094
1095     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1096     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1097
1098     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1099     lstrcatA(keypath, usersid);
1100     lstrcatA(keypath, "\\Components\\");
1101     lstrcatA(keypath, comp_squashed2);
1102
1103     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1105
1106     SetLastError(0xdeadbeef);
1107     state = MsiQueryFeatureStateA(prodcode, "feature");
1108     error = GetLastError();
1109     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1110     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1111        "expected ERROR_SUCCESS, got %u\n", error);
1112
1113     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1114     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1115
1116     SetLastError(0xdeadbeef);
1117     state = MsiQueryFeatureStateA(prodcode, "feature");
1118     error = GetLastError();
1119     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1120     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1121        "expected ERROR_SUCCESS, got %u\n", error);
1122
1123     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1125
1126     SetLastError(0xdeadbeef);
1127     state = MsiQueryFeatureStateA(prodcode, "feature");
1128     error = GetLastError();
1129     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1130     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1131        "expected ERROR_SUCCESS, got %u\n", error);
1132
1133     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1135
1136     /* INSTALLSTATE_LOCAL */
1137     SetLastError(0xdeadbeef);
1138     state = MsiQueryFeatureStateA(prodcode, "feature");
1139     error = GetLastError();
1140     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1141     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1142        "expected ERROR_SUCCESS, got %u\n", error);
1143
1144     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1146
1147     /* INSTALLSTATE_SOURCE */
1148     SetLastError(0xdeadbeef);
1149     state = MsiQueryFeatureStateA(prodcode, "feature");
1150     error = GetLastError();
1151     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1152     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1153        "expected ERROR_SUCCESS, got %u\n", error);
1154
1155     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1157
1158     /* bad INSTALLSTATE_SOURCE */
1159     SetLastError(0xdeadbeef);
1160     state = MsiQueryFeatureStateA(prodcode, "feature");
1161     error = GetLastError();
1162     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1163     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1164        "expected ERROR_SUCCESS, got %u\n", error);
1165
1166     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1168
1169     /* INSTALLSTATE_SOURCE */
1170     SetLastError(0xdeadbeef);
1171     state = MsiQueryFeatureStateA(prodcode, "feature");
1172     error = GetLastError();
1173     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1174     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1175        "expected ERROR_SUCCESS, got %u\n", error);
1176
1177     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1179
1180     /* bad INSTALLSTATE_SOURCE */
1181     SetLastError(0xdeadbeef);
1182     state = MsiQueryFeatureStateA(prodcode, "feature");
1183     error = GetLastError();
1184     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1185     ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1186        "expected ERROR_SUCCESS, got %u\n", error);
1187
1188     RegDeleteValueA(compkey, prod_squashed);
1189     RegDeleteValueA(compkey2, prod_squashed);
1190     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1191     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1192     RegDeleteValueA(localkey, "feature");
1193     RegDeleteValueA(userkey, "feature");
1194     RegDeleteKeyA(userkey, "");
1195     RegCloseKey(compkey);
1196     RegCloseKey(compkey2);
1197     RegCloseKey(localkey);
1198     RegCloseKey(userkey);
1199
1200     /* MSIINSTALLCONTEXT_USERMANAGED */
1201
1202     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1203     lstrcatA(keypath, usersid);
1204     lstrcatA(keypath, "\\Installer\\Features\\");
1205     lstrcatA(keypath, prod_squashed);
1206
1207     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1209
1210     /* feature key exists */
1211     state = MsiQueryFeatureStateA(prodcode, "feature");
1212     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1213
1214     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1216
1217     /* feature value exists */
1218     state = MsiQueryFeatureStateA(prodcode, "feature");
1219     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1220
1221     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1222     lstrcatA(keypath, usersid);
1223     lstrcatA(keypath, "\\Products\\");
1224     lstrcatA(keypath, prod_squashed);
1225     lstrcatA(keypath, "\\Features");
1226
1227     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1229
1230     /* userdata features key exists */
1231     state = MsiQueryFeatureStateA(prodcode, "feature");
1232     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1233
1234     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1236
1237     state = MsiQueryFeatureStateA(prodcode, "feature");
1238     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1239
1240     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1242
1243     state = MsiQueryFeatureStateA(prodcode, "feature");
1244     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1245
1246     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1248
1249     state = MsiQueryFeatureStateA(prodcode, "feature");
1250     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1251
1252     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1254
1255     state = MsiQueryFeatureStateA(prodcode, "feature");
1256     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1257
1258     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1259     lstrcatA(keypath, usersid);
1260     lstrcatA(keypath, "\\Components\\");
1261     lstrcatA(keypath, comp_squashed);
1262
1263     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1264     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1265
1266     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1267     lstrcatA(keypath, usersid);
1268     lstrcatA(keypath, "\\Components\\");
1269     lstrcatA(keypath, comp_squashed2);
1270
1271     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1273
1274     state = MsiQueryFeatureStateA(prodcode, "feature");
1275     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1276
1277     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1279
1280     state = MsiQueryFeatureStateA(prodcode, "feature");
1281     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1282
1283     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1285
1286     state = MsiQueryFeatureStateA(prodcode, "feature");
1287     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1288
1289     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1291
1292     state = MsiQueryFeatureStateA(prodcode, "feature");
1293     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1294
1295     RegDeleteValueA(compkey, prod_squashed);
1296     RegDeleteValueA(compkey2, prod_squashed);
1297     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1298     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1299     RegDeleteValueA(localkey, "feature");
1300     RegDeleteValueA(userkey, "feature");
1301     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1302     RegCloseKey(compkey);
1303     RegCloseKey(compkey2);
1304     RegCloseKey(localkey);
1305     RegCloseKey(userkey);
1306
1307     /* MSIINSTALLCONTEXT_MACHINE */
1308
1309     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1310     lstrcatA(keypath, prod_squashed);
1311
1312     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1314
1315     /* feature key exists */
1316     state = MsiQueryFeatureStateA(prodcode, "feature");
1317     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1318
1319     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1320     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1321
1322     /* feature value exists */
1323     state = MsiQueryFeatureStateA(prodcode, "feature");
1324     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1325
1326     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1327     lstrcatA(keypath, "S-1-5-18\\Products\\");
1328     lstrcatA(keypath, prod_squashed);
1329     lstrcatA(keypath, "\\Features");
1330
1331     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1333
1334     /* userdata features key exists */
1335     state = MsiQueryFeatureStateA(prodcode, "feature");
1336     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1337
1338     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1340
1341     state = MsiQueryFeatureStateA(prodcode, "feature");
1342     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1343
1344     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1346
1347     state = MsiQueryFeatureStateA(prodcode, "feature");
1348     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1349
1350     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1352
1353     state = MsiQueryFeatureStateA(prodcode, "feature");
1354     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1355
1356     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1358
1359     state = MsiQueryFeatureStateA(prodcode, "feature");
1360     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1361
1362     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1363     lstrcatA(keypath, "S-1-5-18\\Components\\");
1364     lstrcatA(keypath, comp_squashed);
1365
1366     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1368
1369     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1370     lstrcatA(keypath, "S-1-5-18\\Components\\");
1371     lstrcatA(keypath, comp_squashed2);
1372
1373     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1375
1376     state = MsiQueryFeatureStateA(prodcode, "feature");
1377     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1378
1379     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1381
1382     state = MsiQueryFeatureStateA(prodcode, "feature");
1383     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1384
1385     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1387
1388     state = MsiQueryFeatureStateA(prodcode, "feature");
1389     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1390
1391     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1392     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1393
1394     state = MsiQueryFeatureStateA(prodcode, "feature");
1395     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1396
1397     RegDeleteValueA(compkey, prod_squashed);
1398     RegDeleteValueA(compkey2, prod_squashed);
1399     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1400     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1401     RegDeleteValueA(localkey, "feature");
1402     RegDeleteValueA(userkey, "feature");
1403     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1404     RegCloseKey(compkey);
1405     RegCloseKey(compkey2);
1406     RegCloseKey(localkey);
1407     RegCloseKey(userkey);
1408     LocalFree(usersid);
1409 }
1410
1411 static void test_MsiQueryComponentState(void)
1412 {
1413     HKEY compkey, prodkey;
1414     CHAR prodcode[MAX_PATH];
1415     CHAR prod_squashed[MAX_PATH];
1416     CHAR component[MAX_PATH];
1417     CHAR comp_base85[MAX_PATH];
1418     CHAR comp_squashed[MAX_PATH];
1419     CHAR keypath[MAX_PATH];
1420     INSTALLSTATE state;
1421     LPSTR usersid;
1422     LONG res;
1423     UINT r;
1424     REGSAM access = KEY_ALL_ACCESS;
1425     DWORD error;
1426
1427     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1428
1429     if (!pMsiQueryComponentStateA)
1430     {
1431         win_skip("MsiQueryComponentStateA not implemented\n");
1432         return;
1433     }
1434
1435     create_test_guid(prodcode, prod_squashed);
1436     compose_base85_guid(component, comp_base85, comp_squashed);
1437     usersid = get_user_sid();
1438
1439     if (is_wow64)
1440         access |= KEY_WOW64_64KEY;
1441
1442     /* NULL szProductCode */
1443     state = MAGIC_ERROR;
1444     SetLastError(0xdeadbeef);
1445     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1446     error = GetLastError();
1447     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1448     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1449     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1450
1451     /* empty szProductCode */
1452     state = MAGIC_ERROR;
1453     SetLastError(0xdeadbeef);
1454     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1455     error = GetLastError();
1456     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1457     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1458     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1459
1460     /* random szProductCode */
1461     state = MAGIC_ERROR;
1462     SetLastError(0xdeadbeef);
1463     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1464     error = GetLastError();
1465     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1466     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1467     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1468
1469     /* GUID-length szProductCode */
1470     state = MAGIC_ERROR;
1471     SetLastError(0xdeadbeef);
1472     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1473     error = GetLastError();
1474     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1475     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1476     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1477
1478     /* GUID-length with brackets */
1479     state = MAGIC_ERROR;
1480     SetLastError(0xdeadbeef);
1481     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1482     error = GetLastError();
1483     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1484     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1485     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1486
1487     /* actual GUID */
1488     state = MAGIC_ERROR;
1489     SetLastError(0xdeadbeef);
1490     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1491     error = GetLastError();
1492     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1493     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1494     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1495
1496     state = MAGIC_ERROR;
1497     SetLastError(0xdeadbeef);
1498     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1499     error = GetLastError();
1500     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1501     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1502     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1503
1504     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1505     lstrcatA(keypath, prod_squashed);
1506
1507     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1508     if (res == ERROR_ACCESS_DENIED)
1509     {
1510         skip("Not enough rights to perform tests\n");
1511         LocalFree(usersid);
1512         return;
1513     }
1514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1515
1516     state = MAGIC_ERROR;
1517     SetLastError(0xdeadbeef);
1518     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1519     error = GetLastError();
1520     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1521     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1522     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1523
1524     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1525     RegCloseKey(prodkey);
1526
1527     /* create local system product key */
1528     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1529     lstrcatA(keypath, prod_squashed);
1530     lstrcatA(keypath, "\\InstallProperties");
1531
1532     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1534
1535     /* local system product key exists */
1536     state = MAGIC_ERROR;
1537     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1538     error = GetLastError();
1539     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1540     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1541     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1542
1543     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1544     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1545
1546     /* LocalPackage value exists */
1547     state = MAGIC_ERROR;
1548     SetLastError(0xdeadbeef);
1549     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1550     error = GetLastError();
1551     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1552     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1553     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1554
1555     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1556     lstrcatA(keypath, comp_squashed);
1557
1558     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1559     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1560
1561     /* component key exists */
1562     state = MAGIC_ERROR;
1563     SetLastError(0xdeadbeef);
1564     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1565     error = GetLastError();
1566     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1567     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1568     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1569
1570     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1572
1573     /* component\product exists */
1574     state = MAGIC_ERROR;
1575     SetLastError(0xdeadbeef);
1576     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1577     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1578     error = GetLastError();
1579     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1580        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1581     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1582
1583     /* NULL component, product exists */
1584     state = MAGIC_ERROR;
1585     SetLastError(0xdeadbeef);
1586     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1587     error = GetLastError();
1588     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1589     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1590     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1591
1592     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1594
1595     /* INSTALLSTATE_LOCAL */
1596     state = MAGIC_ERROR;
1597     SetLastError(0xdeadbeef);
1598     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1599     error = GetLastError();
1600     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1601     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1602     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1603
1604     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1605     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1606
1607     /* INSTALLSTATE_SOURCE */
1608     state = MAGIC_ERROR;
1609     SetLastError(0xdeadbeef);
1610     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1611     error = GetLastError();
1612     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1613     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1614     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1615
1616     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1618
1619     /* bad INSTALLSTATE_SOURCE */
1620     state = MAGIC_ERROR;
1621     SetLastError(0xdeadbeef);
1622     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1623     error = GetLastError();
1624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1625     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1626     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1627
1628     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1630
1631     /* INSTALLSTATE_SOURCE */
1632     state = MAGIC_ERROR;
1633     SetLastError(0xdeadbeef);
1634     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1635     error = GetLastError();
1636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1637     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1638     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1639
1640     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1642
1643     /* bad INSTALLSTATE_SOURCE */
1644     state = MAGIC_ERROR;
1645     SetLastError(0xdeadbeef);
1646     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1647     error = GetLastError();
1648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1649     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1650     ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1651
1652     RegDeleteValueA(prodkey, "LocalPackage");
1653     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1654     RegDeleteValueA(compkey, prod_squashed);
1655     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1656     RegCloseKey(prodkey);
1657     RegCloseKey(compkey);
1658
1659     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1660
1661     state = MAGIC_ERROR;
1662     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1663     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1664     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1665
1666     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1667     lstrcatA(keypath, prod_squashed);
1668
1669     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1671
1672     state = MAGIC_ERROR;
1673     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1674     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1675     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1676
1677     RegDeleteKeyA(prodkey, "");
1678     RegCloseKey(prodkey);
1679
1680     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1681     lstrcatA(keypath, usersid);
1682     lstrcatA(keypath, "\\Products\\");
1683     lstrcatA(keypath, prod_squashed);
1684     lstrcatA(keypath, "\\InstallProperties");
1685
1686     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1688
1689     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1690     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1691
1692     RegCloseKey(prodkey);
1693
1694     state = MAGIC_ERROR;
1695     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1696     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1697     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1698
1699     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1700     lstrcatA(keypath, usersid);
1701     lstrcatA(keypath, "\\Components\\");
1702     lstrcatA(keypath, comp_squashed);
1703
1704     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1706
1707     /* component key exists */
1708     state = MAGIC_ERROR;
1709     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1710     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1711     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1712
1713     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1715
1716     /* component\product exists */
1717     state = MAGIC_ERROR;
1718     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1719     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1720     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1721        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1722
1723     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1725
1726     state = MAGIC_ERROR;
1727     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1728     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1729     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1730
1731     /* MSIINSTALLCONTEXT_USERMANAGED */
1732
1733     state = MAGIC_ERROR;
1734     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1735     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1736     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1737
1738     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1739     lstrcatA(keypath, prod_squashed);
1740
1741     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1743
1744     state = MAGIC_ERROR;
1745     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1746     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1747     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1748
1749     RegDeleteKeyA(prodkey, "");
1750     RegCloseKey(prodkey);
1751
1752     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1753     lstrcatA(keypath, usersid);
1754     lstrcatA(keypath, "\\Installer\\Products\\");
1755     lstrcatA(keypath, prod_squashed);
1756
1757     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1759
1760     state = MAGIC_ERROR;
1761     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1762     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1763     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1764
1765     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1766     RegCloseKey(prodkey);
1767
1768     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1769     lstrcatA(keypath, usersid);
1770     lstrcatA(keypath, "\\Products\\");
1771     lstrcatA(keypath, prod_squashed);
1772     lstrcatA(keypath, "\\InstallProperties");
1773
1774     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1776
1777     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1779
1780     state = MAGIC_ERROR;
1781     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1783     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1784
1785     RegDeleteValueA(prodkey, "LocalPackage");
1786     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1787     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1788     RegDeleteValueA(compkey, prod_squashed);
1789     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1790     RegCloseKey(prodkey);
1791     RegCloseKey(compkey);
1792     LocalFree(usersid);
1793 }
1794
1795 static void test_MsiGetComponentPath(void)
1796 {
1797     HKEY compkey, prodkey, installprop;
1798     CHAR prodcode[MAX_PATH];
1799     CHAR prod_squashed[MAX_PATH];
1800     CHAR component[MAX_PATH];
1801     CHAR comp_base85[MAX_PATH];
1802     CHAR comp_squashed[MAX_PATH];
1803     CHAR keypath[MAX_PATH];
1804     CHAR path[MAX_PATH];
1805     INSTALLSTATE state;
1806     LPSTR usersid;
1807     DWORD size, val;
1808     REGSAM access = KEY_ALL_ACCESS;
1809     LONG res;
1810
1811     create_test_guid(prodcode, prod_squashed);
1812     compose_base85_guid(component, comp_base85, comp_squashed);
1813     usersid = get_user_sid();
1814
1815     if (is_wow64)
1816         access |= KEY_WOW64_64KEY;
1817
1818     /* NULL szProduct */
1819     size = MAX_PATH;
1820     state = MsiGetComponentPathA(NULL, component, path, &size);
1821     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1822     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1823
1824     /* NULL szComponent */
1825     size = MAX_PATH;
1826     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1827     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1828     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1829
1830     size = MAX_PATH;
1831     state = MsiLocateComponentA(NULL, path, &size);
1832     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1833     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1834
1835     /* NULL lpPathBuf */
1836     size = MAX_PATH;
1837     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1838     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1839     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1840
1841     size = MAX_PATH;
1842     state = MsiLocateComponentA(component, NULL, &size);
1843     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1844     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1845
1846     /* NULL pcchBuf */
1847     size = MAX_PATH;
1848     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1849     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1850     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1851
1852     size = MAX_PATH;
1853     state = MsiLocateComponentA(component, path, NULL);
1854     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1855     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1856
1857     /* all params valid */
1858     size = MAX_PATH;
1859     state = MsiGetComponentPathA(prodcode, component, path, &size);
1860     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1861     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1862
1863     size = MAX_PATH;
1864     state = MsiLocateComponentA(component, path, &size);
1865     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1866     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1867
1868     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1869     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1870     lstrcatA(keypath, comp_squashed);
1871
1872     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1873     if (res == ERROR_ACCESS_DENIED)
1874     {
1875         skip("Not enough rights to perform tests\n");
1876         LocalFree(usersid);
1877         return;
1878     }
1879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1880
1881     /* local system component key exists */
1882     size = MAX_PATH;
1883     state = MsiGetComponentPathA(prodcode, component, path, &size);
1884     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1885     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1886
1887     size = MAX_PATH;
1888     state = MsiLocateComponentA(component, path, &size);
1889     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1890     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1891
1892     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1894
1895     /* product value exists */
1896     path[0] = 0;
1897     size = MAX_PATH;
1898     state = MsiGetComponentPathA(prodcode, component, path, &size);
1899     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1900     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1901     ok(size == 10, "Expected 10, got %d\n", size);
1902
1903     path[0] = 0;
1904     size = MAX_PATH;
1905     state = MsiLocateComponentA(component, path, &size);
1906     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1907     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1908     ok(size == 10, "Expected 10, got %d\n", size);
1909
1910     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1911     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1912     lstrcatA(keypath, prod_squashed);
1913     lstrcatA(keypath, "\\InstallProperties");
1914
1915     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1917
1918     val = 1;
1919     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1921
1922     /* install properties key exists */
1923     path[0] = 0;
1924     size = MAX_PATH;
1925     state = MsiGetComponentPathA(prodcode, component, path, &size);
1926     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1927     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1928     ok(size == 10, "Expected 10, got %d\n", size);
1929
1930     path[0] = 0;
1931     size = MAX_PATH;
1932     state = MsiLocateComponentA(component, path, &size);
1933     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1934     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1935     ok(size == 10, "Expected 10, got %d\n", size);
1936
1937     create_file("C:\\imapath", "C:\\imapath", 11);
1938
1939     /* file exists */
1940     path[0] = 0;
1941     size = MAX_PATH;
1942     state = MsiGetComponentPathA(prodcode, component, path, &size);
1943     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1944     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1945     ok(size == 10, "Expected 10, got %d\n", size);
1946
1947     path[0] = 0;
1948     size = MAX_PATH;
1949     state = MsiLocateComponentA(component, path, &size);
1950     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1951     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1952     ok(size == 10, "Expected 10, got %d\n", size);
1953
1954     RegDeleteValueA(compkey, prod_squashed);
1955     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1956     RegDeleteValueA(installprop, "WindowsInstaller");
1957     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1958     RegCloseKey(compkey);
1959     RegCloseKey(installprop);
1960     DeleteFileA("C:\\imapath");
1961
1962     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1963     lstrcatA(keypath, "Installer\\UserData\\");
1964     lstrcatA(keypath, usersid);
1965     lstrcatA(keypath, "\\Components\\");
1966     lstrcatA(keypath, comp_squashed);
1967
1968     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1970
1971     /* user managed component key exists */
1972     size = MAX_PATH;
1973     state = MsiGetComponentPathA(prodcode, component, path, &size);
1974     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1975     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1976
1977     size = MAX_PATH;
1978     state = MsiLocateComponentA(component, path, &size);
1979     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1980     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1981
1982     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1984
1985     /* product value exists */
1986     path[0] = 0;
1987     size = MAX_PATH;
1988     state = MsiGetComponentPathA(prodcode, component, path, &size);
1989     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1990     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1991     ok(size == 10, "Expected 10, got %d\n", size);
1992
1993     path[0] = 0;
1994     size = MAX_PATH;
1995     state = MsiLocateComponentA(component, path, &size);
1996     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1997     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1998     ok(size == 10, "Expected 10, got %d\n", size);
1999
2000     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2001     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2002     lstrcatA(keypath, prod_squashed);
2003     lstrcatA(keypath, "\\InstallProperties");
2004
2005     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2007
2008     val = 1;
2009     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2010     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2011
2012     /* install properties key exists */
2013     path[0] = 0;
2014     size = MAX_PATH;
2015     state = MsiGetComponentPathA(prodcode, component, path, &size);
2016     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2017     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2018     ok(size == 10, "Expected 10, got %d\n", size);
2019
2020     path[0] = 0;
2021     size = MAX_PATH;
2022     state = MsiLocateComponentA(component, path, &size);
2023     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2024     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2025     ok(size == 10, "Expected 10, got %d\n", size);
2026
2027     create_file("C:\\imapath", "C:\\imapath", 11);
2028
2029     /* file exists */
2030     path[0] = 0;
2031     size = MAX_PATH;
2032     state = MsiGetComponentPathA(prodcode, component, path, &size);
2033     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2034     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2035     ok(size == 10, "Expected 10, got %d\n", size);
2036
2037     path[0] = 0;
2038     size = MAX_PATH;
2039     state = MsiLocateComponentA(component, path, &size);
2040     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2041     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2042     ok(size == 10, "Expected 10, got %d\n", size);
2043
2044     RegDeleteValueA(compkey, prod_squashed);
2045     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2046     RegDeleteValueA(installprop, "WindowsInstaller");
2047     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2048     RegCloseKey(compkey);
2049     RegCloseKey(installprop);
2050     DeleteFileA("C:\\imapath");
2051
2052     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2053     lstrcatA(keypath, "Installer\\Managed\\");
2054     lstrcatA(keypath, usersid);
2055     lstrcatA(keypath, "\\Installer\\Products\\");
2056     lstrcatA(keypath, prod_squashed);
2057
2058     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2059     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2060
2061     /* user managed product key exists */
2062     size = MAX_PATH;
2063     state = MsiGetComponentPathA(prodcode, component, path, &size);
2064     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2065     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2066
2067     size = MAX_PATH;
2068     state = MsiLocateComponentA(component, path, &size);
2069     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2070     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2071
2072     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2073     lstrcatA(keypath, "Installer\\UserData\\");
2074     lstrcatA(keypath, usersid);
2075     lstrcatA(keypath, "\\Components\\");
2076     lstrcatA(keypath, comp_squashed);
2077
2078     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2080
2081     /* user managed component key exists */
2082     size = MAX_PATH;
2083     state = MsiGetComponentPathA(prodcode, component, path, &size);
2084     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2085     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2086
2087     size = MAX_PATH;
2088     state = MsiLocateComponentA(component, path, &size);
2089     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2090     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2091
2092     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2094
2095     /* product value exists */
2096     path[0] = 0;
2097     size = MAX_PATH;
2098     state = MsiGetComponentPathA(prodcode, component, path, &size);
2099     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2100     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2101     ok(size == 10, "Expected 10, got %d\n", size);
2102
2103     path[0] = 0;
2104     size = MAX_PATH;
2105     state = MsiLocateComponentA(component, path, &size);
2106     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2107     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2108     ok(size == 10, "Expected 10, got %d\n", size);
2109
2110     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2111     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2112     lstrcatA(keypath, prod_squashed);
2113     lstrcatA(keypath, "\\InstallProperties");
2114
2115     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2117
2118     val = 1;
2119     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2121
2122     /* install properties key exists */
2123     path[0] = 0;
2124     size = MAX_PATH;
2125     state = MsiGetComponentPathA(prodcode, component, path, &size);
2126     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2127     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2128     ok(size == 10, "Expected 10, got %d\n", size);
2129
2130     path[0] = 0;
2131     size = MAX_PATH;
2132     state = MsiLocateComponentA(component, path, &size);
2133     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2134     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2135     ok(size == 10, "Expected 10, got %d\n", size);
2136
2137     create_file("C:\\imapath", "C:\\imapath", 11);
2138
2139     /* file exists */
2140     path[0] = 0;
2141     size = MAX_PATH;
2142     state = MsiGetComponentPathA(prodcode, component, path, &size);
2143     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2144     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2145     ok(size == 10, "Expected 10, got %d\n", size);
2146
2147     path[0] = 0;
2148     size = MAX_PATH;
2149     state = MsiLocateComponentA(component, path, &size);
2150     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2151     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2152     ok(size == 10, "Expected 10, got %d\n", size);
2153
2154     RegDeleteValueA(compkey, prod_squashed);
2155     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2156     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2157     RegDeleteValueA(installprop, "WindowsInstaller");
2158     delete_key(installprop, "", access & KEY_WOW64_64KEY);
2159     RegCloseKey(prodkey);
2160     RegCloseKey(compkey);
2161     RegCloseKey(installprop);
2162     DeleteFileA("C:\\imapath");
2163
2164     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2165     lstrcatA(keypath, prod_squashed);
2166
2167     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2168     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2169
2170     /* user unmanaged product key exists */
2171     size = MAX_PATH;
2172     state = MsiGetComponentPathA(prodcode, component, path, &size);
2173     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2174     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2175
2176     size = MAX_PATH;
2177     state = MsiLocateComponentA(component, path, &size);
2178     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2179     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2180
2181     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2182     lstrcatA(keypath, "Installer\\UserData\\");
2183     lstrcatA(keypath, usersid);
2184     lstrcatA(keypath, "\\Components\\");
2185     lstrcatA(keypath, comp_squashed);
2186
2187     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2189
2190     /* user unmanaged component key exists */
2191     size = MAX_PATH;
2192     state = MsiGetComponentPathA(prodcode, component, path, &size);
2193     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2194     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2195
2196     size = MAX_PATH;
2197     state = MsiLocateComponentA(component, path, &size);
2198     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2199     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2200
2201     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2203
2204     /* product value exists */
2205     path[0] = 0;
2206     size = MAX_PATH;
2207     state = MsiGetComponentPathA(prodcode, component, path, &size);
2208     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2209     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2210     ok(size == 10, "Expected 10, got %d\n", size);
2211
2212     path[0] = 0;
2213     size = MAX_PATH;
2214     state = MsiLocateComponentA(component, path, &size);
2215     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2216     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2217     ok(size == 10, "Expected 10, got %d\n", size);
2218
2219     create_file("C:\\imapath", "C:\\imapath", 11);
2220
2221     /* file exists */
2222     path[0] = 0;
2223     size = MAX_PATH;
2224     state = MsiGetComponentPathA(prodcode, component, path, &size);
2225     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2226     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2227     ok(size == 10, "Expected 10, got %d\n", size);
2228
2229     path[0] = 0;
2230     size = MAX_PATH;
2231     state = MsiLocateComponentA(component, path, &size);
2232     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2233     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2234     ok(size == 10, "Expected 10, got %d\n", size);
2235
2236     RegDeleteValueA(compkey, prod_squashed);
2237     RegDeleteKeyA(prodkey, "");
2238     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2239     RegCloseKey(prodkey);
2240     RegCloseKey(compkey);
2241     DeleteFileA("C:\\imapath");
2242
2243     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2244     lstrcatA(keypath, prod_squashed);
2245
2246     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2248
2249     /* local classes product key exists */
2250     size = MAX_PATH;
2251     state = MsiGetComponentPathA(prodcode, component, path, &size);
2252     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2253     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2254
2255     size = MAX_PATH;
2256     state = MsiLocateComponentA(component, path, &size);
2257     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2258     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2259
2260     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2261     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2262     lstrcatA(keypath, comp_squashed);
2263
2264     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2266
2267     /* local user component key exists */
2268     size = MAX_PATH;
2269     state = MsiGetComponentPathA(prodcode, component, path, &size);
2270     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2271     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2272
2273     size = MAX_PATH;
2274     state = MsiLocateComponentA(component, path, &size);
2275     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2276     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2277
2278     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2280
2281     /* product value exists */
2282     path[0] = 0;
2283     size = MAX_PATH;
2284     state = MsiGetComponentPathA(prodcode, component, path, &size);
2285     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2286     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2287     ok(size == 10, "Expected 10, got %d\n", size);
2288
2289     path[0] = 0;
2290     size = MAX_PATH;
2291     state = MsiLocateComponentA(component, path, &size);
2292     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2293     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2294     ok(size == 10, "Expected 10, got %d\n", size);
2295
2296     create_file("C:\\imapath", "C:\\imapath", 11);
2297
2298     /* file exists */
2299     path[0] = 0;
2300     size = MAX_PATH;
2301     state = MsiGetComponentPathA(prodcode, component, path, &size);
2302     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2303     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2304     ok(size == 10, "Expected 10, got %d\n", size);
2305
2306     path[0] = 0;
2307     size = MAX_PATH;
2308     state = MsiLocateComponentA(component, path, &size);
2309     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2310     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2311     ok(size == 10, "Expected 10, got %d\n", size);
2312
2313     RegDeleteValueA(compkey, prod_squashed);
2314     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2315     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2316     RegCloseKey(prodkey);
2317     RegCloseKey(compkey);
2318     DeleteFileA("C:\\imapath");
2319     LocalFree(usersid);
2320 }
2321
2322 static void test_MsiGetProductCode(void)
2323 {
2324     HKEY compkey, prodkey;
2325     CHAR prodcode[MAX_PATH];
2326     CHAR prod_squashed[MAX_PATH];
2327     CHAR prodcode2[MAX_PATH];
2328     CHAR prod2_squashed[MAX_PATH];
2329     CHAR component[MAX_PATH];
2330     CHAR comp_base85[MAX_PATH];
2331     CHAR comp_squashed[MAX_PATH];
2332     CHAR keypath[MAX_PATH];
2333     CHAR product[MAX_PATH];
2334     LPSTR usersid;
2335     LONG res;
2336     UINT r;
2337     REGSAM access = KEY_ALL_ACCESS;
2338
2339     create_test_guid(prodcode, prod_squashed);
2340     create_test_guid(prodcode2, prod2_squashed);
2341     compose_base85_guid(component, comp_base85, comp_squashed);
2342     usersid = get_user_sid();
2343
2344     if (is_wow64)
2345         access |= KEY_WOW64_64KEY;
2346
2347     /* szComponent is NULL */
2348     lstrcpyA(product, "prod");
2349     r = MsiGetProductCodeA(NULL, product);
2350     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2351     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2352
2353     /* szComponent is empty */
2354     lstrcpyA(product, "prod");
2355     r = MsiGetProductCodeA("", product);
2356     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2357     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2358
2359     /* garbage szComponent */
2360     lstrcpyA(product, "prod");
2361     r = MsiGetProductCodeA("garbage", product);
2362     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2363     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2364
2365     /* guid without brackets */
2366     lstrcpyA(product, "prod");
2367     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2368     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2369     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2370
2371     /* guid with brackets */
2372     lstrcpyA(product, "prod");
2373     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2374     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2375     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2376
2377     /* same length as guid, but random */
2378     lstrcpyA(product, "prod");
2379     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2380     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2381     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2382
2383     /* all params correct, szComponent not published */
2384     lstrcpyA(product, "prod");
2385     r = MsiGetProductCodeA(component, product);
2386     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2387     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2388
2389     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2390     lstrcatA(keypath, "Installer\\UserData\\");
2391     lstrcatA(keypath, usersid);
2392     lstrcatA(keypath, "\\Components\\");
2393     lstrcatA(keypath, comp_squashed);
2394
2395     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2396     if (res == ERROR_ACCESS_DENIED)
2397     {
2398         skip("Not enough rights to perform tests\n");
2399         LocalFree(usersid);
2400         return;
2401     }
2402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2403
2404     /* user unmanaged component key exists */
2405     lstrcpyA(product, "prod");
2406     r = MsiGetProductCodeA(component, product);
2407     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2408     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2409
2410     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2412
2413     /* product value exists */
2414     lstrcpyA(product, "prod");
2415     r = MsiGetProductCodeA(component, product);
2416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2417     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2418
2419     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2421
2422     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2423     lstrcatA(keypath, "Installer\\Managed\\");
2424     lstrcatA(keypath, usersid);
2425     lstrcatA(keypath, "\\Installer\\Products\\");
2426     lstrcatA(keypath, prod_squashed);
2427
2428     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2430
2431     /* user managed product key of first product exists */
2432     lstrcpyA(product, "prod");
2433     r = MsiGetProductCodeA(component, product);
2434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2435     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2436
2437     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2438     RegCloseKey(prodkey);
2439
2440     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2441     lstrcatA(keypath, prod_squashed);
2442
2443     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2445
2446     /* user unmanaged product key exists */
2447     lstrcpyA(product, "prod");
2448     r = MsiGetProductCodeA(component, product);
2449     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2450     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2451
2452     RegDeleteKeyA(prodkey, "");
2453     RegCloseKey(prodkey);
2454
2455     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2456     lstrcatA(keypath, prod_squashed);
2457
2458     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2460
2461     /* local classes product key exists */
2462     lstrcpyA(product, "prod");
2463     r = MsiGetProductCodeA(component, product);
2464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2465     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2466
2467     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2468     RegCloseKey(prodkey);
2469
2470     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2471     lstrcatA(keypath, "Installer\\Managed\\");
2472     lstrcatA(keypath, usersid);
2473     lstrcatA(keypath, "\\Installer\\Products\\");
2474     lstrcatA(keypath, prod2_squashed);
2475
2476     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2478
2479     /* user managed product key of second product exists */
2480     lstrcpyA(product, "prod");
2481     r = MsiGetProductCodeA(component, product);
2482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2483     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2484
2485     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2486     RegCloseKey(prodkey);
2487     RegDeleteValueA(compkey, prod_squashed);
2488     RegDeleteValueA(compkey, prod2_squashed);
2489     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2490     RegCloseKey(compkey);
2491
2492     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2493     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2494     lstrcatA(keypath, comp_squashed);
2495
2496     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2497     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2498
2499     /* local user component key exists */
2500     lstrcpyA(product, "prod");
2501     r = MsiGetProductCodeA(component, product);
2502     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2503     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2504
2505     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2507
2508     /* product value exists */
2509     lstrcpyA(product, "prod");
2510     r = MsiGetProductCodeA(component, product);
2511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2512     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2513
2514     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2516
2517     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2518     lstrcatA(keypath, "Installer\\Managed\\");
2519     lstrcatA(keypath, usersid);
2520     lstrcatA(keypath, "\\Installer\\Products\\");
2521     lstrcatA(keypath, prod_squashed);
2522
2523     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2525
2526     /* user managed product key of first product exists */
2527     lstrcpyA(product, "prod");
2528     r = MsiGetProductCodeA(component, product);
2529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2530     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2531
2532     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2533     RegCloseKey(prodkey);
2534
2535     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2536     lstrcatA(keypath, prod_squashed);
2537
2538     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2540
2541     /* user unmanaged product key exists */
2542     lstrcpyA(product, "prod");
2543     r = MsiGetProductCodeA(component, product);
2544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2545     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2546
2547     RegDeleteKeyA(prodkey, "");
2548     RegCloseKey(prodkey);
2549
2550     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2551     lstrcatA(keypath, prod_squashed);
2552
2553     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2555
2556     /* local classes product key exists */
2557     lstrcpyA(product, "prod");
2558     r = MsiGetProductCodeA(component, product);
2559     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2560     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2561
2562     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2563     RegCloseKey(prodkey);
2564
2565     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2566     lstrcatA(keypath, "Installer\\Managed\\");
2567     lstrcatA(keypath, usersid);
2568     lstrcatA(keypath, "\\Installer\\Products\\");
2569     lstrcatA(keypath, prod2_squashed);
2570
2571     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2573
2574     /* user managed product key of second product exists */
2575     lstrcpyA(product, "prod");
2576     r = MsiGetProductCodeA(component, product);
2577     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2578     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2579
2580     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2581     RegCloseKey(prodkey);
2582     RegDeleteValueA(compkey, prod_squashed);
2583     RegDeleteValueA(compkey, prod2_squashed);
2584     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2585     RegCloseKey(compkey);
2586     LocalFree(usersid);
2587 }
2588
2589 static void test_MsiEnumClients(void)
2590 {
2591     HKEY compkey;
2592     CHAR prodcode[MAX_PATH];
2593     CHAR prod_squashed[MAX_PATH];
2594     CHAR prodcode2[MAX_PATH];
2595     CHAR prod2_squashed[MAX_PATH];
2596     CHAR component[MAX_PATH];
2597     CHAR comp_base85[MAX_PATH];
2598     CHAR comp_squashed[MAX_PATH];
2599     CHAR product[MAX_PATH];
2600     CHAR keypath[MAX_PATH];
2601     LPSTR usersid;
2602     LONG res;
2603     UINT r;
2604     REGSAM access = KEY_ALL_ACCESS;
2605
2606     create_test_guid(prodcode, prod_squashed);
2607     create_test_guid(prodcode2, prod2_squashed);
2608     compose_base85_guid(component, comp_base85, comp_squashed);
2609     usersid = get_user_sid();
2610
2611     if (is_wow64)
2612         access |= KEY_WOW64_64KEY;
2613
2614     /* NULL szComponent */
2615     product[0] = '\0';
2616     r = MsiEnumClientsA(NULL, 0, product);
2617     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2618     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2619
2620     /* empty szComponent */
2621     product[0] = '\0';
2622     r = MsiEnumClientsA("", 0, product);
2623     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2624     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2625
2626     /* NULL lpProductBuf */
2627     r = MsiEnumClientsA(component, 0, NULL);
2628     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2629
2630     /* all params correct, component missing */
2631     product[0] = '\0';
2632     r = MsiEnumClientsA(component, 0, product);
2633     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2634     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2635
2636     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2637     lstrcatA(keypath, "Installer\\UserData\\");
2638     lstrcatA(keypath, usersid);
2639     lstrcatA(keypath, "\\Components\\");
2640     lstrcatA(keypath, comp_squashed);
2641
2642     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2643     if (res == ERROR_ACCESS_DENIED)
2644     {
2645         skip("Not enough rights to perform tests\n");
2646         LocalFree(usersid);
2647         return;
2648     }
2649     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2650
2651     /* user unmanaged component key exists */
2652     product[0] = '\0';
2653     r = MsiEnumClientsA(component, 0, product);
2654     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2655     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2656
2657     /* index > 0, no products exist */
2658     product[0] = '\0';
2659     r = MsiEnumClientsA(component, 1, product);
2660     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2661     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2662
2663     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2665
2666     /* product value exists */
2667     r = MsiEnumClientsA(component, 0, product);
2668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2669     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2670
2671     /* try index 0 again */
2672     product[0] = '\0';
2673     r = MsiEnumClientsA(component, 0, product);
2674     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2675     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2676
2677     /* try index 1, second product value does not exist */
2678     product[0] = '\0';
2679     r = MsiEnumClientsA(component, 1, product);
2680     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2681     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2682
2683     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2685
2686     /* try index 1, second product value does exist */
2687     product[0] = '\0';
2688     r = MsiEnumClientsA(component, 1, product);
2689     todo_wine
2690     {
2691         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2692         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2693     }
2694
2695     /* start the enumeration over */
2696     product[0] = '\0';
2697     r = MsiEnumClientsA(component, 0, product);
2698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2699     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2700        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2701
2702     /* correctly query second product */
2703     product[0] = '\0';
2704     r = MsiEnumClientsA(component, 1, product);
2705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2706     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2707        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2708
2709     RegDeleteValueA(compkey, prod_squashed);
2710     RegDeleteValueA(compkey, prod2_squashed);
2711     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2712     RegCloseKey(compkey);
2713
2714     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2715     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2716     lstrcatA(keypath, comp_squashed);
2717
2718     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2720
2721     /* user local component key exists */
2722     product[0] = '\0';
2723     r = MsiEnumClientsA(component, 0, product);
2724     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2725     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2726
2727     /* index > 0, no products exist */
2728     product[0] = '\0';
2729     r = MsiEnumClientsA(component, 1, product);
2730     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2731     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2732
2733     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2735
2736     /* product value exists */
2737     product[0] = '\0';
2738     r = MsiEnumClientsA(component, 0, product);
2739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2740     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2741
2742     /* try index 0 again */
2743     product[0] = '\0';
2744     r = MsiEnumClientsA(component, 0, product);
2745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2746
2747     /* try index 1, second product value does not exist */
2748     product[0] = '\0';
2749     r = MsiEnumClientsA(component, 1, product);
2750     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2751     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2752
2753     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2754     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2755
2756     /* try index 1, second product value does exist */
2757     product[0] = '\0';
2758     r = MsiEnumClientsA(component, 1, product);
2759     todo_wine
2760     {
2761         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2762         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2763     }
2764
2765     /* start the enumeration over */
2766     product[0] = '\0';
2767     r = MsiEnumClientsA(component, 0, product);
2768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2769     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2770        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2771
2772     /* correctly query second product */
2773     product[0] = '\0';
2774     r = MsiEnumClientsA(component, 1, product);
2775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2776     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2777        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2778
2779     RegDeleteValueA(compkey, prod_squashed);
2780     RegDeleteValueA(compkey, prod2_squashed);
2781     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2782     RegCloseKey(compkey);
2783     LocalFree(usersid);
2784 }
2785
2786 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2787                              LPSTR *langcheck, LPDWORD langchecksz)
2788 {
2789     LPSTR version;
2790     VS_FIXEDFILEINFO *ffi;
2791     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2792     USHORT *lang;
2793
2794     version = HeapAlloc(GetProcessHeap(), 0, size);
2795     GetFileVersionInfoA(path, 0, size, version);
2796
2797     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2798     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2799     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2800             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2801             LOWORD(ffi->dwFileVersionLS));
2802     *verchecksz = lstrlenA(*vercheck);
2803
2804     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2805     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2806     sprintf(*langcheck, "%d", *lang);
2807     *langchecksz = lstrlenA(*langcheck);
2808
2809     HeapFree(GetProcessHeap(), 0, version);
2810 }
2811
2812 static void test_MsiGetFileVersion(void)
2813 {
2814     UINT r;
2815     DWORD versz, langsz;
2816     char version[MAX_PATH];
2817     char lang[MAX_PATH];
2818     char path[MAX_PATH];
2819     LPSTR vercheck, langcheck;
2820     DWORD verchecksz, langchecksz;
2821
2822     /* NULL szFilePath */
2823     versz = MAX_PATH;
2824     langsz = MAX_PATH;
2825     lstrcpyA(version, "version");
2826     lstrcpyA(lang, "lang");
2827     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2828     ok(r == ERROR_INVALID_PARAMETER,
2829        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2830     ok(!lstrcmpA(version, "version"),
2831        "Expected version to be unchanged, got %s\n", version);
2832     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2833     ok(!lstrcmpA(lang, "lang"),
2834        "Expected lang to be unchanged, got %s\n", lang);
2835     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2836
2837     /* empty szFilePath */
2838     versz = MAX_PATH;
2839     langsz = MAX_PATH;
2840     lstrcpyA(version, "version");
2841     lstrcpyA(lang, "lang");
2842     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2843     ok(r == ERROR_FILE_NOT_FOUND,
2844        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2845     ok(!lstrcmpA(version, "version"),
2846        "Expected version to be unchanged, got %s\n", version);
2847     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2848     ok(!lstrcmpA(lang, "lang"),
2849        "Expected lang to be unchanged, got %s\n", lang);
2850     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2851
2852     /* nonexistent szFilePath */
2853     versz = MAX_PATH;
2854     langsz = MAX_PATH;
2855     lstrcpyA(version, "version");
2856     lstrcpyA(lang, "lang");
2857     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2858     ok(r == ERROR_FILE_NOT_FOUND,
2859        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2860     ok(!lstrcmpA(version, "version"),
2861        "Expected version to be unchanged, got %s\n", version);
2862     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2863     ok(!lstrcmpA(lang, "lang"),
2864        "Expected lang to be unchanged, got %s\n", lang);
2865     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2866
2867     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2868     versz = MAX_PATH;
2869     langsz = MAX_PATH;
2870     lstrcpyA(version, "version");
2871     lstrcpyA(lang, "lang");
2872     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2873     ok(r == ERROR_INVALID_PARAMETER,
2874        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2875     ok(!lstrcmpA(version, "version"),
2876        "Expected version to be unchanged, got %s\n", version);
2877     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2878     ok(!lstrcmpA(lang, "lang"),
2879        "Expected lang to be unchanged, got %s\n", lang);
2880     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2881
2882     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2883     versz = MAX_PATH;
2884     langsz = MAX_PATH;
2885     lstrcpyA(version, "version");
2886     lstrcpyA(lang, "lang");
2887     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2888     ok(r == ERROR_INVALID_PARAMETER,
2889        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2890     ok(!lstrcmpA(version, "version"),
2891        "Expected version to be unchanged, got %s\n", version);
2892     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2893     ok(!lstrcmpA(lang, "lang"),
2894        "Expected lang to be unchanged, got %s\n", lang);
2895     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2896
2897     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2898     versz = 0;
2899     langsz = MAX_PATH;
2900     lstrcpyA(version, "version");
2901     lstrcpyA(lang, "lang");
2902     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2903     ok(r == ERROR_FILE_NOT_FOUND,
2904        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2905     ok(!lstrcmpA(version, "version"),
2906        "Expected version to be unchanged, got %s\n", version);
2907     ok(versz == 0, "Expected 0, got %d\n", versz);
2908     ok(!lstrcmpA(lang, "lang"),
2909        "Expected lang to be unchanged, got %s\n", lang);
2910     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2911
2912     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2913     versz = MAX_PATH;
2914     langsz = 0;
2915     lstrcpyA(version, "version");
2916     lstrcpyA(lang, "lang");
2917     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2918     ok(r == ERROR_FILE_NOT_FOUND,
2919        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2920     ok(!lstrcmpA(version, "version"),
2921        "Expected version to be unchanged, got %s\n", version);
2922     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2923     ok(!lstrcmpA(lang, "lang"),
2924        "Expected lang to be unchanged, got %s\n", lang);
2925     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2926
2927     /* nonexistent szFilePath, rest NULL */
2928     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2929     ok(r == ERROR_FILE_NOT_FOUND,
2930        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2931
2932     create_file("ver.txt", "ver.txt", 20);
2933
2934     /* file exists, no version information */
2935     versz = MAX_PATH;
2936     langsz = MAX_PATH;
2937     lstrcpyA(version, "version");
2938     lstrcpyA(lang, "lang");
2939     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2940     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2941     ok(!lstrcmpA(version, "version"),
2942        "Expected version to be unchanged, got %s\n", version);
2943     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2944     ok(!lstrcmpA(lang, "lang"),
2945        "Expected lang to be unchanged, got %s\n", lang);
2946     ok(r == ERROR_FILE_INVALID,
2947        "Expected ERROR_FILE_INVALID, got %d\n", r);
2948
2949     DeleteFileA("ver.txt");
2950
2951     /* relative path, has version information */
2952     versz = MAX_PATH;
2953     langsz = MAX_PATH;
2954     lstrcpyA(version, "version");
2955     lstrcpyA(lang, "lang");
2956     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2957     todo_wine
2958     {
2959         ok(r == ERROR_FILE_NOT_FOUND,
2960            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2961         ok(!lstrcmpA(version, "version"),
2962            "Expected version to be unchanged, got %s\n", version);
2963         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2964         ok(!lstrcmpA(lang, "lang"),
2965            "Expected lang to be unchanged, got %s\n", lang);
2966         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2967     }
2968
2969     GetSystemDirectoryA(path, MAX_PATH);
2970     lstrcatA(path, "\\kernel32.dll");
2971
2972     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2973
2974     /* absolute path, has version information */
2975     versz = MAX_PATH;
2976     langsz = MAX_PATH;
2977     lstrcpyA(version, "version");
2978     lstrcpyA(lang, "lang");
2979     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2981     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2982     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2983     ok(!lstrcmpA(version, vercheck),
2984         "Expected %s, got %s\n", vercheck, version);
2985
2986     /* only check version */
2987     versz = MAX_PATH;
2988     lstrcpyA(version, "version");
2989     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2991     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2992     ok(!lstrcmpA(version, vercheck),
2993        "Expected %s, got %s\n", vercheck, version);
2994
2995     /* only check language */
2996     langsz = MAX_PATH;
2997     lstrcpyA(lang, "lang");
2998     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2999     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3000     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
3001
3002     /* check neither version nor language */
3003     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
3004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3005
3006     /* get pcchVersionBuf */
3007     versz = MAX_PATH;
3008     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
3009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3010     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3011
3012     /* get pcchLangBuf */
3013     langsz = MAX_PATH;
3014     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
3015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3016     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3017
3018     /* pcchVersionBuf not big enough */
3019     versz = 5;
3020     lstrcpyA(version, "version");
3021     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
3022     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3023     ok(!strncmp(version, vercheck, 4),
3024        "Expected first 4 characters of %s, got %s\n", vercheck, version);
3025     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3026
3027     /* pcchLangBuf not big enough */
3028     langsz = 3;
3029     lstrcpyA(lang, "lang");
3030     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
3031     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3032     ok(!strncmp(lang, langcheck, 2),
3033        "Expected first character of %s, got %s\n", langcheck, lang);
3034     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3035
3036     HeapFree(GetProcessHeap(), 0, vercheck);
3037     HeapFree(GetProcessHeap(), 0, langcheck);
3038 }
3039
3040 static void test_MsiGetProductInfo(void)
3041 {
3042     UINT r;
3043     LONG res;
3044     HKEY propkey, source;
3045     HKEY prodkey, localkey;
3046     CHAR prodcode[MAX_PATH];
3047     CHAR prod_squashed[MAX_PATH];
3048     CHAR packcode[MAX_PATH];
3049     CHAR pack_squashed[MAX_PATH];
3050     CHAR buf[MAX_PATH];
3051     CHAR keypath[MAX_PATH];
3052     LPSTR usersid;
3053     DWORD sz, val = 42;
3054     REGSAM access = KEY_ALL_ACCESS;
3055
3056     create_test_guid(prodcode, prod_squashed);
3057     create_test_guid(packcode, pack_squashed);
3058     usersid = get_user_sid();
3059
3060     if (is_wow64)
3061         access |= KEY_WOW64_64KEY;
3062
3063     /* NULL szProduct */
3064     sz = MAX_PATH;
3065     lstrcpyA(buf, "apple");
3066     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
3067     ok(r == ERROR_INVALID_PARAMETER,
3068        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3069     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3070     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3071
3072     /* empty szProduct */
3073     sz = MAX_PATH;
3074     lstrcpyA(buf, "apple");
3075     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
3076     ok(r == ERROR_INVALID_PARAMETER,
3077        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3078     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3079     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3080
3081     /* garbage szProduct */
3082     sz = MAX_PATH;
3083     lstrcpyA(buf, "apple");
3084     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
3085     ok(r == ERROR_INVALID_PARAMETER,
3086        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3087     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3088     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3089
3090     /* guid without brackets */
3091     sz = MAX_PATH;
3092     lstrcpyA(buf, "apple");
3093     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
3094                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3095     ok(r == ERROR_INVALID_PARAMETER,
3096        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3097     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3098     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3099
3100     /* guid with brackets */
3101     sz = MAX_PATH;
3102     lstrcpyA(buf, "apple");
3103     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
3104                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3105     ok(r == ERROR_UNKNOWN_PRODUCT,
3106        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3107     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3108     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3109
3110     /* same length as guid, but random */
3111     sz = MAX_PATH;
3112     lstrcpyA(buf, "apple");
3113     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
3114                            INSTALLPROPERTY_HELPLINK, buf, &sz);
3115     ok(r == ERROR_INVALID_PARAMETER,
3116        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3117     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3118     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3119
3120     /* not installed, NULL szAttribute */
3121     sz = MAX_PATH;
3122     lstrcpyA(buf, "apple");
3123     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
3124     ok(r == ERROR_INVALID_PARAMETER,
3125        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3126     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3127     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3128
3129     /* not installed, NULL lpValueBuf */
3130     sz = MAX_PATH;
3131     lstrcpyA(buf, "apple");
3132     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3133     ok(r == ERROR_UNKNOWN_PRODUCT,
3134        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3135     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3136     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3137
3138     /* not installed, NULL pcchValueBuf */
3139     sz = MAX_PATH;
3140     lstrcpyA(buf, "apple");
3141     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
3142     ok(r == ERROR_INVALID_PARAMETER,
3143        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3144     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3145     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3146
3147     /* created guid cannot possibly be an installed product code */
3148     sz = MAX_PATH;
3149     lstrcpyA(buf, "apple");
3150     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3151     ok(r == ERROR_UNKNOWN_PRODUCT,
3152        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3153     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3154     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3155
3156     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3157     lstrcatA(keypath, usersid);
3158     lstrcatA(keypath, "\\Installer\\Products\\");
3159     lstrcatA(keypath, prod_squashed);
3160
3161     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3162     if (res == ERROR_ACCESS_DENIED)
3163     {
3164         skip("Not enough rights to perform tests\n");
3165         LocalFree(usersid);
3166         return;
3167     }
3168     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3169
3170     /* managed product code exists */
3171     sz = MAX_PATH;
3172     lstrcpyA(buf, "apple");
3173     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3174     ok(r == ERROR_UNKNOWN_PROPERTY,
3175        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3176     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3177     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3178
3179     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3180     RegCloseKey(prodkey);
3181
3182     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3183     lstrcatA(keypath, usersid);
3184     lstrcatA(keypath, "\\Products\\");
3185     lstrcatA(keypath, prod_squashed);
3186
3187     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3189
3190     /* local user product code exists */
3191     sz = MAX_PATH;
3192     lstrcpyA(buf, "apple");
3193     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3194     ok(r == ERROR_UNKNOWN_PRODUCT,
3195        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3196     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3197     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3198
3199     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3200     lstrcatA(keypath, usersid);
3201     lstrcatA(keypath, "\\Installer\\Products\\");
3202     lstrcatA(keypath, prod_squashed);
3203
3204     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3206
3207     /* both local and managed product code exist */
3208     sz = MAX_PATH;
3209     lstrcpyA(buf, "apple");
3210     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3211     ok(r == ERROR_UNKNOWN_PROPERTY,
3212        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3213     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3214     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3215
3216     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3218
3219     /* InstallProperties key exists */
3220     sz = MAX_PATH;
3221     lstrcpyA(buf, "apple");
3222     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3224     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3225     ok(sz == 0, "Expected 0, got %d\n", sz);
3226
3227     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3229
3230     /* HelpLink value exists */
3231     sz = MAX_PATH;
3232     lstrcpyA(buf, "apple");
3233     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3235     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3236     ok(sz == 4, "Expected 4, got %d\n", sz);
3237
3238     /* pcchBuf is NULL */
3239     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3241
3242     /* lpValueBuf is NULL */
3243     sz = MAX_PATH;
3244     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3246     ok(sz == 4, "Expected 4, got %d\n", sz);
3247
3248     /* lpValueBuf is NULL, pcchValueBuf is too small */
3249     sz = 2;
3250     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3252     ok(sz == 4, "Expected 4, got %d\n", sz);
3253
3254     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3255     sz = 2;
3256     lstrcpyA(buf, "apple");
3257     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3258     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3259     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3260     ok(sz == 4, "Expected 4, got %d\n", sz);
3261
3262     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3263     sz = 4;
3264     lstrcpyA(buf, "apple");
3265     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3266     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3267     ok(!lstrcmpA(buf, "apple"),
3268        "Expected buf to remain unchanged, got \"%s\"\n", buf);
3269     ok(sz == 4, "Expected 4, got %d\n", sz);
3270
3271     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3273
3274     /* random property not supported by MSI, value exists */
3275     sz = MAX_PATH;
3276     lstrcpyA(buf, "apple");
3277     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3278     ok(r == ERROR_UNKNOWN_PROPERTY,
3279        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3280     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3281     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3282
3283     RegDeleteValueA(propkey, "IMadeThis");
3284     RegDeleteValueA(propkey, "HelpLink");
3285     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3286     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3287     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3288     RegCloseKey(propkey);
3289     RegCloseKey(localkey);
3290     RegCloseKey(prodkey);
3291
3292     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3293     lstrcatA(keypath, prod_squashed);
3294
3295     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* user product key exists */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3302     ok(r == ERROR_UNKNOWN_PROPERTY,
3303        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3304     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3305     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3306
3307     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3308     lstrcatA(keypath, usersid);
3309     lstrcatA(keypath, "\\Products\\");
3310     lstrcatA(keypath, prod_squashed);
3311
3312     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3314
3315     /* local user product key exists */
3316     sz = MAX_PATH;
3317     lstrcpyA(buf, "apple");
3318     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3319     ok(r == ERROR_UNKNOWN_PROPERTY,
3320        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3321     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3322     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3323
3324     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3326
3327     /* InstallProperties key exists */
3328     sz = MAX_PATH;
3329     lstrcpyA(buf, "apple");
3330     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3331     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3332     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3333     ok(sz == 0, "Expected 0, got %d\n", sz);
3334
3335     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3337
3338     /* HelpLink value exists */
3339     sz = MAX_PATH;
3340     lstrcpyA(buf, "apple");
3341     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3343     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3344     ok(sz == 4, "Expected 4, got %d\n", sz);
3345
3346     RegDeleteValueA(propkey, "HelpLink");
3347     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3348     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3349     RegDeleteKeyA(prodkey, "");
3350     RegCloseKey(propkey);
3351     RegCloseKey(localkey);
3352     RegCloseKey(prodkey);
3353
3354     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3355     lstrcatA(keypath, prod_squashed);
3356
3357     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3359
3360     /* classes product key exists */
3361     sz = MAX_PATH;
3362     lstrcpyA(buf, "apple");
3363     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3364     ok(r == ERROR_UNKNOWN_PROPERTY,
3365        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3366     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3367     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3368
3369     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3370     lstrcatA(keypath, usersid);
3371     lstrcatA(keypath, "\\Products\\");
3372     lstrcatA(keypath, prod_squashed);
3373
3374     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3376
3377     /* local user product key exists */
3378     sz = MAX_PATH;
3379     lstrcpyA(buf, "apple");
3380     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3381     ok(r == ERROR_UNKNOWN_PROPERTY,
3382        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3383     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3384     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3385
3386     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3387     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3388
3389     /* InstallProperties key exists */
3390     sz = MAX_PATH;
3391     lstrcpyA(buf, "apple");
3392     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3393     ok(r == ERROR_UNKNOWN_PROPERTY,
3394        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3395     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3396     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3397
3398     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3399     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3400     RegCloseKey(propkey);
3401     RegCloseKey(localkey);
3402
3403     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3404     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3405     lstrcatA(keypath, prod_squashed);
3406
3407     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3409
3410     /* Local System product key exists */
3411     sz = MAX_PATH;
3412     lstrcpyA(buf, "apple");
3413     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3414     ok(r == ERROR_UNKNOWN_PROPERTY,
3415         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3416     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3417     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3418
3419     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3421
3422     /* InstallProperties key exists */
3423     sz = MAX_PATH;
3424     lstrcpyA(buf, "apple");
3425     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3426     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3427     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3428     ok(sz == 0, "Expected 0, got %d\n", sz);
3429
3430     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3432
3433     /* HelpLink value exists */
3434     sz = MAX_PATH;
3435     lstrcpyA(buf, "apple");
3436     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3438     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3439     ok(sz == 4, "Expected 4, got %d\n", sz);
3440
3441     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3442                          (const BYTE *)&val, sizeof(DWORD));
3443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3444
3445     /* HelpLink type is REG_DWORD */
3446     sz = MAX_PATH;
3447     lstrcpyA(buf, "apple");
3448     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3449     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3450     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3451     ok(sz == 2, "Expected 2, got %d\n", sz);
3452
3453     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3454     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3455
3456     /* DisplayName value exists */
3457     sz = MAX_PATH;
3458     lstrcpyA(buf, "apple");
3459     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3461     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3462     ok(sz == 4, "Expected 4, got %d\n", sz);
3463
3464     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3465                          (const BYTE *)&val, sizeof(DWORD));
3466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3467
3468     /* DisplayName type is REG_DWORD */
3469     sz = MAX_PATH;
3470     lstrcpyA(buf, "apple");
3471     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3473     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3474     ok(sz == 2, "Expected 2, got %d\n", sz);
3475
3476     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3478
3479     /* DisplayVersion value exists */
3480     sz = MAX_PATH;
3481     lstrcpyA(buf, "apple");
3482     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3484     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3485     ok(sz == 5, "Expected 5, got %d\n", sz);
3486
3487     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3488                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3490
3491     /* DisplayVersion type is REG_DWORD */
3492     sz = MAX_PATH;
3493     lstrcpyA(buf, "apple");
3494     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3495     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3496     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3497     ok(sz == 2, "Expected 2, got %d\n", sz);
3498
3499     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3501
3502     /* HelpTelephone value exists */
3503     sz = MAX_PATH;
3504     lstrcpyA(buf, "apple");
3505     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3506     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3507     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3508     ok(sz == 4, "Expected 4, got %d\n", sz);
3509
3510     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3511                          (const BYTE *)&val, sizeof(DWORD));
3512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3513
3514     /* HelpTelephone type is REG_DWORD */
3515     sz = MAX_PATH;
3516     lstrcpyA(buf, "apple");
3517     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3518     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3519     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3520     ok(sz == 2, "Expected 2, got %d\n", sz);
3521
3522     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3524
3525     /* InstallLocation value exists */
3526     sz = MAX_PATH;
3527     lstrcpyA(buf, "apple");
3528     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3530     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3531     ok(sz == 3, "Expected 3, got %d\n", sz);
3532
3533     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3534                          (const BYTE *)&val, sizeof(DWORD));
3535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3536
3537     /* InstallLocation type is REG_DWORD */
3538     sz = MAX_PATH;
3539     lstrcpyA(buf, "apple");
3540     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3542     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3543     ok(sz == 2, "Expected 2, got %d\n", sz);
3544
3545     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3547
3548     /* InstallSource value exists */
3549     sz = MAX_PATH;
3550     lstrcpyA(buf, "apple");
3551     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3553     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3554     ok(sz == 6, "Expected 6, got %d\n", sz);
3555
3556     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3557                          (const BYTE *)&val, sizeof(DWORD));
3558     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3559
3560     /* InstallSource type is REG_DWORD */
3561     sz = MAX_PATH;
3562     lstrcpyA(buf, "apple");
3563     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3564     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3565     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3566     ok(sz == 2, "Expected 2, got %d\n", sz);
3567
3568     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3570
3571     /* InstallDate value exists */
3572     sz = MAX_PATH;
3573     lstrcpyA(buf, "apple");
3574     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3575     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3576     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3577     ok(sz == 4, "Expected 4, got %d\n", sz);
3578
3579     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3580                          (const BYTE *)&val, sizeof(DWORD));
3581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3582
3583     /* InstallDate type is REG_DWORD */
3584     sz = MAX_PATH;
3585     lstrcpyA(buf, "apple");
3586     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3587     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3588     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3589     ok(sz == 2, "Expected 2, got %d\n", sz);
3590
3591     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3593
3594     /* Publisher value exists */
3595     sz = MAX_PATH;
3596     lstrcpyA(buf, "apple");
3597     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3598     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3599     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3600     ok(sz == 3, "Expected 3, got %d\n", sz);
3601
3602     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3603                          (const BYTE *)&val, sizeof(DWORD));
3604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3605
3606     /* Publisher type is REG_DWORD */
3607     sz = MAX_PATH;
3608     lstrcpyA(buf, "apple");
3609     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3610     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3611     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3612     ok(sz == 2, "Expected 2, got %d\n", sz);
3613
3614     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3616
3617     /* LocalPackage value exists */
3618     sz = MAX_PATH;
3619     lstrcpyA(buf, "apple");
3620     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3621     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3622     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3623     ok(sz == 4, "Expected 4, got %d\n", sz);
3624
3625     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3626                          (const BYTE *)&val, sizeof(DWORD));
3627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3628
3629     /* LocalPackage type is REG_DWORD */
3630     sz = MAX_PATH;
3631     lstrcpyA(buf, "apple");
3632     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3634     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3635     ok(sz == 2, "Expected 2, got %d\n", sz);
3636
3637     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3639
3640     /* UrlInfoAbout value exists */
3641     sz = MAX_PATH;
3642     lstrcpyA(buf, "apple");
3643     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3644     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3645     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3646     ok(sz == 5, "Expected 5, got %d\n", sz);
3647
3648     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3649                          (const BYTE *)&val, sizeof(DWORD));
3650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3651
3652     /* UrlInfoAbout type is REG_DWORD */
3653     sz = MAX_PATH;
3654     lstrcpyA(buf, "apple");
3655     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3657     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3658     ok(sz == 2, "Expected 2, got %d\n", sz);
3659
3660     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3661     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3662
3663     /* UrlUpdateInfo value exists */
3664     sz = MAX_PATH;
3665     lstrcpyA(buf, "apple");
3666     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3667     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3668     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3669     ok(sz == 4, "Expected 4, got %d\n", sz);
3670
3671     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3672                          (const BYTE *)&val, sizeof(DWORD));
3673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3674
3675     /* UrlUpdateInfo type is REG_DWORD */
3676     sz = MAX_PATH;
3677     lstrcpyA(buf, "apple");
3678     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3679     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3680     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3681     ok(sz == 2, "Expected 2, got %d\n", sz);
3682
3683     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3685
3686     /* VersionMinor value exists */
3687     sz = MAX_PATH;
3688     lstrcpyA(buf, "apple");
3689     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3691     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3692     ok(sz == 1, "Expected 1, got %d\n", sz);
3693
3694     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3695                          (const BYTE *)&val, sizeof(DWORD));
3696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3697
3698     /* VersionMinor type is REG_DWORD */
3699     sz = MAX_PATH;
3700     lstrcpyA(buf, "apple");
3701     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3703     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3704     ok(sz == 2, "Expected 2, got %d\n", sz);
3705
3706     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3708
3709     /* VersionMajor value exists */
3710     sz = MAX_PATH;
3711     lstrcpyA(buf, "apple");
3712     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3714     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3715     ok(sz == 1, "Expected 1, got %d\n", sz);
3716
3717     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3718                          (const BYTE *)&val, sizeof(DWORD));
3719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3720
3721     /* VersionMajor type is REG_DWORD */
3722     sz = MAX_PATH;
3723     lstrcpyA(buf, "apple");
3724     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3726     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3727     ok(sz == 2, "Expected 2, got %d\n", sz);
3728
3729     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3731
3732     /* ProductID value exists */
3733     sz = MAX_PATH;
3734     lstrcpyA(buf, "apple");
3735     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3737     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3738     ok(sz == 2, "Expected 2, got %d\n", sz);
3739
3740     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3741                          (const BYTE *)&val, sizeof(DWORD));
3742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3743
3744     /* ProductID type is REG_DWORD */
3745     sz = MAX_PATH;
3746     lstrcpyA(buf, "apple");
3747     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3749     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3750     ok(sz == 2, "Expected 2, got %d\n", sz);
3751
3752     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3754
3755     /* RegCompany value exists */
3756     sz = MAX_PATH;
3757     lstrcpyA(buf, "apple");
3758     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3759     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3760     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3761     ok(sz == 4, "Expected 4, got %d\n", sz);
3762
3763     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3764                          (const BYTE *)&val, sizeof(DWORD));
3765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3766
3767     /* RegCompany type is REG_DWORD */
3768     sz = MAX_PATH;
3769     lstrcpyA(buf, "apple");
3770     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3772     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3773     ok(sz == 2, "Expected 2, got %d\n", sz);
3774
3775     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3777
3778     /* RegOwner value exists */
3779     sz = MAX_PATH;
3780     lstrcpyA(buf, "apple");
3781     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3783     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3784     ok(sz == 3, "Expected 3, got %d\n", sz);
3785
3786     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3787                          (const BYTE *)&val, sizeof(DWORD));
3788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3789
3790     /* RegOwner type is REG_DWORD */
3791     sz = MAX_PATH;
3792     lstrcpyA(buf, "apple");
3793     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3795     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3796     ok(sz == 2, "Expected 2, got %d\n", sz);
3797
3798     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3800
3801     /* InstanceType value exists */
3802     sz = MAX_PATH;
3803     lstrcpyA(buf, "apple");
3804     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3806     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3807     ok(sz == 0, "Expected 0, got %d\n", sz);
3808
3809     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3810                          (const BYTE *)&val, sizeof(DWORD));
3811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3812
3813     /* InstanceType type is REG_DWORD */
3814     sz = MAX_PATH;
3815     lstrcpyA(buf, "apple");
3816     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3817     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3818     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3819     ok(sz == 0, "Expected 0, got %d\n", sz);
3820
3821     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3822     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3823
3824     /* InstanceType value exists */
3825     sz = MAX_PATH;
3826     lstrcpyA(buf, "apple");
3827     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3829     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3830     ok(sz == 4, "Expected 4, got %d\n", sz);
3831
3832     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3833                          (const BYTE *)&val, sizeof(DWORD));
3834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3835
3836     /* InstanceType type is REG_DWORD */
3837     sz = MAX_PATH;
3838     lstrcpyA(buf, "apple");
3839     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3840     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3841     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3842     ok(sz == 2, "Expected 2, got %d\n", sz);
3843
3844     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3845     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3846
3847     /* Transforms value exists */
3848     sz = MAX_PATH;
3849     lstrcpyA(buf, "apple");
3850     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3851     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3852     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3853     ok(sz == 0, "Expected 0, got %d\n", sz);
3854
3855     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3856                          (const BYTE *)&val, sizeof(DWORD));
3857     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3858
3859     /* Transforms type is REG_DWORD */
3860     sz = MAX_PATH;
3861     lstrcpyA(buf, "apple");
3862     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3863     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3864     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3865     ok(sz == 0, "Expected 0, got %d\n", sz);
3866
3867     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3869
3870     /* Transforms value exists */
3871     sz = MAX_PATH;
3872     lstrcpyA(buf, "apple");
3873     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3875     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3876     ok(sz == 6, "Expected 6, got %d\n", sz);
3877
3878     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3879                          (const BYTE *)&val, sizeof(DWORD));
3880     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3881
3882     /* Transforms type is REG_DWORD */
3883     sz = MAX_PATH;
3884     lstrcpyA(buf, "apple");
3885     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3886     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3887     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3888     ok(sz == 2, "Expected 2, got %d\n", sz);
3889
3890     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3892
3893     /* Language value exists */
3894     sz = MAX_PATH;
3895     lstrcpyA(buf, "apple");
3896     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3897     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3898     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3899     ok(sz == 0, "Expected 0, got %d\n", sz);
3900
3901     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3902                          (const BYTE *)&val, sizeof(DWORD));
3903     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3904
3905     /* Language type is REG_DWORD */
3906     sz = MAX_PATH;
3907     lstrcpyA(buf, "apple");
3908     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3910     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3911     ok(sz == 0, "Expected 0, got %d\n", sz);
3912
3913     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3915
3916     /* Language value exists */
3917     sz = MAX_PATH;
3918     lstrcpyA(buf, "apple");
3919     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3920     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3921     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3922     ok(sz == 4, "Expected 4, got %d\n", sz);
3923
3924     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3925                          (const BYTE *)&val, sizeof(DWORD));
3926     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3927
3928     /* Language type is REG_DWORD */
3929     sz = MAX_PATH;
3930     lstrcpyA(buf, "apple");
3931     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3932     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3933     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3934     ok(sz == 2, "Expected 2, got %d\n", sz);
3935
3936     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3938
3939     /* ProductName value exists */
3940     sz = MAX_PATH;
3941     lstrcpyA(buf, "apple");
3942     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3944     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3945     ok(sz == 0, "Expected 0, got %d\n", sz);
3946
3947     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3948                          (const BYTE *)&val, sizeof(DWORD));
3949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3950
3951     /* ProductName type is REG_DWORD */
3952     sz = MAX_PATH;
3953     lstrcpyA(buf, "apple");
3954     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3955     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3956     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3957     ok(sz == 0, "Expected 0, got %d\n", sz);
3958
3959     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3960     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3961
3962     /* ProductName value exists */
3963     sz = MAX_PATH;
3964     lstrcpyA(buf, "apple");
3965     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3967     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3968     ok(sz == 4, "Expected 4, got %d\n", sz);
3969
3970     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3971                          (const BYTE *)&val, sizeof(DWORD));
3972     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3973
3974     /* ProductName type is REG_DWORD */
3975     sz = MAX_PATH;
3976     lstrcpyA(buf, "apple");
3977     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3978     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3979     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3980     ok(sz == 2, "Expected 2, got %d\n", sz);
3981
3982     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3984
3985     /* Assignment value exists */
3986     sz = MAX_PATH;
3987     lstrcpyA(buf, "apple");
3988     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3989     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3990     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3991     ok(sz == 0, "Expected 0, got %d\n", sz);
3992
3993     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3994                          (const BYTE *)&val, sizeof(DWORD));
3995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3996
3997     /* Assignment type is REG_DWORD */
3998     sz = MAX_PATH;
3999     lstrcpyA(buf, "apple");
4000     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4001     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4002     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4003     ok(sz == 0, "Expected 0, got %d\n", sz);
4004
4005     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
4006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4007
4008     /* Assignment value exists */
4009     sz = MAX_PATH;
4010     lstrcpyA(buf, "apple");
4011     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4012     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4013     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
4014     ok(sz == 2, "Expected 2, got %d\n", sz);
4015
4016     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
4017                          (const BYTE *)&val, sizeof(DWORD));
4018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4019
4020     /* Assignment type is REG_DWORD */
4021     sz = MAX_PATH;
4022     lstrcpyA(buf, "apple");
4023     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4025     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4026     ok(sz == 2, "Expected 2, got %d\n", sz);
4027
4028     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4030
4031     /* PackageCode value exists */
4032     sz = MAX_PATH;
4033     lstrcpyA(buf, "apple");
4034     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4036     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4037     ok(sz == 0, "Expected 0, got %d\n", sz);
4038
4039     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
4040                          (const BYTE *)&val, sizeof(DWORD));
4041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4042
4043     /* PackageCode type is REG_DWORD */
4044     sz = MAX_PATH;
4045     lstrcpyA(buf, "apple");
4046     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4047     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4048     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4049     ok(sz == 0, "Expected 0, got %d\n", sz);
4050
4051     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4053
4054     /* PackageCode value exists */
4055     sz = MAX_PATH;
4056     lstrcpyA(buf, "apple");
4057     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4058     ok(r == ERROR_BAD_CONFIGURATION,
4059        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4060     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
4061     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4062
4063     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
4064                          (const BYTE *)&val, sizeof(DWORD));
4065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4066
4067     /* PackageCode type is REG_DWORD */
4068     sz = MAX_PATH;
4069     lstrcpyA(buf, "apple");
4070     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4072     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4073     ok(sz == 2, "Expected 2, got %d\n", sz);
4074
4075     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
4076     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4077
4078     /* PackageCode value exists */
4079     sz = MAX_PATH;
4080     lstrcpyA(buf, "apple");
4081     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4083     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
4084     ok(sz == 38, "Expected 38, got %d\n", sz);
4085
4086     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4088
4089     /* Version value exists */
4090     sz = MAX_PATH;
4091     lstrcpyA(buf, "apple");
4092     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4093     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4094     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4095     ok(sz == 0, "Expected 0, got %d\n", sz);
4096
4097     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
4098                          (const BYTE *)&val, sizeof(DWORD));
4099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4100
4101     /* Version type is REG_DWORD */
4102     sz = MAX_PATH;
4103     lstrcpyA(buf, "apple");
4104     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4106     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4107     ok(sz == 0, "Expected 0, got %d\n", sz);
4108
4109     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4111
4112     /* Version value exists */
4113     sz = MAX_PATH;
4114     lstrcpyA(buf, "apple");
4115     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4116     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4117     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4118     ok(sz == 3, "Expected 3, got %d\n", sz);
4119
4120     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
4121                          (const BYTE *)&val, sizeof(DWORD));
4122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4123
4124     /* Version type is REG_DWORD */
4125     sz = MAX_PATH;
4126     lstrcpyA(buf, "apple");
4127     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4129     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4130     ok(sz == 2, "Expected 2, got %d\n", sz);
4131
4132     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4134
4135     /* ProductIcon value exists */
4136     sz = MAX_PATH;
4137     lstrcpyA(buf, "apple");
4138     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4140     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4141     ok(sz == 0, "Expected 0, got %d\n", sz);
4142
4143     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
4144                          (const BYTE *)&val, sizeof(DWORD));
4145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4146
4147     /* ProductIcon type is REG_DWORD */
4148     sz = MAX_PATH;
4149     lstrcpyA(buf, "apple");
4150     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4152     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4153     ok(sz == 0, "Expected 0, got %d\n", sz);
4154
4155     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4157
4158     /* ProductIcon value exists */
4159     sz = MAX_PATH;
4160     lstrcpyA(buf, "apple");
4161     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4162     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4163     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
4164     ok(sz == 3, "Expected 3, got %d\n", sz);
4165
4166     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
4167                          (const BYTE *)&val, sizeof(DWORD));
4168     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4169
4170     /* ProductIcon type is REG_DWORD */
4171     sz = MAX_PATH;
4172     lstrcpyA(buf, "apple");
4173     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4174     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4175     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4176     ok(sz == 2, "Expected 2, got %d\n", sz);
4177
4178     /* SourceList key does not exist */
4179     sz = MAX_PATH;
4180     lstrcpyA(buf, "apple");
4181     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4182     ok(r == ERROR_UNKNOWN_PRODUCT,
4183        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4184     ok(!lstrcmpA(buf, "apple"),
4185        "Expected buf to be unchanged, got \"%s\"\n", buf);
4186     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
4187
4188     res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
4189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4190
4191     /* SourceList key exists, but PackageName val does not exist */
4192     sz = MAX_PATH;
4193     lstrcpyA(buf, "apple");
4194     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4196     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4197     ok(sz == 0, "Expected 0, got %d\n", sz);
4198
4199     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
4200     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4201
4202     /* PackageName val exists */
4203     sz = MAX_PATH;
4204     lstrcpyA(buf, "apple");
4205     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4207     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4208     ok(sz == 8, "Expected 8, got %d\n", sz);
4209
4210     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4211                          (const BYTE *)&val, sizeof(DWORD));
4212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4213
4214     /* PackageName type is REG_DWORD */
4215     sz = MAX_PATH;
4216     lstrcpyA(buf, "apple");
4217     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4219     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4220     ok(sz == 2, "Expected 2, got %d\n", sz);
4221
4222     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4224
4225     /* Authorized value exists */
4226     sz = MAX_PATH;
4227     lstrcpyA(buf, "apple");
4228     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4229     if (r != ERROR_UNKNOWN_PROPERTY)
4230     {
4231         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4232         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4233         ok(sz == 0, "Expected 0, got %d\n", sz);
4234     }
4235
4236     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4237                          (const BYTE *)&val, sizeof(DWORD));
4238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4239
4240     /* AuthorizedLUAApp type is REG_DWORD */
4241     sz = MAX_PATH;
4242     lstrcpyA(buf, "apple");
4243     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4244     if (r != ERROR_UNKNOWN_PROPERTY)
4245     {
4246         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4247         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4248         ok(sz == 0, "Expected 0, got %d\n", sz);
4249     }
4250
4251     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4253
4254     /* Authorized value exists */
4255     sz = MAX_PATH;
4256     lstrcpyA(buf, "apple");
4257     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4258     if (r != ERROR_UNKNOWN_PROPERTY)
4259     {
4260         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4261         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4262         ok(sz == 4, "Expected 4, got %d\n", sz);
4263     }
4264
4265     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4266                          (const BYTE *)&val, sizeof(DWORD));
4267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4268
4269     /* AuthorizedLUAApp type is REG_DWORD */
4270     sz = MAX_PATH;
4271     lstrcpyA(buf, "apple");
4272     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4273     if (r != ERROR_UNKNOWN_PROPERTY)
4274     {
4275         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4276         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4277         ok(sz == 2, "Expected 2, got %d\n", sz);
4278     }
4279
4280     RegDeleteValueA(propkey, "HelpLink");
4281     RegDeleteValueA(propkey, "DisplayName");
4282     RegDeleteValueA(propkey, "DisplayVersion");
4283     RegDeleteValueA(propkey, "HelpTelephone");
4284     RegDeleteValueA(propkey, "InstallLocation");
4285     RegDeleteValueA(propkey, "InstallSource");
4286     RegDeleteValueA(propkey, "InstallDate");
4287     RegDeleteValueA(propkey, "Publisher");
4288     RegDeleteValueA(propkey, "LocalPackage");
4289     RegDeleteValueA(propkey, "UrlInfoAbout");
4290     RegDeleteValueA(propkey, "UrlUpdateInfo");
4291     RegDeleteValueA(propkey, "VersionMinor");
4292     RegDeleteValueA(propkey, "VersionMajor");
4293     RegDeleteValueA(propkey, "ProductID");
4294     RegDeleteValueA(propkey, "RegCompany");
4295     RegDeleteValueA(propkey, "RegOwner");
4296     RegDeleteValueA(propkey, "InstanceType");
4297     RegDeleteValueA(propkey, "Transforms");
4298     RegDeleteValueA(propkey, "Language");
4299     RegDeleteValueA(propkey, "ProductName");
4300     RegDeleteValueA(propkey, "Assignment");
4301     RegDeleteValueA(propkey, "PackageCode");
4302     RegDeleteValueA(propkey, "Version");
4303     RegDeleteValueA(propkey, "ProductIcon");
4304     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4305     delete_key(propkey, "", access & KEY_WOW64_64KEY);
4306     delete_key(localkey, "", access & KEY_WOW64_64KEY);
4307     RegDeleteValueA(prodkey, "InstanceType");
4308     RegDeleteValueA(prodkey, "Transforms");
4309     RegDeleteValueA(prodkey, "Language");
4310     RegDeleteValueA(prodkey, "ProductName");
4311     RegDeleteValueA(prodkey, "Assignment");
4312     RegDeleteValueA(prodkey, "PackageCode");
4313     RegDeleteValueA(prodkey, "Version");
4314     RegDeleteValueA(prodkey, "ProductIcon");
4315     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4316     RegDeleteValueA(source, "PackageName");
4317     delete_key(source, "", access & KEY_WOW64_64KEY);
4318     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4319     RegCloseKey(propkey);
4320     RegCloseKey(localkey);
4321     RegCloseKey(source);
4322     RegCloseKey(prodkey);
4323     LocalFree(usersid);
4324 }
4325
4326 static void test_MsiGetProductInfoEx(void)
4327 {
4328     UINT r;
4329     LONG res;
4330     HKEY propkey, userkey;
4331     HKEY prodkey, localkey;
4332     CHAR prodcode[MAX_PATH];
4333     CHAR prod_squashed[MAX_PATH];
4334     CHAR packcode[MAX_PATH];
4335     CHAR pack_squashed[MAX_PATH];
4336     CHAR buf[MAX_PATH];
4337     CHAR keypath[MAX_PATH];
4338     LPSTR usersid;
4339     DWORD sz;
4340     REGSAM access = KEY_ALL_ACCESS;
4341
4342     if (!pMsiGetProductInfoExA)
4343     {
4344         win_skip("MsiGetProductInfoExA is not available\n");
4345         return;
4346     }
4347
4348     create_test_guid(prodcode, prod_squashed);
4349     create_test_guid(packcode, pack_squashed);
4350     usersid = get_user_sid();
4351
4352     if (is_wow64)
4353         access |= KEY_WOW64_64KEY;
4354
4355     /* NULL szProductCode */
4356     sz = MAX_PATH;
4357     lstrcpyA(buf, "apple");
4358     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4359                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4360     ok(r == ERROR_INVALID_PARAMETER,
4361        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4362     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4363     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4364
4365     /* empty szProductCode */
4366     sz = MAX_PATH;
4367     lstrcpyA(buf, "apple");
4368     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4369                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4370     ok(r == ERROR_INVALID_PARAMETER,
4371        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4372     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4373     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4374
4375     /* garbage szProductCode */
4376     sz = MAX_PATH;
4377     lstrcpyA(buf, "apple");
4378     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4379                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4380     ok(r == ERROR_INVALID_PARAMETER,
4381        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4382     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4383     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4384
4385     /* guid without brackets */
4386     sz = MAX_PATH;
4387     lstrcpyA(buf, "apple");
4388     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4389                               MSIINSTALLCONTEXT_USERUNMANAGED,
4390                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4391     ok(r == ERROR_INVALID_PARAMETER,
4392        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4393     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4394     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4395
4396     /* guid with brackets */
4397     sz = MAX_PATH;
4398     lstrcpyA(buf, "apple");
4399     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4400                               MSIINSTALLCONTEXT_USERUNMANAGED,
4401                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4402     ok(r == ERROR_UNKNOWN_PRODUCT,
4403        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4404     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4405     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4406
4407     /* szValue is non-NULL while pcchValue is NULL */
4408     lstrcpyA(buf, "apple");
4409     r = pMsiGetProductInfoExA(prodcode, usersid,
4410                               MSIINSTALLCONTEXT_USERUNMANAGED,
4411                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4412     ok(r == ERROR_INVALID_PARAMETER,
4413        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4414     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4415
4416     /* dwContext is out of range */
4417     sz = MAX_PATH;
4418     lstrcpyA(buf, "apple");
4419     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4420                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4421     ok(r == ERROR_INVALID_PARAMETER,
4422        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4423     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4424     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4425
4426     /* szProperty is NULL */
4427     sz = MAX_PATH;
4428     lstrcpyA(buf, "apple");
4429     r = pMsiGetProductInfoExA(prodcode, usersid,
4430                               MSIINSTALLCONTEXT_USERUNMANAGED,
4431                               NULL, buf, &sz);
4432     ok(r == ERROR_INVALID_PARAMETER,
4433        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4434     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4435     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4436
4437     /* szProperty is empty */
4438     sz = MAX_PATH;
4439     lstrcpyA(buf, "apple");
4440     r = pMsiGetProductInfoExA(prodcode, usersid,
4441                               MSIINSTALLCONTEXT_USERUNMANAGED,
4442                               "", buf, &sz);
4443     ok(r == ERROR_INVALID_PARAMETER,
4444        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4445     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4446     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4447
4448     /* szProperty is not a valid property */
4449     sz = MAX_PATH;
4450     lstrcpyA(buf, "apple");
4451     r = pMsiGetProductInfoExA(prodcode, usersid,
4452                               MSIINSTALLCONTEXT_USERUNMANAGED,
4453                               "notvalid", buf, &sz);
4454     ok(r == ERROR_UNKNOWN_PRODUCT,
4455        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4456     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4457     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4458
4459     /* same length as guid, but random */
4460     sz = MAX_PATH;
4461     lstrcpyA(buf, "apple");
4462     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4463                               MSIINSTALLCONTEXT_USERUNMANAGED,
4464                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4465     ok(r == ERROR_INVALID_PARAMETER,
4466        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4467     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4468     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4469
4470     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4471
4472     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4473     lstrcatA(keypath, usersid);
4474     lstrcatA(keypath, "\\Products\\");
4475     lstrcatA(keypath, prod_squashed);
4476
4477     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4478     if (res == ERROR_ACCESS_DENIED)
4479     {
4480         skip("Not enough rights to perform tests\n");
4481         LocalFree(usersid);
4482         return;
4483     }
4484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4485
4486     /* local user product key exists */
4487     sz = MAX_PATH;
4488     lstrcpyA(buf, "apple");
4489     r = pMsiGetProductInfoExA(prodcode, usersid,
4490                               MSIINSTALLCONTEXT_USERUNMANAGED,
4491                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4492     ok(r == ERROR_UNKNOWN_PRODUCT,
4493        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4494     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4495     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4496
4497     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4499
4500     /* InstallProperties key exists */
4501     sz = MAX_PATH;
4502     lstrcpyA(buf, "apple");
4503     r = pMsiGetProductInfoExA(prodcode, usersid,
4504                               MSIINSTALLCONTEXT_USERUNMANAGED,
4505                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4506     ok(r == ERROR_UNKNOWN_PRODUCT,
4507        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4508     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4509     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4510
4511     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4513
4514     /* LocalPackage value exists */
4515     sz = MAX_PATH;
4516     lstrcpyA(buf, "apple");
4517     r = pMsiGetProductInfoExA(prodcode, usersid,
4518                               MSIINSTALLCONTEXT_USERUNMANAGED,
4519                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4521     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4522     ok(sz == 1, "Expected 1, got %d\n", sz);
4523
4524     RegDeleteValueA(propkey, "LocalPackage");
4525
4526     /* LocalPackage value must exist */
4527     sz = MAX_PATH;
4528     lstrcpyA(buf, "apple");
4529     r = pMsiGetProductInfoExA(prodcode, usersid,
4530                               MSIINSTALLCONTEXT_USERUNMANAGED,
4531                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4532     ok(r == ERROR_UNKNOWN_PRODUCT,
4533        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4534     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4535     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4536
4537     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4539
4540     /* LocalPackage exists, but HelpLink does not exist */
4541     sz = MAX_PATH;
4542     lstrcpyA(buf, "apple");
4543     r = pMsiGetProductInfoExA(prodcode, usersid,
4544                               MSIINSTALLCONTEXT_USERUNMANAGED,
4545                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4546     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4547     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4548     ok(sz == 0, "Expected 0, got %d\n", sz);
4549
4550     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4551     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4552
4553     /* HelpLink value exists */
4554     sz = MAX_PATH;
4555     lstrcpyA(buf, "apple");
4556     r = pMsiGetProductInfoExA(prodcode, usersid,
4557                               MSIINSTALLCONTEXT_USERUNMANAGED,
4558                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4559     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4560     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4561     ok(sz == 4, "Expected 4, got %d\n", sz);
4562
4563     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4564     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4565
4566     /* HelpTelephone value exists */
4567     sz = MAX_PATH;
4568     lstrcpyA(buf, "apple");
4569     r = pMsiGetProductInfoExA(prodcode, usersid,
4570                               MSIINSTALLCONTEXT_USERUNMANAGED,
4571                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4573     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4574     ok(sz == 5, "Expected 5, got %d\n", sz);
4575
4576     /* szValue and pcchValue are NULL */
4577     r = pMsiGetProductInfoExA(prodcode, usersid,
4578                               MSIINSTALLCONTEXT_USERUNMANAGED,
4579                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4580     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4581
4582     /* pcchValue is exactly 5 */
4583     sz = 5;
4584     lstrcpyA(buf, "apple");
4585     r = pMsiGetProductInfoExA(prodcode, usersid,
4586                               MSIINSTALLCONTEXT_USERUNMANAGED,
4587                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4588     ok(r == ERROR_MORE_DATA,
4589        "Expected ERROR_MORE_DATA, got %d\n", r);
4590     ok(sz == 10, "Expected 10, got %d\n", sz);
4591
4592     /* szValue is NULL, pcchValue is exactly 5 */
4593     sz = 5;
4594     r = pMsiGetProductInfoExA(prodcode, usersid,
4595                               MSIINSTALLCONTEXT_USERUNMANAGED,
4596                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4597     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4598     ok(sz == 10, "Expected 10, got %d\n", sz);
4599
4600     /* szValue is NULL, pcchValue is MAX_PATH */
4601     sz = MAX_PATH;
4602     r = pMsiGetProductInfoExA(prodcode, usersid,
4603                               MSIINSTALLCONTEXT_USERUNMANAGED,
4604                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4606     ok(sz == 10, "Expected 10, got %d\n", sz);
4607
4608     /* pcchValue is exactly 0 */
4609     sz = 0;
4610     lstrcpyA(buf, "apple");
4611     r = pMsiGetProductInfoExA(prodcode, usersid,
4612                               MSIINSTALLCONTEXT_USERUNMANAGED,
4613                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4614     ok(r == ERROR_MORE_DATA,
4615        "Expected ERROR_MORE_DATA, got %d\n", r);
4616     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4617     ok(sz == 10, "Expected 10, got %d\n", sz);
4618
4619     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4621
4622     /* szProperty is not a valid property */
4623     sz = MAX_PATH;
4624     lstrcpyA(buf, "apple");
4625     r = pMsiGetProductInfoExA(prodcode, usersid,
4626                               MSIINSTALLCONTEXT_USERUNMANAGED,
4627                               "notvalid", buf, &sz);
4628     ok(r == ERROR_UNKNOWN_PROPERTY,
4629        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4630     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4631     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4632
4633     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4635
4636     /* InstallDate value exists */
4637     sz = MAX_PATH;
4638     lstrcpyA(buf, "apple");
4639     r = pMsiGetProductInfoExA(prodcode, usersid,
4640                               MSIINSTALLCONTEXT_USERUNMANAGED,
4641                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4642     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4643     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4644     ok(sz == 4, "Expected 4, got %d\n", sz);
4645
4646     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4648
4649     /* DisplayName value exists */
4650     sz = MAX_PATH;
4651     lstrcpyA(buf, "apple");
4652     r = pMsiGetProductInfoExA(prodcode, usersid,
4653                               MSIINSTALLCONTEXT_USERUNMANAGED,
4654                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4655     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4656     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4657     ok(sz == 4, "Expected 4, got %d\n", sz);
4658
4659     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4661
4662     /* InstallLocation value exists */
4663     sz = MAX_PATH;
4664     lstrcpyA(buf, "apple");
4665     r = pMsiGetProductInfoExA(prodcode, usersid,
4666                               MSIINSTALLCONTEXT_USERUNMANAGED,
4667                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4669     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4670     ok(sz == 3, "Expected 3, got %d\n", sz);
4671
4672     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4674
4675     /* InstallSource value exists */
4676     sz = MAX_PATH;
4677     lstrcpyA(buf, "apple");
4678     r = pMsiGetProductInfoExA(prodcode, usersid,
4679                               MSIINSTALLCONTEXT_USERUNMANAGED,
4680                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4681     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4682     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4683     ok(sz == 6, "Expected 6, got %d\n", sz);
4684
4685     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4687
4688     /* LocalPackage value exists */
4689     sz = MAX_PATH;
4690     lstrcpyA(buf, "apple");
4691     r = pMsiGetProductInfoExA(prodcode, usersid,
4692                               MSIINSTALLCONTEXT_USERUNMANAGED,
4693                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4694     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4695     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4696     ok(sz == 5, "Expected 5, got %d\n", sz);
4697
4698     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4700
4701     /* Publisher value exists */
4702     sz = MAX_PATH;
4703     lstrcpyA(buf, "apple");
4704     r = pMsiGetProductInfoExA(prodcode, usersid,
4705                               MSIINSTALLCONTEXT_USERUNMANAGED,
4706                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4708     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4709     ok(sz == 3, "Expected 3, got %d\n", sz);
4710
4711     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4713
4714     /* URLInfoAbout value exists */
4715     sz = MAX_PATH;
4716     lstrcpyA(buf, "apple");
4717     r = pMsiGetProductInfoExA(prodcode, usersid,
4718                               MSIINSTALLCONTEXT_USERUNMANAGED,
4719                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4720     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4721     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4722     ok(sz == 5, "Expected 5, got %d\n", sz);
4723
4724     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4726
4727     /* URLUpdateInfo value exists */
4728     sz = MAX_PATH;
4729     lstrcpyA(buf, "apple");
4730     r = pMsiGetProductInfoExA(prodcode, usersid,
4731                               MSIINSTALLCONTEXT_USERUNMANAGED,
4732                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4734     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4735     ok(sz == 6, "Expected 6, got %d\n", sz);
4736
4737     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4739
4740     /* VersionMinor value exists */
4741     sz = MAX_PATH;
4742     lstrcpyA(buf, "apple");
4743     r = pMsiGetProductInfoExA(prodcode, usersid,
4744                               MSIINSTALLCONTEXT_USERUNMANAGED,
4745                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4747     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4748     ok(sz == 1, "Expected 1, got %d\n", sz);
4749
4750     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4752
4753     /* VersionMajor value exists */
4754     sz = MAX_PATH;
4755     lstrcpyA(buf, "apple");
4756     r = pMsiGetProductInfoExA(prodcode, usersid,
4757                               MSIINSTALLCONTEXT_USERUNMANAGED,
4758                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4759     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4760     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4761     ok(sz == 1, "Expected 1, got %d\n", sz);
4762
4763     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4765
4766     /* DisplayVersion value exists */
4767     sz = MAX_PATH;
4768     lstrcpyA(buf, "apple");
4769     r = pMsiGetProductInfoExA(prodcode, usersid,
4770                               MSIINSTALLCONTEXT_USERUNMANAGED,
4771                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4772     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4773     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4774     ok(sz == 5, "Expected 5, got %d\n", sz);
4775
4776     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4778
4779     /* ProductID value exists */
4780     sz = MAX_PATH;
4781     lstrcpyA(buf, "apple");
4782     r = pMsiGetProductInfoExA(prodcode, usersid,
4783                               MSIINSTALLCONTEXT_USERUNMANAGED,
4784                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4786     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4787     ok(sz == 2, "Expected 2, got %d\n", sz);
4788
4789     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4790     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4791
4792     /* RegCompany value exists */
4793     sz = MAX_PATH;
4794     lstrcpyA(buf, "apple");
4795     r = pMsiGetProductInfoExA(prodcode, usersid,
4796                               MSIINSTALLCONTEXT_USERUNMANAGED,
4797                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4798     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4799     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4800     ok(sz == 4, "Expected 4, got %d\n", sz);
4801
4802     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4803     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4804
4805     /* RegOwner value exists */
4806     sz = MAX_PATH;
4807     lstrcpyA(buf, "apple");
4808     r = pMsiGetProductInfoExA(prodcode, usersid,
4809                               MSIINSTALLCONTEXT_USERUNMANAGED,
4810                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4812     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4813     ok(sz == 5, "Expected 5, got %d\n", sz);
4814
4815     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4816     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4817
4818     /* Transforms value exists */
4819     sz = MAX_PATH;
4820     lstrcpyA(buf, "apple");
4821     r = pMsiGetProductInfoExA(prodcode, usersid,
4822                               MSIINSTALLCONTEXT_USERUNMANAGED,
4823                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4824     ok(r == ERROR_UNKNOWN_PRODUCT,
4825        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4826     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4827     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4828
4829     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4830     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4831
4832     /* Language value exists */
4833     sz = MAX_PATH;
4834     lstrcpyA(buf, "apple");
4835     r = pMsiGetProductInfoExA(prodcode, usersid,
4836                               MSIINSTALLCONTEXT_USERUNMANAGED,
4837                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4838     ok(r == ERROR_UNKNOWN_PRODUCT,
4839        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4840     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4841     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4842
4843     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4845
4846     /* ProductName value exists */
4847     sz = MAX_PATH;
4848     lstrcpyA(buf, "apple");
4849     r = pMsiGetProductInfoExA(prodcode, usersid,
4850                               MSIINSTALLCONTEXT_USERUNMANAGED,
4851                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4852     ok(r == ERROR_UNKNOWN_PRODUCT,
4853        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4854     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4855     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4856
4857     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4858     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4859
4860     /* FIXME */
4861
4862     /* AssignmentType value exists */
4863     sz = MAX_PATH;
4864     lstrcpyA(buf, "apple");
4865     r = pMsiGetProductInfoExA(prodcode, usersid,
4866                               MSIINSTALLCONTEXT_USERUNMANAGED,
4867                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4868     ok(r == ERROR_UNKNOWN_PRODUCT,
4869        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4870     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4871     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4872
4873     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4874     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4875
4876     /* PackageCode value exists */
4877     sz = MAX_PATH;
4878     lstrcpyA(buf, "apple");
4879     r = pMsiGetProductInfoExA(prodcode, usersid,
4880                               MSIINSTALLCONTEXT_USERUNMANAGED,
4881                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4882     ok(r == ERROR_UNKNOWN_PRODUCT,
4883        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4884     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4885     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4886
4887     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4889
4890     /* Version value exists */
4891     sz = MAX_PATH;
4892     lstrcpyA(buf, "apple");
4893     r = pMsiGetProductInfoExA(prodcode, usersid,
4894                               MSIINSTALLCONTEXT_USERUNMANAGED,
4895                               INSTALLPROPERTY_VERSION, buf, &sz);
4896     ok(r == ERROR_UNKNOWN_PRODUCT,
4897        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4898     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4899     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4900
4901     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4903
4904     /* ProductIcon value exists */
4905     sz = MAX_PATH;
4906     lstrcpyA(buf, "apple");
4907     r = pMsiGetProductInfoExA(prodcode, usersid,
4908                               MSIINSTALLCONTEXT_USERUNMANAGED,
4909                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4910     ok(r == ERROR_UNKNOWN_PRODUCT,
4911        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4912     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4913     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4914
4915     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4917
4918     /* PackageName value exists */
4919     sz = MAX_PATH;
4920     lstrcpyA(buf, "apple");
4921     r = pMsiGetProductInfoExA(prodcode, usersid,
4922                               MSIINSTALLCONTEXT_USERUNMANAGED,
4923                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4924     ok(r == ERROR_UNKNOWN_PRODUCT,
4925        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4926     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4927     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4928
4929     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4931
4932     /* AuthorizedLUAApp value exists */
4933     sz = MAX_PATH;
4934     lstrcpyA(buf, "apple");
4935     r = pMsiGetProductInfoExA(prodcode, usersid,
4936                               MSIINSTALLCONTEXT_USERUNMANAGED,
4937                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4938     ok(r == ERROR_UNKNOWN_PRODUCT,
4939        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4940     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4941     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4942
4943     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4944     RegDeleteValueA(propkey, "PackageName");
4945     RegDeleteValueA(propkey, "ProductIcon");
4946     RegDeleteValueA(propkey, "Version");
4947     RegDeleteValueA(propkey, "PackageCode");
4948     RegDeleteValueA(propkey, "AssignmentType");
4949     RegDeleteValueA(propkey, "ProductName");
4950     RegDeleteValueA(propkey, "Language");
4951     RegDeleteValueA(propkey, "Transforms");
4952     RegDeleteValueA(propkey, "RegOwner");
4953     RegDeleteValueA(propkey, "RegCompany");
4954     RegDeleteValueA(propkey, "ProductID");
4955     RegDeleteValueA(propkey, "DisplayVersion");
4956     RegDeleteValueA(propkey, "VersionMajor");
4957     RegDeleteValueA(propkey, "VersionMinor");
4958     RegDeleteValueA(propkey, "URLUpdateInfo");
4959     RegDeleteValueA(propkey, "URLInfoAbout");
4960     RegDeleteValueA(propkey, "Publisher");
4961     RegDeleteValueA(propkey, "LocalPackage");
4962     RegDeleteValueA(propkey, "InstallSource");
4963     RegDeleteValueA(propkey, "InstallLocation");
4964     RegDeleteValueA(propkey, "DisplayName");
4965     RegDeleteValueA(propkey, "InstallDate");
4966     RegDeleteValueA(propkey, "HelpTelephone");
4967     RegDeleteValueA(propkey, "HelpLink");
4968     RegDeleteValueA(propkey, "LocalPackage");
4969     RegDeleteKeyA(propkey, "");
4970     RegCloseKey(propkey);
4971     RegDeleteKeyA(localkey, "");
4972     RegCloseKey(localkey);
4973
4974     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4975     lstrcatA(keypath, usersid);
4976     lstrcatA(keypath, "\\Installer\\Products\\");
4977     lstrcatA(keypath, prod_squashed);
4978
4979     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
4980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4981
4982     /* user product key exists */
4983     sz = MAX_PATH;
4984     lstrcpyA(buf, "apple");
4985     r = pMsiGetProductInfoExA(prodcode, usersid,
4986                               MSIINSTALLCONTEXT_USERUNMANAGED,
4987                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4988     ok(r == ERROR_UNKNOWN_PRODUCT,
4989        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4990     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4991     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4992
4993     RegDeleteKeyA(userkey, "");
4994     RegCloseKey(userkey);
4995
4996     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4997     lstrcatA(keypath, prod_squashed);
4998
4999     res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
5000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5001
5002     sz = MAX_PATH;
5003     lstrcpyA(buf, "apple");
5004     r = pMsiGetProductInfoExA(prodcode, usersid,
5005                               MSIINSTALLCONTEXT_USERUNMANAGED,
5006                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5007     ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
5008     if (r == ERROR_UNKNOWN_PRODUCT)
5009     {
5010         win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
5011         delete_key(prodkey, "", access);
5012         RegCloseKey(prodkey);
5013         return;
5014     }
5015     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5016     ok(sz == 1, "Expected 1, got %d\n", sz);
5017
5018     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5020
5021     /* HelpLink value exists */
5022     sz = MAX_PATH;
5023     lstrcpyA(buf, "apple");
5024     r = pMsiGetProductInfoExA(prodcode, usersid,
5025                               MSIINSTALLCONTEXT_USERUNMANAGED,
5026                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5027     ok(r == ERROR_UNKNOWN_PROPERTY,
5028        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5029     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5030     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5031
5032     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5034
5035     /* HelpTelephone value exists */
5036     sz = MAX_PATH;
5037     lstrcpyA(buf, "apple");
5038     r = pMsiGetProductInfoExA(prodcode, usersid,
5039                               MSIINSTALLCONTEXT_USERUNMANAGED,
5040                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5041     ok(r == ERROR_UNKNOWN_PROPERTY,
5042        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5043     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5044     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5045
5046     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5048
5049     /* InstallDate value exists */
5050     sz = MAX_PATH;
5051     lstrcpyA(buf, "apple");
5052     r = pMsiGetProductInfoExA(prodcode, usersid,
5053                               MSIINSTALLCONTEXT_USERUNMANAGED,
5054                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5055     ok(r == ERROR_UNKNOWN_PROPERTY,
5056        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5057     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5058     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5059
5060     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5062
5063     /* DisplayName value exists */
5064     sz = MAX_PATH;
5065     lstrcpyA(buf, "apple");
5066     r = pMsiGetProductInfoExA(prodcode, usersid,
5067                               MSIINSTALLCONTEXT_USERUNMANAGED,
5068                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5069     ok(r == ERROR_UNKNOWN_PROPERTY,
5070        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5071     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5072     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5073
5074     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5076
5077     /* InstallLocation value exists */
5078     sz = MAX_PATH;
5079     lstrcpyA(buf, "apple");
5080     r = pMsiGetProductInfoExA(prodcode, usersid,
5081                               MSIINSTALLCONTEXT_USERUNMANAGED,
5082                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5083     ok(r == ERROR_UNKNOWN_PROPERTY,
5084        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5085     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5086     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5087
5088     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5090
5091     /* InstallSource value exists */
5092     sz = MAX_PATH;
5093     lstrcpyA(buf, "apple");
5094     r = pMsiGetProductInfoExA(prodcode, usersid,
5095                               MSIINSTALLCONTEXT_USERUNMANAGED,
5096                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5097     ok(r == ERROR_UNKNOWN_PROPERTY,
5098        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5099     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5100     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5101
5102     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5103     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5104
5105     /* LocalPackage value exists */
5106     sz = MAX_PATH;
5107     lstrcpyA(buf, "apple");
5108     r = pMsiGetProductInfoExA(prodcode, usersid,
5109                               MSIINSTALLCONTEXT_USERUNMANAGED,
5110                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5111     ok(r == ERROR_UNKNOWN_PROPERTY,
5112        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5113     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5114     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5115
5116     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5118
5119     /* Publisher value exists */
5120     sz = MAX_PATH;
5121     lstrcpyA(buf, "apple");
5122     r = pMsiGetProductInfoExA(prodcode, usersid,
5123                               MSIINSTALLCONTEXT_USERUNMANAGED,
5124                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5125     ok(r == ERROR_UNKNOWN_PROPERTY,
5126        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5127     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5128     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5129
5130     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5132
5133     /* URLInfoAbout value exists */
5134     sz = MAX_PATH;
5135     lstrcpyA(buf, "apple");
5136     r = pMsiGetProductInfoExA(prodcode, usersid,
5137                               MSIINSTALLCONTEXT_USERUNMANAGED,
5138                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5139     ok(r == ERROR_UNKNOWN_PROPERTY,
5140        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5141     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5142     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5143
5144     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5146
5147     /* URLUpdateInfo value exists */
5148     sz = MAX_PATH;
5149     lstrcpyA(buf, "apple");
5150     r = pMsiGetProductInfoExA(prodcode, usersid,
5151                               MSIINSTALLCONTEXT_USERUNMANAGED,
5152                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5153     ok(r == ERROR_UNKNOWN_PROPERTY,
5154        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5155     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5156     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5157
5158     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5159     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5160
5161     /* VersionMinor value exists */
5162     sz = MAX_PATH;
5163     lstrcpyA(buf, "apple");
5164     r = pMsiGetProductInfoExA(prodcode, usersid,
5165                               MSIINSTALLCONTEXT_USERUNMANAGED,
5166                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5167     ok(r == ERROR_UNKNOWN_PROPERTY,
5168        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5169     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5170     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5171
5172     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5174
5175     /* VersionMajor value exists */
5176     sz = MAX_PATH;
5177     lstrcpyA(buf, "apple");
5178     r = pMsiGetProductInfoExA(prodcode, usersid,
5179                               MSIINSTALLCONTEXT_USERUNMANAGED,
5180                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5181     ok(r == ERROR_UNKNOWN_PROPERTY,
5182        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5183     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5184     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5185
5186     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5188
5189     /* DisplayVersion value exists */
5190     sz = MAX_PATH;
5191     lstrcpyA(buf, "apple");
5192     r = pMsiGetProductInfoExA(prodcode, usersid,
5193                               MSIINSTALLCONTEXT_USERUNMANAGED,
5194                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5195     ok(r == ERROR_UNKNOWN_PROPERTY,
5196        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5197     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5198     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5199
5200     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5202
5203     /* ProductID value exists */
5204     sz = MAX_PATH;
5205     lstrcpyA(buf, "apple");
5206     r = pMsiGetProductInfoExA(prodcode, usersid,
5207                               MSIINSTALLCONTEXT_USERUNMANAGED,
5208                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5209     ok(r == ERROR_UNKNOWN_PROPERTY,
5210        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5211     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5212     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5213
5214     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5216
5217     /* RegCompany value exists */
5218     sz = MAX_PATH;
5219     lstrcpyA(buf, "apple");
5220     r = pMsiGetProductInfoExA(prodcode, usersid,
5221                               MSIINSTALLCONTEXT_USERUNMANAGED,
5222                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5223     ok(r == ERROR_UNKNOWN_PROPERTY,
5224        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5225     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5226     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5227
5228     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5229     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5230
5231     /* RegOwner value exists */
5232     sz = MAX_PATH;
5233     lstrcpyA(buf, "apple");
5234     r = pMsiGetProductInfoExA(prodcode, usersid,
5235                               MSIINSTALLCONTEXT_USERUNMANAGED,
5236                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5237     ok(r == ERROR_UNKNOWN_PROPERTY,
5238        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5239     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5240     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5241
5242     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5244
5245     /* Transforms value exists */
5246     sz = MAX_PATH;
5247     lstrcpyA(buf, "apple");
5248     r = pMsiGetProductInfoExA(prodcode, usersid,
5249                               MSIINSTALLCONTEXT_USERUNMANAGED,
5250                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5252     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5253     ok(sz == 5, "Expected 5, got %d\n", sz);
5254
5255     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5257
5258     /* Language value exists */
5259     sz = MAX_PATH;
5260     lstrcpyA(buf, "apple");
5261     r = pMsiGetProductInfoExA(prodcode, usersid,
5262                               MSIINSTALLCONTEXT_USERUNMANAGED,
5263                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5264     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5265     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5266     ok(sz == 4, "Expected 4, got %d\n", sz);
5267
5268     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5270
5271     /* ProductName value exists */
5272     sz = MAX_PATH;
5273     lstrcpyA(buf, "apple");
5274     r = pMsiGetProductInfoExA(prodcode, usersid,
5275                               MSIINSTALLCONTEXT_USERUNMANAGED,
5276                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5278     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5279     ok(sz == 4, "Expected 4, got %d\n", sz);
5280
5281     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5283
5284     /* FIXME */
5285
5286     /* AssignmentType value exists */
5287     sz = MAX_PATH;
5288     lstrcpyA(buf, "apple");
5289     r = pMsiGetProductInfoExA(prodcode, usersid,
5290                               MSIINSTALLCONTEXT_USERUNMANAGED,
5291                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5292     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5293     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5294     ok(sz == 0, "Expected 0, got %d\n", sz);
5295
5296     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5298
5299     /* FIXME */
5300
5301     /* PackageCode value exists */
5302     sz = MAX_PATH;
5303     lstrcpyA(buf, "apple");
5304     r = pMsiGetProductInfoExA(prodcode, usersid,
5305                               MSIINSTALLCONTEXT_USERUNMANAGED,
5306                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5307     todo_wine
5308     {
5309         ok(r == ERROR_BAD_CONFIGURATION,
5310            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5311         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5312         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5313     }
5314
5315     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5317
5318     /* Version value exists */
5319     sz = MAX_PATH;
5320     lstrcpyA(buf, "apple");
5321     r = pMsiGetProductInfoExA(prodcode, usersid,
5322                               MSIINSTALLCONTEXT_USERUNMANAGED,
5323                               INSTALLPROPERTY_VERSION, buf, &sz);
5324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5325     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5326     ok(sz == 3, "Expected 3, got %d\n", sz);
5327
5328     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5330
5331     /* ProductIcon value exists */
5332     sz = MAX_PATH;
5333     lstrcpyA(buf, "apple");
5334     r = pMsiGetProductInfoExA(prodcode, usersid,
5335                               MSIINSTALLCONTEXT_USERUNMANAGED,
5336                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5338     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5339     ok(sz == 4, "Expected 4, got %d\n", sz);
5340
5341     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5343
5344     /* PackageName value exists */
5345     sz = MAX_PATH;
5346     lstrcpyA(buf, "apple");
5347     r = pMsiGetProductInfoExA(prodcode, usersid,
5348                               MSIINSTALLCONTEXT_USERUNMANAGED,
5349                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5350     todo_wine
5351     {
5352         ok(r == ERROR_UNKNOWN_PRODUCT,
5353            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5354         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5355         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5356     }
5357
5358     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5359     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5360
5361     /* AuthorizedLUAApp value exists */
5362     sz = MAX_PATH;
5363     lstrcpyA(buf, "apple");
5364     r = pMsiGetProductInfoExA(prodcode, usersid,
5365                               MSIINSTALLCONTEXT_USERUNMANAGED,
5366                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5367     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5368     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5369     ok(sz == 4, "Expected 4, got %d\n", sz);
5370
5371     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5372     RegDeleteValueA(prodkey, "PackageName");
5373     RegDeleteValueA(prodkey, "ProductIcon");
5374     RegDeleteValueA(prodkey, "Version");
5375     RegDeleteValueA(prodkey, "PackageCode");
5376     RegDeleteValueA(prodkey, "AssignmentType");
5377     RegDeleteValueA(prodkey, "ProductName");
5378     RegDeleteValueA(prodkey, "Language");
5379     RegDeleteValueA(prodkey, "Transforms");
5380     RegDeleteValueA(prodkey, "RegOwner");
5381     RegDeleteValueA(prodkey, "RegCompany");
5382     RegDeleteValueA(prodkey, "ProductID");
5383     RegDeleteValueA(prodkey, "DisplayVersion");
5384     RegDeleteValueA(prodkey, "VersionMajor");
5385     RegDeleteValueA(prodkey, "VersionMinor");
5386     RegDeleteValueA(prodkey, "URLUpdateInfo");
5387     RegDeleteValueA(prodkey, "URLInfoAbout");
5388     RegDeleteValueA(prodkey, "Publisher");
5389     RegDeleteValueA(prodkey, "LocalPackage");
5390     RegDeleteValueA(prodkey, "InstallSource");
5391     RegDeleteValueA(prodkey, "InstallLocation");
5392     RegDeleteValueA(prodkey, "DisplayName");
5393     RegDeleteValueA(prodkey, "InstallDate");
5394     RegDeleteValueA(prodkey, "HelpTelephone");
5395     RegDeleteValueA(prodkey, "HelpLink");
5396     RegDeleteValueA(prodkey, "LocalPackage");
5397     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5398     RegCloseKey(prodkey);
5399
5400     /* MSIINSTALLCONTEXT_USERMANAGED */
5401
5402     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5403     lstrcatA(keypath, usersid);
5404     lstrcatA(keypath, "\\Products\\");
5405     lstrcatA(keypath, prod_squashed);
5406
5407     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5409
5410     /* local user product key exists */
5411     sz = MAX_PATH;
5412     lstrcpyA(buf, "apple");
5413     r = pMsiGetProductInfoExA(prodcode, usersid,
5414                               MSIINSTALLCONTEXT_USERMANAGED,
5415                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5416     ok(r == ERROR_UNKNOWN_PRODUCT,
5417        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5418     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5419     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5420
5421     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5423
5424     /* InstallProperties key exists */
5425     sz = MAX_PATH;
5426     lstrcpyA(buf, "apple");
5427     r = pMsiGetProductInfoExA(prodcode, usersid,
5428                               MSIINSTALLCONTEXT_USERMANAGED,
5429                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5430     ok(r == ERROR_UNKNOWN_PRODUCT,
5431        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5432     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5433     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5434
5435     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5437
5438     /* ManagedLocalPackage value exists */
5439     sz = MAX_PATH;
5440     lstrcpyA(buf, "apple");
5441     r = pMsiGetProductInfoExA(prodcode, usersid,
5442                               MSIINSTALLCONTEXT_USERMANAGED,
5443                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5444     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5445     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5446     ok(sz == 1, "Expected 1, got %d\n", sz);
5447
5448     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5449     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5450
5451     /* HelpLink value exists */
5452     sz = MAX_PATH;
5453     lstrcpyA(buf, "apple");
5454     r = pMsiGetProductInfoExA(prodcode, usersid,
5455                               MSIINSTALLCONTEXT_USERMANAGED,
5456                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5458     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5459     ok(sz == 4, "Expected 4, got %d\n", sz);
5460
5461     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5463
5464     /* HelpTelephone value exists */
5465     sz = MAX_PATH;
5466     lstrcpyA(buf, "apple");
5467     r = pMsiGetProductInfoExA(prodcode, usersid,
5468                               MSIINSTALLCONTEXT_USERMANAGED,
5469                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5471     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5472     ok(sz == 5, "Expected 5, got %d\n", sz);
5473
5474     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5476
5477     /* InstallDate value exists */
5478     sz = MAX_PATH;
5479     lstrcpyA(buf, "apple");
5480     r = pMsiGetProductInfoExA(prodcode, usersid,
5481                               MSIINSTALLCONTEXT_USERMANAGED,
5482                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5484     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5485     ok(sz == 4, "Expected 4, got %d\n", sz);
5486
5487     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5488     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5489
5490     /* DisplayName value exists */
5491     sz = MAX_PATH;
5492     lstrcpyA(buf, "apple");
5493     r = pMsiGetProductInfoExA(prodcode, usersid,
5494                               MSIINSTALLCONTEXT_USERMANAGED,
5495                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5496     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5497     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5498     ok(sz == 4, "Expected 4, got %d\n", sz);
5499
5500     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5501     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5502
5503     /* InstallLocation value exists */
5504     sz = MAX_PATH;
5505     lstrcpyA(buf, "apple");
5506     r = pMsiGetProductInfoExA(prodcode, usersid,
5507                               MSIINSTALLCONTEXT_USERMANAGED,
5508                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5510     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5511     ok(sz == 3, "Expected 3, got %d\n", sz);
5512
5513     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5515
5516     /* InstallSource value exists */
5517     sz = MAX_PATH;
5518     lstrcpyA(buf, "apple");
5519     r = pMsiGetProductInfoExA(prodcode, usersid,
5520                               MSIINSTALLCONTEXT_USERMANAGED,
5521                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5522     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5523     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5524     ok(sz == 6, "Expected 6, got %d\n", sz);
5525
5526     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5528
5529     /* LocalPackage value exists */
5530     sz = MAX_PATH;
5531     lstrcpyA(buf, "apple");
5532     r = pMsiGetProductInfoExA(prodcode, usersid,
5533                               MSIINSTALLCONTEXT_USERMANAGED,
5534                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5535     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5536     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5537     ok(sz == 5, "Expected 5, got %d\n", sz);
5538
5539     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5541
5542     /* Publisher value exists */
5543     sz = MAX_PATH;
5544     lstrcpyA(buf, "apple");
5545     r = pMsiGetProductInfoExA(prodcode, usersid,
5546                               MSIINSTALLCONTEXT_USERMANAGED,
5547                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5548     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5549     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5550     ok(sz == 3, "Expected 3, got %d\n", sz);
5551
5552     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5554
5555     /* URLInfoAbout value exists */
5556     sz = MAX_PATH;
5557     lstrcpyA(buf, "apple");
5558     r = pMsiGetProductInfoExA(prodcode, usersid,
5559                               MSIINSTALLCONTEXT_USERMANAGED,
5560                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5562     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5563     ok(sz == 5, "Expected 5, got %d\n", sz);
5564
5565     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5566     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5567
5568     /* URLUpdateInfo value exists */
5569     sz = MAX_PATH;
5570     lstrcpyA(buf, "apple");
5571     r = pMsiGetProductInfoExA(prodcode, usersid,
5572                               MSIINSTALLCONTEXT_USERMANAGED,
5573                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5574     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5575     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5576     ok(sz == 6, "Expected 6, got %d\n", sz);
5577
5578     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5580
5581     /* VersionMinor value exists */
5582     sz = MAX_PATH;
5583     lstrcpyA(buf, "apple");
5584     r = pMsiGetProductInfoExA(prodcode, usersid,
5585                               MSIINSTALLCONTEXT_USERMANAGED,
5586                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5587     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5588     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5589     ok(sz == 1, "Expected 1, got %d\n", sz);
5590
5591     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5593
5594     /* VersionMajor value exists */
5595     sz = MAX_PATH;
5596     lstrcpyA(buf, "apple");
5597     r = pMsiGetProductInfoExA(prodcode, usersid,
5598                               MSIINSTALLCONTEXT_USERMANAGED,
5599                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5600     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5601     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5602     ok(sz == 1, "Expected 1, got %d\n", sz);
5603
5604     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5605     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5606
5607     /* DisplayVersion value exists */
5608     sz = MAX_PATH;
5609     lstrcpyA(buf, "apple");
5610     r = pMsiGetProductInfoExA(prodcode, usersid,
5611                               MSIINSTALLCONTEXT_USERMANAGED,
5612                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5614     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5615     ok(sz == 5, "Expected 5, got %d\n", sz);
5616
5617     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5619
5620     /* ProductID value exists */
5621     sz = MAX_PATH;
5622     lstrcpyA(buf, "apple");
5623     r = pMsiGetProductInfoExA(prodcode, usersid,
5624                               MSIINSTALLCONTEXT_USERMANAGED,
5625                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5626     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5627     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5628     ok(sz == 2, "Expected 2, got %d\n", sz);
5629
5630     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5631     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5632
5633     /* RegCompany value exists */
5634     sz = MAX_PATH;
5635     lstrcpyA(buf, "apple");
5636     r = pMsiGetProductInfoExA(prodcode, usersid,
5637                               MSIINSTALLCONTEXT_USERMANAGED,
5638                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5639     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5640     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5641     ok(sz == 4, "Expected 4, got %d\n", sz);
5642
5643     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5645
5646     /* RegOwner value exists */
5647     sz = MAX_PATH;
5648     lstrcpyA(buf, "apple");
5649     r = pMsiGetProductInfoExA(prodcode, usersid,
5650                               MSIINSTALLCONTEXT_USERMANAGED,
5651                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5652     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5653     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5654     ok(sz == 5, "Expected 5, got %d\n", sz);
5655
5656     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5658
5659     /* Transforms value exists */
5660     sz = MAX_PATH;
5661     lstrcpyA(buf, "apple");
5662     r = pMsiGetProductInfoExA(prodcode, usersid,
5663                               MSIINSTALLCONTEXT_USERMANAGED,
5664                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5665     ok(r == ERROR_UNKNOWN_PRODUCT,
5666        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5667     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5668     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5669
5670     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5671     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5672
5673     /* Language value exists */
5674     sz = MAX_PATH;
5675     lstrcpyA(buf, "apple");
5676     r = pMsiGetProductInfoExA(prodcode, usersid,
5677                               MSIINSTALLCONTEXT_USERMANAGED,
5678                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5679     ok(r == ERROR_UNKNOWN_PRODUCT,
5680        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5681     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5682     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5683
5684     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5686
5687     /* ProductName value exists */
5688     sz = MAX_PATH;
5689     lstrcpyA(buf, "apple");
5690     r = pMsiGetProductInfoExA(prodcode, usersid,
5691                               MSIINSTALLCONTEXT_USERMANAGED,
5692                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5693     ok(r == ERROR_UNKNOWN_PRODUCT,
5694        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5695     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5696     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5697
5698     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5700
5701     /* FIXME */
5702
5703     /* AssignmentType value exists */
5704     sz = MAX_PATH;
5705     lstrcpyA(buf, "apple");
5706     r = pMsiGetProductInfoExA(prodcode, usersid,
5707                               MSIINSTALLCONTEXT_USERMANAGED,
5708                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5709     ok(r == ERROR_UNKNOWN_PRODUCT,
5710        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5711     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5712     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5713
5714     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5716
5717     /* PackageCode value exists */
5718     sz = MAX_PATH;
5719     lstrcpyA(buf, "apple");
5720     r = pMsiGetProductInfoExA(prodcode, usersid,
5721                               MSIINSTALLCONTEXT_USERMANAGED,
5722                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5723     ok(r == ERROR_UNKNOWN_PRODUCT,
5724        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5725     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5726     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5727
5728     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5730
5731     /* Version value exists */
5732     sz = MAX_PATH;
5733     lstrcpyA(buf, "apple");
5734     r = pMsiGetProductInfoExA(prodcode, usersid,
5735                               MSIINSTALLCONTEXT_USERMANAGED,
5736                               INSTALLPROPERTY_VERSION, buf, &sz);
5737     ok(r == ERROR_UNKNOWN_PRODUCT,
5738        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5739     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5740     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5741
5742     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5744
5745     /* ProductIcon value exists */
5746     sz = MAX_PATH;
5747     lstrcpyA(buf, "apple");
5748     r = pMsiGetProductInfoExA(prodcode, usersid,
5749                               MSIINSTALLCONTEXT_USERMANAGED,
5750                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5751     ok(r == ERROR_UNKNOWN_PRODUCT,
5752        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5753     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5754     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5755
5756     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5757     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5758
5759     /* PackageName value exists */
5760     sz = MAX_PATH;
5761     lstrcpyA(buf, "apple");
5762     r = pMsiGetProductInfoExA(prodcode, usersid,
5763                               MSIINSTALLCONTEXT_USERMANAGED,
5764                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5765     ok(r == ERROR_UNKNOWN_PRODUCT,
5766        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5767     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5768     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5769
5770     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5772
5773     /* AuthorizedLUAApp value exists */
5774     sz = MAX_PATH;
5775     lstrcpyA(buf, "apple");
5776     r = pMsiGetProductInfoExA(prodcode, usersid,
5777                               MSIINSTALLCONTEXT_USERMANAGED,
5778                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5779     ok(r == ERROR_UNKNOWN_PRODUCT,
5780        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5781     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5782     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5783
5784     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5785     RegDeleteValueA(propkey, "PackageName");
5786     RegDeleteValueA(propkey, "ProductIcon");
5787     RegDeleteValueA(propkey, "Version");
5788     RegDeleteValueA(propkey, "PackageCode");
5789     RegDeleteValueA(propkey, "AssignmentType");
5790     RegDeleteValueA(propkey, "ProductName");
5791     RegDeleteValueA(propkey, "Language");
5792     RegDeleteValueA(propkey, "Transforms");
5793     RegDeleteValueA(propkey, "RegOwner");
5794     RegDeleteValueA(propkey, "RegCompany");
5795     RegDeleteValueA(propkey, "ProductID");
5796     RegDeleteValueA(propkey, "DisplayVersion");
5797     RegDeleteValueA(propkey, "VersionMajor");
5798     RegDeleteValueA(propkey, "VersionMinor");
5799     RegDeleteValueA(propkey, "URLUpdateInfo");
5800     RegDeleteValueA(propkey, "URLInfoAbout");
5801     RegDeleteValueA(propkey, "Publisher");
5802     RegDeleteValueA(propkey, "LocalPackage");
5803     RegDeleteValueA(propkey, "InstallSource");
5804     RegDeleteValueA(propkey, "InstallLocation");
5805     RegDeleteValueA(propkey, "DisplayName");
5806     RegDeleteValueA(propkey, "InstallDate");
5807     RegDeleteValueA(propkey, "HelpTelephone");
5808     RegDeleteValueA(propkey, "HelpLink");
5809     RegDeleteValueA(propkey, "ManagedLocalPackage");
5810     delete_key(propkey, "", access & KEY_WOW64_64KEY);
5811     RegCloseKey(propkey);
5812     delete_key(localkey, "", access & KEY_WOW64_64KEY);
5813     RegCloseKey(localkey);
5814
5815     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5816     lstrcatA(keypath, usersid);
5817     lstrcatA(keypath, "\\Installer\\Products\\");
5818     lstrcatA(keypath, prod_squashed);
5819
5820     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5821     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5822
5823     /* user product key exists */
5824     sz = MAX_PATH;
5825     lstrcpyA(buf, "apple");
5826     r = pMsiGetProductInfoExA(prodcode, usersid,
5827                               MSIINSTALLCONTEXT_USERMANAGED,
5828                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5829     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5830     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5831     ok(sz == 1, "Expected 1, got %d\n", sz);
5832
5833     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5834     RegCloseKey(userkey);
5835
5836     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5837     lstrcatA(keypath, prod_squashed);
5838
5839     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5841
5842     /* current user product key exists */
5843     sz = MAX_PATH;
5844     lstrcpyA(buf, "apple");
5845     r = pMsiGetProductInfoExA(prodcode, usersid,
5846                               MSIINSTALLCONTEXT_USERMANAGED,
5847                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5848     ok(r == ERROR_UNKNOWN_PRODUCT,
5849        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5850     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5851     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5852
5853     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5854     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5855
5856     /* HelpLink value exists, user product key does not exist */
5857     sz = MAX_PATH;
5858     lstrcpyA(buf, "apple");
5859     r = pMsiGetProductInfoExA(prodcode, usersid,
5860                               MSIINSTALLCONTEXT_USERMANAGED,
5861                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5862     ok(r == ERROR_UNKNOWN_PRODUCT,
5863        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5864     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5865     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5866
5867     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5868     lstrcatA(keypath, usersid);
5869     lstrcatA(keypath, "\\Installer\\Products\\");
5870     lstrcatA(keypath, prod_squashed);
5871
5872     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5874
5875     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5877
5878     /* HelpLink value exists, user product key does exist */
5879     sz = MAX_PATH;
5880     lstrcpyA(buf, "apple");
5881     r = pMsiGetProductInfoExA(prodcode, usersid,
5882                               MSIINSTALLCONTEXT_USERMANAGED,
5883                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5884     ok(r == ERROR_UNKNOWN_PROPERTY,
5885        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5886     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5887     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5888
5889     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5891
5892     /* HelpTelephone value exists */
5893     sz = MAX_PATH;
5894     lstrcpyA(buf, "apple");
5895     r = pMsiGetProductInfoExA(prodcode, usersid,
5896                               MSIINSTALLCONTEXT_USERMANAGED,
5897                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5898     ok(r == ERROR_UNKNOWN_PROPERTY,
5899        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5900     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5901     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5902
5903     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5905
5906     /* InstallDate value exists */
5907     sz = MAX_PATH;
5908     lstrcpyA(buf, "apple");
5909     r = pMsiGetProductInfoExA(prodcode, usersid,
5910                               MSIINSTALLCONTEXT_USERMANAGED,
5911                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5912     ok(r == ERROR_UNKNOWN_PROPERTY,
5913        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5914     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5915     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5916
5917     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5919
5920     /* DisplayName value exists */
5921     sz = MAX_PATH;
5922     lstrcpyA(buf, "apple");
5923     r = pMsiGetProductInfoExA(prodcode, usersid,
5924                               MSIINSTALLCONTEXT_USERMANAGED,
5925                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5926     ok(r == ERROR_UNKNOWN_PROPERTY,
5927        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5928     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5929     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5930
5931     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5933
5934     /* InstallLocation value exists */
5935     sz = MAX_PATH;
5936     lstrcpyA(buf, "apple");
5937     r = pMsiGetProductInfoExA(prodcode, usersid,
5938                               MSIINSTALLCONTEXT_USERMANAGED,
5939                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5940     ok(r == ERROR_UNKNOWN_PROPERTY,
5941        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5942     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5943     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5944
5945     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5947
5948     /* InstallSource value exists */
5949     sz = MAX_PATH;
5950     lstrcpyA(buf, "apple");
5951     r = pMsiGetProductInfoExA(prodcode, usersid,
5952                               MSIINSTALLCONTEXT_USERMANAGED,
5953                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5954     ok(r == ERROR_UNKNOWN_PROPERTY,
5955        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5956     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5957     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5958
5959     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5960     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5961
5962     /* LocalPackage value exists */
5963     sz = MAX_PATH;
5964     lstrcpyA(buf, "apple");
5965     r = pMsiGetProductInfoExA(prodcode, usersid,
5966                               MSIINSTALLCONTEXT_USERMANAGED,
5967                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5968     ok(r == ERROR_UNKNOWN_PROPERTY,
5969        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5970     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5971     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5972
5973     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5975
5976     /* Publisher value exists */
5977     sz = MAX_PATH;
5978     lstrcpyA(buf, "apple");
5979     r = pMsiGetProductInfoExA(prodcode, usersid,
5980                               MSIINSTALLCONTEXT_USERMANAGED,
5981                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5982     ok(r == ERROR_UNKNOWN_PROPERTY,
5983        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5984     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5985     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5986
5987     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5989
5990     /* URLInfoAbout value exists */
5991     sz = MAX_PATH;
5992     lstrcpyA(buf, "apple");
5993     r = pMsiGetProductInfoExA(prodcode, usersid,
5994                               MSIINSTALLCONTEXT_USERMANAGED,
5995                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5996     ok(r == ERROR_UNKNOWN_PROPERTY,
5997        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5998     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5999     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6000
6001     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6003
6004     /* URLUpdateInfo value exists */
6005     sz = MAX_PATH;
6006     lstrcpyA(buf, "apple");
6007     r = pMsiGetProductInfoExA(prodcode, usersid,
6008                               MSIINSTALLCONTEXT_USERMANAGED,
6009                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6010     ok(r == ERROR_UNKNOWN_PROPERTY,
6011        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6012     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6013     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6014
6015     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6017
6018     /* VersionMinor value exists */
6019     sz = MAX_PATH;
6020     lstrcpyA(buf, "apple");
6021     r = pMsiGetProductInfoExA(prodcode, usersid,
6022                               MSIINSTALLCONTEXT_USERMANAGED,
6023                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6024     ok(r == ERROR_UNKNOWN_PROPERTY,
6025        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6026     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6027     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6028
6029     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6030     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6031
6032     /* VersionMajor value exists */
6033     sz = MAX_PATH;
6034     lstrcpyA(buf, "apple");
6035     r = pMsiGetProductInfoExA(prodcode, usersid,
6036                               MSIINSTALLCONTEXT_USERMANAGED,
6037                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6038     ok(r == ERROR_UNKNOWN_PROPERTY,
6039        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6040     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6041     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6042
6043     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6044     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6045
6046     /* DisplayVersion value exists */
6047     sz = MAX_PATH;
6048     lstrcpyA(buf, "apple");
6049     r = pMsiGetProductInfoExA(prodcode, usersid,
6050                               MSIINSTALLCONTEXT_USERMANAGED,
6051                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6052     ok(r == ERROR_UNKNOWN_PROPERTY,
6053        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6054     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6055     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6056
6057     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6059
6060     /* ProductID value exists */
6061     sz = MAX_PATH;
6062     lstrcpyA(buf, "apple");
6063     r = pMsiGetProductInfoExA(prodcode, usersid,
6064                               MSIINSTALLCONTEXT_USERMANAGED,
6065                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6066     ok(r == ERROR_UNKNOWN_PROPERTY,
6067        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6068     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6069     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6070
6071     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6073
6074     /* RegCompany value exists */
6075     sz = MAX_PATH;
6076     lstrcpyA(buf, "apple");
6077     r = pMsiGetProductInfoExA(prodcode, usersid,
6078                               MSIINSTALLCONTEXT_USERMANAGED,
6079                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6080     ok(r == ERROR_UNKNOWN_PROPERTY,
6081        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6082     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6083     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6084
6085     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6087
6088     /* RegOwner value exists */
6089     sz = MAX_PATH;
6090     lstrcpyA(buf, "apple");
6091     r = pMsiGetProductInfoExA(prodcode, usersid,
6092                               MSIINSTALLCONTEXT_USERMANAGED,
6093                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6094     ok(r == ERROR_UNKNOWN_PROPERTY,
6095        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6096     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6097     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6098
6099     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6101
6102     /* Transforms value exists */
6103     sz = MAX_PATH;
6104     lstrcpyA(buf, "apple");
6105     r = pMsiGetProductInfoExA(prodcode, usersid,
6106                               MSIINSTALLCONTEXT_USERMANAGED,
6107                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6109     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6110     ok(sz == 5, "Expected 5, got %d\n", sz);
6111
6112     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6114
6115     /* Language value exists */
6116     sz = MAX_PATH;
6117     lstrcpyA(buf, "apple");
6118     r = pMsiGetProductInfoExA(prodcode, usersid,
6119                               MSIINSTALLCONTEXT_USERMANAGED,
6120                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6121     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6122     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6123     ok(sz == 4, "Expected 4, got %d\n", sz);
6124
6125     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6127
6128     /* ProductName value exists */
6129     sz = MAX_PATH;
6130     lstrcpyA(buf, "apple");
6131     r = pMsiGetProductInfoExA(prodcode, usersid,
6132                               MSIINSTALLCONTEXT_USERMANAGED,
6133                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6135     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6136     ok(sz == 4, "Expected 4, got %d\n", sz);
6137
6138     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6140
6141     /* FIXME */
6142
6143     /* AssignmentType value exists */
6144     sz = MAX_PATH;
6145     lstrcpyA(buf, "apple");
6146     r = pMsiGetProductInfoExA(prodcode, usersid,
6147                               MSIINSTALLCONTEXT_USERMANAGED,
6148                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6149     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6150     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6151     ok(sz == 0, "Expected 0, got %d\n", sz);
6152
6153     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6155
6156     /* FIXME */
6157
6158     /* PackageCode value exists */
6159     sz = MAX_PATH;
6160     lstrcpyA(buf, "apple");
6161     r = pMsiGetProductInfoExA(prodcode, usersid,
6162                               MSIINSTALLCONTEXT_USERMANAGED,
6163                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6164     todo_wine
6165     {
6166         ok(r == ERROR_BAD_CONFIGURATION,
6167            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6168         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6169         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6170     }
6171
6172     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6174
6175     /* Version value exists */
6176     sz = MAX_PATH;
6177     lstrcpyA(buf, "apple");
6178     r = pMsiGetProductInfoExA(prodcode, usersid,
6179                               MSIINSTALLCONTEXT_USERMANAGED,
6180                               INSTALLPROPERTY_VERSION, buf, &sz);
6181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6182     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6183     ok(sz == 3, "Expected 3, got %d\n", sz);
6184
6185     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6187
6188     /* ProductIcon value exists */
6189     sz = MAX_PATH;
6190     lstrcpyA(buf, "apple");
6191     r = pMsiGetProductInfoExA(prodcode, usersid,
6192                               MSIINSTALLCONTEXT_USERMANAGED,
6193                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6194     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6195     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6196     ok(sz == 4, "Expected 4, got %d\n", sz);
6197
6198     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6200
6201     /* PackageName value exists */
6202     sz = MAX_PATH;
6203     lstrcpyA(buf, "apple");
6204     r = pMsiGetProductInfoExA(prodcode, usersid,
6205                               MSIINSTALLCONTEXT_USERMANAGED,
6206                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6207     todo_wine
6208     {
6209         ok(r == ERROR_UNKNOWN_PRODUCT,
6210            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6211         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6212         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6213     }
6214
6215     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6217
6218     /* AuthorizedLUAApp value exists */
6219     sz = MAX_PATH;
6220     lstrcpyA(buf, "apple");
6221     r = pMsiGetProductInfoExA(prodcode, usersid,
6222                               MSIINSTALLCONTEXT_USERMANAGED,
6223                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6225     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6226     ok(sz == 4, "Expected 4, got %d\n", sz);
6227
6228     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6229     RegDeleteValueA(userkey, "PackageName");
6230     RegDeleteValueA(userkey, "ProductIcon");
6231     RegDeleteValueA(userkey, "Version");
6232     RegDeleteValueA(userkey, "PackageCode");
6233     RegDeleteValueA(userkey, "AssignmentType");
6234     RegDeleteValueA(userkey, "ProductName");
6235     RegDeleteValueA(userkey, "Language");
6236     RegDeleteValueA(userkey, "Transforms");
6237     RegDeleteValueA(userkey, "RegOwner");
6238     RegDeleteValueA(userkey, "RegCompany");
6239     RegDeleteValueA(userkey, "ProductID");
6240     RegDeleteValueA(userkey, "DisplayVersion");
6241     RegDeleteValueA(userkey, "VersionMajor");
6242     RegDeleteValueA(userkey, "VersionMinor");
6243     RegDeleteValueA(userkey, "URLUpdateInfo");
6244     RegDeleteValueA(userkey, "URLInfoAbout");
6245     RegDeleteValueA(userkey, "Publisher");
6246     RegDeleteValueA(userkey, "LocalPackage");
6247     RegDeleteValueA(userkey, "InstallSource");
6248     RegDeleteValueA(userkey, "InstallLocation");
6249     RegDeleteValueA(userkey, "DisplayName");
6250     RegDeleteValueA(userkey, "InstallDate");
6251     RegDeleteValueA(userkey, "HelpTelephone");
6252     RegDeleteValueA(userkey, "HelpLink");
6253     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6254     RegCloseKey(userkey);
6255     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6256     RegCloseKey(prodkey);
6257
6258     /* MSIINSTALLCONTEXT_MACHINE */
6259
6260     /* szUserSid is non-NULL */
6261     sz = MAX_PATH;
6262     lstrcpyA(buf, "apple");
6263     r = pMsiGetProductInfoExA(prodcode, usersid,
6264                               MSIINSTALLCONTEXT_MACHINE,
6265                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6266     ok(r == ERROR_INVALID_PARAMETER,
6267        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6268     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6269     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6270
6271     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6272     lstrcatA(keypath, prod_squashed);
6273
6274     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6275     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6276
6277     /* local system product key exists */
6278     sz = MAX_PATH;
6279     lstrcpyA(buf, "apple");
6280     r = pMsiGetProductInfoExA(prodcode, NULL,
6281                               MSIINSTALLCONTEXT_MACHINE,
6282                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6283     ok(r == ERROR_UNKNOWN_PRODUCT,
6284        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6285     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6286     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6287
6288     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6290
6291     /* InstallProperties key exists */
6292     sz = MAX_PATH;
6293     lstrcpyA(buf, "apple");
6294     r = pMsiGetProductInfoExA(prodcode, NULL,
6295                               MSIINSTALLCONTEXT_MACHINE,
6296                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6297     ok(r == ERROR_UNKNOWN_PRODUCT,
6298        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6299     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6300     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6301
6302     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6304
6305     /* LocalPackage value exists */
6306     sz = MAX_PATH;
6307     lstrcpyA(buf, "apple");
6308     r = pMsiGetProductInfoExA(prodcode, NULL,
6309                               MSIINSTALLCONTEXT_MACHINE,
6310                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6312     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6313     ok(sz == 1, "Expected 1, got %d\n", sz);
6314
6315     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6317
6318     /* HelpLink value exists */
6319     sz = MAX_PATH;
6320     lstrcpyA(buf, "apple");
6321     r = pMsiGetProductInfoExA(prodcode, NULL,
6322                               MSIINSTALLCONTEXT_MACHINE,
6323                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6325     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6326     ok(sz == 4, "Expected 4, got %d\n", sz);
6327
6328     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6330
6331     /* HelpTelephone value exists */
6332     sz = MAX_PATH;
6333     lstrcpyA(buf, "apple");
6334     r = pMsiGetProductInfoExA(prodcode, NULL,
6335                               MSIINSTALLCONTEXT_MACHINE,
6336                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6338     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6339     ok(sz == 5, "Expected 5, got %d\n", sz);
6340
6341     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6343
6344     /* InstallDate value exists */
6345     sz = MAX_PATH;
6346     lstrcpyA(buf, "apple");
6347     r = pMsiGetProductInfoExA(prodcode, NULL,
6348                               MSIINSTALLCONTEXT_MACHINE,
6349                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6351     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6352     ok(sz == 4, "Expected 4, got %d\n", sz);
6353
6354     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6356
6357     /* DisplayName value exists */
6358     sz = MAX_PATH;
6359     lstrcpyA(buf, "apple");
6360     r = pMsiGetProductInfoExA(prodcode, NULL,
6361                               MSIINSTALLCONTEXT_MACHINE,
6362                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6364     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6365     ok(sz == 4, "Expected 4, got %d\n", sz);
6366
6367     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6369
6370     /* InstallLocation value exists */
6371     sz = MAX_PATH;
6372     lstrcpyA(buf, "apple");
6373     r = pMsiGetProductInfoExA(prodcode, NULL,
6374                               MSIINSTALLCONTEXT_MACHINE,
6375                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6377     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6378     ok(sz == 3, "Expected 3, got %d\n", sz);
6379
6380     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6382
6383     /* InstallSource value exists */
6384     sz = MAX_PATH;
6385     lstrcpyA(buf, "apple");
6386     r = pMsiGetProductInfoExA(prodcode, NULL,
6387                               MSIINSTALLCONTEXT_MACHINE,
6388                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6390     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6391     ok(sz == 6, "Expected 6, got %d\n", sz);
6392
6393     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6395
6396     /* LocalPackage value exists */
6397     sz = MAX_PATH;
6398     lstrcpyA(buf, "apple");
6399     r = pMsiGetProductInfoExA(prodcode, NULL,
6400                               MSIINSTALLCONTEXT_MACHINE,
6401                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6403     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6404     ok(sz == 5, "Expected 5, got %d\n", sz);
6405
6406     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6408
6409     /* Publisher value exists */
6410     sz = MAX_PATH;
6411     lstrcpyA(buf, "apple");
6412     r = pMsiGetProductInfoExA(prodcode, NULL,
6413                               MSIINSTALLCONTEXT_MACHINE,
6414                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6416     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6417     ok(sz == 3, "Expected 3, got %d\n", sz);
6418
6419     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6421
6422     /* URLInfoAbout value exists */
6423     sz = MAX_PATH;
6424     lstrcpyA(buf, "apple");
6425     r = pMsiGetProductInfoExA(prodcode, NULL,
6426                               MSIINSTALLCONTEXT_MACHINE,
6427                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6429     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6430     ok(sz == 5, "Expected 5, got %d\n", sz);
6431
6432     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6434
6435     /* URLUpdateInfo value exists */
6436     sz = MAX_PATH;
6437     lstrcpyA(buf, "apple");
6438     r = pMsiGetProductInfoExA(prodcode, NULL,
6439                               MSIINSTALLCONTEXT_MACHINE,
6440                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6442     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6443     ok(sz == 6, "Expected 6, got %d\n", sz);
6444
6445     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6447
6448     /* VersionMinor value exists */
6449     sz = MAX_PATH;
6450     lstrcpyA(buf, "apple");
6451     r = pMsiGetProductInfoExA(prodcode, NULL,
6452                               MSIINSTALLCONTEXT_MACHINE,
6453                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6455     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6456     ok(sz == 1, "Expected 1, got %d\n", sz);
6457
6458     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6460
6461     /* VersionMajor value exists */
6462     sz = MAX_PATH;
6463     lstrcpyA(buf, "apple");
6464     r = pMsiGetProductInfoExA(prodcode, NULL,
6465                               MSIINSTALLCONTEXT_MACHINE,
6466                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6467     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6468     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6469     ok(sz == 1, "Expected 1, got %d\n", sz);
6470
6471     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6473
6474     /* DisplayVersion value exists */
6475     sz = MAX_PATH;
6476     lstrcpyA(buf, "apple");
6477     r = pMsiGetProductInfoExA(prodcode, NULL,
6478                               MSIINSTALLCONTEXT_MACHINE,
6479                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6480     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6481     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6482     ok(sz == 5, "Expected 5, got %d\n", sz);
6483
6484     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6485     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6486
6487     /* ProductID value exists */
6488     sz = MAX_PATH;
6489     lstrcpyA(buf, "apple");
6490     r = pMsiGetProductInfoExA(prodcode, NULL,
6491                               MSIINSTALLCONTEXT_MACHINE,
6492                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6494     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6495     ok(sz == 2, "Expected 2, got %d\n", sz);
6496
6497     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6499
6500     /* RegCompany value exists */
6501     sz = MAX_PATH;
6502     lstrcpyA(buf, "apple");
6503     r = pMsiGetProductInfoExA(prodcode, NULL,
6504                               MSIINSTALLCONTEXT_MACHINE,
6505                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6506     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6507     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6508     ok(sz == 4, "Expected 4, got %d\n", sz);
6509
6510     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6511     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6512
6513     /* RegOwner value exists */
6514     sz = MAX_PATH;
6515     lstrcpyA(buf, "apple");
6516     r = pMsiGetProductInfoExA(prodcode, NULL,
6517                               MSIINSTALLCONTEXT_MACHINE,
6518                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6519     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6520     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6521     ok(sz == 5, "Expected 5, got %d\n", sz);
6522
6523     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6525
6526     /* Transforms value exists */
6527     sz = MAX_PATH;
6528     lstrcpyA(buf, "apple");
6529     r = pMsiGetProductInfoExA(prodcode, NULL,
6530                               MSIINSTALLCONTEXT_MACHINE,
6531                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6532     ok(r == ERROR_UNKNOWN_PRODUCT,
6533        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6534     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6535     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6536
6537     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6539
6540     /* Language value exists */
6541     sz = MAX_PATH;
6542     lstrcpyA(buf, "apple");
6543     r = pMsiGetProductInfoExA(prodcode, NULL,
6544                               MSIINSTALLCONTEXT_MACHINE,
6545                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6546     ok(r == ERROR_UNKNOWN_PRODUCT,
6547        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6548     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6549     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6550
6551     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6553
6554     /* ProductName value exists */
6555     sz = MAX_PATH;
6556     lstrcpyA(buf, "apple");
6557     r = pMsiGetProductInfoExA(prodcode, NULL,
6558                               MSIINSTALLCONTEXT_MACHINE,
6559                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6560     ok(r == ERROR_UNKNOWN_PRODUCT,
6561        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6562     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6563     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6564
6565     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6566     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6567
6568     /* FIXME */
6569
6570     /* AssignmentType value exists */
6571     sz = MAX_PATH;
6572     lstrcpyA(buf, "apple");
6573     r = pMsiGetProductInfoExA(prodcode, NULL,
6574                               MSIINSTALLCONTEXT_MACHINE,
6575                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6576     ok(r == ERROR_UNKNOWN_PRODUCT,
6577        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6578     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6579     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6580
6581     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6583
6584     /* PackageCode value exists */
6585     sz = MAX_PATH;
6586     lstrcpyA(buf, "apple");
6587     r = pMsiGetProductInfoExA(prodcode, NULL,
6588                               MSIINSTALLCONTEXT_MACHINE,
6589                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6590     ok(r == ERROR_UNKNOWN_PRODUCT,
6591        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6592     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6593     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6594
6595     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6597
6598     /* Version value exists */
6599     sz = MAX_PATH;
6600     lstrcpyA(buf, "apple");
6601     r = pMsiGetProductInfoExA(prodcode, NULL,
6602                               MSIINSTALLCONTEXT_MACHINE,
6603                               INSTALLPROPERTY_VERSION, buf, &sz);
6604     ok(r == ERROR_UNKNOWN_PRODUCT,
6605        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6608
6609     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6611
6612     /* ProductIcon value exists */
6613     sz = MAX_PATH;
6614     lstrcpyA(buf, "apple");
6615     r = pMsiGetProductInfoExA(prodcode, NULL,
6616                               MSIINSTALLCONTEXT_MACHINE,
6617                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6618     ok(r == ERROR_UNKNOWN_PRODUCT,
6619        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6620     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6621     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6622
6623     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6625
6626     /* PackageName value exists */
6627     sz = MAX_PATH;
6628     lstrcpyA(buf, "apple");
6629     r = pMsiGetProductInfoExA(prodcode, NULL,
6630                               MSIINSTALLCONTEXT_MACHINE,
6631                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6632     ok(r == ERROR_UNKNOWN_PRODUCT,
6633        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6634     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6635     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6636
6637     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6639
6640     /* AuthorizedLUAApp value exists */
6641     sz = MAX_PATH;
6642     lstrcpyA(buf, "apple");
6643     r = pMsiGetProductInfoExA(prodcode, NULL,
6644                               MSIINSTALLCONTEXT_MACHINE,
6645                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6646     ok(r == ERROR_UNKNOWN_PRODUCT,
6647        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6648     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6649     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6650
6651     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6652     RegDeleteValueA(propkey, "PackageName");
6653     RegDeleteValueA(propkey, "ProductIcon");
6654     RegDeleteValueA(propkey, "Version");
6655     RegDeleteValueA(propkey, "PackageCode");
6656     RegDeleteValueA(propkey, "AssignmentType");
6657     RegDeleteValueA(propkey, "ProductName");
6658     RegDeleteValueA(propkey, "Language");
6659     RegDeleteValueA(propkey, "Transforms");
6660     RegDeleteValueA(propkey, "RegOwner");
6661     RegDeleteValueA(propkey, "RegCompany");
6662     RegDeleteValueA(propkey, "ProductID");
6663     RegDeleteValueA(propkey, "DisplayVersion");
6664     RegDeleteValueA(propkey, "VersionMajor");
6665     RegDeleteValueA(propkey, "VersionMinor");
6666     RegDeleteValueA(propkey, "URLUpdateInfo");
6667     RegDeleteValueA(propkey, "URLInfoAbout");
6668     RegDeleteValueA(propkey, "Publisher");
6669     RegDeleteValueA(propkey, "LocalPackage");
6670     RegDeleteValueA(propkey, "InstallSource");
6671     RegDeleteValueA(propkey, "InstallLocation");
6672     RegDeleteValueA(propkey, "DisplayName");
6673     RegDeleteValueA(propkey, "InstallDate");
6674     RegDeleteValueA(propkey, "HelpTelephone");
6675     RegDeleteValueA(propkey, "HelpLink");
6676     RegDeleteValueA(propkey, "LocalPackage");
6677     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6678     RegCloseKey(propkey);
6679     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6680     RegCloseKey(localkey);
6681
6682     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6683     lstrcatA(keypath, prod_squashed);
6684
6685     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6687
6688     /* local classes product key exists */
6689     sz = MAX_PATH;
6690     lstrcpyA(buf, "apple");
6691     r = pMsiGetProductInfoExA(prodcode, NULL,
6692                               MSIINSTALLCONTEXT_MACHINE,
6693                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6694     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6695     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6696     ok(sz == 1, "Expected 1, got %d\n", sz);
6697
6698     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6700
6701     /* HelpLink value exists */
6702     sz = MAX_PATH;
6703     lstrcpyA(buf, "apple");
6704     r = pMsiGetProductInfoExA(prodcode, NULL,
6705                               MSIINSTALLCONTEXT_MACHINE,
6706                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6707     ok(r == ERROR_UNKNOWN_PROPERTY,
6708        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6709     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6710     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6711
6712     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6714
6715     /* HelpTelephone value exists */
6716     sz = MAX_PATH;
6717     lstrcpyA(buf, "apple");
6718     r = pMsiGetProductInfoExA(prodcode, NULL,
6719                               MSIINSTALLCONTEXT_MACHINE,
6720                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6721     ok(r == ERROR_UNKNOWN_PROPERTY,
6722        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6723     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6724     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6725
6726     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6728
6729     /* InstallDate value exists */
6730     sz = MAX_PATH;
6731     lstrcpyA(buf, "apple");
6732     r = pMsiGetProductInfoExA(prodcode, NULL,
6733                               MSIINSTALLCONTEXT_MACHINE,
6734                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6735     ok(r == ERROR_UNKNOWN_PROPERTY,
6736        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6737     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6738     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6739
6740     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6742
6743     /* DisplayName value exists */
6744     sz = MAX_PATH;
6745     lstrcpyA(buf, "apple");
6746     r = pMsiGetProductInfoExA(prodcode, NULL,
6747                               MSIINSTALLCONTEXT_MACHINE,
6748                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6749     ok(r == ERROR_UNKNOWN_PROPERTY,
6750        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6751     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6752     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6753
6754     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6755     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6756
6757     /* InstallLocation value exists */
6758     sz = MAX_PATH;
6759     lstrcpyA(buf, "apple");
6760     r = pMsiGetProductInfoExA(prodcode, NULL,
6761                               MSIINSTALLCONTEXT_MACHINE,
6762                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6763     ok(r == ERROR_UNKNOWN_PROPERTY,
6764        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6765     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6766     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6767
6768     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6770
6771     /* InstallSource value exists */
6772     sz = MAX_PATH;
6773     lstrcpyA(buf, "apple");
6774     r = pMsiGetProductInfoExA(prodcode, NULL,
6775                               MSIINSTALLCONTEXT_MACHINE,
6776                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6777     ok(r == ERROR_UNKNOWN_PROPERTY,
6778        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6779     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6780     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6781
6782     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6784
6785     /* LocalPackage value exists */
6786     sz = MAX_PATH;
6787     lstrcpyA(buf, "apple");
6788     r = pMsiGetProductInfoExA(prodcode, NULL,
6789                               MSIINSTALLCONTEXT_MACHINE,
6790                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6791     ok(r == ERROR_UNKNOWN_PROPERTY,
6792        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6793     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6794     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6795
6796     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6798
6799     /* Publisher value exists */
6800     sz = MAX_PATH;
6801     lstrcpyA(buf, "apple");
6802     r = pMsiGetProductInfoExA(prodcode, NULL,
6803                               MSIINSTALLCONTEXT_MACHINE,
6804                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6805     ok(r == ERROR_UNKNOWN_PROPERTY,
6806        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6807     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6808     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6809
6810     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6812
6813     /* URLInfoAbout value exists */
6814     sz = MAX_PATH;
6815     lstrcpyA(buf, "apple");
6816     r = pMsiGetProductInfoExA(prodcode, NULL,
6817                               MSIINSTALLCONTEXT_MACHINE,
6818                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6819     ok(r == ERROR_UNKNOWN_PROPERTY,
6820        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6821     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6822     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6823
6824     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6826
6827     /* URLUpdateInfo value exists */
6828     sz = MAX_PATH;
6829     lstrcpyA(buf, "apple");
6830     r = pMsiGetProductInfoExA(prodcode, NULL,
6831                               MSIINSTALLCONTEXT_MACHINE,
6832                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6833     ok(r == ERROR_UNKNOWN_PROPERTY,
6834        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6835     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6836     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6837
6838     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6840
6841     /* VersionMinor value exists */
6842     sz = MAX_PATH;
6843     lstrcpyA(buf, "apple");
6844     r = pMsiGetProductInfoExA(prodcode, NULL,
6845                               MSIINSTALLCONTEXT_MACHINE,
6846                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6847     ok(r == ERROR_UNKNOWN_PROPERTY,
6848        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6849     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6850     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6851
6852     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6854
6855     /* VersionMajor value exists */
6856     sz = MAX_PATH;
6857     lstrcpyA(buf, "apple");
6858     r = pMsiGetProductInfoExA(prodcode, NULL,
6859                               MSIINSTALLCONTEXT_MACHINE,
6860                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6861     ok(r == ERROR_UNKNOWN_PROPERTY,
6862        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6863     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6864     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6865
6866     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6868
6869     /* DisplayVersion value exists */
6870     sz = MAX_PATH;
6871     lstrcpyA(buf, "apple");
6872     r = pMsiGetProductInfoExA(prodcode, NULL,
6873                               MSIINSTALLCONTEXT_MACHINE,
6874                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6875     ok(r == ERROR_UNKNOWN_PROPERTY,
6876        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6877     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6878     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6879
6880     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6881     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6882
6883     /* ProductID value exists */
6884     sz = MAX_PATH;
6885     lstrcpyA(buf, "apple");
6886     r = pMsiGetProductInfoExA(prodcode, NULL,
6887                               MSIINSTALLCONTEXT_MACHINE,
6888                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6889     ok(r == ERROR_UNKNOWN_PROPERTY,
6890        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6891     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6892     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6893
6894     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6896
6897     /* RegCompany value exists */
6898     sz = MAX_PATH;
6899     lstrcpyA(buf, "apple");
6900     r = pMsiGetProductInfoExA(prodcode, NULL,
6901                               MSIINSTALLCONTEXT_MACHINE,
6902                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6903     ok(r == ERROR_UNKNOWN_PROPERTY,
6904        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6905     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6906     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6907
6908     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6909     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6910
6911     /* RegOwner value exists */
6912     sz = MAX_PATH;
6913     lstrcpyA(buf, "apple");
6914     r = pMsiGetProductInfoExA(prodcode, NULL,
6915                               MSIINSTALLCONTEXT_MACHINE,
6916                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6917     ok(r == ERROR_UNKNOWN_PROPERTY,
6918        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6919     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6920     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6921
6922     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6924
6925     /* Transforms value exists */
6926     sz = MAX_PATH;
6927     lstrcpyA(buf, "apple");
6928     r = pMsiGetProductInfoExA(prodcode, NULL,
6929                               MSIINSTALLCONTEXT_MACHINE,
6930                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6932     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6933     ok(sz == 5, "Expected 5, got %d\n", sz);
6934
6935     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6936     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6937
6938     /* Language value exists */
6939     sz = MAX_PATH;
6940     lstrcpyA(buf, "apple");
6941     r = pMsiGetProductInfoExA(prodcode, NULL,
6942                               MSIINSTALLCONTEXT_MACHINE,
6943                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6944     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6945     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6946     ok(sz == 4, "Expected 4, got %d\n", sz);
6947
6948     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6950
6951     /* ProductName value exists */
6952     sz = MAX_PATH;
6953     lstrcpyA(buf, "apple");
6954     r = pMsiGetProductInfoExA(prodcode, NULL,
6955                               MSIINSTALLCONTEXT_MACHINE,
6956                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6957     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6958     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6959     ok(sz == 4, "Expected 4, got %d\n", sz);
6960
6961     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6963
6964     /* FIXME */
6965
6966     /* AssignmentType value exists */
6967     sz = MAX_PATH;
6968     lstrcpyA(buf, "apple");
6969     r = pMsiGetProductInfoExA(prodcode, NULL,
6970                               MSIINSTALLCONTEXT_MACHINE,
6971                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6972     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6973     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6974     ok(sz == 0, "Expected 0, got %d\n", sz);
6975
6976     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6978
6979     /* FIXME */
6980
6981     /* PackageCode value exists */
6982     sz = MAX_PATH;
6983     lstrcpyA(buf, "apple");
6984     r = pMsiGetProductInfoExA(prodcode, NULL,
6985                               MSIINSTALLCONTEXT_MACHINE,
6986                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6987     todo_wine
6988     {
6989         ok(r == ERROR_BAD_CONFIGURATION,
6990            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6991         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6992         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6993     }
6994
6995     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6997
6998     /* Version value exists */
6999     sz = MAX_PATH;
7000     lstrcpyA(buf, "apple");
7001     r = pMsiGetProductInfoExA(prodcode, NULL,
7002                               MSIINSTALLCONTEXT_MACHINE,
7003                               INSTALLPROPERTY_VERSION, buf, &sz);
7004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7005     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7006     ok(sz == 3, "Expected 3, got %d\n", sz);
7007
7008     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7010
7011     /* ProductIcon value exists */
7012     sz = MAX_PATH;
7013     lstrcpyA(buf, "apple");
7014     r = pMsiGetProductInfoExA(prodcode, NULL,
7015                               MSIINSTALLCONTEXT_MACHINE,
7016                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7018     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7019     ok(sz == 4, "Expected 4, got %d\n", sz);
7020
7021     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7023
7024     /* PackageName value exists */
7025     sz = MAX_PATH;
7026     lstrcpyA(buf, "apple");
7027     r = pMsiGetProductInfoExA(prodcode, NULL,
7028                               MSIINSTALLCONTEXT_MACHINE,
7029                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7030     todo_wine
7031     {
7032         ok(r == ERROR_UNKNOWN_PRODUCT,
7033            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7034         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7035         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7036     }
7037
7038     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7039     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7040
7041     /* AuthorizedLUAApp value exists */
7042     sz = MAX_PATH;
7043     lstrcpyA(buf, "apple");
7044     r = pMsiGetProductInfoExA(prodcode, NULL,
7045                               MSIINSTALLCONTEXT_MACHINE,
7046                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7047     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7048     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7049     ok(sz == 4, "Expected 4, got %d\n", sz);
7050
7051     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7052     RegDeleteValueA(prodkey, "PackageName");
7053     RegDeleteValueA(prodkey, "ProductIcon");
7054     RegDeleteValueA(prodkey, "Version");
7055     RegDeleteValueA(prodkey, "PackageCode");
7056     RegDeleteValueA(prodkey, "AssignmentType");
7057     RegDeleteValueA(prodkey, "ProductName");
7058     RegDeleteValueA(prodkey, "Language");
7059     RegDeleteValueA(prodkey, "Transforms");
7060     RegDeleteValueA(prodkey, "RegOwner");
7061     RegDeleteValueA(prodkey, "RegCompany");
7062     RegDeleteValueA(prodkey, "ProductID");
7063     RegDeleteValueA(prodkey, "DisplayVersion");
7064     RegDeleteValueA(prodkey, "VersionMajor");
7065     RegDeleteValueA(prodkey, "VersionMinor");
7066     RegDeleteValueA(prodkey, "URLUpdateInfo");
7067     RegDeleteValueA(prodkey, "URLInfoAbout");
7068     RegDeleteValueA(prodkey, "Publisher");
7069     RegDeleteValueA(prodkey, "LocalPackage");
7070     RegDeleteValueA(prodkey, "InstallSource");
7071     RegDeleteValueA(prodkey, "InstallLocation");
7072     RegDeleteValueA(prodkey, "DisplayName");
7073     RegDeleteValueA(prodkey, "InstallDate");
7074     RegDeleteValueA(prodkey, "HelpTelephone");
7075     RegDeleteValueA(prodkey, "HelpLink");
7076     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7077     RegCloseKey(prodkey);
7078     LocalFree(usersid);
7079 }
7080
7081 #define INIT_USERINFO() \
7082     lstrcpyA(user, "apple"); \
7083     lstrcpyA(org, "orange"); \
7084     lstrcpyA(serial, "banana"); \
7085     usersz = orgsz = serialsz = MAX_PATH;
7086
7087 static void test_MsiGetUserInfo(void)
7088 {
7089     USERINFOSTATE state;
7090     CHAR user[MAX_PATH];
7091     CHAR org[MAX_PATH];
7092     CHAR serial[MAX_PATH];
7093     DWORD usersz, orgsz, serialsz;
7094     CHAR keypath[MAX_PATH * 2];
7095     CHAR prodcode[MAX_PATH];
7096     CHAR prod_squashed[MAX_PATH];
7097     HKEY prodkey, userprod, props;
7098     LPSTR usersid;
7099     LONG res;
7100     REGSAM access = KEY_ALL_ACCESS;
7101
7102     create_test_guid(prodcode, prod_squashed);
7103     usersid = get_user_sid();
7104
7105     if (is_wow64)
7106         access |= KEY_WOW64_64KEY;
7107
7108     /* NULL szProduct */
7109     INIT_USERINFO();
7110     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
7111     ok(state == USERINFOSTATE_INVALIDARG,
7112        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7113     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7114     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7115     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7116     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7117     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7118     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7119
7120     /* empty szProductCode */
7121     INIT_USERINFO();
7122     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
7123     ok(state == USERINFOSTATE_INVALIDARG,
7124        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7125     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7126     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7127     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7128     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7129     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7130     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7131
7132     /* garbage szProductCode */
7133     INIT_USERINFO();
7134     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
7135     ok(state == USERINFOSTATE_INVALIDARG,
7136        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7137     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7138     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7139     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7140     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7141     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7142     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7143
7144     /* guid without brackets */
7145     INIT_USERINFO();
7146     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7147                             user, &usersz, org, &orgsz, serial, &serialsz);
7148     ok(state == USERINFOSTATE_INVALIDARG,
7149        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7150     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7151     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7152     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7153     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7154     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7155     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7156
7157     /* guid with brackets */
7158     INIT_USERINFO();
7159     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7160                             user, &usersz, org, &orgsz, serial, &serialsz);
7161     ok(state == USERINFOSTATE_UNKNOWN,
7162        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7163     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
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 lpUserNameBuf */
7171     INIT_USERINFO();
7172     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7173     ok(state == USERINFOSTATE_UNKNOWN,
7174        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7175     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7176     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7177     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
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     /* NULL pcchUserNameBuf */
7182     INIT_USERINFO();
7183     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
7184     ok(state == USERINFOSTATE_INVALIDARG,
7185        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7186     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7187     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7188     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7189     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7190     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7191
7192     /* both lpUserNameBuf and pcchUserNameBuf NULL */
7193     INIT_USERINFO();
7194     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7195     ok(state == USERINFOSTATE_UNKNOWN,
7196        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7197     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7198     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
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 lpOrgNameBuf */
7203     INIT_USERINFO();
7204     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
7205     ok(state == USERINFOSTATE_UNKNOWN,
7206        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7207     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7208     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7209     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7210     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7211     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7212
7213     /* NULL pcchOrgNameBuf */
7214     INIT_USERINFO();
7215     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7216     ok(state == USERINFOSTATE_INVALIDARG,
7217        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7218     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7219     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7220     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7221     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7222     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7223
7224     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7225     INIT_USERINFO();
7226     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7227     ok(state == USERINFOSTATE_UNKNOWN,
7228        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7229     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7230     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7231     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7232     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7233
7234     /* NULL lpSerialBuf */
7235     INIT_USERINFO();
7236     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7237     ok(state == USERINFOSTATE_UNKNOWN,
7238        "Expected USERINFOSTATE_UNKNOWN, 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(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7242     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7243     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7244
7245     /* NULL pcchSerialBuf */
7246     INIT_USERINFO();
7247     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7248     ok(state == USERINFOSTATE_INVALIDARG,
7249        "Expected USERINFOSTATE_INVALIDARG, 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(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7253     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7254     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7255
7256     /* both lpSerialBuf and pcchSerialBuf NULL */
7257     INIT_USERINFO();
7258     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7259     ok(state == USERINFOSTATE_UNKNOWN,
7260        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7261     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7262     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7263     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7264     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7265
7266     /* MSIINSTALLCONTEXT_USERMANAGED */
7267
7268     /* create local system product key */
7269     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7270     lstrcatA(keypath, usersid);
7271     lstrcatA(keypath, "\\Installer\\Products\\");
7272     lstrcatA(keypath, prod_squashed);
7273
7274     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7275     if (res == ERROR_ACCESS_DENIED)
7276     {
7277         skip("Not enough rights to perform tests\n");
7278         LocalFree(usersid);
7279         return;
7280     }
7281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7282
7283     /* managed product key exists */
7284     INIT_USERINFO();
7285     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7286     ok(state == USERINFOSTATE_ABSENT,
7287        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7288     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7289     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7290     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7291     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7292     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7293     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7294
7295     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7296     lstrcatA(keypath, "Installer\\UserData\\");
7297     lstrcatA(keypath, usersid);
7298     lstrcatA(keypath, "\\Products\\");
7299     lstrcatA(keypath, prod_squashed);
7300
7301     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7303
7304     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7306
7307     /* InstallProperties key exists */
7308     INIT_USERINFO();
7309     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7310     ok(state == USERINFOSTATE_ABSENT,
7311        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7312     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7313     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7314     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7315     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7316     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7317     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7318
7319     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7320     INIT_USERINFO();
7321     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7322     ok(state == USERINFOSTATE_ABSENT,
7323        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7324     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7325     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7326     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7327     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7328
7329     /* RegOwner, RegCompany don't exist, out params are NULL */
7330     INIT_USERINFO();
7331     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7332     ok(state == USERINFOSTATE_ABSENT,
7333        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7334     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7335     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7336
7337     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7339
7340     /* RegOwner value exists */
7341     INIT_USERINFO();
7342     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7343     ok(state == USERINFOSTATE_ABSENT,
7344        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7345     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7346     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7347     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7348     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7349     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7350     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7351
7352     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7354
7355     /* RegCompany value exists */
7356     INIT_USERINFO();
7357     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7358     ok(state == USERINFOSTATE_ABSENT,
7359        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7360     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7361     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7362     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7363     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7364     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7365     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7366
7367     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7369
7370     /* ProductID value exists */
7371     INIT_USERINFO();
7372     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7373     ok(state == USERINFOSTATE_PRESENT,
7374        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7375     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7376     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7377     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7378     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7379     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7380     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7381
7382     /* pcchUserNameBuf is too small */
7383     INIT_USERINFO();
7384     usersz = 0;
7385     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7386     ok(state == USERINFOSTATE_MOREDATA,
7387        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7388     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7389     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7390     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7391     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7392     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7393     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7394
7395     /* pcchUserNameBuf has no room for NULL terminator */
7396     INIT_USERINFO();
7397     usersz = 5;
7398     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7399     ok(state == USERINFOSTATE_MOREDATA,
7400        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7401     todo_wine
7402     {
7403         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7404     }
7405     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7406     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7407     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7408     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7409     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7410
7411     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7412     INIT_USERINFO();
7413     usersz = 0;
7414     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7415     ok(state == USERINFOSTATE_PRESENT,
7416        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7417     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7418     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7419     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7420     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7421     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7422     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7423
7424     RegDeleteValueA(props, "ProductID");
7425     RegDeleteValueA(props, "RegCompany");
7426     RegDeleteValueA(props, "RegOwner");
7427     delete_key(props, "", access & KEY_WOW64_64KEY);
7428     RegCloseKey(props);
7429     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7430     RegCloseKey(userprod);
7431     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7432     RegCloseKey(prodkey);
7433
7434     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7435
7436     /* create local system product key */
7437     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7438     lstrcatA(keypath, prod_squashed);
7439
7440     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7441     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7442
7443     /* product key exists */
7444     INIT_USERINFO();
7445     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7446     ok(state == USERINFOSTATE_ABSENT,
7447        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7448     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7449     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7450     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7451     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7452     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7453     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7454
7455     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7456     lstrcatA(keypath, "Installer\\UserData\\");
7457     lstrcatA(keypath, usersid);
7458     lstrcatA(keypath, "\\Products\\");
7459     lstrcatA(keypath, prod_squashed);
7460
7461     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7463
7464     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7465     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7466
7467     /* InstallProperties key exists */
7468     INIT_USERINFO();
7469     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7470     ok(state == USERINFOSTATE_ABSENT,
7471        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7472     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7473     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7474     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7475     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7476     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7477     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7478
7479     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7480     INIT_USERINFO();
7481     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7482     ok(state == USERINFOSTATE_ABSENT,
7483        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7484     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7485     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7486     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7487     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7488
7489     /* RegOwner, RegCompany don't exist, out params are NULL */
7490     INIT_USERINFO();
7491     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7492     ok(state == USERINFOSTATE_ABSENT,
7493        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7494     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7495     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7496
7497     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7499
7500     /* RegOwner value exists */
7501     INIT_USERINFO();
7502     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7503     ok(state == USERINFOSTATE_ABSENT,
7504        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7505     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7506     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7507     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7508     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7509     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7510     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7511
7512     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7513     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7514
7515     /* RegCompany value exists */
7516     INIT_USERINFO();
7517     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7518     ok(state == USERINFOSTATE_ABSENT,
7519        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7520     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7521     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7522     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7523     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7524     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7525     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7526
7527     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7529
7530     /* ProductID value exists */
7531     INIT_USERINFO();
7532     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7533     ok(state == USERINFOSTATE_PRESENT,
7534        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7535     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7536     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7537     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7538     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7539     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7540     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7541
7542     RegDeleteValueA(props, "ProductID");
7543     RegDeleteValueA(props, "RegCompany");
7544     RegDeleteValueA(props, "RegOwner");
7545     delete_key(props, "", access & KEY_WOW64_64KEY);
7546     RegCloseKey(props);
7547     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7548     RegCloseKey(userprod);
7549     RegDeleteKeyA(prodkey, "");
7550     RegCloseKey(prodkey);
7551
7552     /* MSIINSTALLCONTEXT_MACHINE */
7553
7554     /* create local system product key */
7555     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7556     lstrcatA(keypath, prod_squashed);
7557
7558     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7559     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7560
7561     /* product key exists */
7562     INIT_USERINFO();
7563     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7564     ok(state == USERINFOSTATE_ABSENT,
7565        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7566     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7567     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7568     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7569     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7570     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7571     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7572
7573     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7574     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7575     lstrcatA(keypath, "\\Products\\");
7576     lstrcatA(keypath, prod_squashed);
7577
7578     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7580
7581     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7583
7584     /* InstallProperties key exists */
7585     INIT_USERINFO();
7586     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7587     ok(state == USERINFOSTATE_ABSENT,
7588        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7589     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7590     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7591     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7592     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7593     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7594     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7595
7596     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7597     INIT_USERINFO();
7598     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7599     ok(state == USERINFOSTATE_ABSENT,
7600        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7601     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7602     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7603     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7604     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7605
7606     /* RegOwner, RegCompany don't exist, out params are NULL */
7607     INIT_USERINFO();
7608     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7609     ok(state == USERINFOSTATE_ABSENT,
7610        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7611     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7612     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7613
7614     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7616
7617     /* RegOwner value exists */
7618     INIT_USERINFO();
7619     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7620     ok(state == USERINFOSTATE_ABSENT,
7621        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7622     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7623     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7624     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7625     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7626     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7627     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7628
7629     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7631
7632     /* RegCompany value exists */
7633     INIT_USERINFO();
7634     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7635     ok(state == USERINFOSTATE_ABSENT,
7636        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7637     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7638     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7639     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7640     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7641     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7642     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7643
7644     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7646
7647     /* ProductID value exists */
7648     INIT_USERINFO();
7649     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7650     ok(state == USERINFOSTATE_PRESENT,
7651        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7652     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7653     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7654     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7655     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7656     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7657     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7658
7659     RegDeleteValueA(props, "ProductID");
7660     RegDeleteValueA(props, "RegCompany");
7661     RegDeleteValueA(props, "RegOwner");
7662     delete_key(props, "", access & KEY_WOW64_64KEY);
7663     RegCloseKey(props);
7664     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7665     RegCloseKey(userprod);
7666     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7667     RegCloseKey(prodkey);
7668     LocalFree(usersid);
7669 }
7670
7671 static void test_MsiOpenProduct(void)
7672 {
7673     MSIHANDLE hprod, hdb;
7674     CHAR val[MAX_PATH];
7675     CHAR path[MAX_PATH];
7676     CHAR keypath[MAX_PATH*2];
7677     CHAR prodcode[MAX_PATH];
7678     CHAR prod_squashed[MAX_PATH];
7679     HKEY prodkey, userkey, props;
7680     LPSTR usersid;
7681     DWORD size;
7682     LONG res;
7683     UINT r;
7684     REGSAM access = KEY_ALL_ACCESS;
7685
7686     GetCurrentDirectoryA(MAX_PATH, path);
7687     lstrcatA(path, "\\");
7688
7689     create_test_guid(prodcode, prod_squashed);
7690     usersid = get_user_sid();
7691
7692     if (is_wow64)
7693         access |= KEY_WOW64_64KEY;
7694
7695     hdb = create_package_db(prodcode);
7696     MsiCloseHandle(hdb);
7697
7698     /* NULL szProduct */
7699     hprod = 0xdeadbeef;
7700     r = MsiOpenProductA(NULL, &hprod);
7701     ok(r == ERROR_INVALID_PARAMETER,
7702        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7703     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7704
7705     /* empty szProduct */
7706     hprod = 0xdeadbeef;
7707     r = MsiOpenProductA("", &hprod);
7708     ok(r == ERROR_INVALID_PARAMETER,
7709        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7710     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7711
7712     /* garbage szProduct */
7713     hprod = 0xdeadbeef;
7714     r = MsiOpenProductA("garbage", &hprod);
7715     ok(r == ERROR_INVALID_PARAMETER,
7716        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7717     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7718
7719     /* guid without brackets */
7720     hprod = 0xdeadbeef;
7721     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7722     ok(r == ERROR_INVALID_PARAMETER,
7723        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7724     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7725
7726     /* guid with brackets */
7727     hprod = 0xdeadbeef;
7728     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7729     ok(r == ERROR_UNKNOWN_PRODUCT,
7730        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7731     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7732
7733     /* same length as guid, but random */
7734     hprod = 0xdeadbeef;
7735     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7736     ok(r == ERROR_INVALID_PARAMETER,
7737        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7738     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7739
7740     /* hProduct is NULL */
7741     hprod = 0xdeadbeef;
7742     r = MsiOpenProductA(prodcode, NULL);
7743     ok(r == ERROR_INVALID_PARAMETER,
7744        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7745     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7746
7747     /* MSIINSTALLCONTEXT_USERMANAGED */
7748
7749     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7750     lstrcatA(keypath, "Installer\\Managed\\");
7751     lstrcatA(keypath, usersid);
7752     lstrcatA(keypath, "\\Installer\\Products\\");
7753     lstrcatA(keypath, prod_squashed);
7754
7755     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7756     if (res == ERROR_ACCESS_DENIED)
7757     {
7758         skip("Not enough rights to perform tests\n");
7759         LocalFree(usersid);
7760         return;
7761     }
7762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7763
7764     /* managed product key exists */
7765     hprod = 0xdeadbeef;
7766     r = MsiOpenProductA(prodcode, &hprod);
7767     ok(r == ERROR_UNKNOWN_PRODUCT,
7768        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7769     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7770
7771     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7772     lstrcatA(keypath, "Installer\\UserData\\");
7773     lstrcatA(keypath, usersid);
7774     lstrcatA(keypath, "\\Products\\");
7775     lstrcatA(keypath, prod_squashed);
7776
7777     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7779
7780     /* user product key exists */
7781     hprod = 0xdeadbeef;
7782     r = MsiOpenProductA(prodcode, &hprod);
7783     ok(r == ERROR_UNKNOWN_PRODUCT,
7784        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7785     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7786
7787     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7789
7790     /* InstallProperties key exists */
7791     hprod = 0xdeadbeef;
7792     r = MsiOpenProductA(prodcode, &hprod);
7793     ok(r == ERROR_UNKNOWN_PRODUCT,
7794        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7795     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7796
7797     lstrcpyA(val, path);
7798     lstrcatA(val, "\\winetest.msi");
7799     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7800                          (const BYTE *)val, lstrlenA(val) + 1);
7801     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7802
7803     /* ManagedLocalPackage value exists */
7804     hprod = 0xdeadbeef;
7805     r = MsiOpenProductA(prodcode, &hprod);
7806     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7807     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7808
7809     size = MAX_PATH;
7810     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7812     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7813     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7814
7815     MsiCloseHandle(hprod);
7816
7817     RegDeleteValueA(props, "ManagedLocalPackage");
7818     delete_key(props, "", access & KEY_WOW64_64KEY);
7819     RegCloseKey(props);
7820     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7821     RegCloseKey(userkey);
7822     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7823     RegCloseKey(prodkey);
7824
7825     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7826
7827     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7828     lstrcatA(keypath, prod_squashed);
7829
7830     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7832
7833     /* unmanaged product key exists */
7834     hprod = 0xdeadbeef;
7835     r = MsiOpenProductA(prodcode, &hprod);
7836     ok(r == ERROR_UNKNOWN_PRODUCT,
7837        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7838     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7839
7840     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7841     lstrcatA(keypath, "Installer\\UserData\\");
7842     lstrcatA(keypath, usersid);
7843     lstrcatA(keypath, "\\Products\\");
7844     lstrcatA(keypath, prod_squashed);
7845
7846     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7847     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7848
7849     /* user product key exists */
7850     hprod = 0xdeadbeef;
7851     r = MsiOpenProductA(prodcode, &hprod);
7852     ok(r == ERROR_UNKNOWN_PRODUCT,
7853        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7854     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7855
7856     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7857     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7858
7859     /* InstallProperties key exists */
7860     hprod = 0xdeadbeef;
7861     r = MsiOpenProductA(prodcode, &hprod);
7862     ok(r == ERROR_UNKNOWN_PRODUCT,
7863        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7864     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7865
7866     lstrcpyA(val, path);
7867     lstrcatA(val, "\\winetest.msi");
7868     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7869                          (const BYTE *)val, lstrlenA(val) + 1);
7870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7871
7872     /* LocalPackage value exists */
7873     hprod = 0xdeadbeef;
7874     r = MsiOpenProductA(prodcode, &hprod);
7875     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7876     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7877
7878     size = MAX_PATH;
7879     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7881     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7882     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7883
7884     MsiCloseHandle(hprod);
7885
7886     RegDeleteValueA(props, "LocalPackage");
7887     delete_key(props, "", access & KEY_WOW64_64KEY);
7888     RegCloseKey(props);
7889     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7890     RegCloseKey(userkey);
7891     RegDeleteKeyA(prodkey, "");
7892     RegCloseKey(prodkey);
7893
7894     /* MSIINSTALLCONTEXT_MACHINE */
7895
7896     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7897     lstrcatA(keypath, prod_squashed);
7898
7899     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7901
7902     /* managed product key exists */
7903     hprod = 0xdeadbeef;
7904     r = MsiOpenProductA(prodcode, &hprod);
7905     ok(r == ERROR_UNKNOWN_PRODUCT,
7906        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7907     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7908
7909     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7910     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7911     lstrcatA(keypath, prod_squashed);
7912
7913     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7915
7916     /* user product key exists */
7917     hprod = 0xdeadbeef;
7918     r = MsiOpenProductA(prodcode, &hprod);
7919     ok(r == ERROR_UNKNOWN_PRODUCT,
7920        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7921     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7922
7923     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7925
7926     /* InstallProperties key exists */
7927     hprod = 0xdeadbeef;
7928     r = MsiOpenProductA(prodcode, &hprod);
7929     ok(r == ERROR_UNKNOWN_PRODUCT,
7930        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7931     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7932
7933     lstrcpyA(val, path);
7934     lstrcatA(val, "\\winetest.msi");
7935     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7936                          (const BYTE *)val, lstrlenA(val) + 1);
7937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7938
7939     /* LocalPackage value exists */
7940     hprod = 0xdeadbeef;
7941     r = MsiOpenProductA(prodcode, &hprod);
7942     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7943     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7944
7945     size = MAX_PATH;
7946     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7947     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7948     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7949     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7950
7951     MsiCloseHandle(hprod);
7952
7953     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7954                          (const BYTE *)"winetest.msi", 13);
7955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7956
7957     /* LocalPackage has just the package name */
7958     hprod = 0xdeadbeef;
7959     r = MsiOpenProductA(prodcode, &hprod);
7960     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
7961     {
7962         skip("Not enough rights to perform tests\n");
7963         goto error;
7964     }
7965     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7966        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7967     if (r == ERROR_SUCCESS)
7968         MsiCloseHandle(hprod);
7969     else
7970         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7971
7972     lstrcpyA(val, path);
7973     lstrcatA(val, "\\winetest.msi");
7974     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7975                          (const BYTE *)val, lstrlenA(val) + 1);
7976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7977
7978     DeleteFileA(msifile);
7979
7980     /* local package does not exist */
7981     hprod = 0xdeadbeef;
7982     r = MsiOpenProductA(prodcode, &hprod);
7983     ok(r == ERROR_UNKNOWN_PRODUCT,
7984        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7985     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7986
7987 error:
7988     RegDeleteValueA(props, "LocalPackage");
7989     delete_key(props, "", access & KEY_WOW64_64KEY);
7990     RegCloseKey(props);
7991     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7992     RegCloseKey(userkey);
7993     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7994     RegCloseKey(prodkey);
7995
7996     DeleteFileA(msifile);
7997     LocalFree(usersid);
7998 }
7999
8000 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
8001 {
8002     MSIINSTALLCONTEXT context;
8003     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8004     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8005     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8006     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8007     HKEY prodkey, patches, udprod, udpatch, hpatch;
8008     DWORD size, data;
8009     LONG res;
8010     UINT r;
8011     REGSAM access = KEY_ALL_ACCESS;
8012
8013     create_test_guid(prodcode, prod_squashed);
8014     create_test_guid(patch, patch_squashed);
8015
8016     if (is_wow64)
8017         access |= KEY_WOW64_64KEY;
8018
8019     /* MSIPATCHSTATE_APPLIED */
8020
8021     lstrcpyA(patchcode, "apple");
8022     lstrcpyA(targetprod, "banana");
8023     context = 0xdeadbeef;
8024     lstrcpyA(targetsid, "kiwi");
8025     size = MAX_PATH;
8026     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8027                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8028                            &context, targetsid, &size);
8029     if (r == ERROR_ACCESS_DENIED)
8030     {
8031         skip("Not enough rights to perform tests\n");
8032         return;
8033     }
8034     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8035     ok(!lstrcmpA(patchcode, "apple"),
8036        "Expected patchcode to be unchanged, got %s\n", patchcode);
8037     ok(!lstrcmpA(targetprod, "banana"),
8038        "Expected targetprod to be unchanged, got %s\n", targetprod);
8039     ok(context == 0xdeadbeef,
8040        "Expected context to be unchanged, got %d\n", context);
8041     ok(!lstrcmpA(targetsid, "kiwi"),
8042        "Expected targetsid to be unchanged, got %s\n", targetsid);
8043     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8044
8045     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8046     lstrcatA(keypath, expectedsid);
8047     lstrcatA(keypath, "\\Installer\\Products\\");
8048     lstrcatA(keypath, prod_squashed);
8049
8050     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8051     if (res == ERROR_ACCESS_DENIED)
8052     {
8053         skip("Not enough rights to perform tests\n");
8054         return;
8055     }
8056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8057
8058     /* managed product key exists */
8059     lstrcpyA(patchcode, "apple");
8060     lstrcpyA(targetprod, "banana");
8061     context = 0xdeadbeef;
8062     lstrcpyA(targetsid, "kiwi");
8063     size = MAX_PATH;
8064     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8065                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8066                            &context, targetsid, &size);
8067     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8068     ok(!lstrcmpA(patchcode, "apple"),
8069        "Expected patchcode to be unchanged, got %s\n", patchcode);
8070     ok(!lstrcmpA(targetprod, "banana"),
8071        "Expected targetprod to be unchanged, got %s\n", targetprod);
8072     ok(context == 0xdeadbeef,
8073        "Expected context to be unchanged, got %d\n", context);
8074     ok(!lstrcmpA(targetsid, "kiwi"),
8075        "Expected targetsid to be unchanged, got %s\n", targetsid);
8076     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8077
8078     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8080
8081     /* patches key exists */
8082     lstrcpyA(patchcode, "apple");
8083     lstrcpyA(targetprod, "banana");
8084     context = 0xdeadbeef;
8085     lstrcpyA(targetsid, "kiwi");
8086     size = MAX_PATH;
8087     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8088                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8089                            &context, targetsid, &size);
8090     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8091     ok(!lstrcmpA(patchcode, "apple"),
8092        "Expected patchcode to be unchanged, got %s\n", patchcode);
8093     ok(!lstrcmpA(targetprod, "banana"),
8094        "Expected targetprod to be unchanged, got %s\n", targetprod);
8095     ok(context == 0xdeadbeef,
8096        "Expected context to be unchanged, got %d\n", context);
8097     ok(!lstrcmpA(targetsid, "kiwi"),
8098        "Expected targetsid to be unchanged, got %s\n", targetsid);
8099     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8100
8101     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8102                          (const BYTE *)patch_squashed,
8103                          lstrlenA(patch_squashed) + 1);
8104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8105
8106     /* Patches value exists, is not REG_MULTI_SZ */
8107     lstrcpyA(patchcode, "apple");
8108     lstrcpyA(targetprod, "banana");
8109     context = 0xdeadbeef;
8110     lstrcpyA(targetsid, "kiwi");
8111     size = MAX_PATH;
8112     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8113                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8114                            &context, targetsid, &size);
8115     ok(r == ERROR_BAD_CONFIGURATION,
8116        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8117     ok(!lstrcmpA(patchcode, "apple"),
8118        "Expected patchcode to be unchanged, got %s\n", patchcode);
8119     ok(!lstrcmpA(targetprod, "banana"),
8120        "Expected targetprod to be unchanged, got %s\n", targetprod);
8121     ok(context == 0xdeadbeef,
8122        "Expected context to be unchanged, got %d\n", context);
8123     ok(!lstrcmpA(targetsid, "kiwi"),
8124        "Expected targetsid to be unchanged, got %s\n", targetsid);
8125     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8126
8127     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8128                          (const BYTE *)"a\0b\0c\0\0", 7);
8129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8130
8131     /* Patches value exists, is not a squashed guid */
8132     lstrcpyA(patchcode, "apple");
8133     lstrcpyA(targetprod, "banana");
8134     context = 0xdeadbeef;
8135     lstrcpyA(targetsid, "kiwi");
8136     size = MAX_PATH;
8137     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8138                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8139                            &context, targetsid, &size);
8140     ok(r == ERROR_BAD_CONFIGURATION,
8141        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8142     ok(!lstrcmpA(patchcode, "apple"),
8143        "Expected patchcode to be unchanged, got %s\n", patchcode);
8144     ok(!lstrcmpA(targetprod, "banana"),
8145        "Expected targetprod to be unchanged, got %s\n", targetprod);
8146     ok(context == 0xdeadbeef,
8147        "Expected context to be unchanged, got %d\n", context);
8148     ok(!lstrcmpA(targetsid, "kiwi"),
8149        "Expected targetsid to be unchanged, got %s\n", targetsid);
8150     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8151
8152     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8153     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8154                          (const BYTE *)patch_squashed,
8155                          lstrlenA(patch_squashed) + 2);
8156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8157
8158     /* Patches value exists */
8159     lstrcpyA(patchcode, "apple");
8160     lstrcpyA(targetprod, "banana");
8161     context = 0xdeadbeef;
8162     lstrcpyA(targetsid, "kiwi");
8163     size = MAX_PATH;
8164     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8165                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8166                            &context, targetsid, &size);
8167     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8168     ok(!lstrcmpA(patchcode, "apple"),
8169        "Expected patchcode to be unchanged, got %s\n", patchcode);
8170     ok(!lstrcmpA(targetprod, "banana"),
8171        "Expected targetprod to be unchanged, got %s\n", targetprod);
8172     ok(context == 0xdeadbeef,
8173        "Expected context to be unchanged, got %d\n", context);
8174     ok(!lstrcmpA(targetsid, "kiwi"),
8175        "Expected targetsid to be unchanged, got %s\n", targetsid);
8176     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8177
8178     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8179                          (const BYTE *)"whatever", 9);
8180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8181
8182     /* patch squashed value exists */
8183     lstrcpyA(patchcode, "apple");
8184     lstrcpyA(targetprod, "banana");
8185     context = 0xdeadbeef;
8186     lstrcpyA(targetsid, "kiwi");
8187     size = MAX_PATH;
8188     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8189                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8190                            &context, targetsid, &size);
8191     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8192     ok(!lstrcmpA(patchcode, patch),
8193        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8194     ok(!lstrcmpA(targetprod, prodcode),
8195        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8196     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8197        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8198     ok(!lstrcmpA(targetsid, expectedsid),
8199        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8200     ok(size == lstrlenA(expectedsid),
8201        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8202
8203     /* increase the index */
8204     lstrcpyA(patchcode, "apple");
8205     lstrcpyA(targetprod, "banana");
8206     context = 0xdeadbeef;
8207     lstrcpyA(targetsid, "kiwi");
8208     size = MAX_PATH;
8209     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8210                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
8211                            &context, targetsid, &size);
8212     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8213     ok(!lstrcmpA(patchcode, "apple"),
8214        "Expected patchcode to be unchanged, got %s\n", patchcode);
8215     ok(!lstrcmpA(targetprod, "banana"),
8216        "Expected targetprod to be unchanged, got %s\n", targetprod);
8217     ok(context == 0xdeadbeef,
8218        "Expected context to be unchanged, got %d\n", context);
8219     ok(!lstrcmpA(targetsid, "kiwi"),
8220        "Expected targetsid to be unchanged, got %s\n", targetsid);
8221     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8222
8223     /* increase again */
8224     lstrcpyA(patchcode, "apple");
8225     lstrcpyA(targetprod, "banana");
8226     context = 0xdeadbeef;
8227     lstrcpyA(targetsid, "kiwi");
8228     size = MAX_PATH;
8229     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8230                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8231                            &context, targetsid, &size);
8232     ok(r == ERROR_INVALID_PARAMETER,
8233        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8234     ok(!lstrcmpA(patchcode, "apple"),
8235        "Expected patchcode to be unchanged, got %s\n", patchcode);
8236     ok(!lstrcmpA(targetprod, "banana"),
8237        "Expected targetprod to be unchanged, got %s\n", targetprod);
8238     ok(context == 0xdeadbeef,
8239        "Expected context to be unchanged, got %d\n", context);
8240     ok(!lstrcmpA(targetsid, "kiwi"),
8241        "Expected targetsid to be unchanged, got %s\n", targetsid);
8242     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8243
8244     /* szPatchCode is NULL */
8245     lstrcpyA(targetprod, "banana");
8246     context = 0xdeadbeef;
8247     lstrcpyA(targetsid, "kiwi");
8248     size = MAX_PATH;
8249     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8250                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8251                            &context, targetsid, &size);
8252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8253     ok(!lstrcmpA(targetprod, prodcode),
8254        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8255     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8256        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8257     ok(!lstrcmpA(targetsid, expectedsid),
8258        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8259     ok(size == lstrlenA(expectedsid),
8260        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8261
8262     /* szTargetProductCode is NULL */
8263     lstrcpyA(patchcode, "apple");
8264     context = 0xdeadbeef;
8265     lstrcpyA(targetsid, "kiwi");
8266     size = MAX_PATH;
8267     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8268                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8269                            &context, targetsid, &size);
8270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8271     ok(!lstrcmpA(patchcode, patch),
8272        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8273     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8274        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8275     ok(!lstrcmpA(targetsid, expectedsid),
8276        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8277     ok(size == lstrlenA(expectedsid),
8278        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8279
8280     /* pdwTargetProductContext is NULL */
8281     lstrcpyA(patchcode, "apple");
8282     lstrcpyA(targetprod, "banana");
8283     lstrcpyA(targetsid, "kiwi");
8284     size = MAX_PATH;
8285     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8286                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8287                            NULL, targetsid, &size);
8288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8289     ok(!lstrcmpA(patchcode, patch),
8290        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8291     ok(!lstrcmpA(targetprod, prodcode),
8292        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8293     ok(!lstrcmpA(targetsid, expectedsid),
8294        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8295     ok(size == lstrlenA(expectedsid),
8296        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8297
8298     /* szTargetUserSid is NULL */
8299     lstrcpyA(patchcode, "apple");
8300     lstrcpyA(targetprod, "banana");
8301     context = 0xdeadbeef;
8302     size = MAX_PATH;
8303     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8304                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8305                            &context, NULL, &size);
8306     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8307     ok(!lstrcmpA(patchcode, patch),
8308        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8309     ok(!lstrcmpA(targetprod, prodcode),
8310        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8311     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8312        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8313     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8314        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8315
8316     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8317     lstrcpyA(patchcode, "apple");
8318     lstrcpyA(targetprod, "banana");
8319     context = 0xdeadbeef;
8320     lstrcpyA(targetsid, "kiwi");
8321     size = lstrlenA(expectedsid);
8322     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8323                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8324                            &context, targetsid, &size);
8325     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8326     ok(!lstrcmpA(patchcode, patch),
8327        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8328     ok(!lstrcmpA(targetprod, prodcode),
8329        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8330     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8331        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8332     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8333        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8334     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8335        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8336
8337     /* pcchTargetUserSid has enough room for NULL terminator */
8338     lstrcpyA(patchcode, "apple");
8339     lstrcpyA(targetprod, "banana");
8340     context = 0xdeadbeef;
8341     lstrcpyA(targetsid, "kiwi");
8342     size = lstrlenA(expectedsid) + 1;
8343     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8344                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8345                            &context, targetsid, &size);
8346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8347     ok(!lstrcmpA(patchcode, patch),
8348        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8349     ok(!lstrcmpA(targetprod, prodcode),
8350        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8351     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8352        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8353     ok(!lstrcmpA(targetsid, expectedsid),
8354        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8355     ok(size == lstrlenA(expectedsid),
8356        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8357
8358     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8359     lstrcpyA(patchcode, "apple");
8360     lstrcpyA(targetprod, "banana");
8361     context = 0xdeadbeef;
8362     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8363                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8364                            &context, NULL, NULL);
8365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8366     ok(!lstrcmpA(patchcode, patch),
8367        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8368     ok(!lstrcmpA(targetprod, prodcode),
8369        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8370     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8371        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8372
8373     /* MSIPATCHSTATE_SUPERSEDED */
8374
8375     lstrcpyA(patchcode, "apple");
8376     lstrcpyA(targetprod, "banana");
8377     context = 0xdeadbeef;
8378     lstrcpyA(targetsid, "kiwi");
8379     size = MAX_PATH;
8380     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8381                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8382                            &context, targetsid, &size);
8383     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8384     ok(!lstrcmpA(patchcode, "apple"),
8385        "Expected patchcode to be unchanged, got %s\n", patchcode);
8386     ok(!lstrcmpA(targetprod, "banana"),
8387        "Expected targetprod to be unchanged, got %s\n", targetprod);
8388     ok(context == 0xdeadbeef,
8389        "Expected context to be unchanged, got %d\n", context);
8390     ok(!lstrcmpA(targetsid, "kiwi"),
8391        "Expected targetsid to be unchanged, got %s\n", targetsid);
8392     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8393
8394     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8395     lstrcatA(keypath, expectedsid);
8396     lstrcatA(keypath, "\\Products\\");
8397     lstrcatA(keypath, prod_squashed);
8398
8399     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8401
8402     /* UserData product key exists */
8403     lstrcpyA(patchcode, "apple");
8404     lstrcpyA(targetprod, "banana");
8405     context = 0xdeadbeef;
8406     lstrcpyA(targetsid, "kiwi");
8407     size = MAX_PATH;
8408     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8409                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8410                            &context, targetsid, &size);
8411     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8412     ok(!lstrcmpA(patchcode, "apple"),
8413        "Expected patchcode to be unchanged, got %s\n", patchcode);
8414     ok(!lstrcmpA(targetprod, "banana"),
8415        "Expected targetprod to be unchanged, got %s\n", targetprod);
8416     ok(context == 0xdeadbeef,
8417        "Expected context to be unchanged, got %d\n", context);
8418     ok(!lstrcmpA(targetsid, "kiwi"),
8419        "Expected targetsid to be unchanged, got %s\n", targetsid);
8420     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8421
8422     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8424
8425     /* UserData patches key exists */
8426     lstrcpyA(patchcode, "apple");
8427     lstrcpyA(targetprod, "banana");
8428     context = 0xdeadbeef;
8429     lstrcpyA(targetsid, "kiwi");
8430     size = MAX_PATH;
8431     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8432                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8433                            &context, targetsid, &size);
8434     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8435     ok(!lstrcmpA(patchcode, "apple"),
8436        "Expected patchcode to be unchanged, got %s\n", patchcode);
8437     ok(!lstrcmpA(targetprod, "banana"),
8438        "Expected targetprod to be unchanged, got %s\n", targetprod);
8439     ok(context == 0xdeadbeef,
8440        "Expected context to be unchanged, got %d\n", context);
8441     ok(!lstrcmpA(targetsid, "kiwi"),
8442        "Expected targetsid to be unchanged, got %s\n", targetsid);
8443     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8444
8445     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8447
8448     /* specific UserData patch key exists */
8449     lstrcpyA(patchcode, "apple");
8450     lstrcpyA(targetprod, "banana");
8451     context = 0xdeadbeef;
8452     lstrcpyA(targetsid, "kiwi");
8453     size = MAX_PATH;
8454     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8455                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8456                            &context, targetsid, &size);
8457     ok(r == ERROR_BAD_CONFIGURATION,
8458        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8459     ok(!lstrcmpA(patchcode, "apple"),
8460        "Expected patchcode to be unchanged, got %s\n", patchcode);
8461     ok(!lstrcmpA(targetprod, "banana"),
8462        "Expected targetprod to be unchanged, got %s\n", targetprod);
8463     ok(context == 0xdeadbeef,
8464        "Expected context to be unchanged, got %d\n", context);
8465     ok(!lstrcmpA(targetsid, "kiwi"),
8466        "Expected targetsid to be unchanged, got %s\n", targetsid);
8467     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8468
8469     data = MSIPATCHSTATE_SUPERSEDED;
8470     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8471                          (const BYTE *)&data, sizeof(DWORD));
8472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8473
8474     /* State value exists */
8475     lstrcpyA(patchcode, "apple");
8476     lstrcpyA(targetprod, "banana");
8477     context = 0xdeadbeef;
8478     lstrcpyA(targetsid, "kiwi");
8479     size = MAX_PATH;
8480     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8481                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8482                            &context, targetsid, &size);
8483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8484     ok(!lstrcmpA(patchcode, patch),
8485        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8486     ok(!lstrcmpA(targetprod, prodcode),
8487        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8488     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8489        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8490     ok(!lstrcmpA(targetsid, expectedsid),
8491        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8492     ok(size == lstrlenA(expectedsid),
8493        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8494
8495     /* MSIPATCHSTATE_OBSOLETED */
8496
8497     lstrcpyA(patchcode, "apple");
8498     lstrcpyA(targetprod, "banana");
8499     context = 0xdeadbeef;
8500     lstrcpyA(targetsid, "kiwi");
8501     size = MAX_PATH;
8502     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8503                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8504                            &context, targetsid, &size);
8505     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8506     ok(!lstrcmpA(patchcode, "apple"),
8507        "Expected patchcode to be unchanged, got %s\n", patchcode);
8508     ok(!lstrcmpA(targetprod, "banana"),
8509        "Expected targetprod to be unchanged, got %s\n", targetprod);
8510     ok(context == 0xdeadbeef,
8511        "Expected context to be unchanged, got %d\n", context);
8512     ok(!lstrcmpA(targetsid, "kiwi"),
8513        "Expected targetsid to be unchanged, got %s\n", targetsid);
8514     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8515
8516     data = MSIPATCHSTATE_OBSOLETED;
8517     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8518                          (const BYTE *)&data, sizeof(DWORD));
8519     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8520
8521     /* State value is obsoleted */
8522     lstrcpyA(patchcode, "apple");
8523     lstrcpyA(targetprod, "banana");
8524     context = 0xdeadbeef;
8525     lstrcpyA(targetsid, "kiwi");
8526     size = MAX_PATH;
8527     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8528                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8529                            &context, targetsid, &size);
8530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8531     ok(!lstrcmpA(patchcode, patch),
8532        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8533     ok(!lstrcmpA(targetprod, prodcode),
8534        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8535     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8536        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8537     ok(!lstrcmpA(targetsid, expectedsid),
8538        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8539     ok(size == lstrlenA(expectedsid),
8540        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8541
8542     /* MSIPATCHSTATE_REGISTERED */
8543     /* FIXME */
8544
8545     /* MSIPATCHSTATE_ALL */
8546
8547     /* 1st */
8548     lstrcpyA(patchcode, "apple");
8549     lstrcpyA(targetprod, "banana");
8550     context = 0xdeadbeef;
8551     lstrcpyA(targetsid, "kiwi");
8552     size = MAX_PATH;
8553     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8554                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8555                            &context, targetsid, &size);
8556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8557     ok(!lstrcmpA(patchcode, patch),
8558        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8559     ok(!lstrcmpA(targetprod, prodcode),
8560        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8561     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8562        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8563     ok(!lstrcmpA(targetsid, expectedsid),
8564        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8565     ok(size == lstrlenA(expectedsid),
8566        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8567
8568     /* same patch in multiple places, only one is enumerated */
8569     lstrcpyA(patchcode, "apple");
8570     lstrcpyA(targetprod, "banana");
8571     context = 0xdeadbeef;
8572     lstrcpyA(targetsid, "kiwi");
8573     size = MAX_PATH;
8574     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8575                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8576                            &context, targetsid, &size);
8577     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8578     ok(!lstrcmpA(patchcode, "apple"),
8579        "Expected patchcode to be unchanged, got %s\n", patchcode);
8580     ok(!lstrcmpA(targetprod, "banana"),
8581        "Expected targetprod to be unchanged, got %s\n", targetprod);
8582     ok(context == 0xdeadbeef,
8583        "Expected context to be unchanged, got %d\n", context);
8584     ok(!lstrcmpA(targetsid, "kiwi"),
8585        "Expected targetsid to be unchanged, got %s\n", targetsid);
8586     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8587
8588     RegDeleteValueA(hpatch, "State");
8589     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8590     RegCloseKey(hpatch);
8591     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8592     RegCloseKey(udpatch);
8593     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8594     RegCloseKey(udprod);
8595     RegDeleteValueA(patches, "Patches");
8596     delete_key(patches, "", access & KEY_WOW64_64KEY);
8597     RegCloseKey(patches);
8598     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8599     RegCloseKey(prodkey);
8600 }
8601
8602 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8603 {
8604     MSIINSTALLCONTEXT context;
8605     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8606     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8607     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8608     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8609     HKEY prodkey, patches, udprod, udpatch;
8610     HKEY userkey, hpatch;
8611     DWORD size, data;
8612     LONG res;
8613     UINT r;
8614     REGSAM access = KEY_ALL_ACCESS;
8615
8616     create_test_guid(prodcode, prod_squashed);
8617     create_test_guid(patch, patch_squashed);
8618
8619     if (is_wow64)
8620         access |= KEY_WOW64_64KEY;
8621
8622     /* MSIPATCHSTATE_APPLIED */
8623
8624     lstrcpyA(patchcode, "apple");
8625     lstrcpyA(targetprod, "banana");
8626     context = 0xdeadbeef;
8627     lstrcpyA(targetsid, "kiwi");
8628     size = MAX_PATH;
8629     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8630                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8631                            &context, targetsid, &size);
8632     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8633     ok(!lstrcmpA(patchcode, "apple"),
8634        "Expected patchcode to be unchanged, got %s\n", patchcode);
8635     ok(!lstrcmpA(targetprod, "banana"),
8636        "Expected targetprod to be unchanged, got %s\n", targetprod);
8637     ok(context == 0xdeadbeef,
8638        "Expected context to be unchanged, got %d\n", context);
8639     ok(!lstrcmpA(targetsid, "kiwi"),
8640        "Expected targetsid to be unchanged, got %s\n", targetsid);
8641     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8642
8643     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8644     lstrcatA(keypath, prod_squashed);
8645
8646     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8648
8649     /* current user product key exists */
8650     lstrcpyA(patchcode, "apple");
8651     lstrcpyA(targetprod, "banana");
8652     context = 0xdeadbeef;
8653     lstrcpyA(targetsid, "kiwi");
8654     size = MAX_PATH;
8655     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8656                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8657                            &context, targetsid, &size);
8658     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8659     ok(!lstrcmpA(patchcode, "apple"),
8660        "Expected patchcode to be unchanged, got %s\n", patchcode);
8661     ok(!lstrcmpA(targetprod, "banana"),
8662        "Expected targetprod to be unchanged, got %s\n", targetprod);
8663     ok(context == 0xdeadbeef,
8664        "Expected context to be unchanged, got %d\n", context);
8665     ok(!lstrcmpA(targetsid, "kiwi"),
8666        "Expected targetsid to be unchanged, got %s\n", targetsid);
8667     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8668
8669     res = RegCreateKeyA(prodkey, "Patches", &patches);
8670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8671
8672     /* Patches key exists */
8673     lstrcpyA(patchcode, "apple");
8674     lstrcpyA(targetprod, "banana");
8675     context = 0xdeadbeef;
8676     lstrcpyA(targetsid, "kiwi");
8677     size = MAX_PATH;
8678     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8679                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8680                            &context, targetsid, &size);
8681     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8682     ok(!lstrcmpA(patchcode, "apple"),
8683        "Expected patchcode to be unchanged, got %s\n", patchcode);
8684     ok(!lstrcmpA(targetprod, "banana"),
8685        "Expected targetprod to be unchanged, got %s\n", targetprod);
8686     ok(context == 0xdeadbeef,
8687        "Expected context to be unchanged, got %d\n", context);
8688     ok(!lstrcmpA(targetsid, "kiwi"),
8689        "Expected targetsid to be unchanged, got %s\n", targetsid);
8690     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8691
8692     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8693                          (const BYTE *)patch_squashed,
8694                          lstrlenA(patch_squashed) + 1);
8695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8696
8697     /* Patches value exists, is not REG_MULTI_SZ */
8698     lstrcpyA(patchcode, "apple");
8699     lstrcpyA(targetprod, "banana");
8700     context = 0xdeadbeef;
8701     lstrcpyA(targetsid, "kiwi");
8702     size = MAX_PATH;
8703     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8704                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8705                            &context, targetsid, &size);
8706     ok(r == ERROR_BAD_CONFIGURATION,
8707        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8708     ok(!lstrcmpA(patchcode, "apple"),
8709        "Expected patchcode to be unchanged, got %s\n", patchcode);
8710     ok(!lstrcmpA(targetprod, "banana"),
8711        "Expected targetprod to be unchanged, got %s\n", targetprod);
8712     ok(context == 0xdeadbeef,
8713        "Expected context to be unchanged, got %d\n", context);
8714     ok(!lstrcmpA(targetsid, "kiwi"),
8715        "Expected targetsid to be unchanged, got %s\n", targetsid);
8716     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8717
8718     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8719                          (const BYTE *)"a\0b\0c\0\0", 7);
8720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8721
8722     /* Patches value exists, is not a squashed guid */
8723     lstrcpyA(patchcode, "apple");
8724     lstrcpyA(targetprod, "banana");
8725     context = 0xdeadbeef;
8726     lstrcpyA(targetsid, "kiwi");
8727     size = MAX_PATH;
8728     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8729                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8730                            &context, targetsid, &size);
8731     ok(r == ERROR_BAD_CONFIGURATION,
8732        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8733     ok(!lstrcmpA(patchcode, "apple"),
8734        "Expected patchcode to be unchanged, got %s\n", patchcode);
8735     ok(!lstrcmpA(targetprod, "banana"),
8736        "Expected targetprod to be unchanged, got %s\n", targetprod);
8737     ok(context == 0xdeadbeef,
8738        "Expected context to be unchanged, got %d\n", context);
8739     ok(!lstrcmpA(targetsid, "kiwi"),
8740        "Expected targetsid to be unchanged, got %s\n", targetsid);
8741     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8742
8743     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8744     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8745                          (const BYTE *)patch_squashed,
8746                          lstrlenA(patch_squashed) + 2);
8747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8748
8749     /* Patches value exists */
8750     lstrcpyA(patchcode, "apple");
8751     lstrcpyA(targetprod, "banana");
8752     context = 0xdeadbeef;
8753     lstrcpyA(targetsid, "kiwi");
8754     size = MAX_PATH;
8755     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8756                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8757                            &context, targetsid, &size);
8758     ok(r == ERROR_NO_MORE_ITEMS ||
8759        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8760        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8761     ok(!lstrcmpA(patchcode, "apple"),
8762        "Expected patchcode to be unchanged, got %s\n", patchcode);
8763     ok(!lstrcmpA(targetprod, "banana"),
8764        "Expected targetprod to be unchanged, got %s\n", targetprod);
8765     ok(context == 0xdeadbeef,
8766        "Expected context to be unchanged, got %d\n", context);
8767     ok(!lstrcmpA(targetsid, "kiwi"),
8768        "Expected targetsid to be unchanged, got %s\n", targetsid);
8769     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8770
8771     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8772                          (const BYTE *)"whatever", 9);
8773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8774
8775     /* patch code value exists */
8776     lstrcpyA(patchcode, "apple");
8777     lstrcpyA(targetprod, "banana");
8778     context = 0xdeadbeef;
8779     lstrcpyA(targetsid, "kiwi");
8780     size = MAX_PATH;
8781     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8782                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8783                            &context, targetsid, &size);
8784     ok(r == ERROR_NO_MORE_ITEMS ||
8785        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8786        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8787     ok(!lstrcmpA(patchcode, "apple"),
8788        "Expected patchcode to be unchanged, got %s\n", patchcode);
8789     ok(!lstrcmpA(targetprod, "banana"),
8790        "Expected targetprod to be unchanged, got %s\n", targetprod);
8791     ok(context == 0xdeadbeef,
8792        "Expected context to be unchanged, got %d\n", context);
8793     ok(!lstrcmpA(targetsid, "kiwi"),
8794        "Expected targetsid to be unchanged, got %s\n", targetsid);
8795     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8796
8797     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8798     lstrcatA(keypath, expectedsid);
8799     lstrcatA(keypath, "\\Patches\\");
8800     lstrcatA(keypath, patch_squashed);
8801
8802     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8803     if (res == ERROR_ACCESS_DENIED)
8804     {
8805         skip("Not enough rights to perform tests\n");
8806         goto error;
8807     }
8808     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8809
8810     /* userdata patch key exists */
8811     lstrcpyA(patchcode, "apple");
8812     lstrcpyA(targetprod, "banana");
8813     context = 0xdeadbeef;
8814     lstrcpyA(targetsid, "kiwi");
8815     size = MAX_PATH;
8816     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8817                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8818                            &context, targetsid, &size);
8819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8820     ok(!lstrcmpA(patchcode, patch),
8821        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8822     ok(!lstrcmpA(targetprod, prodcode),
8823        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8824     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8825        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8826     ok(!lstrcmpA(targetsid, expectedsid),
8827        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8828     ok(size == lstrlenA(expectedsid),
8829        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8830
8831     /* MSIPATCHSTATE_SUPERSEDED */
8832
8833     lstrcpyA(patchcode, "apple");
8834     lstrcpyA(targetprod, "banana");
8835     context = 0xdeadbeef;
8836     lstrcpyA(targetsid, "kiwi");
8837     size = MAX_PATH;
8838     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8839                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8840                            &context, targetsid, &size);
8841     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8842     ok(!lstrcmpA(patchcode, "apple"),
8843        "Expected patchcode to be unchanged, got %s\n", patchcode);
8844     ok(!lstrcmpA(targetprod, "banana"),
8845        "Expected targetprod to be unchanged, got %s\n", targetprod);
8846     ok(context == 0xdeadbeef,
8847        "Expected context to be unchanged, got %d\n", context);
8848     ok(!lstrcmpA(targetsid, "kiwi"),
8849        "Expected targetsid to be unchanged, got %s\n", targetsid);
8850     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8851
8852     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8853     lstrcatA(keypath, expectedsid);
8854     lstrcatA(keypath, "\\Products\\");
8855     lstrcatA(keypath, prod_squashed);
8856
8857     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8858     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8859
8860     /* UserData product key exists */
8861     lstrcpyA(patchcode, "apple");
8862     lstrcpyA(targetprod, "banana");
8863     context = 0xdeadbeef;
8864     lstrcpyA(targetsid, "kiwi");
8865     size = MAX_PATH;
8866     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8867                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8868                            &context, targetsid, &size);
8869     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8870     ok(!lstrcmpA(patchcode, "apple"),
8871        "Expected patchcode to be unchanged, got %s\n", patchcode);
8872     ok(!lstrcmpA(targetprod, "banana"),
8873        "Expected targetprod to be unchanged, got %s\n", targetprod);
8874     ok(context == 0xdeadbeef,
8875        "Expected context to be unchanged, got %d\n", context);
8876     ok(!lstrcmpA(targetsid, "kiwi"),
8877        "Expected targetsid to be unchanged, got %s\n", targetsid);
8878     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8879
8880     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8881     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8882
8883     /* UserData patches key exists */
8884     lstrcpyA(patchcode, "apple");
8885     lstrcpyA(targetprod, "banana");
8886     context = 0xdeadbeef;
8887     lstrcpyA(targetsid, "kiwi");
8888     size = MAX_PATH;
8889     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8890                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8891                            &context, targetsid, &size);
8892     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8893     ok(!lstrcmpA(patchcode, "apple"),
8894        "Expected patchcode to be unchanged, got %s\n", patchcode);
8895     ok(!lstrcmpA(targetprod, "banana"),
8896        "Expected targetprod to be unchanged, got %s\n", targetprod);
8897     ok(context == 0xdeadbeef,
8898        "Expected context to be unchanged, got %d\n", context);
8899     ok(!lstrcmpA(targetsid, "kiwi"),
8900        "Expected targetsid to be unchanged, got %s\n", targetsid);
8901     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8902
8903     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8905
8906     /* specific UserData patch key exists */
8907     lstrcpyA(patchcode, "apple");
8908     lstrcpyA(targetprod, "banana");
8909     context = 0xdeadbeef;
8910     lstrcpyA(targetsid, "kiwi");
8911     size = MAX_PATH;
8912     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8913                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8914                            &context, targetsid, &size);
8915     ok(r == ERROR_BAD_CONFIGURATION,
8916        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8917     ok(!lstrcmpA(patchcode, "apple"),
8918        "Expected patchcode to be unchanged, got %s\n", patchcode);
8919     ok(!lstrcmpA(targetprod, "banana"),
8920        "Expected targetprod to be unchanged, got %s\n", targetprod);
8921     ok(context == 0xdeadbeef,
8922        "Expected context to be unchanged, got %d\n", context);
8923     ok(!lstrcmpA(targetsid, "kiwi"),
8924        "Expected targetsid to be unchanged, got %s\n", targetsid);
8925     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8926
8927     data = MSIPATCHSTATE_SUPERSEDED;
8928     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8929                          (const BYTE *)&data, sizeof(DWORD));
8930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8931
8932     /* State value exists */
8933     lstrcpyA(patchcode, "apple");
8934     lstrcpyA(targetprod, "banana");
8935     context = 0xdeadbeef;
8936     lstrcpyA(targetsid, "kiwi");
8937     size = MAX_PATH;
8938     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8939                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8940                            &context, targetsid, &size);
8941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8942     ok(!lstrcmpA(patchcode, patch),
8943        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8944     ok(!lstrcmpA(targetprod, prodcode),
8945        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8946     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8947        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8948     ok(!lstrcmpA(targetsid, expectedsid),
8949        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8950     ok(size == lstrlenA(expectedsid),
8951        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8952
8953     /* MSIPATCHSTATE_OBSOLETED */
8954
8955     lstrcpyA(patchcode, "apple");
8956     lstrcpyA(targetprod, "banana");
8957     context = 0xdeadbeef;
8958     lstrcpyA(targetsid, "kiwi");
8959     size = MAX_PATH;
8960     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8961                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8962                            &context, targetsid, &size);
8963     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8964     ok(!lstrcmpA(patchcode, "apple"),
8965        "Expected patchcode to be unchanged, got %s\n", patchcode);
8966     ok(!lstrcmpA(targetprod, "banana"),
8967        "Expected targetprod to be unchanged, got %s\n", targetprod);
8968     ok(context == 0xdeadbeef,
8969        "Expected context to be unchanged, got %d\n", context);
8970     ok(!lstrcmpA(targetsid, "kiwi"),
8971        "Expected targetsid to be unchanged, got %s\n", targetsid);
8972     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8973
8974     data = MSIPATCHSTATE_OBSOLETED;
8975     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8976                          (const BYTE *)&data, sizeof(DWORD));
8977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8978
8979     /* State value is obsoleted */
8980     lstrcpyA(patchcode, "apple");
8981     lstrcpyA(targetprod, "banana");
8982     context = 0xdeadbeef;
8983     lstrcpyA(targetsid, "kiwi");
8984     size = MAX_PATH;
8985     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8986                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8987                            &context, targetsid, &size);
8988     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8989     ok(!lstrcmpA(patchcode, patch),
8990        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8991     ok(!lstrcmpA(targetprod, prodcode),
8992        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8993     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8994        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8995     ok(!lstrcmpA(targetsid, expectedsid),
8996        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8997     ok(size == lstrlenA(expectedsid),
8998        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8999
9000     /* MSIPATCHSTATE_REGISTERED */
9001     /* FIXME */
9002
9003     /* MSIPATCHSTATE_ALL */
9004
9005     /* 1st */
9006     lstrcpyA(patchcode, "apple");
9007     lstrcpyA(targetprod, "banana");
9008     context = 0xdeadbeef;
9009     lstrcpyA(targetsid, "kiwi");
9010     size = MAX_PATH;
9011     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9012                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9013                            &context, targetsid, &size);
9014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9015     ok(!lstrcmpA(patchcode, patch),
9016        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9017     ok(!lstrcmpA(targetprod, prodcode),
9018        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9019     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9020        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9021     ok(!lstrcmpA(targetsid, expectedsid),
9022        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9023     ok(size == lstrlenA(expectedsid),
9024        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9025
9026     /* same patch in multiple places, only one is enumerated */
9027     lstrcpyA(patchcode, "apple");
9028     lstrcpyA(targetprod, "banana");
9029     context = 0xdeadbeef;
9030     lstrcpyA(targetsid, "kiwi");
9031     size = MAX_PATH;
9032     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9033                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9034                            &context, targetsid, &size);
9035     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9036     ok(!lstrcmpA(patchcode, "apple"),
9037        "Expected patchcode to be unchanged, got %s\n", patchcode);
9038     ok(!lstrcmpA(targetprod, "banana"),
9039        "Expected targetprod to be unchanged, got %s\n", targetprod);
9040     ok(context == 0xdeadbeef,
9041        "Expected context to be unchanged, got %d\n", context);
9042     ok(!lstrcmpA(targetsid, "kiwi"),
9043        "Expected targetsid to be unchanged, got %s\n", targetsid);
9044     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9045
9046     RegDeleteValueA(hpatch, "State");
9047     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9048     RegCloseKey(hpatch);
9049     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9050     RegCloseKey(udpatch);
9051     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9052     RegCloseKey(udprod);
9053     delete_key(userkey, "", access & KEY_WOW64_64KEY);
9054     RegCloseKey(userkey);
9055     RegDeleteValueA(patches, patch_squashed);
9056     RegDeleteValueA(patches, "Patches");
9057
9058 error:
9059     RegDeleteKeyA(patches, "");
9060     RegCloseKey(patches);
9061     RegDeleteKeyA(prodkey, "");
9062     RegCloseKey(prodkey);
9063 }
9064
9065 static void test_MsiEnumPatchesEx_machine(void)
9066 {
9067     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9068     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9069     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9070     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9071     HKEY prodkey, patches, udprod, udpatch;
9072     HKEY hpatch;
9073     MSIINSTALLCONTEXT context;
9074     DWORD size, data;
9075     LONG res;
9076     UINT r;
9077     REGSAM access = KEY_ALL_ACCESS;
9078
9079     create_test_guid(prodcode, prod_squashed);
9080     create_test_guid(patch, patch_squashed);
9081
9082     if (is_wow64)
9083         access |= KEY_WOW64_64KEY;
9084
9085     /* MSIPATCHSTATE_APPLIED */
9086
9087     lstrcpyA(patchcode, "apple");
9088     lstrcpyA(targetprod, "banana");
9089     context = 0xdeadbeef;
9090     lstrcpyA(targetsid, "kiwi");
9091     size = MAX_PATH;
9092     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9093                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9094                            &context, targetsid, &size);
9095     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9096     ok(!lstrcmpA(patchcode, "apple"),
9097        "Expected patchcode to be unchanged, got %s\n", patchcode);
9098     ok(!lstrcmpA(targetprod, "banana"),
9099        "Expected targetprod to be unchanged, got %s\n", targetprod);
9100     ok(context == 0xdeadbeef,
9101        "Expected context to be unchanged, got %d\n", context);
9102     ok(!lstrcmpA(targetsid, "kiwi"),
9103        "Expected targetsid to be unchanged, got %s\n", targetsid);
9104     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9105
9106     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9107     lstrcatA(keypath, prod_squashed);
9108
9109     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9110     if (res == ERROR_ACCESS_DENIED)
9111     {
9112         skip("Not enough rights to perform tests\n");
9113         return;
9114     }
9115     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9116
9117     /* local product key exists */
9118     lstrcpyA(patchcode, "apple");
9119     lstrcpyA(targetprod, "banana");
9120     context = 0xdeadbeef;
9121     lstrcpyA(targetsid, "kiwi");
9122     size = MAX_PATH;
9123     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9124                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9125                            &context, targetsid, &size);
9126     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9127     ok(!lstrcmpA(patchcode, "apple"),
9128        "Expected patchcode to be unchanged, got %s\n", patchcode);
9129     ok(!lstrcmpA(targetprod, "banana"),
9130        "Expected targetprod to be unchanged, got %s\n", targetprod);
9131     ok(context == 0xdeadbeef,
9132        "Expected context to be unchanged, got %d\n", context);
9133     ok(!lstrcmpA(targetsid, "kiwi"),
9134        "Expected targetsid to be unchanged, got %s\n", targetsid);
9135     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9136
9137     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9138     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9139
9140     /* Patches key exists */
9141     lstrcpyA(patchcode, "apple");
9142     lstrcpyA(targetprod, "banana");
9143     context = 0xdeadbeef;
9144     lstrcpyA(targetsid, "kiwi");
9145     size = MAX_PATH;
9146     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9147                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9148                            &context, targetsid, &size);
9149     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9150     ok(!lstrcmpA(patchcode, "apple"),
9151        "Expected patchcode to be unchanged, got %s\n", patchcode);
9152     ok(!lstrcmpA(targetprod, "banana"),
9153        "Expected targetprod to be unchanged, got %s\n", targetprod);
9154     ok(context == 0xdeadbeef,
9155        "Expected context to be unchanged, got %d\n", context);
9156     ok(!lstrcmpA(targetsid, "kiwi"),
9157        "Expected targetsid to be unchanged, got %s\n", targetsid);
9158     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9159
9160     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9161                          (const BYTE *)patch_squashed,
9162                          lstrlenA(patch_squashed) + 1);
9163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9164
9165     /* Patches value exists, is not REG_MULTI_SZ */
9166     lstrcpyA(patchcode, "apple");
9167     lstrcpyA(targetprod, "banana");
9168     context = 0xdeadbeef;
9169     lstrcpyA(targetsid, "kiwi");
9170     size = MAX_PATH;
9171     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9172                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9173                            &context, targetsid, &size);
9174     ok(r == ERROR_BAD_CONFIGURATION,
9175        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9176     ok(!lstrcmpA(patchcode, "apple"),
9177        "Expected patchcode to be unchanged, got %s\n", patchcode);
9178     ok(!lstrcmpA(targetprod, "banana"),
9179        "Expected targetprod to be unchanged, got %s\n", targetprod);
9180     ok(context == 0xdeadbeef,
9181        "Expected context to be unchanged, got %d\n", context);
9182     ok(!lstrcmpA(targetsid, "kiwi"),
9183        "Expected targetsid to be unchanged, got %s\n", targetsid);
9184     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9185
9186     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9187                          (const BYTE *)"a\0b\0c\0\0", 7);
9188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9189
9190     /* Patches value exists, is not a squashed guid */
9191     lstrcpyA(patchcode, "apple");
9192     lstrcpyA(targetprod, "banana");
9193     context = 0xdeadbeef;
9194     lstrcpyA(targetsid, "kiwi");
9195     size = MAX_PATH;
9196     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9197                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9198                            &context, targetsid, &size);
9199     ok(r == ERROR_BAD_CONFIGURATION,
9200        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9201     ok(!lstrcmpA(patchcode, "apple"),
9202        "Expected patchcode to be unchanged, got %s\n", patchcode);
9203     ok(!lstrcmpA(targetprod, "banana"),
9204        "Expected targetprod to be unchanged, got %s\n", targetprod);
9205     ok(context == 0xdeadbeef,
9206        "Expected context to be unchanged, got %d\n", context);
9207     ok(!lstrcmpA(targetsid, "kiwi"),
9208        "Expected targetsid to be unchanged, got %s\n", targetsid);
9209     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9210
9211     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9212     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9213                          (const BYTE *)patch_squashed,
9214                          lstrlenA(patch_squashed) + 2);
9215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9216
9217     /* Patches value exists */
9218     lstrcpyA(patchcode, "apple");
9219     lstrcpyA(targetprod, "banana");
9220     context = 0xdeadbeef;
9221     lstrcpyA(targetsid, "kiwi");
9222     size = MAX_PATH;
9223     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9224                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9225                            &context, targetsid, &size);
9226     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9227     ok(!lstrcmpA(patchcode, "apple"),
9228        "Expected patchcode to be unchanged, got %s\n", patchcode);
9229     ok(!lstrcmpA(targetprod, "banana"),
9230        "Expected targetprod to be unchanged, got %s\n", targetprod);
9231     ok(context == 0xdeadbeef,
9232        "Expected context to be unchanged, got %d\n", context);
9233     ok(!lstrcmpA(targetsid, "kiwi"),
9234        "Expected targetsid to be unchanged, got %s\n", targetsid);
9235     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9236
9237     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9238                          (const BYTE *)"whatever", 9);
9239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9240
9241     /* patch code value exists */
9242     lstrcpyA(patchcode, "apple");
9243     lstrcpyA(targetprod, "banana");
9244     context = 0xdeadbeef;
9245     lstrcpyA(targetsid, "kiwi");
9246     size = MAX_PATH;
9247     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9248                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9249                            &context, targetsid, &size);
9250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9251     ok(!lstrcmpA(patchcode, patch),
9252        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9253     ok(!lstrcmpA(targetprod, prodcode),
9254        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9255     ok(context == MSIINSTALLCONTEXT_MACHINE,
9256        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9257     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9258     ok(size == 0, "Expected 0, got %d\n", size);
9259
9260     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9261     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9262     lstrcatA(keypath, prod_squashed);
9263
9264     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9266
9267     /* local UserData product key exists */
9268     lstrcpyA(patchcode, "apple");
9269     lstrcpyA(targetprod, "banana");
9270     context = 0xdeadbeef;
9271     lstrcpyA(targetsid, "kiwi");
9272     size = MAX_PATH;
9273     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9274                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9275                            &context, targetsid, &size);
9276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9277     ok(!lstrcmpA(patchcode, patch),
9278        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9279     ok(!lstrcmpA(targetprod, prodcode),
9280        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9281     ok(context == MSIINSTALLCONTEXT_MACHINE,
9282        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9283     ok(!lstrcmpA(targetsid, ""),
9284        "Expected \"\", got \"%s\"\n", targetsid);
9285     ok(size == 0, "Expected 0, got %d\n", size);
9286
9287     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9289
9290     /* local UserData Patches key exists */
9291     lstrcpyA(patchcode, "apple");
9292     lstrcpyA(targetprod, "banana");
9293     context = 0xdeadbeef;
9294     lstrcpyA(targetsid, "kiwi");
9295     size = MAX_PATH;
9296     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9297                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9298                            &context, targetsid, &size);
9299     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9300     ok(!lstrcmpA(patchcode, patch),
9301        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9302     ok(!lstrcmpA(targetprod, prodcode),
9303        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9304     ok(context == MSIINSTALLCONTEXT_MACHINE,
9305        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9306     ok(!lstrcmpA(targetsid, ""),
9307        "Expected \"\", got \"%s\"\n", targetsid);
9308     ok(size == 0, "Expected 0, got %d\n", size);
9309
9310     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9311     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9312
9313     /* local UserData Product patch key exists */
9314     lstrcpyA(patchcode, "apple");
9315     lstrcpyA(targetprod, "banana");
9316     context = 0xdeadbeef;
9317     lstrcpyA(targetsid, "kiwi");
9318     size = MAX_PATH;
9319     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9320                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9321                            &context, targetsid, &size);
9322     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9323     ok(!lstrcmpA(patchcode, "apple"),
9324        "Expected patchcode to be unchanged, got %s\n", patchcode);
9325     ok(!lstrcmpA(targetprod, "banana"),
9326        "Expected targetprod to be unchanged, got %s\n", targetprod);
9327     ok(context == 0xdeadbeef,
9328        "Expected context to be unchanged, got %d\n", context);
9329     ok(!lstrcmpA(targetsid, "kiwi"),
9330        "Expected targetsid to be unchanged, got %s\n", targetsid);
9331     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9332
9333     data = MSIPATCHSTATE_APPLIED;
9334     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9335                          (const BYTE *)&data, sizeof(DWORD));
9336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9337
9338     /* State value exists */
9339     lstrcpyA(patchcode, "apple");
9340     lstrcpyA(targetprod, "banana");
9341     context = 0xdeadbeef;
9342     lstrcpyA(targetsid, "kiwi");
9343     size = MAX_PATH;
9344     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9345                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9346                            &context, targetsid, &size);
9347     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9348     ok(!lstrcmpA(patchcode, patch),
9349        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9350     ok(!lstrcmpA(targetprod, prodcode),
9351        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9352     ok(context == MSIINSTALLCONTEXT_MACHINE,
9353        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9354     ok(!lstrcmpA(targetsid, ""),
9355        "Expected \"\", got \"%s\"\n", targetsid);
9356     ok(size == 0, "Expected 0, got %d\n", size);
9357
9358     /* MSIPATCHSTATE_SUPERSEDED */
9359
9360     lstrcpyA(patchcode, "apple");
9361     lstrcpyA(targetprod, "banana");
9362     context = 0xdeadbeef;
9363     lstrcpyA(targetsid, "kiwi");
9364     size = MAX_PATH;
9365     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9366                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9367                            &context, targetsid, &size);
9368     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9369     ok(!lstrcmpA(patchcode, "apple"),
9370        "Expected patchcode to be unchanged, got %s\n", patchcode);
9371     ok(!lstrcmpA(targetprod, "banana"),
9372        "Expected targetprod to be unchanged, got %s\n", targetprod);
9373     ok(context == 0xdeadbeef,
9374        "Expected context to be unchanged, got %d\n", context);
9375     ok(!lstrcmpA(targetsid, "kiwi"),
9376        "Expected targetsid to be unchanged, got %s\n", targetsid);
9377     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9378
9379     data = MSIPATCHSTATE_SUPERSEDED;
9380     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9381                          (const BYTE *)&data, sizeof(DWORD));
9382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9383
9384     /* State value is MSIPATCHSTATE_SUPERSEDED */
9385     lstrcpyA(patchcode, "apple");
9386     lstrcpyA(targetprod, "banana");
9387     context = 0xdeadbeef;
9388     lstrcpyA(targetsid, "kiwi");
9389     size = MAX_PATH;
9390     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9391                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9392                            &context, targetsid, &size);
9393     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9394     ok(!lstrcmpA(patchcode, patch),
9395        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9396     ok(!lstrcmpA(targetprod, prodcode),
9397        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9398     ok(context == MSIINSTALLCONTEXT_MACHINE,
9399        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9400     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9401     ok(size == 0, "Expected 0, got %d\n", size);
9402
9403     /* MSIPATCHSTATE_OBSOLETED */
9404
9405     lstrcpyA(patchcode, "apple");
9406     lstrcpyA(targetprod, "banana");
9407     context = 0xdeadbeef;
9408     lstrcpyA(targetsid, "kiwi");
9409     size = MAX_PATH;
9410     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9411                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9412                            &context, targetsid, &size);
9413     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9414     ok(!lstrcmpA(patchcode, "apple"),
9415        "Expected patchcode to be unchanged, got %s\n", patchcode);
9416     ok(!lstrcmpA(targetprod, "banana"),
9417        "Expected targetprod to be unchanged, got %s\n", targetprod);
9418     ok(context == 0xdeadbeef,
9419        "Expected context to be unchanged, got %d\n", context);
9420     ok(!lstrcmpA(targetsid, "kiwi"),
9421        "Expected targetsid to be unchanged, got %s\n", targetsid);
9422     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9423
9424     data = MSIPATCHSTATE_OBSOLETED;
9425     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9426                          (const BYTE *)&data, sizeof(DWORD));
9427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9428
9429     /* State value is obsoleted */
9430     lstrcpyA(patchcode, "apple");
9431     lstrcpyA(targetprod, "banana");
9432     context = 0xdeadbeef;
9433     lstrcpyA(targetsid, "kiwi");
9434     size = MAX_PATH;
9435     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9436                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9437                            &context, targetsid, &size);
9438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9439     ok(!lstrcmpA(patchcode, patch),
9440        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9441     ok(!lstrcmpA(targetprod, prodcode),
9442        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9443     ok(context == MSIINSTALLCONTEXT_MACHINE,
9444        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9445     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9446     ok(size == 0, "Expected 0, got %d\n", size);
9447
9448     /* MSIPATCHSTATE_REGISTERED */
9449     /* FIXME */
9450
9451     /* MSIPATCHSTATE_ALL */
9452
9453     /* 1st */
9454     lstrcpyA(patchcode, "apple");
9455     lstrcpyA(targetprod, "banana");
9456     context = 0xdeadbeef;
9457     lstrcpyA(targetsid, "kiwi");
9458     size = MAX_PATH;
9459     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9460                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9461                            &context, targetsid, &size);
9462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9463     ok(!lstrcmpA(patchcode, patch),
9464        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9465     ok(!lstrcmpA(targetprod, prodcode),
9466        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9467     ok(context == MSIINSTALLCONTEXT_MACHINE,
9468        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9469     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9470     ok(size == 0, "Expected 0, got %d\n", size);
9471
9472     /* same patch in multiple places, only one is enumerated */
9473     lstrcpyA(patchcode, "apple");
9474     lstrcpyA(targetprod, "banana");
9475     context = 0xdeadbeef;
9476     lstrcpyA(targetsid, "kiwi");
9477     size = MAX_PATH;
9478     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9479                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9480                            &context, targetsid, &size);
9481     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9482     ok(!lstrcmpA(patchcode, "apple"),
9483        "Expected patchcode to be unchanged, got %s\n", patchcode);
9484     ok(!lstrcmpA(targetprod, "banana"),
9485        "Expected targetprod to be unchanged, got %s\n", targetprod);
9486     ok(context == 0xdeadbeef,
9487        "Expected context to be unchanged, got %d\n", context);
9488     ok(!lstrcmpA(targetsid, "kiwi"),
9489        "Expected targetsid to be unchanged, got %s\n", targetsid);
9490     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9491
9492     RegDeleteValueA(patches, patch_squashed);
9493     RegDeleteValueA(patches, "Patches");
9494     delete_key(patches, "", access & KEY_WOW64_64KEY);
9495     RegCloseKey(patches);
9496     RegDeleteValueA(hpatch, "State");
9497     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9498     RegCloseKey(hpatch);
9499     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9500     RegCloseKey(udpatch);
9501     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9502     RegCloseKey(udprod);
9503     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9504     RegCloseKey(prodkey);
9505 }
9506
9507 static void test_MsiEnumPatchesEx(void)
9508 {
9509     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9510     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9511     CHAR patchcode[MAX_PATH];
9512     MSIINSTALLCONTEXT context;
9513     LPSTR usersid;
9514     DWORD size;
9515     UINT r;
9516
9517     if (!pMsiEnumPatchesExA)
9518     {
9519         win_skip("MsiEnumPatchesExA not implemented\n");
9520         return;
9521     }
9522
9523     create_test_guid(prodcode, prod_squashed);
9524     usersid = get_user_sid();
9525
9526     /* empty szProductCode */
9527     lstrcpyA(patchcode, "apple");
9528     lstrcpyA(targetprod, "banana");
9529     context = 0xdeadbeef;
9530     lstrcpyA(targetsid, "kiwi");
9531     size = MAX_PATH;
9532     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9533                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9534                            targetsid, &size);
9535     ok(r == ERROR_INVALID_PARAMETER,
9536        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9537     ok(!lstrcmpA(patchcode, "apple"),
9538        "Expected patchcode to be unchanged, got %s\n", patchcode);
9539     ok(!lstrcmpA(targetprod, "banana"),
9540        "Expected targetprod to be unchanged, got %s\n", targetprod);
9541     ok(context == 0xdeadbeef,
9542        "Expected context to be unchanged, got %d\n", context);
9543     ok(!lstrcmpA(targetsid, "kiwi"),
9544        "Expected targetsid to be unchanged, got %s\n", targetsid);
9545     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9546
9547     /* garbage szProductCode */
9548     lstrcpyA(patchcode, "apple");
9549     lstrcpyA(targetprod, "banana");
9550     context = 0xdeadbeef;
9551     lstrcpyA(targetsid, "kiwi");
9552     size = MAX_PATH;
9553     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9554                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9555                            targetsid, &size);
9556     ok(r == ERROR_INVALID_PARAMETER,
9557        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9558     ok(!lstrcmpA(patchcode, "apple"),
9559        "Expected patchcode to be unchanged, got %s\n", patchcode);
9560     ok(!lstrcmpA(targetprod, "banana"),
9561        "Expected targetprod to be unchanged, got %s\n", targetprod);
9562     ok(context == 0xdeadbeef,
9563        "Expected context to be unchanged, got %d\n", context);
9564     ok(!lstrcmpA(targetsid, "kiwi"),
9565        "Expected targetsid to be unchanged, got %s\n", targetsid);
9566     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9567
9568     /* guid without brackets */
9569     lstrcpyA(patchcode, "apple");
9570     lstrcpyA(targetprod, "banana");
9571     context = 0xdeadbeef;
9572     lstrcpyA(targetsid, "kiwi");
9573     size = MAX_PATH;
9574     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9575                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9576                            0, patchcode, targetprod, &context,
9577                            targetsid, &size);
9578     ok(r == ERROR_INVALID_PARAMETER,
9579        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9580     ok(!lstrcmpA(patchcode, "apple"),
9581        "Expected patchcode to be unchanged, got %s\n", patchcode);
9582     ok(!lstrcmpA(targetprod, "banana"),
9583        "Expected targetprod to be unchanged, got %s\n", targetprod);
9584     ok(context == 0xdeadbeef,
9585        "Expected context to be unchanged, got %d\n", context);
9586     ok(!lstrcmpA(targetsid, "kiwi"),
9587        "Expected targetsid to be unchanged, got %s\n", targetsid);
9588     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9589
9590     /* guid with brackets */
9591     lstrcpyA(patchcode, "apple");
9592     lstrcpyA(targetprod, "banana");
9593     context = 0xdeadbeef;
9594     lstrcpyA(targetsid, "kiwi");
9595     size = MAX_PATH;
9596     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9597                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9598                            0, patchcode, targetprod, &context,
9599                            targetsid, &size);
9600     ok(r == ERROR_NO_MORE_ITEMS,
9601        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9602     ok(!lstrcmpA(patchcode, "apple"),
9603        "Expected patchcode to be unchanged, got %s\n", patchcode);
9604     ok(!lstrcmpA(targetprod, "banana"),
9605        "Expected targetprod to be unchanged, got %s\n", targetprod);
9606     ok(context == 0xdeadbeef,
9607        "Expected context to be unchanged, got %d\n", context);
9608     ok(!lstrcmpA(targetsid, "kiwi"),
9609        "Expected targetsid to be unchanged, got %s\n", targetsid);
9610     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9611
9612     /* szUserSid is S-1-5-18 */
9613     lstrcpyA(patchcode, "apple");
9614     lstrcpyA(targetprod, "banana");
9615     context = 0xdeadbeef;
9616     lstrcpyA(targetsid, "kiwi");
9617     size = MAX_PATH;
9618     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9619                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9620                            0, patchcode, targetprod, &context,
9621                            targetsid, &size);
9622     ok(r == ERROR_INVALID_PARAMETER,
9623        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9624     ok(!lstrcmpA(patchcode, "apple"),
9625        "Expected patchcode to be unchanged, got %s\n", patchcode);
9626     ok(!lstrcmpA(targetprod, "banana"),
9627        "Expected targetprod to be unchanged, got %s\n", targetprod);
9628     ok(context == 0xdeadbeef,
9629        "Expected context to be unchanged, got %d\n", context);
9630     ok(!lstrcmpA(targetsid, "kiwi"),
9631        "Expected targetsid to be unchanged, got %s\n", targetsid);
9632     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9633
9634     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9635     lstrcpyA(patchcode, "apple");
9636     lstrcpyA(targetprod, "banana");
9637     context = 0xdeadbeef;
9638     lstrcpyA(targetsid, "kiwi");
9639     size = MAX_PATH;
9640     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9641                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9642                            &context, targetsid, &size);
9643     ok(r == ERROR_INVALID_PARAMETER,
9644        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9645     ok(!lstrcmpA(patchcode, "apple"),
9646        "Expected patchcode to be unchanged, got %s\n", patchcode);
9647     ok(!lstrcmpA(targetprod, "banana"),
9648        "Expected targetprod to be unchanged, got %s\n", targetprod);
9649     ok(context == 0xdeadbeef,
9650        "Expected context to be unchanged, got %d\n", context);
9651     ok(!lstrcmpA(targetsid, "kiwi"),
9652        "Expected targetsid to be unchanged, got %s\n", targetsid);
9653     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9654
9655     /* dwContext is out of bounds */
9656     lstrcpyA(patchcode, "apple");
9657     lstrcpyA(targetprod, "banana");
9658     context = 0xdeadbeef;
9659     lstrcpyA(targetsid, "kiwi");
9660     size = MAX_PATH;
9661     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9662                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9663                            &context, targetsid, &size);
9664     ok(r == ERROR_INVALID_PARAMETER,
9665        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9666     ok(!lstrcmpA(patchcode, "apple"),
9667        "Expected patchcode to be unchanged, got %s\n", patchcode);
9668     ok(!lstrcmpA(targetprod, "banana"),
9669        "Expected targetprod to be unchanged, got %s\n", targetprod);
9670     ok(context == 0xdeadbeef,
9671        "Expected context to be unchanged, got %d\n", context);
9672     ok(!lstrcmpA(targetsid, "kiwi"),
9673        "Expected targetsid to be unchanged, got %s\n", targetsid);
9674     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9675
9676     /* dwContext is out of bounds */
9677     lstrcpyA(patchcode, "apple");
9678     lstrcpyA(targetprod, "banana");
9679     context = 0xdeadbeef;
9680     lstrcpyA(targetsid, "kiwi");
9681     size = MAX_PATH;
9682     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9683                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9684                            &context, targetsid, &size);
9685     ok(r == ERROR_INVALID_PARAMETER,
9686        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9687     ok(!lstrcmpA(patchcode, "apple"),
9688        "Expected patchcode to be unchanged, got %s\n", patchcode);
9689     ok(!lstrcmpA(targetprod, "banana"),
9690        "Expected targetprod to be unchanged, got %s\n", targetprod);
9691     ok(context == 0xdeadbeef,
9692        "Expected context to be unchanged, got %d\n", context);
9693     ok(!lstrcmpA(targetsid, "kiwi"),
9694        "Expected targetsid to be unchanged, got %s\n", targetsid);
9695     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9696
9697     /* dwFilter is out of bounds */
9698     lstrcpyA(patchcode, "apple");
9699     lstrcpyA(targetprod, "banana");
9700     context = 0xdeadbeef;
9701     lstrcpyA(targetsid, "kiwi");
9702     size = MAX_PATH;
9703     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9704                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9705                            &context, targetsid, &size);
9706     ok(r == ERROR_INVALID_PARAMETER,
9707        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9708     ok(!lstrcmpA(patchcode, "apple"),
9709        "Expected patchcode to be unchanged, got %s\n", patchcode);
9710     ok(!lstrcmpA(targetprod, "banana"),
9711        "Expected targetprod to be unchanged, got %s\n", targetprod);
9712     ok(context == 0xdeadbeef,
9713        "Expected context to be unchanged, got %d\n", context);
9714     ok(!lstrcmpA(targetsid, "kiwi"),
9715        "Expected targetsid to be unchanged, got %s\n", targetsid);
9716     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9717
9718     /* dwFilter is out of bounds */
9719     lstrcpyA(patchcode, "apple");
9720     lstrcpyA(targetprod, "banana");
9721     context = 0xdeadbeef;
9722     lstrcpyA(targetsid, "kiwi");
9723     size = MAX_PATH;
9724     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9725                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9726                            &context, targetsid, &size);
9727     ok(r == ERROR_INVALID_PARAMETER,
9728        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9729     ok(!lstrcmpA(patchcode, "apple"),
9730        "Expected patchcode to be unchanged, got %s\n", patchcode);
9731     ok(!lstrcmpA(targetprod, "banana"),
9732        "Expected targetprod to be unchanged, got %s\n", targetprod);
9733     ok(context == 0xdeadbeef,
9734        "Expected context to be unchanged, got %d\n", context);
9735     ok(!lstrcmpA(targetsid, "kiwi"),
9736        "Expected targetsid to be unchanged, got %s\n", targetsid);
9737     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9738
9739     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9740     lstrcpyA(patchcode, "apple");
9741     lstrcpyA(targetprod, "banana");
9742     context = 0xdeadbeef;
9743     lstrcpyA(targetsid, "kiwi");
9744     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9745                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9746                            &context, targetsid, NULL);
9747     ok(r == ERROR_INVALID_PARAMETER,
9748        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9749     ok(!lstrcmpA(patchcode, "apple"),
9750        "Expected patchcode to be unchanged, got %s\n", patchcode);
9751     ok(!lstrcmpA(targetprod, "banana"),
9752        "Expected targetprod to be unchanged, got %s\n", targetprod);
9753     ok(context == 0xdeadbeef,
9754        "Expected context to be unchanged, got %d\n", context);
9755     ok(!lstrcmpA(targetsid, "kiwi"),
9756        "Expected targetsid to be unchanged, got %s\n", targetsid);
9757
9758     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9759     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9760     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9761     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9762     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9763     /* FIXME: Successfully test userunmanaged with a different user */
9764     test_MsiEnumPatchesEx_machine();
9765     LocalFree(usersid);
9766 }
9767
9768 static void test_MsiEnumPatches(void)
9769 {
9770     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9771     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9772     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9773     CHAR transforms[MAX_PATH];
9774     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9775     HKEY prodkey, patches, udprod;
9776     HKEY userkey, hpatch, udpatch;
9777     DWORD size, data;
9778     LPSTR usersid;
9779     LONG res;
9780     UINT r;
9781     REGSAM access = KEY_ALL_ACCESS;
9782
9783     create_test_guid(prodcode, prod_squashed);
9784     create_test_guid(patchcode, patch_squashed);
9785     usersid = get_user_sid();
9786
9787     if (is_wow64)
9788         access |= KEY_WOW64_64KEY;
9789
9790     /* NULL szProduct */
9791     size = MAX_PATH;
9792     lstrcpyA(patch, "apple");
9793     lstrcpyA(transforms, "banana");
9794     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9795     ok(r == ERROR_INVALID_PARAMETER,
9796        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9797     ok(!lstrcmpA(patch, "apple"),
9798        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9799     ok(!lstrcmpA(transforms, "banana"),
9800        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9801     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9802
9803     /* empty szProduct */
9804     size = MAX_PATH;
9805     lstrcpyA(patch, "apple");
9806     lstrcpyA(transforms, "banana");
9807     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9808     ok(r == ERROR_INVALID_PARAMETER,
9809        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9810     ok(!lstrcmpA(patch, "apple"),
9811        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9812     ok(!lstrcmpA(transforms, "banana"),
9813        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9814     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9815
9816     /* garbage szProduct */
9817     size = MAX_PATH;
9818     lstrcpyA(patch, "apple");
9819     lstrcpyA(transforms, "banana");
9820     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9821     ok(r == ERROR_INVALID_PARAMETER,
9822        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9823     ok(!lstrcmpA(patch, "apple"),
9824        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9825     ok(!lstrcmpA(transforms, "banana"),
9826        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9827     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9828
9829     /* guid without brackets */
9830     size = MAX_PATH;
9831     lstrcpyA(patch, "apple");
9832     lstrcpyA(transforms, "banana");
9833     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9834                         transforms, &size);
9835     ok(r == ERROR_INVALID_PARAMETER,
9836        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9837     ok(!lstrcmpA(patch, "apple"),
9838        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9839     ok(!lstrcmpA(transforms, "banana"),
9840        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9841     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9842
9843     /* guid with brackets */
9844     size = MAX_PATH;
9845     lstrcpyA(patch, "apple");
9846     lstrcpyA(transforms, "banana");
9847     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9848                         transforms, &size);
9849     ok(r == ERROR_UNKNOWN_PRODUCT,
9850        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9851     ok(!lstrcmpA(patch, "apple"),
9852        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9853     ok(!lstrcmpA(transforms, "banana"),
9854        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9855     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9856
9857     /* same length as guid, but random */
9858     size = MAX_PATH;
9859     lstrcpyA(patch, "apple");
9860     lstrcpyA(transforms, "banana");
9861     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9862                         transforms, &size);
9863     ok(r == ERROR_INVALID_PARAMETER,
9864        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9865     ok(!lstrcmpA(patch, "apple"),
9866        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9867     ok(!lstrcmpA(transforms, "banana"),
9868        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9869     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9870
9871     /* MSIINSTALLCONTEXT_USERMANAGED */
9872
9873     size = MAX_PATH;
9874     lstrcpyA(patch, "apple");
9875     lstrcpyA(transforms, "banana");
9876     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9877     ok(r == ERROR_UNKNOWN_PRODUCT,
9878        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9879     ok(!lstrcmpA(patch, "apple"),
9880        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9881     ok(!lstrcmpA(transforms, "banana"),
9882        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9883     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9884
9885     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9886     lstrcatA(keypath, usersid);
9887     lstrcatA(keypath, "\\Installer\\Products\\");
9888     lstrcatA(keypath, prod_squashed);
9889
9890     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9891     if (res == ERROR_ACCESS_DENIED)
9892     {
9893         skip("Not enough rights to perform tests\n");
9894         LocalFree(usersid);
9895         return;
9896     }
9897     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9898
9899     /* managed product key exists */
9900     size = MAX_PATH;
9901     lstrcpyA(patch, "apple");
9902     lstrcpyA(transforms, "banana");
9903     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9904     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9905     ok(!lstrcmpA(patch, "apple"),
9906        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9907     ok(!lstrcmpA(transforms, "banana"),
9908        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9909     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9910
9911     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9913
9914     /* patches key exists */
9915     size = MAX_PATH;
9916     lstrcpyA(patch, "apple");
9917     lstrcpyA(transforms, "banana");
9918     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9919     ok(r == ERROR_NO_MORE_ITEMS ||
9920        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9921        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9922     ok(!lstrcmpA(patch, "apple"),
9923        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9924     ok(!lstrcmpA(transforms, "banana"),
9925        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9926     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9927
9928     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9929                          (const BYTE *)patch_squashed,
9930                          lstrlenA(patch_squashed) + 1);
9931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9932
9933     /* Patches value exists, is not REG_MULTI_SZ */
9934     size = MAX_PATH;
9935     lstrcpyA(patch, "apple");
9936     lstrcpyA(transforms, "banana");
9937     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9938     ok(r == ERROR_BAD_CONFIGURATION ||
9939        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9940        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9941     ok(!lstrcmpA(patch, "apple"),
9942        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9943     ok(!lstrcmpA(transforms, "banana"),
9944        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9945     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9946
9947     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9948                          (const BYTE *)"a\0b\0c\0\0", 7);
9949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9950
9951     /* Patches value exists, is not a squashed guid */
9952     size = MAX_PATH;
9953     lstrcpyA(patch, "apple");
9954     lstrcpyA(transforms, "banana");
9955     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9956     ok(r == ERROR_BAD_CONFIGURATION,
9957        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9958     ok(!lstrcmpA(patch, "apple"),
9959        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9960     ok(!lstrcmpA(transforms, "banana"),
9961        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9962     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9963
9964     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9965     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9966                          (const BYTE *)patch_squashed,
9967                          lstrlenA(patch_squashed) + 2);
9968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9969
9970     /* Patches value exists */
9971     size = MAX_PATH;
9972     lstrcpyA(patch, "apple");
9973     lstrcpyA(transforms, "banana");
9974     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9975     ok(r == ERROR_NO_MORE_ITEMS ||
9976        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9977        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9978     ok(!lstrcmpA(patch, "apple") ||
9979        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9980        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9981     ok(!lstrcmpA(transforms, "banana"),
9982        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9983     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9984
9985     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9986                          (const BYTE *)"whatever", 9);
9987     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9988
9989     /* patch squashed value exists */
9990     size = MAX_PATH;
9991     lstrcpyA(patch, "apple");
9992     lstrcpyA(transforms, "banana");
9993     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9995     ok(!lstrcmpA(patch, patchcode),
9996        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9997     ok(!lstrcmpA(transforms, "whatever"),
9998        "Expected \"whatever\", got \"%s\"\n", transforms);
9999     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10000
10001     /* lpPatchBuf is NULL */
10002     size = MAX_PATH;
10003     lstrcpyA(transforms, "banana");
10004     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
10005     ok(r == ERROR_INVALID_PARAMETER,
10006        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10007     ok(!lstrcmpA(transforms, "banana"),
10008        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10009     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10010
10011     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
10012     size = MAX_PATH;
10013     lstrcpyA(patch, "apple");
10014     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
10015     ok(r == ERROR_INVALID_PARAMETER,
10016        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10017     ok(!lstrcmpA(patch, "apple"),
10018        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10019     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10020
10021     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
10022     lstrcpyA(patch, "apple");
10023     lstrcpyA(transforms, "banana");
10024     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
10025     ok(r == ERROR_INVALID_PARAMETER,
10026        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10027     ok(!lstrcmpA(patch, "apple"),
10028        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10029     ok(!lstrcmpA(transforms, "banana"),
10030        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10031
10032     /* pcchTransformsBuf is too small */
10033     size = 6;
10034     lstrcpyA(patch, "apple");
10035     lstrcpyA(transforms, "banana");
10036     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10037     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10038     ok(!lstrcmpA(patch, patchcode),
10039        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10040     ok(!lstrcmpA(transforms, "whate") ||
10041        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10042        "Expected \"whate\", got \"%s\"\n", transforms);
10043     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
10044
10045     /* increase the index */
10046     size = MAX_PATH;
10047     lstrcpyA(patch, "apple");
10048     lstrcpyA(transforms, "banana");
10049     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
10050     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10051     ok(!lstrcmpA(patch, "apple"),
10052        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10053     ok(!lstrcmpA(transforms, "banana"),
10054        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10055     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10056
10057     /* increase again */
10058     size = MAX_PATH;
10059     lstrcpyA(patch, "apple");
10060     lstrcpyA(transforms, "banana");
10061     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
10062     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10063     ok(!lstrcmpA(patch, "apple"),
10064        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10065     ok(!lstrcmpA(transforms, "banana"),
10066        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10067     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10068
10069     RegDeleteValueA(patches, "Patches");
10070     delete_key(patches, "", access & KEY_WOW64_64KEY);
10071     RegCloseKey(patches);
10072     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10073     RegCloseKey(prodkey);
10074
10075     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10076
10077     size = MAX_PATH;
10078     lstrcpyA(patch, "apple");
10079     lstrcpyA(transforms, "banana");
10080     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10081     ok(r == ERROR_UNKNOWN_PRODUCT,
10082        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10083     ok(!lstrcmpA(patch, "apple"),
10084        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10085     ok(!lstrcmpA(transforms, "banana"),
10086        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10087     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10088
10089     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10090     lstrcatA(keypath, prod_squashed);
10091
10092     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10094
10095     /* current user product key exists */
10096     size = MAX_PATH;
10097     lstrcpyA(patch, "apple");
10098     lstrcpyA(transforms, "banana");
10099     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10100     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10101     ok(!lstrcmpA(patch, "apple"),
10102        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10103     ok(!lstrcmpA(transforms, "banana"),
10104        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10105     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10106
10107     res = RegCreateKeyA(prodkey, "Patches", &patches);
10108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10109
10110     /* Patches key exists */
10111     size = MAX_PATH;
10112     lstrcpyA(patch, "apple");
10113     lstrcpyA(transforms, "banana");
10114     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10115     ok(r == ERROR_NO_MORE_ITEMS ||
10116        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10117        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10118     ok(!lstrcmpA(patch, "apple"),
10119        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10120     ok(!lstrcmpA(transforms, "banana"),
10121        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10122     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10123
10124     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10125                          (const BYTE *)patch_squashed,
10126                          lstrlenA(patch_squashed) + 1);
10127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10128
10129     /* Patches value exists, is not REG_MULTI_SZ */
10130     size = MAX_PATH;
10131     lstrcpyA(patch, "apple");
10132     lstrcpyA(transforms, "banana");
10133     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10134     ok(r == ERROR_BAD_CONFIGURATION ||
10135        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10136        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10137     ok(!lstrcmpA(patch, "apple"),
10138        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10139     ok(!lstrcmpA(transforms, "banana"),
10140        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10141     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10142
10143     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10144                          (const BYTE *)"a\0b\0c\0\0", 7);
10145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10146
10147     /* Patches value exists, is not a squashed guid */
10148     size = MAX_PATH;
10149     lstrcpyA(patch, "apple");
10150     lstrcpyA(transforms, "banana");
10151     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10152     ok(r == ERROR_BAD_CONFIGURATION,
10153        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10154     ok(!lstrcmpA(patch, "apple"),
10155        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10156     ok(!lstrcmpA(transforms, "banana"),
10157        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10158     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10159
10160     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10161     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10162                          (const BYTE *)patch_squashed,
10163                          lstrlenA(patch_squashed) + 2);
10164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10165
10166     /* Patches value exists */
10167     size = MAX_PATH;
10168     lstrcpyA(patch, "apple");
10169     lstrcpyA(transforms, "banana");
10170     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10171     ok(r == ERROR_NO_MORE_ITEMS ||
10172        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10173        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10174     ok(!lstrcmpA(patch, "apple") ||
10175        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10176        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10177     ok(!lstrcmpA(transforms, "banana"),
10178        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10179     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10180
10181     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10182                          (const BYTE *)"whatever", 9);
10183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10184
10185     /* patch code value exists */
10186     size = MAX_PATH;
10187     lstrcpyA(patch, "apple");
10188     lstrcpyA(transforms, "banana");
10189     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10190     ok(r == ERROR_NO_MORE_ITEMS ||
10191        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10192        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10193     ok(!lstrcmpA(patch, "apple") ||
10194        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10195        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10196     ok(!lstrcmpA(transforms, "banana") ||
10197        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10198        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10199     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10200
10201     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10202     lstrcatA(keypath, usersid);
10203     lstrcatA(keypath, "\\Patches\\");
10204     lstrcatA(keypath, patch_squashed);
10205
10206     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10207     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10208
10209     /* userdata patch key exists */
10210     size = MAX_PATH;
10211     lstrcpyA(patch, "apple");
10212     lstrcpyA(transforms, "banana");
10213     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10215     ok(!lstrcmpA(patch, patchcode),
10216        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10217     ok(!lstrcmpA(transforms, "whatever"),
10218        "Expected \"whatever\", got \"%s\"\n", transforms);
10219     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10220
10221     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10222     RegCloseKey(userkey);
10223     RegDeleteValueA(patches, patch_squashed);
10224     RegDeleteValueA(patches, "Patches");
10225     RegDeleteKeyA(patches, "");
10226     RegCloseKey(patches);
10227     RegDeleteKeyA(prodkey, "");
10228     RegCloseKey(prodkey);
10229
10230     /* MSIINSTALLCONTEXT_MACHINE */
10231
10232     size = MAX_PATH;
10233     lstrcpyA(patch, "apple");
10234     lstrcpyA(transforms, "banana");
10235     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10236     ok(r == ERROR_UNKNOWN_PRODUCT,
10237        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10238     ok(!lstrcmpA(patch, "apple"),
10239        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10240     ok(!lstrcmpA(transforms, "banana"),
10241        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10242     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10243
10244     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10245     lstrcatA(keypath, prod_squashed);
10246
10247     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10249
10250     /* local product key exists */
10251     size = MAX_PATH;
10252     lstrcpyA(patch, "apple");
10253     lstrcpyA(transforms, "banana");
10254     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10255     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10256     ok(!lstrcmpA(patch, "apple"),
10257        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10258     ok(!lstrcmpA(transforms, "banana"),
10259        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10260     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10261
10262     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10264
10265     /* Patches key exists */
10266     size = MAX_PATH;
10267     lstrcpyA(patch, "apple");
10268     lstrcpyA(transforms, "banana");
10269     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10270     ok(r == ERROR_NO_MORE_ITEMS ||
10271        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10272        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10273     ok(!lstrcmpA(patch, "apple"),
10274        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10275     ok(!lstrcmpA(transforms, "banana"),
10276        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10277     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10278
10279     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10280                          (const BYTE *)patch_squashed,
10281                          lstrlenA(patch_squashed) + 1);
10282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10283
10284     /* Patches value exists, is not REG_MULTI_SZ */
10285     size = MAX_PATH;
10286     lstrcpyA(patch, "apple");
10287     lstrcpyA(transforms, "banana");
10288     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10289     ok(r == ERROR_BAD_CONFIGURATION ||
10290        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10291        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10292     ok(!lstrcmpA(patch, "apple"),
10293        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10294     ok(!lstrcmpA(transforms, "banana"),
10295        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10296     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10297
10298     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10299                          (const BYTE *)"a\0b\0c\0\0", 7);
10300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10301
10302     /* Patches value exists, is not a squashed guid */
10303     size = MAX_PATH;
10304     lstrcpyA(patch, "apple");
10305     lstrcpyA(transforms, "banana");
10306     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10307     ok(r == ERROR_BAD_CONFIGURATION,
10308        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10309     ok(!lstrcmpA(patch, "apple"),
10310        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10311     ok(!lstrcmpA(transforms, "banana"),
10312        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10313     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10314
10315     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10316     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10317                          (const BYTE *)patch_squashed,
10318                          lstrlenA(patch_squashed) + 2);
10319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10320
10321     /* Patches value exists */
10322     size = MAX_PATH;
10323     lstrcpyA(patch, "apple");
10324     lstrcpyA(transforms, "banana");
10325     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10326     ok(r == ERROR_NO_MORE_ITEMS ||
10327        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10328        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10329     ok(!lstrcmpA(patch, "apple") ||
10330        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10331        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10332     ok(!lstrcmpA(transforms, "banana"),
10333        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10334     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10335
10336     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10337                          (const BYTE *)"whatever", 9);
10338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10339
10340     /* patch code value exists */
10341     size = MAX_PATH;
10342     lstrcpyA(patch, "apple");
10343     lstrcpyA(transforms, "banana");
10344     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10346     ok(!lstrcmpA(patch, patchcode),
10347        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10348     ok(!lstrcmpA(transforms, "whatever"),
10349        "Expected \"whatever\", got \"%s\"\n", transforms);
10350     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10351
10352     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10353     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10354     lstrcatA(keypath, prod_squashed);
10355
10356     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10358
10359     /* local UserData product key exists */
10360     size = MAX_PATH;
10361     lstrcpyA(patch, "apple");
10362     lstrcpyA(transforms, "banana");
10363     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10364     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10365     ok(!lstrcmpA(patch, patchcode),
10366        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10367     ok(!lstrcmpA(transforms, "whatever"),
10368        "Expected \"whatever\", got \"%s\"\n", transforms);
10369     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10370
10371     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10373
10374     /* local UserData Patches key exists */
10375     size = MAX_PATH;
10376     lstrcpyA(patch, "apple");
10377     lstrcpyA(transforms, "banana");
10378     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10379     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10380     ok(!lstrcmpA(patch, patchcode),
10381        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10382     ok(!lstrcmpA(transforms, "whatever"),
10383        "Expected \"whatever\", got \"%s\"\n", transforms);
10384     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10385
10386     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10387     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10388
10389     /* local UserData Product patch key exists */
10390     size = MAX_PATH;
10391     lstrcpyA(patch, "apple");
10392     lstrcpyA(transforms, "banana");
10393     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10394     ok(r == ERROR_NO_MORE_ITEMS ||
10395        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10396        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10397     ok(!lstrcmpA(patch, "apple") ||
10398        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10399        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10400     ok(!lstrcmpA(transforms, "banana") ||
10401        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10402        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10403     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10404
10405     data = MSIPATCHSTATE_APPLIED;
10406     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10407                          (const BYTE *)&data, sizeof(DWORD));
10408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10409
10410     /* State value exists */
10411     size = MAX_PATH;
10412     lstrcpyA(patch, "apple");
10413     lstrcpyA(transforms, "banana");
10414     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10416     ok(!lstrcmpA(patch, patchcode),
10417        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10418     ok(!lstrcmpA(transforms, "whatever"),
10419        "Expected \"whatever\", got \"%s\"\n", transforms);
10420     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10421
10422     /* now duplicate some of the tests for the W version */
10423
10424     /* pcchTransformsBuf is too small */
10425     size = 6;
10426     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10427     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10428     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10429     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10430     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10431     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10432     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10433     ok(!lstrcmpA(patch, patchcode),
10434        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10435     ok(!lstrcmpA(transforms, "whate") ||
10436        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10437        "Expected \"whate\", got \"%s\"\n", transforms);
10438     ok(size == 8, "Expected 8, got %d\n", size);
10439
10440     /* patch code value exists */
10441     size = MAX_PATH;
10442     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10443     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10444     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10446     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10447     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10448     ok(!lstrcmpA(patch, patchcode),
10449        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10450     ok(!lstrcmpA(transforms, "whatever"),
10451        "Expected \"whatever\", got \"%s\"\n", transforms);
10452     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10453
10454     RegDeleteValueA(patches, patch_squashed);
10455     RegDeleteValueA(patches, "Patches");
10456     delete_key(patches, "", access & KEY_WOW64_64KEY);
10457     RegCloseKey(patches);
10458     RegDeleteValueA(hpatch, "State");
10459     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10460     RegCloseKey(hpatch);
10461     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10462     RegCloseKey(udpatch);
10463     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10464     RegCloseKey(udprod);
10465     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10466     RegCloseKey(prodkey);
10467     LocalFree(usersid);
10468 }
10469
10470 static void test_MsiGetPatchInfoEx(void)
10471 {
10472     CHAR keypath[MAX_PATH], val[MAX_PATH];
10473     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10474     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10475     HKEY prodkey, patches, udprod, props;
10476     HKEY hpatch, udpatch, prodpatches;
10477     LPSTR usersid;
10478     DWORD size;
10479     LONG res;
10480     UINT r;
10481     REGSAM access = KEY_ALL_ACCESS;
10482
10483     if (!pMsiGetPatchInfoExA)
10484     {
10485         win_skip("MsiGetPatchInfoEx not implemented\n");
10486         return;
10487     }
10488
10489     create_test_guid(prodcode, prod_squashed);
10490     create_test_guid(patchcode, patch_squashed);
10491     usersid = get_user_sid();
10492
10493     if (is_wow64)
10494         access |= KEY_WOW64_64KEY;
10495
10496     /* NULL szPatchCode */
10497     lstrcpyA(val, "apple");
10498     size = MAX_PATH;
10499     r = pMsiGetPatchInfoExA(NULL, 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     /* empty szPatchCode */
10508     size = MAX_PATH;
10509     lstrcpyA(val, "apple");
10510     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10511                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10512     ok(r == ERROR_INVALID_PARAMETER,
10513        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10514     ok(!lstrcmpA(val, "apple"),
10515        "Expected val to be unchanged, got \"%s\"\n", val);
10516     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10517
10518     /* garbage szPatchCode */
10519     size = MAX_PATH;
10520     lstrcpyA(val, "apple");
10521     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10522                             MSIINSTALLCONTEXT_USERMANAGED,
10523                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10524     ok(r == ERROR_INVALID_PARAMETER,
10525        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10526     ok(!lstrcmpA(val, "apple"),
10527        "Expected val to be unchanged, got \"%s\"\n", val);
10528     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10529
10530     /* guid without brackets */
10531     size = MAX_PATH;
10532     lstrcpyA(val, "apple");
10533     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10534                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10535                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10536     ok(r == ERROR_INVALID_PARAMETER,
10537        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10538     ok(!lstrcmpA(val, "apple"),
10539        "Expected val to be unchanged, got \"%s\"\n", val);
10540     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10541
10542     /* guid with brackets */
10543     size = MAX_PATH;
10544     lstrcpyA(val, "apple");
10545     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10546                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10547                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10548     ok(r == ERROR_UNKNOWN_PRODUCT,
10549        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10550     ok(!lstrcmpA(val, "apple"),
10551        "Expected val to be unchanged, got \"%s\"\n", val);
10552     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10553
10554     /* same length as guid, but random */
10555     size = MAX_PATH;
10556     lstrcpyA(val, "apple");
10557     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10558                             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     /* NULL szProductCode */
10567     lstrcpyA(val, "apple");
10568     size = MAX_PATH;
10569     r = pMsiGetPatchInfoExA(patchcode, NULL, 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     /* empty szProductCode */
10578     size = MAX_PATH;
10579     lstrcpyA(val, "apple");
10580     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10581                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10582     ok(r == ERROR_INVALID_PARAMETER,
10583        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10584     ok(!lstrcmpA(val, "apple"),
10585        "Expected val to be unchanged, got \"%s\"\n", val);
10586     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10587
10588     /* garbage szProductCode */
10589     size = MAX_PATH;
10590     lstrcpyA(val, "apple");
10591     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10592                             MSIINSTALLCONTEXT_USERMANAGED,
10593                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10594     ok(r == ERROR_INVALID_PARAMETER,
10595        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10596     ok(!lstrcmpA(val, "apple"),
10597        "Expected val to be unchanged, got \"%s\"\n", val);
10598     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10599
10600     /* guid without brackets */
10601     size = MAX_PATH;
10602     lstrcpyA(val, "apple");
10603     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10604                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10605                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10606     ok(r == ERROR_INVALID_PARAMETER,
10607        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10608     ok(!lstrcmpA(val, "apple"),
10609        "Expected val to be unchanged, got \"%s\"\n", val);
10610     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10611
10612     /* guid with brackets */
10613     size = MAX_PATH;
10614     lstrcpyA(val, "apple");
10615     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10616                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10617                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10618     ok(r == ERROR_UNKNOWN_PRODUCT,
10619        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10620     ok(!lstrcmpA(val, "apple"),
10621        "Expected val to be unchanged, got \"%s\"\n", val);
10622     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10623
10624     /* same length as guid, but random */
10625     size = MAX_PATH;
10626     lstrcpyA(val, "apple");
10627     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10628                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10629                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10630     ok(r == ERROR_INVALID_PARAMETER,
10631        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10632     ok(!lstrcmpA(val, "apple"),
10633        "Expected val to be unchanged, got \"%s\"\n", val);
10634     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10635
10636     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10637     size = MAX_PATH;
10638     lstrcpyA(val, "apple");
10639     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10640                             MSIINSTALLCONTEXT_USERMANAGED,
10641                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10642     ok(r == ERROR_INVALID_PARAMETER,
10643        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10644     ok(!lstrcmpA(val, "apple"),
10645        "Expected val to be unchanged, got \"%s\"\n", val);
10646     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10647
10648     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10649     size = MAX_PATH;
10650     lstrcpyA(val, "apple");
10651     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10652                             MSIINSTALLCONTEXT_USERUNMANAGED,
10653                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10654     ok(r == ERROR_INVALID_PARAMETER,
10655        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10656     ok(!lstrcmpA(val, "apple"),
10657        "Expected val to be unchanged, got \"%s\"\n", val);
10658     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10659
10660     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10661     size = MAX_PATH;
10662     lstrcpyA(val, "apple");
10663     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10664                             MSIINSTALLCONTEXT_MACHINE,
10665                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10666     ok(r == ERROR_INVALID_PARAMETER,
10667        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10668     ok(!lstrcmpA(val, "apple"),
10669        "Expected val to be unchanged, got \"%s\"\n", val);
10670     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10671
10672     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10673     size = MAX_PATH;
10674     lstrcpyA(val, "apple");
10675     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10676                             MSIINSTALLCONTEXT_MACHINE,
10677                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10678     ok(r == ERROR_INVALID_PARAMETER,
10679        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10680     ok(!lstrcmpA(val, "apple"),
10681        "Expected val to be unchanged, got \"%s\"\n", val);
10682     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10683
10684     /* dwContext is out of range */
10685     size = MAX_PATH;
10686     lstrcpyA(val, "apple");
10687     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10688                             MSIINSTALLCONTEXT_NONE,
10689                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10690     ok(r == ERROR_INVALID_PARAMETER,
10691        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10692     ok(!lstrcmpA(val, "apple"),
10693        "Expected val to be unchanged, got \"%s\"\n", val);
10694     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10695
10696     /* dwContext is out of range */
10697     size = MAX_PATH;
10698     lstrcpyA(val, "apple");
10699     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10700                             MSIINSTALLCONTEXT_ALL,
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     /* dwContext is invalid */
10709     size = MAX_PATH;
10710     lstrcpyA(val, "apple");
10711     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10712                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10713     ok(r == ERROR_INVALID_PARAMETER,
10714        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10715     ok(!lstrcmpA(val, "apple"),
10716        "Expected val to be unchanged, got \"%s\"\n", val);
10717     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10718
10719     /* MSIINSTALLCONTEXT_USERMANAGED */
10720
10721     size = MAX_PATH;
10722     lstrcpyA(val, "apple");
10723     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10724                             MSIINSTALLCONTEXT_USERMANAGED,
10725                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10726     ok(r == ERROR_UNKNOWN_PRODUCT,
10727        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10728     ok(!lstrcmpA(val, "apple"),
10729        "Expected val to be unchanged, got \"%s\"\n", val);
10730     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10731
10732     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10733     lstrcatA(keypath, usersid);
10734     lstrcatA(keypath, "\\Products\\");
10735     lstrcatA(keypath, prod_squashed);
10736
10737     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10738     if (res == ERROR_ACCESS_DENIED)
10739     {
10740         skip("Not enough rights to perform tests\n");
10741         LocalFree(usersid);
10742         return;
10743     }
10744     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10745
10746     /* local UserData product key exists */
10747     size = MAX_PATH;
10748     lstrcpyA(val, "apple");
10749     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10750                             MSIINSTALLCONTEXT_USERMANAGED,
10751                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10752     ok(r == ERROR_UNKNOWN_PRODUCT,
10753        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10754     ok(!lstrcmpA(val, "apple"),
10755        "Expected val to be unchanged, got \"%s\"\n", val);
10756     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10757
10758     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10760
10761     /* InstallProperties key exists */
10762     size = MAX_PATH;
10763     lstrcpyA(val, "apple");
10764     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10765                             MSIINSTALLCONTEXT_USERMANAGED,
10766                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10767     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10768     ok(!lstrcmpA(val, "apple"),
10769        "Expected val to be unchanged, got \"%s\"\n", val);
10770     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10771
10772     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10774
10775     /* Patches key exists */
10776     size = MAX_PATH;
10777     lstrcpyA(val, "apple");
10778     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10779                             MSIINSTALLCONTEXT_USERMANAGED,
10780                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10781     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10782     ok(!lstrcmpA(val, "apple"),
10783        "Expected val to be unchanged, got \"%s\"\n", val);
10784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10785
10786     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10788
10789     /* Patches key exists */
10790     size = MAX_PATH;
10791     lstrcpyA(val, "apple");
10792     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10793                             MSIINSTALLCONTEXT_USERMANAGED,
10794                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10795     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10796     ok(!lstrcmpA(val, "apple"),
10797        "Expected val to be unchanged, got \"%s\"\n", val);
10798     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10799
10800     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10801     lstrcatA(keypath, usersid);
10802     lstrcatA(keypath, "\\Installer\\Products\\");
10803     lstrcatA(keypath, prod_squashed);
10804
10805     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10807
10808     /* managed product key exists */
10809     size = MAX_PATH;
10810     lstrcpyA(val, "apple");
10811     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10812                             MSIINSTALLCONTEXT_USERMANAGED,
10813                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10814     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10815     ok(!lstrcmpA(val, "apple"),
10816        "Expected val to be unchanged, got \"%s\"\n", val);
10817     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10818
10819     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10821
10822     /* Patches key exists */
10823     size = MAX_PATH;
10824     lstrcpyA(val, "apple");
10825     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10826                             MSIINSTALLCONTEXT_USERMANAGED,
10827                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10828     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10829     ok(!lstrcmpA(val, "apple"),
10830        "Expected val to be unchanged, got \"%s\"\n", val);
10831     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10832
10833     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10834                          (const BYTE *)"transforms", 11);
10835     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10836
10837     /* specific patch value exists */
10838     size = MAX_PATH;
10839     lstrcpyA(val, "apple");
10840     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10841                             MSIINSTALLCONTEXT_USERMANAGED,
10842                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10843     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10844     ok(!lstrcmpA(val, "apple"),
10845        "Expected val to be unchanged, got \"%s\"\n", val);
10846     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10847
10848     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10849     lstrcatA(keypath, usersid);
10850     lstrcatA(keypath, "\\Patches\\");
10851     lstrcatA(keypath, patch_squashed);
10852
10853     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10854     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10855
10856     /* UserData Patches key exists */
10857     size = MAX_PATH;
10858     lstrcpyA(val, "apple");
10859     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10860                             MSIINSTALLCONTEXT_USERMANAGED,
10861                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10862     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10863     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10864     ok(size == 0, "Expected 0, got %d\n", size);
10865
10866     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10867                          (const BYTE *)"pack", 5);
10868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10869
10870     /* ManagedLocalPatch value exists */
10871     size = MAX_PATH;
10872     lstrcpyA(val, "apple");
10873     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10874                             MSIINSTALLCONTEXT_USERMANAGED,
10875                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10876     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10877     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10878     ok(size == 4, "Expected 4, got %d\n", size);
10879
10880     size = MAX_PATH;
10881     lstrcpyA(val, "apple");
10882     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10883                             MSIINSTALLCONTEXT_USERMANAGED,
10884                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10886     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10887     ok(size == 10, "Expected 10, got %d\n", size);
10888
10889     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10890                          (const BYTE *)"mydate", 7);
10891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10892
10893     /* Installed value exists */
10894     size = MAX_PATH;
10895     lstrcpyA(val, "apple");
10896     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10897                             MSIINSTALLCONTEXT_USERMANAGED,
10898                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10899     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10900     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10901     ok(size == 6, "Expected 6, got %d\n", size);
10902
10903     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10904                          (const BYTE *)"yes", 4);
10905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10906
10907     /* Uninstallable value exists */
10908     size = MAX_PATH;
10909     lstrcpyA(val, "apple");
10910     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10911                             MSIINSTALLCONTEXT_USERMANAGED,
10912                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10913     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10914     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10915     ok(size == 3, "Expected 3, got %d\n", size);
10916
10917     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10918                          (const BYTE *)"good", 5);
10919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10920
10921     /* State value exists */
10922     size = MAX_PATH;
10923     lstrcpyA(val, "apple");
10924     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10925                             MSIINSTALLCONTEXT_USERMANAGED,
10926                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10927     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10928     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10929     ok(size == 4, "Expected 4, got %d\n", size);
10930
10931     size = 1;
10932     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10933                          (const BYTE *)&size, sizeof(DWORD));
10934     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10935
10936     /* State value exists */
10937     size = MAX_PATH;
10938     lstrcpyA(val, "apple");
10939     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10940                             MSIINSTALLCONTEXT_USERMANAGED,
10941                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10942     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10943     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10944     ok(size == 1, "Expected 1, got %d\n", size);
10945
10946     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10947                          (const BYTE *)"display", 8);
10948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10949
10950     /* DisplayName value exists */
10951     size = MAX_PATH;
10952     lstrcpyA(val, "apple");
10953     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10954                             MSIINSTALLCONTEXT_USERMANAGED,
10955                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10957     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10958     ok(size == 7, "Expected 7, got %d\n", size);
10959
10960     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10961                          (const BYTE *)"moreinfo", 9);
10962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10963
10964     /* MoreInfoURL value exists */
10965     size = MAX_PATH;
10966     lstrcpyA(val, "apple");
10967     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10968                             MSIINSTALLCONTEXT_USERMANAGED,
10969                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10971     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10972     ok(size == 8, "Expected 8, got %d\n", size);
10973
10974     /* szProperty is invalid */
10975     size = MAX_PATH;
10976     lstrcpyA(val, "apple");
10977     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10978                             MSIINSTALLCONTEXT_USERMANAGED,
10979                             "IDontExist", val, &size);
10980     ok(r == ERROR_UNKNOWN_PROPERTY,
10981        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10982     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10983     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10984
10985     /* lpValue is NULL, while pcchValue is non-NULL */
10986     size = MAX_PATH;
10987     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10988                             MSIINSTALLCONTEXT_USERMANAGED,
10989                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10991     ok(size == 16, "Expected 16, got %d\n", size);
10992
10993     /* pcchValue is NULL, while lpValue is non-NULL */
10994     lstrcpyA(val, "apple");
10995     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10996                             MSIINSTALLCONTEXT_USERMANAGED,
10997                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10998     ok(r == ERROR_INVALID_PARAMETER,
10999        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11000     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11001
11002     /* both lpValue and pcchValue are NULL */
11003     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11004                             MSIINSTALLCONTEXT_USERMANAGED,
11005                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
11006     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11007
11008     /* pcchValue doesn't have enough room for NULL terminator */
11009     size = 8;
11010     lstrcpyA(val, "apple");
11011     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11012                             MSIINSTALLCONTEXT_USERMANAGED,
11013                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11014     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11015     ok(!lstrcmpA(val, "moreinf"),
11016        "Expected \"moreinf\", got \"%s\"\n", val);
11017     ok(size == 16, "Expected 16, got %d\n", size);
11018
11019     /* pcchValue has exactly enough room for NULL terminator */
11020     size = 9;
11021     lstrcpyA(val, "apple");
11022     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11023                             MSIINSTALLCONTEXT_USERMANAGED,
11024                             INSTALLPROPERTY_MOREINFOURL, val, &size);
11025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11026     ok(!lstrcmpA(val, "moreinfo"),
11027        "Expected \"moreinfo\", got \"%s\"\n", val);
11028     ok(size == 8, "Expected 8, got %d\n", size);
11029
11030     /* pcchValue is too small, lpValue is NULL */
11031     size = 0;
11032     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11033                             MSIINSTALLCONTEXT_USERMANAGED,
11034                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
11035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11036     ok(size == 16, "Expected 16, got %d\n", size);
11037
11038     RegDeleteValueA(prodpatches, patch_squashed);
11039     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11040     RegCloseKey(prodpatches);
11041     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11042     RegCloseKey(prodkey);
11043
11044     /* UserData is sufficient for all properties
11045      * except INSTALLPROPERTY_TRANSFORMS
11046      */
11047     size = MAX_PATH;
11048     lstrcpyA(val, "apple");
11049     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11050                             MSIINSTALLCONTEXT_USERMANAGED,
11051                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11052     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11053     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11054     ok(size == 4, "Expected 4, got %d\n", size);
11055
11056     /* UserData is sufficient for all properties
11057      * except INSTALLPROPERTY_TRANSFORMS
11058      */
11059     size = MAX_PATH;
11060     lstrcpyA(val, "apple");
11061     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11062                             MSIINSTALLCONTEXT_USERMANAGED,
11063                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11064     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11065     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11066     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11067
11068     RegDeleteValueA(hpatch, "MoreInfoURL");
11069     RegDeleteValueA(hpatch, "Display");
11070     RegDeleteValueA(hpatch, "State");
11071     RegDeleteValueA(hpatch, "Uninstallable");
11072     RegDeleteValueA(hpatch, "Installed");
11073     RegDeleteValueA(udpatch, "ManagedLocalPackage");
11074     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11075     RegCloseKey(udpatch);
11076     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11077     RegCloseKey(hpatch);
11078     delete_key(patches, "", access & KEY_WOW64_64KEY);
11079     RegCloseKey(patches);
11080     delete_key(props, "", access & KEY_WOW64_64KEY);
11081     RegCloseKey(props);
11082     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11083     RegCloseKey(udprod);
11084
11085     /* MSIINSTALLCONTEXT_USERUNMANAGED */
11086
11087     size = MAX_PATH;
11088     lstrcpyA(val, "apple");
11089     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11090                             MSIINSTALLCONTEXT_USERUNMANAGED,
11091                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11092     ok(r == ERROR_UNKNOWN_PRODUCT,
11093        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11094     ok(!lstrcmpA(val, "apple"),
11095        "Expected val to be unchanged, got \"%s\"\n", val);
11096     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11097
11098     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11099     lstrcatA(keypath, usersid);
11100     lstrcatA(keypath, "\\Products\\");
11101     lstrcatA(keypath, prod_squashed);
11102
11103     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11105
11106     /* local UserData product key exists */
11107     size = MAX_PATH;
11108     lstrcpyA(val, "apple");
11109     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11110                             MSIINSTALLCONTEXT_USERUNMANAGED,
11111                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11112     ok(r == ERROR_UNKNOWN_PRODUCT,
11113        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11114     ok(!lstrcmpA(val, "apple"),
11115        "Expected val to be unchanged, got \"%s\"\n", val);
11116     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11117
11118     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11120
11121     /* InstallProperties key exists */
11122     size = MAX_PATH;
11123     lstrcpyA(val, "apple");
11124     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11125                             MSIINSTALLCONTEXT_USERUNMANAGED,
11126                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11127     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11128     ok(!lstrcmpA(val, "apple"),
11129        "Expected val to be unchanged, got \"%s\"\n", val);
11130     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11131
11132     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11134
11135     /* Patches key exists */
11136     size = MAX_PATH;
11137     lstrcpyA(val, "apple");
11138     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11139                             MSIINSTALLCONTEXT_USERUNMANAGED,
11140                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11141     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11142     ok(!lstrcmpA(val, "apple"),
11143        "Expected val to be unchanged, got \"%s\"\n", val);
11144     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11145
11146     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11148
11149     /* Patches key exists */
11150     size = MAX_PATH;
11151     lstrcpyA(val, "apple");
11152     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11153                             MSIINSTALLCONTEXT_USERUNMANAGED,
11154                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11155     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11156     ok(!lstrcmpA(val, "apple"),
11157        "Expected val to be unchanged, got \"%s\"\n", val);
11158     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11159
11160     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11161     lstrcatA(keypath, prod_squashed);
11162
11163     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11165
11166     /* current user product key exists */
11167     size = MAX_PATH;
11168     lstrcpyA(val, "apple");
11169     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11170                             MSIINSTALLCONTEXT_USERUNMANAGED,
11171                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11172     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11173     ok(!lstrcmpA(val, "apple"),
11174        "Expected val to be unchanged, got \"%s\"\n", val);
11175     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11176
11177     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
11178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11179
11180     /* Patches key exists */
11181     size = MAX_PATH;
11182     lstrcpyA(val, "apple");
11183     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11184                             MSIINSTALLCONTEXT_USERUNMANAGED,
11185                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11186     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11187     ok(!lstrcmpA(val, "apple"),
11188        "Expected val to be unchanged, got \"%s\"\n", val);
11189     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11190
11191     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11192                          (const BYTE *)"transforms", 11);
11193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11194
11195     /* specific patch value exists */
11196     size = MAX_PATH;
11197     lstrcpyA(val, "apple");
11198     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11199                             MSIINSTALLCONTEXT_USERUNMANAGED,
11200                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11201     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11202     ok(!lstrcmpA(val, "apple"),
11203        "Expected val to be unchanged, got \"%s\"\n", val);
11204     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11205
11206     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11207     lstrcatA(keypath, usersid);
11208     lstrcatA(keypath, "\\Patches\\");
11209     lstrcatA(keypath, patch_squashed);
11210
11211     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11213
11214     /* UserData Patches key exists */
11215     size = MAX_PATH;
11216     lstrcpyA(val, "apple");
11217     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11218                             MSIINSTALLCONTEXT_USERUNMANAGED,
11219                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11220     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11221     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11222     ok(size == 0, "Expected 0, got %d\n", size);
11223
11224     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11225                          (const BYTE *)"pack", 5);
11226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11227
11228     /* LocalPatch value exists */
11229     size = MAX_PATH;
11230     lstrcpyA(val, "apple");
11231     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11232                             MSIINSTALLCONTEXT_USERUNMANAGED,
11233                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11235     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11236     ok(size == 4, "Expected 4, got %d\n", size);
11237
11238     size = MAX_PATH;
11239     lstrcpyA(val, "apple");
11240     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11241                             MSIINSTALLCONTEXT_USERUNMANAGED,
11242                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11244     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11245     ok(size == 10, "Expected 10, got %d\n", size);
11246
11247     RegDeleteValueA(prodpatches, patch_squashed);
11248     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11249     RegCloseKey(prodpatches);
11250     RegDeleteKeyA(prodkey, "");
11251     RegCloseKey(prodkey);
11252
11253     /* UserData is sufficient for all properties
11254      * except INSTALLPROPERTY_TRANSFORMS
11255      */
11256     size = MAX_PATH;
11257     lstrcpyA(val, "apple");
11258     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11259                             MSIINSTALLCONTEXT_USERUNMANAGED,
11260                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11262     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11263     ok(size == 4, "Expected 4, got %d\n", size);
11264
11265     /* UserData is sufficient for all properties
11266      * except INSTALLPROPERTY_TRANSFORMS
11267      */
11268     size = MAX_PATH;
11269     lstrcpyA(val, "apple");
11270     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11271                             MSIINSTALLCONTEXT_USERUNMANAGED,
11272                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11273     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11274     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11275     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11276
11277     RegDeleteValueA(udpatch, "LocalPackage");
11278     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11279     RegCloseKey(udpatch);
11280     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11281     RegCloseKey(hpatch);
11282     delete_key(patches, "", access & KEY_WOW64_64KEY);
11283     RegCloseKey(patches);
11284     delete_key(props, "", access & KEY_WOW64_64KEY);
11285     RegCloseKey(props);
11286     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11287     RegCloseKey(udprod);
11288
11289     /* MSIINSTALLCONTEXT_MACHINE */
11290
11291     size = MAX_PATH;
11292     lstrcpyA(val, "apple");
11293     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11294                             MSIINSTALLCONTEXT_MACHINE,
11295                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11296     ok(r == ERROR_UNKNOWN_PRODUCT,
11297        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11298     ok(!lstrcmpA(val, "apple"),
11299        "Expected val to be unchanged, got \"%s\"\n", val);
11300     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11301
11302     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11303     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11304     lstrcatA(keypath, prod_squashed);
11305
11306     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11308
11309     /* local UserData product key exists */
11310     size = MAX_PATH;
11311     lstrcpyA(val, "apple");
11312     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11313                             MSIINSTALLCONTEXT_MACHINE,
11314                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11315     ok(r == ERROR_UNKNOWN_PRODUCT,
11316        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11317     ok(!lstrcmpA(val, "apple"),
11318        "Expected val to be unchanged, got \"%s\"\n", val);
11319     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11320
11321     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11322     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11323
11324     /* InstallProperties key exists */
11325     size = MAX_PATH;
11326     lstrcpyA(val, "apple");
11327     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11328                             MSIINSTALLCONTEXT_MACHINE,
11329                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11330     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11331     ok(!lstrcmpA(val, "apple"),
11332        "Expected val to be unchanged, got \"%s\"\n", val);
11333     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11334
11335     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11337
11338     /* Patches key exists */
11339     size = MAX_PATH;
11340     lstrcpyA(val, "apple");
11341     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11342                             MSIINSTALLCONTEXT_MACHINE,
11343                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11344     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11345     ok(!lstrcmpA(val, "apple"),
11346        "Expected val to be unchanged, got \"%s\"\n", val);
11347     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11348
11349     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11351
11352     /* Patches key exists */
11353     size = MAX_PATH;
11354     lstrcpyA(val, "apple");
11355     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11356                             MSIINSTALLCONTEXT_MACHINE,
11357                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11358     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11359     ok(!lstrcmpA(val, "apple"),
11360        "Expected val to be unchanged, got \"%s\"\n", val);
11361     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11362
11363     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11364     lstrcatA(keypath, prod_squashed);
11365
11366     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11368
11369     /* local product key exists */
11370     size = MAX_PATH;
11371     lstrcpyA(val, "apple");
11372     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11373                             MSIINSTALLCONTEXT_MACHINE,
11374                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11375     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11376     ok(!lstrcmpA(val, "apple"),
11377        "Expected val to be unchanged, got \"%s\"\n", val);
11378     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11379
11380     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11382
11383     /* Patches key exists */
11384     size = MAX_PATH;
11385     lstrcpyA(val, "apple");
11386     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11387                             MSIINSTALLCONTEXT_MACHINE,
11388                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11389     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11390     ok(!lstrcmpA(val, "apple"),
11391        "Expected val to be unchanged, got \"%s\"\n", val);
11392     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11393
11394     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11395                          (const BYTE *)"transforms", 11);
11396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11397
11398     /* specific patch value exists */
11399     size = MAX_PATH;
11400     lstrcpyA(val, "apple");
11401     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11402                             MSIINSTALLCONTEXT_MACHINE,
11403                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11404     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11405     ok(!lstrcmpA(val, "apple"),
11406        "Expected val to be unchanged, got \"%s\"\n", val);
11407     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11408
11409     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11410     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11411     lstrcatA(keypath, patch_squashed);
11412
11413     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11415
11416     /* UserData Patches key exists */
11417     size = MAX_PATH;
11418     lstrcpyA(val, "apple");
11419     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11420                             MSIINSTALLCONTEXT_MACHINE,
11421                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11423     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11424     ok(size == 0, "Expected 0, got %d\n", size);
11425
11426     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11427                          (const BYTE *)"pack", 5);
11428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11429
11430     /* LocalPatch value exists */
11431     size = MAX_PATH;
11432     lstrcpyA(val, "apple");
11433     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11434                             MSIINSTALLCONTEXT_MACHINE,
11435                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11437     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11438     ok(size == 4, "Expected 4, got %d\n", size);
11439
11440     size = MAX_PATH;
11441     lstrcpyA(val, "apple");
11442     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11443                             MSIINSTALLCONTEXT_MACHINE,
11444                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11446     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11447     ok(size == 10, "Expected 10, got %d\n", size);
11448
11449     RegDeleteValueA(prodpatches, patch_squashed);
11450     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11451     RegCloseKey(prodpatches);
11452     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11453     RegCloseKey(prodkey);
11454
11455     /* UserData is sufficient for all properties
11456      * except INSTALLPROPERTY_TRANSFORMS
11457      */
11458     size = MAX_PATH;
11459     lstrcpyA(val, "apple");
11460     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11461                             MSIINSTALLCONTEXT_MACHINE,
11462                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11464     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11465     ok(size == 4, "Expected 4, got %d\n", size);
11466
11467     /* UserData is sufficient for all properties
11468      * except INSTALLPROPERTY_TRANSFORMS
11469      */
11470     size = MAX_PATH;
11471     lstrcpyA(val, "apple");
11472     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11473                             MSIINSTALLCONTEXT_MACHINE,
11474                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11475     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11476     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11477     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11478
11479     RegDeleteValueA(udpatch, "LocalPackage");
11480     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11481     RegCloseKey(udpatch);
11482     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11483     RegCloseKey(hpatch);
11484     delete_key(patches, "", access & KEY_WOW64_64KEY);
11485     RegCloseKey(patches);
11486     delete_key(props, "", access & KEY_WOW64_64KEY);
11487     RegCloseKey(props);
11488     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11489     RegCloseKey(udprod);
11490     LocalFree(usersid);
11491 }
11492
11493 static void test_MsiGetPatchInfo(void)
11494 {
11495     UINT r;
11496     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11497     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11498     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11499     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11500     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11501     DWORD size;
11502     LONG res;
11503     REGSAM access = KEY_ALL_ACCESS;
11504
11505     create_test_guid(patch_code, patch_squashed);
11506     create_test_guid(prod_code, prod_squashed);
11507     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11508
11509     if (is_wow64)
11510         access |= KEY_WOW64_64KEY;
11511
11512     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11513     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11514
11515     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11516     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11517
11518     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11519     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11520
11521     size = 0;
11522     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11523     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11524
11525     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11526     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11527
11528     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11529     lstrcatA(keypath, prod_squashed);
11530
11531     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11532     if (res == ERROR_ACCESS_DENIED)
11533     {
11534         skip("Not enough rights to perform tests\n");
11535         return;
11536     }
11537     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11538
11539     /* product 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_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11548     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11549
11550     /* patches 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     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11559     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11560
11561     /* patch key exists */
11562     size = MAX_PATH;
11563     lstrcpyA(val, "apple");
11564     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11565     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11566     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11567     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11568
11569     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11570     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11571     lstrcatA(keypath, prod_squashed);
11572
11573     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11575
11576     /* UserData product 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, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11585     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11586
11587     /* InstallProperties 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_udpatches, NULL);
11596     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11597
11598     /* UserData Patches key exists */
11599     size = MAX_PATH;
11600     lstrcpyA(val, "apple");
11601     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11602     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11603     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11604     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11605
11606     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11608
11609     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11611
11612     /* UserData product patch key exists */
11613     size = MAX_PATH;
11614     lstrcpyA(val, "apple");
11615     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11616     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11617     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11618     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11619
11620     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11621     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11622     lstrcatA(keypath, patch_squashed);
11623
11624     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11625     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11626
11627     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11628     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11629
11630     /* UserData Patch key exists */
11631     size = 0;
11632     lstrcpyA(val, "apple");
11633     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11634     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11635     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11636     ok(size == 11, "expected 11 got %u\n", size);
11637
11638     size = MAX_PATH;
11639     lstrcpyA(val, "apple");
11640     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11641     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11642     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11643     ok(size == 11, "expected 11 got %u\n", size);
11644
11645     size = 0;
11646     valW[0] = 0;
11647     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11648     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11649     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11650     ok(size == 11, "expected 11 got %u\n", size);
11651
11652     size = MAX_PATH;
11653     valW[0] = 0;
11654     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11655     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11656     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11657     ok(size == 11, "expected 11 got %u\n", size);
11658
11659     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11660     RegCloseKey(hkey_udproductpatch);
11661     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11662     RegCloseKey(hkey_udproductpatches);
11663     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11664     RegCloseKey(hkey_udpatch);
11665     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11666     RegCloseKey(hkey_patches);
11667     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11668     RegCloseKey(hkey_product);
11669     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11670     RegCloseKey(hkey_patch);
11671     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11672     RegCloseKey(hkey_udpatches);
11673     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11674     RegCloseKey(hkey_udprops);
11675     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11676     RegCloseKey(hkey_udproduct);
11677 }
11678
11679 static void test_MsiEnumProducts(void)
11680 {
11681     UINT r;
11682     int found1, found2, found3;
11683     DWORD index;
11684     char product1[39], product2[39], product3[39], guid[39];
11685     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11686     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11687     char *usersid;
11688     HKEY key1, key2, key3;
11689     REGSAM access = KEY_ALL_ACCESS;
11690
11691     create_test_guid(product1, product_squashed1);
11692     create_test_guid(product2, product_squashed2);
11693     create_test_guid(product3, product_squashed3);
11694     usersid = get_user_sid();
11695
11696     if (is_wow64)
11697         access |= KEY_WOW64_64KEY;
11698
11699     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11700     strcat(keypath1, product_squashed1);
11701
11702     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11703     if (r == ERROR_ACCESS_DENIED)
11704     {
11705         skip("Not enough rights to perform tests\n");
11706         LocalFree(usersid);
11707         return;
11708     }
11709     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11710
11711     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11712     strcat(keypath2, usersid);
11713     strcat(keypath2, "\\Installer\\Products\\");
11714     strcat(keypath2, product_squashed2);
11715
11716     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11717     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11718
11719     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11720     strcat(keypath3, product_squashed3);
11721
11722     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\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     r = MsiEnumProductsA(index, NULL);
11730     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11731
11732     index = 2;
11733     r = MsiEnumProductsA(index, guid);
11734     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11735
11736     index = 0;
11737     r = MsiEnumProductsA(index, guid);
11738     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11739
11740     found1 = found2 = found3 = 0;
11741     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11742     {
11743         if (!strcmp(product1, guid)) found1 = 1;
11744         if (!strcmp(product2, guid)) found2 = 1;
11745         if (!strcmp(product3, guid)) found3 = 1;
11746         index++;
11747     }
11748     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11749     ok(found1, "product1 not found\n");
11750     ok(found2, "product2 not found\n");
11751     ok(found3, "product3 not found\n");
11752
11753     delete_key(key1, "", access & KEY_WOW64_64KEY);
11754     delete_key(key2, "", access & KEY_WOW64_64KEY);
11755     RegDeleteKeyA(key3, "");
11756     RegCloseKey(key1);
11757     RegCloseKey(key2);
11758     RegCloseKey(key3);
11759     LocalFree(usersid);
11760 }
11761
11762 static void test_MsiGetFileSignatureInformation(void)
11763 {
11764     HRESULT hr;
11765     const CERT_CONTEXT *cert;
11766     DWORD len;
11767
11768     hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
11769     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11770
11771     hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
11772     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11773
11774     hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
11775     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11776
11777     hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
11778     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11779
11780     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
11781     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11782
11783     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
11784     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11785
11786     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
11787     todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
11788
11789     create_file( "signature.bin", "signature", sizeof("signature") );
11790
11791     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
11792     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11793
11794     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
11795     ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
11796
11797     hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
11798     todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
11799
11800     DeleteFileA( "signature.bin" );
11801 }
11802
11803 static void test_MsiEnumProductsEx(void)
11804 {
11805     UINT r;
11806     DWORD len, index;
11807     MSIINSTALLCONTEXT context;
11808     char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
11809     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11810     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11811     HKEY key1, key2, key3;
11812     REGSAM access = KEY_ALL_ACCESS;
11813     char *usersid = get_user_sid();
11814
11815     create_test_guid( product0, NULL );
11816     create_test_guid( product1, product_squashed1 );
11817     create_test_guid( product2, product_squashed2 );
11818     create_test_guid( product3, product_squashed3 );
11819
11820     if (is_wow64) access |= KEY_WOW64_64KEY;
11821
11822     strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
11823     strcat( keypath1, product_squashed1 );
11824
11825     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
11826     if (r == ERROR_ACCESS_DENIED)
11827     {
11828         skip( "insufficient rights\n" );
11829         LocalFree( usersid );
11830         return;
11831     }
11832     ok( r == ERROR_SUCCESS, "got %u\n", r );
11833
11834     strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
11835     strcat( keypath2, usersid );
11836     strcat( keypath2, "\\Installer\\Products\\" );
11837     strcat( keypath2, product_squashed2 );
11838
11839     r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
11840     ok( r == ERROR_SUCCESS, "got %u\n", r );
11841
11842     strcpy( keypath3, usersid );
11843     strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
11844     strcat( keypath3, product_squashed3 );
11845
11846     r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
11847     ok( r == ERROR_SUCCESS, "got %u\n", r );
11848
11849     r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
11850     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
11851
11852     len = sizeof(sid);
11853     r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
11854     ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
11855     ok( len == sizeof(sid), "got %u\n", len );
11856
11857     r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
11858     ok( r == ERROR_SUCCESS, "got %u\n", r );
11859
11860     sid[0] = 0;
11861     len = sizeof(sid);
11862     r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
11863     ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
11864     ok( len == sizeof(sid), "got %u\n", len );
11865     ok( !sid[0], "got %s\n", sid );
11866
11867     sid[0] = 0;
11868     len = sizeof(sid);
11869     r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
11870     ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
11871     ok( len == sizeof(sid), "got %u\n", len );
11872     ok( !sid[0], "got %s\n", sid );
11873
11874     guid[0] = 0;
11875     context = 0xdeadbeef;
11876     sid[0] = 0;
11877     len = sizeof(sid);
11878     r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
11879     ok( r == ERROR_SUCCESS, "got %u\n", r );
11880     ok( guid[0], "empty guid\n" );
11881     ok( context != 0xdeadbeef, "context unchanged\n" );
11882     ok( !len, "got %u\n", len );
11883     ok( !sid[0], "got %s\n", sid );
11884
11885     guid[0] = 0;
11886     context = 0xdeadbeef;
11887     sid[0] = 0;
11888     len = sizeof(sid);
11889     r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
11890     ok( r == ERROR_SUCCESS, "got %u\n", r );
11891     ok( guid[0], "empty guid\n" );
11892     ok( context != 0xdeadbeef, "context unchanged\n" );
11893     ok( !len, "got %u\n", len );
11894     ok( !sid[0], "got %s\n", sid );
11895
11896     guid[0] = 0;
11897     context = 0xdeadbeef;
11898     sid[0] = 0;
11899     len = sizeof(sid);
11900     r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
11901     if (r == ERROR_ACCESS_DENIED)
11902     {
11903         skip( "insufficient rights\n" );
11904         LocalFree( usersid );
11905         return;
11906     }
11907     ok( r == ERROR_SUCCESS, "got %u\n", r );
11908     ok( guid[0], "empty guid\n" );
11909     ok( context != 0xdeadbeef, "context unchanged\n" );
11910     ok( !len, "got %u\n", len );
11911     ok( !sid[0], "got %s\n", sid );
11912
11913     index = 0;
11914     guid[0] = 0;
11915     context = 0xdeadbeef;
11916     sid[0] = 0;
11917     len = sizeof(sid);
11918     while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
11919     {
11920         if (!strcmp( product1, guid ))
11921         {
11922             ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
11923             ok( !sid[0], "got \"%s\"\n", sid );
11924             ok( !len, "unexpected length %u\n", len );
11925         }
11926         if (!strcmp( product2, guid ))
11927         {
11928             ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
11929             ok( sid[0], "empty sid\n" );
11930             ok( len == strlen(sid), "unexpected length %u\n", len );
11931         }
11932         if (!strcmp( product3, guid ))
11933         {
11934             ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
11935             ok( sid[0], "empty sid\n" );
11936             ok( len == strlen(sid), "unexpected length %u\n", len );
11937         }
11938         index++;
11939         guid[0] = 0;
11940         context = 0xdeadbeef;
11941         sid[0] = 0;
11942         len = sizeof(sid);
11943     }
11944
11945     delete_key( key1, "", access );
11946     delete_key( key2, "", access );
11947     delete_key( key3, "", access );
11948     RegCloseKey( key1 );
11949     RegCloseKey( key2 );
11950     RegCloseKey( key3 );
11951     LocalFree( usersid );
11952 }
11953
11954 START_TEST(msi)
11955 {
11956     init_functionpointers();
11957
11958     if (pIsWow64Process)
11959         pIsWow64Process(GetCurrentProcess(), &is_wow64);
11960
11961     test_usefeature();
11962     test_null();
11963     test_getcomponentpath();
11964     test_MsiGetFileHash();
11965
11966     if (!pConvertSidToStringSidA)
11967         win_skip("ConvertSidToStringSidA not implemented\n");
11968     else
11969     {
11970         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11971         test_MsiQueryProductState();
11972         test_MsiQueryFeatureState();
11973         test_MsiQueryComponentState();
11974         test_MsiGetComponentPath();
11975         test_MsiGetProductCode();
11976         test_MsiEnumClients();
11977         test_MsiGetProductInfo();
11978         test_MsiGetProductInfoEx();
11979         test_MsiGetUserInfo();
11980         test_MsiOpenProduct();
11981         test_MsiEnumPatchesEx();
11982         test_MsiEnumPatches();
11983         test_MsiGetPatchInfoEx();
11984         test_MsiGetPatchInfo();
11985         test_MsiEnumProducts();
11986         test_MsiEnumProductsEx();
11987     }
11988     test_MsiGetFileVersion();
11989     test_MsiGetFileSignatureInformation();
11990 }