d3dx8: Add a few tests for MatrixStack.
[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 const char msifile[] = "winetest.msi";
33
34 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
35
36 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
37     (LPCSTR, LPCSTR, LPSTR, DWORD*);
38 static UINT (WINAPI *pMsiGetFileHashA)
39     (LPCSTR, DWORD, PMSIFILEHASHINFO);
40 static UINT (WINAPI *pMsiGetProductInfoExA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiOpenPackageExA)
43     (LPCSTR, DWORD, MSIHANDLE*);
44 static UINT (WINAPI *pMsiOpenPackageExW)
45     (LPCWSTR, DWORD, MSIHANDLE*);
46 static UINT (WINAPI *pMsiQueryComponentStateA)
47     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
48 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
49     (LPCSTR, LPCSTR ,DWORD, DWORD );
50
51 static void init_functionpointers(void)
52 {
53     HMODULE hmsi = GetModuleHandleA("msi.dll");
54     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
55
56 #define GET_PROC(dll, func) \
57     p ## func = (void *)GetProcAddress(dll, #func); \
58     if(!p ## func) \
59       trace("GetProcAddress(%s) failed\n", #func);
60
61     GET_PROC(hmsi, MsiGetComponentPathA)
62     GET_PROC(hmsi, MsiGetFileHashA)
63     GET_PROC(hmsi, MsiGetProductInfoExA)
64     GET_PROC(hmsi, MsiOpenPackageExA)
65     GET_PROC(hmsi, MsiOpenPackageExW)
66     GET_PROC(hmsi, MsiQueryComponentStateA)
67     GET_PROC(hmsi, MsiUseFeatureExA)
68
69     GET_PROC(hadvapi32, ConvertSidToStringSidA)
70
71 #undef GET_PROC
72 }
73
74 static UINT run_query(MSIHANDLE hdb, const char *query)
75 {
76     MSIHANDLE hview = 0;
77     UINT r;
78
79     r = MsiDatabaseOpenView(hdb, query, &hview);
80     if (r != ERROR_SUCCESS)
81         return r;
82
83     r = MsiViewExecute(hview, 0);
84     if (r == ERROR_SUCCESS)
85         r = MsiViewClose(hview);
86     MsiCloseHandle(hview);
87     return r;
88 }
89
90 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
91 {
92     UINT res;
93     MSIHANDLE suminfo;
94
95     /* build summary info */
96     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
97     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
98
99     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
100                                     "Installation Database");
101     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
102
103     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
104                                     "Installation Database");
105     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
106
107     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
108                                     "Wine Hackers");
109     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
110
111     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
112                                     ";1033");
113     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
114
115     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
116                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
117     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
118
119     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
120     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
121
122     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
123     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
124
125     res = MsiSummaryInfoPersist(suminfo);
126     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
127
128     res = MsiCloseHandle(suminfo);
129     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
130
131     return res;
132 }
133
134 static MSIHANDLE create_package_db(LPSTR prodcode)
135 {
136     MSIHANDLE hdb = 0;
137     CHAR query[MAX_PATH];
138     UINT res;
139
140     DeleteFile(msifile);
141
142     /* create an empty database */
143     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
144     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
145     if (res != ERROR_SUCCESS)
146         return hdb;
147
148     res = MsiDatabaseCommit(hdb);
149     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
150
151     set_summary_info(hdb, prodcode);
152
153     res = run_query(hdb,
154             "CREATE TABLE `Directory` ( "
155             "`Directory` CHAR(255) NOT NULL, "
156             "`Directory_Parent` CHAR(255), "
157             "`DefaultDir` CHAR(255) NOT NULL "
158             "PRIMARY KEY `Directory`)");
159     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
160
161     res = run_query(hdb,
162             "CREATE TABLE `Property` ( "
163             "`Property` CHAR(72) NOT NULL, "
164             "`Value` CHAR(255) "
165             "PRIMARY KEY `Property`)");
166     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
167
168     sprintf(query, "INSERT INTO `Property` "
169             "(`Property`, `Value`) "
170             "VALUES( 'ProductCode', '%s' )", prodcode);
171     res = run_query(hdb, query);
172     ok(res == ERROR_SUCCESS , "Failed\n");
173
174     res = MsiDatabaseCommit(hdb);
175     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
176
177     return hdb;
178 }
179
180 static void test_usefeature(void)
181 {
182     INSTALLSTATE r;
183
184     if (!pMsiUseFeatureExA)
185     {
186         skip("MsiUseFeatureExA not implemented\n");
187         return;
188     }
189
190     r = MsiQueryFeatureState(NULL,NULL);
191     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
192
193     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
194     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
195
196     r = pMsiUseFeatureExA(NULL,NULL,0,0);
197     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
198
199     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
200     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
201
202     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
203                          NULL, -2, 0 );
204     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
205
206     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
207                          "WORDVIEWFiles", -2, 0 );
208     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
209
210     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
211                          "WORDVIEWFiles", -2, 0 );
212     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
213
214     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
215                          "WORDVIEWFiles", -2, 1 );
216     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
217 }
218
219 static void test_null(void)
220 {
221     MSIHANDLE hpkg;
222     UINT r;
223     HKEY hkey;
224     DWORD dwType, cbData;
225     LPBYTE lpData = NULL;
226     INSTALLSTATE state;
227
228     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
229     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
230
231     state = MsiQueryProductStateW(NULL);
232     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
233
234     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
235     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
236
237     r = MsiConfigureFeatureW(NULL, NULL, 0);
238     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
239
240     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
241     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
242
243     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
244     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
245
246     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
247     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
248
249     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
250      * necessary registry values */
251
252     /* empty product string */
253     r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
254     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
255
256     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
257     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
258     if ( r == ERROR_SUCCESS )
259     {
260         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
261         if (!lpData)
262             skip("Out of memory\n");
263         else
264         {
265             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
266             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
267         }
268     }
269
270     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
271     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
272
273     r = MsiGetProductInfoA("", "", NULL, NULL);
274     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
275
276     if (lpData)
277     {
278         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
279         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
280
281         HeapFree(GetProcessHeap(), 0, lpData);
282     }
283     else
284     {
285         r = RegDeleteValueA(hkey, NULL);
286         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
287     }
288
289     r = RegCloseKey(hkey);
290     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
291
292     /* empty attribute */
293     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
294     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
295
296     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
297     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
298
299     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
300     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
301
302     r = RegCloseKey(hkey);
303     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
304
305     r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
306     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
307 }
308
309 static void test_getcomponentpath(void)
310 {
311     INSTALLSTATE r;
312     char buffer[0x100];
313     DWORD sz;
314
315     if(!pMsiGetComponentPathA)
316         return;
317
318     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
319     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
320
321     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
322     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
323
324     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
325     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
326
327     sz = sizeof buffer;
328     buffer[0]=0;
329     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
330     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
331
332     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
333         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
334     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
335
336     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
337         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
338     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
339
340     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
341         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
342     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
343
344     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
345                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
346     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
347 }
348
349 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
350 {
351     HANDLE file;
352     DWORD written;
353
354     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
355     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
356     WriteFile(file, data, strlen(data), &written, NULL);
357
358     if (size)
359     {
360         SetFilePointer(file, size, NULL, FILE_BEGIN);
361         SetEndOfFile(file);
362     }
363
364     CloseHandle(file);
365 }
366
367 #define HASHSIZE sizeof(MSIFILEHASHINFO)
368
369 static const struct
370 {
371     LPCSTR data;
372     DWORD size;
373     MSIFILEHASHINFO hash;
374 } hash_data[] =
375 {
376     { "abc", 0,
377       { HASHSIZE,
378         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
379       },
380     },
381
382     { "C:\\Program Files\\msitest\\caesar\n", 0,
383       { HASHSIZE,
384         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
385       },
386     },
387
388     { "C:\\Program Files\\msitest\\caesar\n", 500,
389       { HASHSIZE,
390         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
391       },
392     },
393 };
394
395 static void test_MsiGetFileHash(void)
396 {
397     const char name[] = "msitest.bin";
398     UINT r;
399     MSIFILEHASHINFO hash;
400     DWORD i;
401
402     if (!pMsiGetFileHashA)
403     {
404         skip("MsiGetFileHash not implemented\n");
405         return;
406     }
407
408     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
409
410     /* szFilePath is NULL */
411     r = pMsiGetFileHashA(NULL, 0, &hash);
412     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
413
414     /* szFilePath is empty */
415     r = pMsiGetFileHashA("", 0, &hash);
416     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
417        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
418
419     /* szFilePath is nonexistent */
420     r = pMsiGetFileHashA(name, 0, &hash);
421     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
422
423     /* dwOptions is non-zero */
424     r = pMsiGetFileHashA(name, 1, &hash);
425     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
426
427     /* pHash.dwFileHashInfoSize is not correct */
428     hash.dwFileHashInfoSize = 0;
429     r = pMsiGetFileHashA(name, 0, &hash);
430     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
431
432     /* pHash is NULL */
433     r = pMsiGetFileHashA(name, 0, NULL);
434     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
435
436     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
437     {
438         int ret;
439
440         create_file(name, hash_data[i].data, hash_data[i].size);
441
442         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
443         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
444
445         r = pMsiGetFileHashA(name, 0, &hash);
446         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
447
448         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
449         ok(ret == 0 ||
450            broken(ret != 0), /* win95 */
451            "Hash incorrect\n");
452
453         DeleteFile(name);
454     }
455 }
456
457 /* copied from dlls/msi/registry.c */
458 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
459 {
460     DWORD i,n=1;
461     GUID guid;
462
463     if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
464         return FALSE;
465
466     for(i=0; i<8; i++)
467         out[7-i] = in[n++];
468     n++;
469     for(i=0; i<4; i++)
470         out[11-i] = in[n++];
471     n++;
472     for(i=0; i<4; i++)
473         out[15-i] = in[n++];
474     n++;
475     for(i=0; i<2; i++)
476     {
477         out[17+i*2] = in[n++];
478         out[16+i*2] = in[n++];
479     }
480     n++;
481     for( ; i<8; i++)
482     {
483         out[17+i*2] = in[n++];
484         out[16+i*2] = in[n++];
485     }
486     out[32]=0;
487     return TRUE;
488 }
489
490 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
491 {
492     WCHAR guidW[MAX_PATH];
493     WCHAR squashedW[MAX_PATH];
494     GUID guid;
495     HRESULT hr;
496     int size;
497
498     hr = CoCreateGuid(&guid);
499     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
500
501     size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
502     ok(size == 39, "Expected 39, got %d\n", hr);
503
504     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
505     squash_guid(guidW, squashedW);
506     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
507 }
508
509 static void get_user_sid(LPSTR *usersid)
510 {
511     HANDLE token;
512     BYTE buf[1024];
513     DWORD size;
514     PTOKEN_USER user;
515
516     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
517     size = sizeof(buf);
518     GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
519     user = (PTOKEN_USER)buf;
520     pConvertSidToStringSidA(user->User.Sid, usersid);
521 }
522
523 static void test_MsiQueryProductState(void)
524 {
525     CHAR prodcode[MAX_PATH];
526     CHAR prod_squashed[MAX_PATH];
527     CHAR keypath[MAX_PATH*2];
528     LPSTR usersid;
529     INSTALLSTATE state;
530     LONG res;
531     HKEY userkey, localkey, props;
532     HKEY prodkey;
533     DWORD data;
534
535     create_test_guid(prodcode, prod_squashed);
536     get_user_sid(&usersid);
537
538     /* NULL prodcode */
539     state = MsiQueryProductStateA(NULL);
540     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
541
542     /* empty prodcode */
543     state = MsiQueryProductStateA("");
544     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
545
546     /* garbage prodcode */
547     state = MsiQueryProductStateA("garbage");
548     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
549
550     /* guid without brackets */
551     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
552     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
553
554     /* guid with brackets */
555     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
556     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
557
558     /* same length as guid, but random */
559     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
560     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
561
562     /* MSIINSTALLCONTEXT_USERUNMANAGED */
563
564     state = MsiQueryProductStateA(prodcode);
565     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
566
567     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
568     lstrcatA(keypath, prod_squashed);
569
570     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
572
573     /* user product key exists */
574     state = MsiQueryProductStateA(prodcode);
575     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
576
577     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
578     lstrcatA(keypath, prodcode);
579
580     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
582
583     /* local uninstall key exists */
584     state = MsiQueryProductStateA(prodcode);
585     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
586
587     data = 1;
588     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
590
591     /* WindowsInstaller value exists */
592     state = MsiQueryProductStateA(prodcode);
593     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
594
595     RegDeleteValueA(localkey, "WindowsInstaller");
596     RegDeleteKeyA(localkey, "");
597
598     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
599     lstrcatA(keypath, usersid);
600     lstrcatA(keypath, "\\Products\\");
601     lstrcatA(keypath, prod_squashed);
602
603     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
605
606     /* local product key exists */
607     state = MsiQueryProductStateA(prodcode);
608     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
609
610     res = RegCreateKeyA(localkey, "InstallProperties", &props);
611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
612
613     /* install properties key exists */
614     state = MsiQueryProductStateA(prodcode);
615     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
616
617     data = 1;
618     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
620
621     /* WindowsInstaller value exists */
622     state = MsiQueryProductStateA(prodcode);
623     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
624
625     data = 2;
626     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
628
629     /* WindowsInstaller value is not 1 */
630     state = MsiQueryProductStateA(prodcode);
631     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
632
633     RegDeleteKeyA(userkey, "");
634
635     /* user product key does not exist */
636     state = MsiQueryProductStateA(prodcode);
637     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
638
639     RegDeleteValueA(props, "WindowsInstaller");
640     RegDeleteKeyA(props, "");
641     RegCloseKey(props);
642     RegDeleteKeyA(localkey, "");
643     RegCloseKey(localkey);
644     RegDeleteKeyA(userkey, "");
645     RegCloseKey(userkey);
646
647     /* MSIINSTALLCONTEXT_USERMANAGED */
648
649     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
650     lstrcatA(keypath, usersid);
651     lstrcatA(keypath, "\\Installer\\Products\\");
652     lstrcatA(keypath, prod_squashed);
653
654     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
656
657     state = MsiQueryProductStateA(prodcode);
658     ok(state == INSTALLSTATE_ADVERTISED,
659        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
660
661     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
662     lstrcatA(keypath, usersid);
663     lstrcatA(keypath, "\\Products\\");
664     lstrcatA(keypath, prod_squashed);
665
666     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
668
669     state = MsiQueryProductStateA(prodcode);
670     ok(state == INSTALLSTATE_ADVERTISED,
671        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
672
673     res = RegCreateKeyA(localkey, "InstallProperties", &props);
674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
675
676     state = MsiQueryProductStateA(prodcode);
677     ok(state == INSTALLSTATE_ADVERTISED,
678        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
679
680     data = 1;
681     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
683
684     /* WindowsInstaller value exists */
685     state = MsiQueryProductStateA(prodcode);
686     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
687
688     RegDeleteValueA(props, "WindowsInstaller");
689     RegDeleteKeyA(props, "");
690     RegCloseKey(props);
691     RegDeleteKeyA(localkey, "");
692     RegCloseKey(localkey);
693     RegDeleteKeyA(prodkey, "");
694     RegCloseKey(prodkey);
695
696     /* MSIINSTALLCONTEXT_MACHINE */
697
698     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
699     lstrcatA(keypath, prod_squashed);
700
701     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
703
704     state = MsiQueryProductStateA(prodcode);
705     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
706
707     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
708     lstrcatA(keypath, "S-1-5-18\\Products\\");
709     lstrcatA(keypath, prod_squashed);
710
711     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
713
714     state = MsiQueryProductStateA(prodcode);
715     ok(state == INSTALLSTATE_ADVERTISED,
716        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
717
718     res = RegCreateKeyA(localkey, "InstallProperties", &props);
719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
720
721     state = MsiQueryProductStateA(prodcode);
722     ok(state == INSTALLSTATE_ADVERTISED,
723        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
724
725     data = 1;
726     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
728
729     /* WindowsInstaller value exists */
730     state = MsiQueryProductStateA(prodcode);
731     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
732
733     RegDeleteValueA(props, "WindowsInstaller");
734     RegDeleteKeyA(props, "");
735     RegCloseKey(props);
736     RegDeleteKeyA(localkey, "");
737     RegCloseKey(localkey);
738     RegDeleteKeyA(prodkey, "");
739     RegCloseKey(prodkey);
740
741     LocalFree(usersid);
742 }
743
744 static const char table_enc85[] =
745 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
746 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
747 "yz{}~";
748
749 /*
750  *  Encodes a base85 guid given a GUID pointer
751  *  Caller should provide a 21 character buffer for the encoded string.
752  *
753  *  returns TRUE if successful, FALSE if not
754  */
755 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
756 {
757     unsigned int x, *p, i;
758
759     p = (unsigned int*) guid;
760     for( i=0; i<4; i++ )
761     {
762         x = p[i];
763         *str++ = table_enc85[x%85];
764         x = x/85;
765         *str++ = table_enc85[x%85];
766         x = x/85;
767         *str++ = table_enc85[x%85];
768         x = x/85;
769         *str++ = table_enc85[x%85];
770         x = x/85;
771         *str++ = table_enc85[x%85];
772     }
773     *str = 0;
774
775     return TRUE;
776 }
777
778 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
779 {
780     WCHAR guidW[MAX_PATH];
781     WCHAR base85W[MAX_PATH];
782     WCHAR squashedW[MAX_PATH];
783     GUID guid;
784     HRESULT hr;
785     int size;
786
787     hr = CoCreateGuid(&guid);
788     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
789
790     size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
791     ok(size == 39, "Expected 39, got %d\n", hr);
792
793     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
794     encode_base85_guid(&guid, base85W);
795     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
796     squash_guid(guidW, squashedW);
797     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
798 }
799
800 static void test_MsiQueryFeatureState(void)
801 {
802     HKEY userkey, localkey, compkey;
803     CHAR prodcode[MAX_PATH];
804     CHAR prod_squashed[MAX_PATH];
805     CHAR component[MAX_PATH];
806     CHAR comp_base85[MAX_PATH];
807     CHAR comp_squashed[MAX_PATH];
808     CHAR keypath[MAX_PATH*2];
809     INSTALLSTATE state;
810     LPSTR usersid;
811     LONG res;
812
813     create_test_guid(prodcode, prod_squashed);
814     compose_base85_guid(component, comp_base85, comp_squashed);
815     get_user_sid(&usersid);
816
817     /* NULL prodcode */
818     state = MsiQueryFeatureStateA(NULL, "feature");
819     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
820
821     /* empty prodcode */
822     state = MsiQueryFeatureStateA("", "feature");
823     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
824
825     /* garbage prodcode */
826     state = MsiQueryFeatureStateA("garbage", "feature");
827     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
828
829     /* guid without brackets */
830     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
831     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
832
833     /* guid with brackets */
834     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
835     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
836
837     /* same length as guid, but random */
838     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
839     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
840
841     /* NULL szFeature */
842     state = MsiQueryFeatureStateA(prodcode, NULL);
843     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
844
845     /* empty szFeature */
846     state = MsiQueryFeatureStateA(prodcode, "");
847     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
848
849     /* feature key does not exist yet */
850     state = MsiQueryFeatureStateA(prodcode, "feature");
851     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
852
853     /* MSIINSTALLCONTEXT_USERUNMANAGED */
854
855     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
856     lstrcatA(keypath, prod_squashed);
857
858     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
860
861     /* feature key exists */
862     state = MsiQueryFeatureStateA(prodcode, "feature");
863     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
864
865     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
867
868     /* feature value exists */
869     state = MsiQueryFeatureStateA(prodcode, "feature");
870     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
871
872     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
873     lstrcatA(keypath, usersid);
874     lstrcatA(keypath, "\\Products\\");
875     lstrcatA(keypath, prod_squashed);
876     lstrcatA(keypath, "\\Features");
877
878     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
880
881     /* userdata features key exists */
882     state = MsiQueryFeatureStateA(prodcode, "feature");
883     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
884
885     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
887
888     state = MsiQueryFeatureStateA(prodcode, "feature");
889     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
890
891     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
892     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
893
894     state = MsiQueryFeatureStateA(prodcode, "feature");
895     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
896
897     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
899
900     state = MsiQueryFeatureStateA(prodcode, "feature");
901     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
902
903     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
905
906     state = MsiQueryFeatureStateA(prodcode, "feature");
907     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
908
909     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
910     lstrcatA(keypath, usersid);
911     lstrcatA(keypath, "\\Components\\");
912     lstrcatA(keypath, comp_squashed);
913
914     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
916
917     state = MsiQueryFeatureStateA(prodcode, "feature");
918     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
919
920     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
922
923     state = MsiQueryFeatureStateA(prodcode, "feature");
924     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
925
926     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
928
929     /* INSTALLSTATE_LOCAL */
930     state = MsiQueryFeatureStateA(prodcode, "feature");
931     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
932
933     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
934     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
935
936     /* INSTALLSTATE_SOURCE */
937     state = MsiQueryFeatureStateA(prodcode, "feature");
938     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
939
940     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
941     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
942
943     /* bad INSTALLSTATE_SOURCE */
944     state = MsiQueryFeatureStateA(prodcode, "feature");
945     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
946
947     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
949
950     /* INSTALLSTATE_SOURCE */
951     state = MsiQueryFeatureStateA(prodcode, "feature");
952     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
953
954     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
956
957     /* bad INSTALLSTATE_SOURCE */
958     state = MsiQueryFeatureStateA(prodcode, "feature");
959     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
960
961     RegDeleteValueA(compkey, prod_squashed);
962     RegDeleteKeyA(compkey, "");
963     RegDeleteValueA(localkey, "feature");
964     RegDeleteValueA(userkey, "feature");
965     RegDeleteKeyA(userkey, "");
966     RegCloseKey(compkey);
967     RegCloseKey(localkey);
968     RegCloseKey(userkey);
969
970     /* MSIINSTALLCONTEXT_USERMANAGED */
971
972     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
973     lstrcatA(keypath, usersid);
974     lstrcatA(keypath, "\\Installer\\Features\\");
975     lstrcatA(keypath, prod_squashed);
976
977     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
978     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
979
980     /* feature key exists */
981     state = MsiQueryFeatureStateA(prodcode, "feature");
982     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
983
984     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
986
987     /* feature value exists */
988     state = MsiQueryFeatureStateA(prodcode, "feature");
989     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
990
991     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
992     lstrcatA(keypath, usersid);
993     lstrcatA(keypath, "\\Products\\");
994     lstrcatA(keypath, prod_squashed);
995     lstrcatA(keypath, "\\Features");
996
997     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
999
1000     /* userdata features key exists */
1001     state = MsiQueryFeatureStateA(prodcode, "feature");
1002     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1003
1004     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1006
1007     state = MsiQueryFeatureStateA(prodcode, "feature");
1008     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1009
1010     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1012
1013     state = MsiQueryFeatureStateA(prodcode, "feature");
1014     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1015
1016     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1017     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1018
1019     state = MsiQueryFeatureStateA(prodcode, "feature");
1020     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1021
1022     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1023     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1024
1025     state = MsiQueryFeatureStateA(prodcode, "feature");
1026     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1027
1028     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1029     lstrcatA(keypath, usersid);
1030     lstrcatA(keypath, "\\Components\\");
1031     lstrcatA(keypath, comp_squashed);
1032
1033     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1035
1036     state = MsiQueryFeatureStateA(prodcode, "feature");
1037     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1038
1039     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1041
1042     state = MsiQueryFeatureStateA(prodcode, "feature");
1043     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1044
1045     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1046     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1047
1048     state = MsiQueryFeatureStateA(prodcode, "feature");
1049     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1050
1051     RegDeleteValueA(compkey, prod_squashed);
1052     RegDeleteKeyA(compkey, "");
1053     RegDeleteValueA(localkey, "feature");
1054     RegDeleteValueA(userkey, "feature");
1055     RegDeleteKeyA(userkey, "");
1056     RegCloseKey(compkey);
1057     RegCloseKey(localkey);
1058     RegCloseKey(userkey);
1059
1060     /* MSIINSTALLCONTEXT_MACHINE */
1061
1062     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1063     lstrcatA(keypath, prod_squashed);
1064
1065     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1067
1068     /* feature key exists */
1069     state = MsiQueryFeatureStateA(prodcode, "feature");
1070     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1071
1072     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1074
1075     /* feature value exists */
1076     state = MsiQueryFeatureStateA(prodcode, "feature");
1077     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1078
1079     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1080     lstrcatA(keypath, "S-1-5-18\\Products\\");
1081     lstrcatA(keypath, prod_squashed);
1082     lstrcatA(keypath, "\\Features");
1083
1084     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1086
1087     /* userdata features key exists */
1088     state = MsiQueryFeatureStateA(prodcode, "feature");
1089     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1090
1091     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1093
1094     state = MsiQueryFeatureStateA(prodcode, "feature");
1095     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1096
1097     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1099
1100     state = MsiQueryFeatureStateA(prodcode, "feature");
1101     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1102
1103     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1105
1106     state = MsiQueryFeatureStateA(prodcode, "feature");
1107     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1108
1109     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1111
1112     state = MsiQueryFeatureStateA(prodcode, "feature");
1113     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1114
1115     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1116     lstrcatA(keypath, "S-1-5-18\\Components\\");
1117     lstrcatA(keypath, comp_squashed);
1118
1119     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1121
1122     state = MsiQueryFeatureStateA(prodcode, "feature");
1123     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1124
1125     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1127
1128     state = MsiQueryFeatureStateA(prodcode, "feature");
1129     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1130
1131     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1133
1134     state = MsiQueryFeatureStateA(prodcode, "feature");
1135     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1136
1137     RegDeleteValueA(compkey, prod_squashed);
1138     RegDeleteKeyA(compkey, "");
1139     RegDeleteValueA(localkey, "feature");
1140     RegDeleteValueA(userkey, "feature");
1141     RegDeleteKeyA(userkey, "");
1142     RegCloseKey(compkey);
1143     RegCloseKey(localkey);
1144     RegCloseKey(userkey);
1145 }
1146
1147 static void test_MsiQueryComponentState(void)
1148 {
1149     HKEY compkey, prodkey;
1150     CHAR prodcode[MAX_PATH];
1151     CHAR prod_squashed[MAX_PATH];
1152     CHAR component[MAX_PATH];
1153     CHAR comp_base85[MAX_PATH];
1154     CHAR comp_squashed[MAX_PATH];
1155     CHAR keypath[MAX_PATH];
1156     INSTALLSTATE state;
1157     LPSTR usersid;
1158     LONG res;
1159     UINT r;
1160
1161     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1162
1163     if (!pMsiQueryComponentStateA)
1164     {
1165         skip("MsiQueryComponentStateA not implemented\n");
1166         return;
1167     }
1168
1169     create_test_guid(prodcode, prod_squashed);
1170     compose_base85_guid(component, comp_base85, comp_squashed);
1171     get_user_sid(&usersid);
1172
1173     /* NULL szProductCode */
1174     state = MAGIC_ERROR;
1175     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1176     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1177     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1178
1179     /* empty szProductCode */
1180     state = MAGIC_ERROR;
1181     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1182     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1183     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1184
1185     /* random szProductCode */
1186     state = MAGIC_ERROR;
1187     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1188     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1189     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1190
1191     /* GUID-length szProductCode */
1192     state = MAGIC_ERROR;
1193     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1194     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1195     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1196
1197     /* GUID-length with brackets */
1198     state = MAGIC_ERROR;
1199     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1200     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1201     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1202
1203     /* actual GUID */
1204     state = MAGIC_ERROR;
1205     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1206     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1207     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1208
1209     state = MAGIC_ERROR;
1210     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1211     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1212     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1213
1214     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1215     lstrcatA(keypath, prod_squashed);
1216
1217     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1218     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1219
1220     state = MAGIC_ERROR;
1221     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1222     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1223     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1224
1225     RegDeleteKeyA(prodkey, "");
1226     RegCloseKey(prodkey);
1227
1228     /* create local system product key */
1229     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1230     lstrcatA(keypath, prod_squashed);
1231     lstrcatA(keypath, "\\InstallProperties");
1232
1233     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1235
1236     /* local system product key exists */
1237     state = MAGIC_ERROR;
1238     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1239     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1240     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1241
1242     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1244
1245     /* LocalPackage value exists */
1246     state = MAGIC_ERROR;
1247     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1248     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1249     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1250
1251     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1252     lstrcatA(keypath, comp_squashed);
1253
1254     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1255     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1256
1257     /* component key exists */
1258     state = MAGIC_ERROR;
1259     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1260     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1261     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1262
1263     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1264     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1265
1266     /* component\product exists */
1267     state = MAGIC_ERROR;
1268     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1269     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1270     ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
1271
1272     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1274
1275     /* INSTALLSTATE_LOCAL */
1276     state = MAGIC_ERROR;
1277     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1279     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1280
1281     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1283
1284     /* INSTALLSTATE_SOURCE */
1285     state = MAGIC_ERROR;
1286     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1287     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1288     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1289
1290     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1292
1293     /* bad INSTALLSTATE_SOURCE */
1294     state = MAGIC_ERROR;
1295     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1297     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1298
1299     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1301
1302     /* INSTALLSTATE_SOURCE */
1303     state = MAGIC_ERROR;
1304     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1306     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1307
1308     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1310
1311     /* bad INSTALLSTATE_SOURCE */
1312     state = MAGIC_ERROR;
1313     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1315     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1316
1317     RegDeleteValueA(prodkey, "LocalPackage");
1318     RegDeleteKeyA(prodkey, "");
1319     RegDeleteValueA(compkey, prod_squashed);
1320     RegDeleteKeyA(prodkey, "");
1321     RegCloseKey(prodkey);
1322     RegCloseKey(compkey);
1323
1324     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1325
1326     state = MAGIC_ERROR;
1327     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1328     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1329     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1330
1331     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1332     lstrcatA(keypath, prod_squashed);
1333
1334     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1336
1337     state = MAGIC_ERROR;
1338     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1339     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1340     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1341
1342     RegDeleteKeyA(prodkey, "");
1343     RegCloseKey(prodkey);
1344
1345     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1346     lstrcatA(keypath, usersid);
1347     lstrcatA(keypath, "\\Products\\");
1348     lstrcatA(keypath, prod_squashed);
1349     lstrcatA(keypath, "\\InstallProperties");
1350
1351     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1353
1354     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1356
1357     RegCloseKey(prodkey);
1358
1359     state = MAGIC_ERROR;
1360     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1361     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1362     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1363
1364     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1365     lstrcatA(keypath, usersid);
1366     lstrcatA(keypath, "\\Components\\");
1367     lstrcatA(keypath, comp_squashed);
1368
1369     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1371
1372     /* component key exists */
1373     state = MAGIC_ERROR;
1374     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1375     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1376     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1377
1378     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1380
1381     /* component\product exists */
1382     state = MAGIC_ERROR;
1383     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1384     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1385     ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
1386
1387     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1389
1390     state = MAGIC_ERROR;
1391     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1392     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1393     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1394
1395     /* MSIINSTALLCONTEXT_USERMANAGED */
1396
1397     state = MAGIC_ERROR;
1398     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1399     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1400     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1401
1402     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1403     lstrcatA(keypath, prod_squashed);
1404
1405     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1406     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1407
1408     state = MAGIC_ERROR;
1409     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1410     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1411     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1412
1413     RegDeleteKeyA(prodkey, "");
1414     RegCloseKey(prodkey);
1415
1416     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1417     lstrcatA(keypath, usersid);
1418     lstrcatA(keypath, "\\Installer\\Products\\");
1419     lstrcatA(keypath, prod_squashed);
1420
1421     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1423
1424     state = MAGIC_ERROR;
1425     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1426     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1427     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1428
1429     RegDeleteKeyA(prodkey, "");
1430     RegCloseKey(prodkey);
1431
1432     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1433     lstrcatA(keypath, usersid);
1434     lstrcatA(keypath, "\\Products\\");
1435     lstrcatA(keypath, prod_squashed);
1436     lstrcatA(keypath, "\\InstallProperties");
1437
1438     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1439     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1440
1441     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1443
1444     state = MAGIC_ERROR;
1445     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1447     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1448
1449     RegDeleteValueA(prodkey, "LocalPackage");
1450     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1451     RegDeleteKeyA(prodkey, "");
1452     RegDeleteValueA(compkey, prod_squashed);
1453     RegDeleteKeyA(compkey, "");
1454     RegCloseKey(prodkey);
1455     RegCloseKey(compkey);
1456 }
1457
1458 static void test_MsiGetComponentPath(void)
1459 {
1460     HKEY compkey, prodkey, installprop;
1461     CHAR prodcode[MAX_PATH];
1462     CHAR prod_squashed[MAX_PATH];
1463     CHAR component[MAX_PATH];
1464     CHAR comp_base85[MAX_PATH];
1465     CHAR comp_squashed[MAX_PATH];
1466     CHAR keypath[MAX_PATH];
1467     CHAR path[MAX_PATH];
1468     INSTALLSTATE state;
1469     LPSTR usersid;
1470     DWORD size, val;
1471     LONG res;
1472
1473     create_test_guid(prodcode, prod_squashed);
1474     compose_base85_guid(component, comp_base85, comp_squashed);
1475     get_user_sid(&usersid);
1476
1477     /* NULL szProduct */
1478     size = MAX_PATH;
1479     state = MsiGetComponentPathA(NULL, component, path, &size);
1480     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1481     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1482
1483     /* NULL szComponent */
1484     size = MAX_PATH;
1485     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1486     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1487     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1488
1489     /* NULL lpPathBuf */
1490     size = MAX_PATH;
1491     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1492     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1493     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1494
1495     /* NULL pcchBuf */
1496     size = MAX_PATH;
1497     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1498     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1499     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1500
1501     /* all params valid */
1502     size = MAX_PATH;
1503     state = MsiGetComponentPathA(prodcode, component, path, &size);
1504     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1505     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1506
1507     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1508     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1509     lstrcatA(keypath, comp_squashed);
1510
1511     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1513
1514     /* local system component key exists */
1515     size = MAX_PATH;
1516     state = MsiGetComponentPathA(prodcode, component, path, &size);
1517     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1518     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1519
1520     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1521     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1522
1523     /* product value exists */
1524     size = MAX_PATH;
1525     state = MsiGetComponentPathA(prodcode, component, path, &size);
1526     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1527     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1528     ok(size == 10, "Expected 10, got %d\n", size);
1529
1530     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1531     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1532     lstrcatA(keypath, prod_squashed);
1533     lstrcatA(keypath, "\\InstallProperties");
1534
1535     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1536     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1537
1538     val = 1;
1539     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1541
1542     /* install properties key exists */
1543     size = MAX_PATH;
1544     state = MsiGetComponentPathA(prodcode, component, path, &size);
1545     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1546     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1547     ok(size == 10, "Expected 10, got %d\n", size);
1548
1549     create_file("C:\\imapath", "C:\\imapath", 11);
1550
1551     /* file exists */
1552     size = MAX_PATH;
1553     state = MsiGetComponentPathA(prodcode, component, path, &size);
1554     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1555     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1556     ok(size == 10, "Expected 10, got %d\n", size);
1557
1558     RegDeleteValueA(compkey, prod_squashed);
1559     RegDeleteKeyA(compkey, "");
1560     RegDeleteValueA(installprop, "WindowsInstaller");
1561     RegDeleteKeyA(installprop, "");
1562     RegCloseKey(compkey);
1563     RegCloseKey(installprop);
1564     DeleteFileA("C:\\imapath");
1565
1566     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1567     lstrcatA(keypath, "Installer\\UserData\\");
1568     lstrcatA(keypath, usersid);
1569     lstrcatA(keypath, "\\Components\\");
1570     lstrcatA(keypath, comp_squashed);
1571
1572     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1574
1575     /* user managed component key exists */
1576     size = MAX_PATH;
1577     state = MsiGetComponentPathA(prodcode, component, path, &size);
1578     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1579     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1580
1581     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1583
1584     /* product value exists */
1585     size = MAX_PATH;
1586     state = MsiGetComponentPathA(prodcode, component, path, &size);
1587     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1588     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1589     ok(size == 10, "Expected 10, got %d\n", size);
1590
1591     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1592     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1593     lstrcatA(keypath, prod_squashed);
1594     lstrcatA(keypath, "\\InstallProperties");
1595
1596     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1598
1599     val = 1;
1600     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1602
1603     /* install properties key exists */
1604     size = MAX_PATH;
1605     state = MsiGetComponentPathA(prodcode, component, path, &size);
1606     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1607     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1608     ok(size == 10, "Expected 10, got %d\n", size);
1609
1610     create_file("C:\\imapath", "C:\\imapath", 11);
1611
1612     /* file exists */
1613     size = MAX_PATH;
1614     state = MsiGetComponentPathA(prodcode, component, path, &size);
1615     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1616     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1617     ok(size == 10, "Expected 10, got %d\n", size);
1618
1619     RegDeleteValueA(compkey, prod_squashed);
1620     RegDeleteKeyA(compkey, "");
1621     RegDeleteValueA(installprop, "WindowsInstaller");
1622     RegDeleteKeyA(installprop, "");
1623     RegCloseKey(compkey);
1624     RegCloseKey(installprop);
1625     DeleteFileA("C:\\imapath");
1626
1627     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1628     lstrcatA(keypath, "Installer\\Managed\\");
1629     lstrcatA(keypath, usersid);
1630     lstrcatA(keypath, "\\Installer\\Products\\");
1631     lstrcatA(keypath, prod_squashed);
1632
1633     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1635
1636     /* user managed product key exists */
1637     size = MAX_PATH;
1638     state = MsiGetComponentPathA(prodcode, component, path, &size);
1639     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1640     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1641
1642     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1643     lstrcatA(keypath, "Installer\\UserData\\");
1644     lstrcatA(keypath, usersid);
1645     lstrcatA(keypath, "\\Components\\");
1646     lstrcatA(keypath, comp_squashed);
1647
1648     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1649     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1650
1651     /* user managed component key exists */
1652     size = MAX_PATH;
1653     state = MsiGetComponentPathA(prodcode, component, path, &size);
1654     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1655     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1656
1657     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1659
1660     /* product value exists */
1661     size = MAX_PATH;
1662     state = MsiGetComponentPathA(prodcode, component, path, &size);
1663     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1664     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1665     ok(size == 10, "Expected 10, got %d\n", size);
1666
1667     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1668     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1669     lstrcatA(keypath, prod_squashed);
1670     lstrcatA(keypath, "\\InstallProperties");
1671
1672     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1674
1675     val = 1;
1676     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1677     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1678
1679     /* install properties key exists */
1680     size = MAX_PATH;
1681     state = MsiGetComponentPathA(prodcode, component, path, &size);
1682     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1683     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1684     ok(size == 10, "Expected 10, got %d\n", size);
1685
1686     create_file("C:\\imapath", "C:\\imapath", 11);
1687
1688     /* file exists */
1689     size = MAX_PATH;
1690     state = MsiGetComponentPathA(prodcode, component, path, &size);
1691     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1692     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1693     ok(size == 10, "Expected 10, got %d\n", size);
1694
1695     RegDeleteValueA(compkey, prod_squashed);
1696     RegDeleteKeyA(prodkey, "");
1697     RegDeleteKeyA(compkey, "");
1698     RegDeleteValueA(installprop, "WindowsInstaller");
1699     RegDeleteKeyA(installprop, "");
1700     RegCloseKey(prodkey);
1701     RegCloseKey(compkey);
1702     RegCloseKey(installprop);
1703     DeleteFileA("C:\\imapath");
1704
1705     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1706     lstrcatA(keypath, prod_squashed);
1707
1708     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1710
1711     /* user unmanaged product key exists */
1712     size = MAX_PATH;
1713     state = MsiGetComponentPathA(prodcode, component, path, &size);
1714     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1715     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1716
1717     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1718     lstrcatA(keypath, "Installer\\UserData\\");
1719     lstrcatA(keypath, usersid);
1720     lstrcatA(keypath, "\\Components\\");
1721     lstrcatA(keypath, comp_squashed);
1722
1723     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1725
1726     /* user unmanaged component key exists */
1727     size = MAX_PATH;
1728     state = MsiGetComponentPathA(prodcode, component, path, &size);
1729     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1730     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1731
1732     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1734
1735     /* product value exists */
1736     size = MAX_PATH;
1737     state = MsiGetComponentPathA(prodcode, component, path, &size);
1738     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1739     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1740     ok(size == 10, "Expected 10, got %d\n", size);
1741
1742     create_file("C:\\imapath", "C:\\imapath", 11);
1743
1744     /* file exists */
1745     size = MAX_PATH;
1746     state = MsiGetComponentPathA(prodcode, component, path, &size);
1747     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1748     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1749     ok(size == 10, "Expected 10, got %d\n", size);
1750
1751     RegDeleteValueA(compkey, prod_squashed);
1752     RegDeleteKeyA(prodkey, "");
1753     RegDeleteKeyA(compkey, "");
1754     RegCloseKey(prodkey);
1755     RegCloseKey(compkey);
1756     RegCloseKey(installprop);
1757     DeleteFileA("C:\\imapath");
1758
1759     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1760     lstrcatA(keypath, prod_squashed);
1761
1762     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1764
1765     /* local classes product key exists */
1766     size = MAX_PATH;
1767     state = MsiGetComponentPathA(prodcode, component, path, &size);
1768     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1769     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1770
1771     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1772     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1773     lstrcatA(keypath, comp_squashed);
1774
1775     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1777
1778     /* local user component key exists */
1779     size = MAX_PATH;
1780     state = MsiGetComponentPathA(prodcode, component, path, &size);
1781     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1782     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1783
1784     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1786
1787     /* product value exists */
1788     size = MAX_PATH;
1789     state = MsiGetComponentPathA(prodcode, component, path, &size);
1790     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1791     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1792     ok(size == 10, "Expected 10, got %d\n", size);
1793
1794     create_file("C:\\imapath", "C:\\imapath", 11);
1795
1796     /* file exists */
1797     size = MAX_PATH;
1798     state = MsiGetComponentPathA(prodcode, component, path, &size);
1799     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1800     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1801     ok(size == 10, "Expected 10, got %d\n", size);
1802
1803     RegDeleteValueA(compkey, prod_squashed);
1804     RegDeleteKeyA(prodkey, "");
1805     RegDeleteKeyA(compkey, "");
1806     RegCloseKey(prodkey);
1807     RegCloseKey(compkey);
1808     DeleteFileA("C:\\imapath");
1809 }
1810
1811 static void test_MsiGetProductCode(void)
1812 {
1813     HKEY compkey, prodkey;
1814     CHAR prodcode[MAX_PATH];
1815     CHAR prod_squashed[MAX_PATH];
1816     CHAR prodcode2[MAX_PATH];
1817     CHAR prod2_squashed[MAX_PATH];
1818     CHAR component[MAX_PATH];
1819     CHAR comp_base85[MAX_PATH];
1820     CHAR comp_squashed[MAX_PATH];
1821     CHAR keypath[MAX_PATH];
1822     CHAR product[MAX_PATH];
1823     LPSTR usersid;
1824     LONG res;
1825     UINT r;
1826
1827     create_test_guid(prodcode, prod_squashed);
1828     create_test_guid(prodcode2, prod2_squashed);
1829     compose_base85_guid(component, comp_base85, comp_squashed);
1830     get_user_sid(&usersid);
1831
1832     /* szComponent is NULL */
1833     lstrcpyA(product, "prod");
1834     r = MsiGetProductCodeA(NULL, product);
1835     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1836     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1837
1838     /* szComponent is empty */
1839     lstrcpyA(product, "prod");
1840     r = MsiGetProductCodeA("", product);
1841     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1842     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1843
1844     /* garbage szComponent */
1845     lstrcpyA(product, "prod");
1846     r = MsiGetProductCodeA("garbage", product);
1847     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1848     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1849
1850     /* guid without brackets */
1851     lstrcpyA(product, "prod");
1852     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1853     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1854     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1855
1856     /* guid with brackets */
1857     lstrcpyA(product, "prod");
1858     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1859     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1860     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1861
1862     /* same length as guid, but random */
1863     lstrcpyA(product, "prod");
1864     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1865     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1866     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1867
1868     /* all params correct, szComponent not published */
1869     lstrcpyA(product, "prod");
1870     r = MsiGetProductCodeA(component, product);
1871     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1872     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1873
1874     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1875     lstrcatA(keypath, "Installer\\UserData\\");
1876     lstrcatA(keypath, usersid);
1877     lstrcatA(keypath, "\\Components\\");
1878     lstrcatA(keypath, comp_squashed);
1879
1880     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1881     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1882
1883     /* user unmanaged component key exists */
1884     lstrcpyA(product, "prod");
1885     r = MsiGetProductCodeA(component, product);
1886     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1887     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1888
1889     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1891
1892     /* product value exists */
1893     lstrcpyA(product, "prod");
1894     r = MsiGetProductCodeA(component, product);
1895     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1896     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1897
1898     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1900
1901     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1902     lstrcatA(keypath, "Installer\\Managed\\");
1903     lstrcatA(keypath, usersid);
1904     lstrcatA(keypath, "\\Installer\\Products\\");
1905     lstrcatA(keypath, prod_squashed);
1906
1907     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1909
1910     /* user managed product key of first product exists */
1911     lstrcpyA(product, "prod");
1912     r = MsiGetProductCodeA(component, product);
1913     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1914     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1915
1916     RegDeleteKeyA(prodkey, "");
1917     RegCloseKey(prodkey);
1918
1919     RegDeleteKeyA(prodkey, "");
1920     RegCloseKey(prodkey);
1921
1922     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1923     lstrcatA(keypath, prod_squashed);
1924
1925     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1926     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1927
1928     /* user unmanaged product key exists */
1929     lstrcpyA(product, "prod");
1930     r = MsiGetProductCodeA(component, product);
1931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1932     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1933
1934     RegDeleteKeyA(prodkey, "");
1935     RegCloseKey(prodkey);
1936
1937     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1938     lstrcatA(keypath, prod_squashed);
1939
1940     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1941     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1942
1943     /* local classes product key exists */
1944     lstrcpyA(product, "prod");
1945     r = MsiGetProductCodeA(component, product);
1946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1947     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1948
1949     RegDeleteKeyA(prodkey, "");
1950     RegCloseKey(prodkey);
1951
1952     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1953     lstrcatA(keypath, "Installer\\Managed\\");
1954     lstrcatA(keypath, usersid);
1955     lstrcatA(keypath, "\\Installer\\Products\\");
1956     lstrcatA(keypath, prod2_squashed);
1957
1958     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1960
1961     /* user managed product key of second product exists */
1962     lstrcpyA(product, "prod");
1963     r = MsiGetProductCodeA(component, product);
1964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1965     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1966
1967     RegDeleteKeyA(prodkey, "");
1968     RegCloseKey(prodkey);
1969     RegDeleteValueA(compkey, prod_squashed);
1970     RegDeleteValueA(compkey, prod2_squashed);
1971     RegDeleteKeyA(compkey, "");
1972     RegCloseKey(compkey);
1973
1974     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1975     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1976     lstrcatA(keypath, comp_squashed);
1977
1978     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1980
1981     /* local user component key exists */
1982     lstrcpyA(product, "prod");
1983     r = MsiGetProductCodeA(component, product);
1984     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1985     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1986
1987     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1989
1990     /* product value exists */
1991     lstrcpyA(product, "prod");
1992     r = MsiGetProductCodeA(component, product);
1993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1994     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1995
1996     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1998
1999     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2000     lstrcatA(keypath, "Installer\\Managed\\");
2001     lstrcatA(keypath, usersid);
2002     lstrcatA(keypath, "\\Installer\\Products\\");
2003     lstrcatA(keypath, prod_squashed);
2004
2005     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2007
2008     /* user managed product key of first product exists */
2009     lstrcpyA(product, "prod");
2010     r = MsiGetProductCodeA(component, product);
2011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2012     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2013
2014     RegDeleteKeyA(prodkey, "");
2015     RegCloseKey(prodkey);
2016
2017     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2018     lstrcatA(keypath, prod_squashed);
2019
2020     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2021     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2022
2023     /* user unmanaged product key exists */
2024     lstrcpyA(product, "prod");
2025     r = MsiGetProductCodeA(component, product);
2026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2027     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2028
2029     RegDeleteKeyA(prodkey, "");
2030     RegCloseKey(prodkey);
2031
2032     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2033     lstrcatA(keypath, prod_squashed);
2034
2035     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2036     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2037
2038     /* local classes product key exists */
2039     lstrcpyA(product, "prod");
2040     r = MsiGetProductCodeA(component, product);
2041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2042     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2043
2044     RegDeleteKeyA(prodkey, "");
2045     RegCloseKey(prodkey);
2046
2047     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2048     lstrcatA(keypath, "Installer\\Managed\\");
2049     lstrcatA(keypath, usersid);
2050     lstrcatA(keypath, "\\Installer\\Products\\");
2051     lstrcatA(keypath, prod2_squashed);
2052
2053     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2055
2056     /* user managed product key of second product exists */
2057     lstrcpyA(product, "prod");
2058     r = MsiGetProductCodeA(component, product);
2059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2060     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2061
2062     RegDeleteKeyA(prodkey, "");
2063     RegCloseKey(prodkey);
2064     RegDeleteValueA(compkey, prod_squashed);
2065     RegDeleteValueA(compkey, prod2_squashed);
2066     RegDeleteKeyA(compkey, "");
2067     RegCloseKey(compkey);
2068 }
2069
2070 static void test_MsiEnumClients(void)
2071 {
2072     HKEY compkey;
2073     CHAR prodcode[MAX_PATH];
2074     CHAR prod_squashed[MAX_PATH];
2075     CHAR prodcode2[MAX_PATH];
2076     CHAR prod2_squashed[MAX_PATH];
2077     CHAR component[MAX_PATH];
2078     CHAR comp_base85[MAX_PATH];
2079     CHAR comp_squashed[MAX_PATH];
2080     CHAR product[MAX_PATH];
2081     CHAR keypath[MAX_PATH];
2082     LPSTR usersid;
2083     LONG res;
2084     UINT r;
2085
2086     create_test_guid(prodcode, prod_squashed);
2087     create_test_guid(prodcode2, prod2_squashed);
2088     compose_base85_guid(component, comp_base85, comp_squashed);
2089     get_user_sid(&usersid);
2090
2091     /* NULL szComponent */
2092     product[0] = '\0';
2093     r = MsiEnumClientsA(NULL, 0, product);
2094     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2095     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2096
2097     /* empty szComponent */
2098     product[0] = '\0';
2099     r = MsiEnumClientsA("", 0, product);
2100     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2101     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2102
2103     /* NULL lpProductBuf */
2104     r = MsiEnumClientsA(component, 0, NULL);
2105     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2106
2107     /* all params correct, component missing */
2108     product[0] = '\0';
2109     r = MsiEnumClientsA(component, 0, product);
2110     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2111     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2112
2113     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2114     lstrcatA(keypath, "Installer\\UserData\\");
2115     lstrcatA(keypath, usersid);
2116     lstrcatA(keypath, "\\Components\\");
2117     lstrcatA(keypath, comp_squashed);
2118
2119     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2121
2122     /* user unmanaged component key exists */
2123     product[0] = '\0';
2124     r = MsiEnumClientsA(component, 0, product);
2125     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2126     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2127
2128     /* index > 0, no products exist */
2129     product[0] = '\0';
2130     r = MsiEnumClientsA(component, 1, product);
2131     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2132     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2133
2134     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2136
2137     /* product value exists */
2138     r = MsiEnumClientsA(component, 0, product);
2139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2140     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2141
2142     /* try index 0 again */
2143     product[0] = '\0';
2144     r = MsiEnumClientsA(component, 0, product);
2145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2146     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2147
2148     /* try index 1, second product value does not exist */
2149     product[0] = '\0';
2150     r = MsiEnumClientsA(component, 1, product);
2151     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2152     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2153
2154     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2156
2157     /* try index 1, second product value does exist */
2158     product[0] = '\0';
2159     r = MsiEnumClientsA(component, 1, product);
2160     todo_wine
2161     {
2162         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2163         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2164     }
2165
2166     /* start the enumeration over */
2167     product[0] = '\0';
2168     r = MsiEnumClientsA(component, 0, product);
2169     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2170     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2171        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2172
2173     /* correctly query second product */
2174     product[0] = '\0';
2175     r = MsiEnumClientsA(component, 1, product);
2176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2177     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2178        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2179
2180     RegDeleteValueA(compkey, prod_squashed);
2181     RegDeleteValueA(compkey, prod2_squashed);
2182     RegDeleteKeyA(compkey, "");
2183     RegCloseKey(compkey);
2184
2185     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2186     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2187     lstrcatA(keypath, comp_squashed);
2188
2189     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2190     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2191
2192     /* user local component key exists */
2193     product[0] = '\0';
2194     r = MsiEnumClientsA(component, 0, product);
2195     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2196     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2197
2198     /* index > 0, no products exist */
2199     product[0] = '\0';
2200     r = MsiEnumClientsA(component, 1, product);
2201     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2202     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2203
2204     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2206
2207     /* product value exists */
2208     product[0] = '\0';
2209     r = MsiEnumClientsA(component, 0, product);
2210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2211     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2212
2213     /* try index 0 again */
2214     product[0] = '\0';
2215     r = MsiEnumClientsA(component, 0, product);
2216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2217
2218     /* try index 1, second product value does not exist */
2219     product[0] = '\0';
2220     r = MsiEnumClientsA(component, 1, product);
2221     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2222     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2223
2224     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2226
2227     /* try index 1, second product value does exist */
2228     product[0] = '\0';
2229     r = MsiEnumClientsA(component, 1, product);
2230     todo_wine
2231     {
2232         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2233         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2234     }
2235
2236     /* start the enumeration over */
2237     product[0] = '\0';
2238     r = MsiEnumClientsA(component, 0, product);
2239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2240     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2241        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2242
2243     /* correctly query second product */
2244     product[0] = '\0';
2245     r = MsiEnumClientsA(component, 1, product);
2246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2247     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2248        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2249
2250     RegDeleteValueA(compkey, prod_squashed);
2251     RegDeleteValueA(compkey, prod2_squashed);
2252     RegDeleteKeyA(compkey, "");
2253     RegCloseKey(compkey);
2254 }
2255
2256 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2257                              LPSTR *langcheck, LPDWORD langchecksz)
2258 {
2259     LPSTR version;
2260     VS_FIXEDFILEINFO *ffi;
2261     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2262     USHORT *lang;
2263
2264     version = HeapAlloc(GetProcessHeap(), 0, size);
2265     GetFileVersionInfoA(path, 0, size, version);
2266
2267     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2268     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2269     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2270             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2271             LOWORD(ffi->dwFileVersionLS));
2272     *verchecksz = lstrlenA(*vercheck);
2273
2274     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2275     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2276     sprintf(*langcheck, "%d", *lang);
2277     *langchecksz = lstrlenA(*langcheck);
2278
2279     HeapFree(GetProcessHeap(), 0, version);
2280 }
2281
2282 static void test_MsiGetFileVersion(void)
2283 {
2284     UINT r;
2285     DWORD versz, langsz;
2286     char version[MAX_PATH];
2287     char lang[MAX_PATH];
2288     char path[MAX_PATH];
2289     LPSTR vercheck, langcheck;
2290     DWORD verchecksz, langchecksz;
2291
2292     /* NULL szFilePath */
2293     versz = MAX_PATH;
2294     langsz = MAX_PATH;
2295     lstrcpyA(version, "version");
2296     lstrcpyA(lang, "lang");
2297     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2298     ok(r == ERROR_INVALID_PARAMETER,
2299        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2300     ok(!lstrcmpA(version, "version"),
2301        "Expected version to be unchanged, got %s\n", version);
2302     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2303     ok(!lstrcmpA(lang, "lang"),
2304        "Expected lang to be unchanged, got %s\n", lang);
2305     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2306
2307     /* empty szFilePath */
2308     versz = MAX_PATH;
2309     langsz = MAX_PATH;
2310     lstrcpyA(version, "version");
2311     lstrcpyA(lang, "lang");
2312     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2313     ok(r == ERROR_FILE_NOT_FOUND,
2314        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2315     ok(!lstrcmpA(version, "version"),
2316        "Expected version to be unchanged, got %s\n", version);
2317     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2318     ok(!lstrcmpA(lang, "lang"),
2319        "Expected lang to be unchanged, got %s\n", lang);
2320     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2321
2322     /* nonexistent szFilePath */
2323     versz = MAX_PATH;
2324     langsz = MAX_PATH;
2325     lstrcpyA(version, "version");
2326     lstrcpyA(lang, "lang");
2327     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2328     ok(r == ERROR_FILE_NOT_FOUND,
2329        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2330     ok(!lstrcmpA(version, "version"),
2331        "Expected version to be unchanged, got %s\n", version);
2332     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2333     ok(!lstrcmpA(lang, "lang"),
2334        "Expected lang to be unchanged, got %s\n", lang);
2335     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2336
2337     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2338     versz = MAX_PATH;
2339     langsz = MAX_PATH;
2340     lstrcpyA(version, "version");
2341     lstrcpyA(lang, "lang");
2342     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2343     ok(r == ERROR_INVALID_PARAMETER,
2344        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2345     ok(!lstrcmpA(version, "version"),
2346        "Expected version to be unchanged, got %s\n", version);
2347     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2348     ok(!lstrcmpA(lang, "lang"),
2349        "Expected lang to be unchanged, got %s\n", lang);
2350     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2351
2352     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2353     versz = MAX_PATH;
2354     langsz = MAX_PATH;
2355     lstrcpyA(version, "version");
2356     lstrcpyA(lang, "lang");
2357     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2358     ok(r == ERROR_INVALID_PARAMETER,
2359        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2360     ok(!lstrcmpA(version, "version"),
2361        "Expected version to be unchanged, got %s\n", version);
2362     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2363     ok(!lstrcmpA(lang, "lang"),
2364        "Expected lang to be unchanged, got %s\n", lang);
2365     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2366
2367     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2368     versz = 0;
2369     langsz = MAX_PATH;
2370     lstrcpyA(version, "version");
2371     lstrcpyA(lang, "lang");
2372     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2373     ok(r == ERROR_FILE_NOT_FOUND,
2374        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2375     ok(!lstrcmpA(version, "version"),
2376        "Expected version to be unchanged, got %s\n", version);
2377     ok(versz == 0, "Expected 0, got %d\n", versz);
2378     ok(!lstrcmpA(lang, "lang"),
2379        "Expected lang to be unchanged, got %s\n", lang);
2380     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2381
2382     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2383     versz = MAX_PATH;
2384     langsz = 0;
2385     lstrcpyA(version, "version");
2386     lstrcpyA(lang, "lang");
2387     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2388     ok(r == ERROR_FILE_NOT_FOUND,
2389        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2390     ok(!lstrcmpA(version, "version"),
2391        "Expected version to be unchanged, got %s\n", version);
2392     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2393     ok(!lstrcmpA(lang, "lang"),
2394        "Expected lang to be unchanged, got %s\n", lang);
2395     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2396
2397     /* nonexistent szFilePath, rest NULL */
2398     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2399     ok(r == ERROR_FILE_NOT_FOUND,
2400        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2401
2402     create_file("ver.txt", "ver.txt", 20);
2403
2404     /* file exists, no version information */
2405     versz = MAX_PATH;
2406     langsz = MAX_PATH;
2407     lstrcpyA(version, "version");
2408     lstrcpyA(lang, "lang");
2409     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2410     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2411     ok(!lstrcmpA(version, "version"),
2412        "Expected version to be unchanged, got %s\n", version);
2413     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2414     ok(!lstrcmpA(lang, "lang"),
2415        "Expected lang to be unchanged, got %s\n", lang);
2416     ok(r == ERROR_FILE_INVALID,
2417        "Expected ERROR_FILE_INVALID, got %d\n", r);
2418
2419     DeleteFileA("ver.txt");
2420
2421     /* relative path, has version information */
2422     versz = MAX_PATH;
2423     langsz = MAX_PATH;
2424     lstrcpyA(version, "version");
2425     lstrcpyA(lang, "lang");
2426     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2427     todo_wine
2428     {
2429         ok(r == ERROR_FILE_NOT_FOUND,
2430            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2431         ok(!lstrcmpA(version, "version"),
2432            "Expected version to be unchanged, got %s\n", version);
2433         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2434         ok(!lstrcmpA(lang, "lang"),
2435            "Expected lang to be unchanged, got %s\n", lang);
2436         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2437     }
2438
2439     GetSystemDirectoryA(path, MAX_PATH);
2440     lstrcatA(path, "\\kernel32.dll");
2441
2442     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2443
2444     /* absolute path, has version information */
2445     versz = MAX_PATH;
2446     langsz = MAX_PATH;
2447     lstrcpyA(version, "version");
2448     lstrcpyA(lang, "lang");
2449     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2451     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2452     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2453     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2454     ok(!lstrcmpA(version, vercheck),
2455         "Expected %s, got %s\n", vercheck, version);
2456
2457     /* only check version */
2458     versz = MAX_PATH;
2459     lstrcpyA(version, "version");
2460     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2461     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2462     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2463     ok(!lstrcmpA(version, vercheck),
2464        "Expected %s, got %s\n", vercheck, version);
2465
2466     /* only check language */
2467     langsz = MAX_PATH;
2468     lstrcpyA(lang, "lang");
2469     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2471     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2472     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2473
2474     /* check neither version nor language */
2475     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2477
2478     /* get pcchVersionBuf */
2479     versz = MAX_PATH;
2480     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2482     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2483
2484     /* get pcchLangBuf */
2485     langsz = MAX_PATH;
2486     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2487     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2488     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2489
2490     /* pcchVersionBuf not big enough */
2491     versz = 5;
2492     lstrcpyA(version, "version");
2493     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2494     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2495     ok(!strncmp(version, vercheck, 4),
2496        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2497     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2498
2499     /* pcchLangBuf not big enough */
2500     langsz = 3;
2501     lstrcpyA(lang, "lang");
2502     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2503     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2504     ok(!strncmp(lang, langcheck, 2),
2505        "Expected first character of %s, got %s\n", langcheck, lang);
2506     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2507
2508     HeapFree(GetProcessHeap(), 0, vercheck);
2509     HeapFree(GetProcessHeap(), 0, langcheck);
2510 }
2511
2512 static void test_MsiGetProductInfo(void)
2513 {
2514     UINT r;
2515     LONG res;
2516     HKEY propkey, source;
2517     HKEY prodkey, localkey;
2518     CHAR prodcode[MAX_PATH];
2519     CHAR prod_squashed[MAX_PATH];
2520     CHAR packcode[MAX_PATH];
2521     CHAR pack_squashed[MAX_PATH];
2522     CHAR buf[MAX_PATH];
2523     CHAR keypath[MAX_PATH];
2524     LPSTR usersid;
2525     DWORD sz, val = 42;
2526
2527     create_test_guid(prodcode, prod_squashed);
2528     create_test_guid(packcode, pack_squashed);
2529     get_user_sid(&usersid);
2530
2531     /* NULL szProduct */
2532     sz = MAX_PATH;
2533     lstrcpyA(buf, "apple");
2534     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2535     ok(r == ERROR_INVALID_PARAMETER,
2536        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2537     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2538     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2539
2540     /* empty szProduct */
2541     sz = MAX_PATH;
2542     lstrcpyA(buf, "apple");
2543     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2544     ok(r == ERROR_INVALID_PARAMETER,
2545        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2546     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2547     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2548
2549     /* garbage szProduct */
2550     sz = MAX_PATH;
2551     lstrcpyA(buf, "apple");
2552     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2553     ok(r == ERROR_INVALID_PARAMETER,
2554        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2555     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2556     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2557
2558     /* guid without brackets */
2559     sz = MAX_PATH;
2560     lstrcpyA(buf, "apple");
2561     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2562                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2563     ok(r == ERROR_INVALID_PARAMETER,
2564        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2565     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2566     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2567
2568     /* guid with brackets */
2569     sz = MAX_PATH;
2570     lstrcpyA(buf, "apple");
2571     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2572                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2573     ok(r == ERROR_UNKNOWN_PRODUCT,
2574        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2575     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2576     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2577
2578     /* same length as guid, but random */
2579     sz = MAX_PATH;
2580     lstrcpyA(buf, "apple");
2581     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2582                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2583     ok(r == ERROR_INVALID_PARAMETER,
2584        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2585     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2586     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2587
2588     /* not installed, NULL szAttribute */
2589     sz = MAX_PATH;
2590     lstrcpyA(buf, "apple");
2591     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2592     ok(r == ERROR_INVALID_PARAMETER,
2593        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2594     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2595     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2596
2597     /* not installed, NULL lpValueBuf */
2598     sz = MAX_PATH;
2599     lstrcpyA(buf, "apple");
2600     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2601     ok(r == ERROR_UNKNOWN_PRODUCT,
2602        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2603     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2604     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2605
2606     /* not installed, NULL pcchValueBuf */
2607     sz = MAX_PATH;
2608     lstrcpyA(buf, "apple");
2609     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2610     ok(r == ERROR_INVALID_PARAMETER,
2611        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2612     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2613     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2614
2615     /* created guid cannot possibly be an installed product code */
2616     sz = MAX_PATH;
2617     lstrcpyA(buf, "apple");
2618     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2619     ok(r == ERROR_UNKNOWN_PRODUCT,
2620        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2621     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2622     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2623
2624     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2625     lstrcatA(keypath, usersid);
2626     lstrcatA(keypath, "\\Installer\\Products\\");
2627     lstrcatA(keypath, prod_squashed);
2628
2629     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2631
2632     /* managed product code exists */
2633     sz = MAX_PATH;
2634     lstrcpyA(buf, "apple");
2635     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2636     ok(r == ERROR_UNKNOWN_PROPERTY,
2637        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2638     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2639     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2640
2641     RegDeleteKeyA(prodkey, "");
2642     RegCloseKey(prodkey);
2643
2644     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2645     lstrcatA(keypath, usersid);
2646     lstrcatA(keypath, "\\Products\\");
2647     lstrcatA(keypath, prod_squashed);
2648
2649     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2651
2652     /* local user product code exists */
2653     sz = MAX_PATH;
2654     lstrcpyA(buf, "apple");
2655     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2656     ok(r == ERROR_UNKNOWN_PRODUCT,
2657        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2658     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2659     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2660
2661     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2662     lstrcatA(keypath, usersid);
2663     lstrcatA(keypath, "\\Installer\\Products\\");
2664     lstrcatA(keypath, prod_squashed);
2665
2666     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2668
2669     /* both local and managed product code exist */
2670     sz = MAX_PATH;
2671     lstrcpyA(buf, "apple");
2672     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2673     ok(r == ERROR_UNKNOWN_PROPERTY,
2674        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2675     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2676     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2677
2678     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2680
2681     /* InstallProperties key exists */
2682     sz = MAX_PATH;
2683     lstrcpyA(buf, "apple");
2684     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2685     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2686     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2687     ok(sz == 0, "Expected 0, got %d\n", sz);
2688
2689     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2690     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2691
2692     /* HelpLink value exists */
2693     sz = MAX_PATH;
2694     lstrcpyA(buf, "apple");
2695     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2696     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2697     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2698     ok(sz == 4, "Expected 4, got %d\n", sz);
2699
2700     /* pcchBuf is NULL */
2701     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2703
2704     /* lpValueBuf is NULL */
2705     sz = MAX_PATH;
2706     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2708     ok(sz == 4, "Expected 4, got %d\n", sz);
2709
2710     /* lpValueBuf is NULL, pcchValueBuf is too small */
2711     sz = 2;
2712     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2714     ok(sz == 4, "Expected 4, got %d\n", sz);
2715
2716     /* lpValueBuf is NULL, pcchValueBuf is too small */
2717     sz = 2;
2718     lstrcpyA(buf, "apple");
2719     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2720     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2721     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2722     ok(sz == 4, "Expected 4, got %d\n", sz);
2723
2724     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2725     sz = 4;
2726     lstrcpyA(buf, "apple");
2727     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2728     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2729     ok(!lstrcmpA(buf, "apple"),
2730        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2731     ok(sz == 4, "Expected 4, got %d\n", sz);
2732
2733     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2735
2736     /* random property not supported by MSI, value exists */
2737     sz = MAX_PATH;
2738     lstrcpyA(buf, "apple");
2739     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2740     ok(r == ERROR_UNKNOWN_PROPERTY,
2741        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2742     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2743     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2744
2745     RegDeleteValueA(propkey, "IMadeThis");
2746     RegDeleteValueA(propkey, "HelpLink");
2747     RegDeleteKeyA(propkey, "");
2748     RegDeleteKeyA(localkey, "");
2749     RegDeleteKeyA(prodkey, "");
2750     RegCloseKey(propkey);
2751     RegCloseKey(localkey);
2752     RegCloseKey(prodkey);
2753
2754     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2755     lstrcatA(keypath, prod_squashed);
2756
2757     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2759
2760     /* user product key exists */
2761     sz = MAX_PATH;
2762     lstrcpyA(buf, "apple");
2763     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2764     ok(r == ERROR_UNKNOWN_PROPERTY,
2765        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2766     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2767     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2768
2769     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2770     lstrcatA(keypath, usersid);
2771     lstrcatA(keypath, "\\Products\\");
2772     lstrcatA(keypath, prod_squashed);
2773
2774     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2776
2777     /* local user product key exists */
2778     sz = MAX_PATH;
2779     lstrcpyA(buf, "apple");
2780     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2781     ok(r == ERROR_UNKNOWN_PROPERTY,
2782        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2783     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2784     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2785
2786     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2788
2789     /* InstallProperties key exists */
2790     sz = MAX_PATH;
2791     lstrcpyA(buf, "apple");
2792     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2794     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2795     ok(sz == 0, "Expected 0, got %d\n", sz);
2796
2797     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2798     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2799
2800     /* HelpLink value exists */
2801     sz = MAX_PATH;
2802     lstrcpyA(buf, "apple");
2803     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2805     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2806     ok(sz == 4, "Expected 4, got %d\n", sz);
2807
2808     RegDeleteValueA(propkey, "HelpLink");
2809     RegDeleteKeyA(propkey, "");
2810     RegDeleteKeyA(localkey, "");
2811     RegDeleteKeyA(prodkey, "");
2812     RegCloseKey(propkey);
2813     RegCloseKey(localkey);
2814     RegCloseKey(prodkey);
2815
2816     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2817     lstrcatA(keypath, prod_squashed);
2818
2819     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2821
2822     /* classes product key exists */
2823     sz = MAX_PATH;
2824     lstrcpyA(buf, "apple");
2825     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2826     ok(r == ERROR_UNKNOWN_PROPERTY,
2827        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2828     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2829     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2830
2831     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2832     lstrcatA(keypath, usersid);
2833     lstrcatA(keypath, "\\Products\\");
2834     lstrcatA(keypath, prod_squashed);
2835
2836     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2837     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2838
2839     /* local user product key exists */
2840     sz = MAX_PATH;
2841     lstrcpyA(buf, "apple");
2842     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2843     ok(r == ERROR_UNKNOWN_PROPERTY,
2844        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2845     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2846     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2847
2848     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2850
2851     /* InstallProperties key exists */
2852     sz = MAX_PATH;
2853     lstrcpyA(buf, "apple");
2854     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2855     ok(r == ERROR_UNKNOWN_PROPERTY,
2856        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2857     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2858     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2859
2860     RegDeleteKeyA(propkey, "");
2861     RegDeleteKeyA(localkey, "");
2862     RegCloseKey(propkey);
2863     RegCloseKey(localkey);
2864
2865     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2866     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2867     lstrcatA(keypath, prod_squashed);
2868
2869     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2871
2872     /* Local System product key exists */
2873     sz = MAX_PATH;
2874     lstrcpyA(buf, "apple");
2875     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2876     ok(r == ERROR_UNKNOWN_PROPERTY,
2877         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2878     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2879     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2880
2881     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2883
2884     /* InstallProperties key exists */
2885     sz = MAX_PATH;
2886     lstrcpyA(buf, "apple");
2887     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2889     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2890     ok(sz == 0, "Expected 0, got %d\n", sz);
2891
2892     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2894
2895     /* HelpLink value exists */
2896     sz = MAX_PATH;
2897     lstrcpyA(buf, "apple");
2898     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2899     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2900     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2901     ok(sz == 4, "Expected 4, got %d\n", sz);
2902
2903     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2904                          (const BYTE *)&val, sizeof(DWORD));
2905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2906
2907     /* HelpLink type is REG_DWORD */
2908     sz = MAX_PATH;
2909     lstrcpyA(buf, "apple");
2910     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2912     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2913     ok(sz == 2, "Expected 2, got %d\n", sz);
2914
2915     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2917
2918     /* DisplayName value exists */
2919     sz = MAX_PATH;
2920     lstrcpyA(buf, "apple");
2921     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2922     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2923     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2924     ok(sz == 4, "Expected 4, got %d\n", sz);
2925
2926     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2927                          (const BYTE *)&val, sizeof(DWORD));
2928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2929
2930     /* DisplayName type is REG_DWORD */
2931     sz = MAX_PATH;
2932     lstrcpyA(buf, "apple");
2933     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2934     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2935     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2936     ok(sz == 2, "Expected 2, got %d\n", sz);
2937
2938     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
2939     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2940
2941     /* DisplayVersion value exists */
2942     sz = MAX_PATH;
2943     lstrcpyA(buf, "apple");
2944     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2945     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2946     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
2947     ok(sz == 5, "Expected 5, got %d\n", sz);
2948
2949     res = RegSetValueExA(propkey, "DisplayVersion", 0,
2950                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2952
2953     /* DisplayVersion type is REG_DWORD */
2954     sz = MAX_PATH;
2955     lstrcpyA(buf, "apple");
2956     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2957     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2958     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2959     ok(sz == 2, "Expected 2, got %d\n", sz);
2960
2961     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
2962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2963
2964     /* HelpTelephone value exists */
2965     sz = MAX_PATH;
2966     lstrcpyA(buf, "apple");
2967     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2969     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
2970     ok(sz == 4, "Expected 4, got %d\n", sz);
2971
2972     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
2973                          (const BYTE *)&val, sizeof(DWORD));
2974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2975
2976     /* HelpTelephone type is REG_DWORD */
2977     sz = MAX_PATH;
2978     lstrcpyA(buf, "apple");
2979     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2981     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2982     ok(sz == 2, "Expected 2, got %d\n", sz);
2983
2984     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
2985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2986
2987     /* InstallLocation value exists */
2988     sz = MAX_PATH;
2989     lstrcpyA(buf, "apple");
2990     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
2991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2992     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
2993     ok(sz == 3, "Expected 3, got %d\n", sz);
2994
2995     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
2996                          (const BYTE *)&val, sizeof(DWORD));
2997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2998
2999     /* InstallLocation type is REG_DWORD */
3000     sz = MAX_PATH;
3001     lstrcpyA(buf, "apple");
3002     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3004     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3005     ok(sz == 2, "Expected 2, got %d\n", sz);
3006
3007     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3009
3010     /* InstallSource value exists */
3011     sz = MAX_PATH;
3012     lstrcpyA(buf, "apple");
3013     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3015     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3016     ok(sz == 6, "Expected 6, got %d\n", sz);
3017
3018     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3019                          (const BYTE *)&val, sizeof(DWORD));
3020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3021
3022     /* InstallSource type is REG_DWORD */
3023     sz = MAX_PATH;
3024     lstrcpyA(buf, "apple");
3025     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3027     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3028     ok(sz == 2, "Expected 2, got %d\n", sz);
3029
3030     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3032
3033     /* InstallDate value exists */
3034     sz = MAX_PATH;
3035     lstrcpyA(buf, "apple");
3036     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3037     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3038     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3039     ok(sz == 4, "Expected 4, got %d\n", sz);
3040
3041     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3042                          (const BYTE *)&val, sizeof(DWORD));
3043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3044
3045     /* InstallDate type is REG_DWORD */
3046     sz = MAX_PATH;
3047     lstrcpyA(buf, "apple");
3048     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3050     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3051     ok(sz == 2, "Expected 2, got %d\n", sz);
3052
3053     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3055
3056     /* Publisher value exists */
3057     sz = MAX_PATH;
3058     lstrcpyA(buf, "apple");
3059     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3060     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3061     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3062     ok(sz == 3, "Expected 3, got %d\n", sz);
3063
3064     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3065                          (const BYTE *)&val, sizeof(DWORD));
3066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3067
3068     /* Publisher type is REG_DWORD */
3069     sz = MAX_PATH;
3070     lstrcpyA(buf, "apple");
3071     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3073     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3074     ok(sz == 2, "Expected 2, got %d\n", sz);
3075
3076     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3078
3079     /* LocalPackage value exists */
3080     sz = MAX_PATH;
3081     lstrcpyA(buf, "apple");
3082     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3083     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3084     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3085     ok(sz == 4, "Expected 4, got %d\n", sz);
3086
3087     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3088                          (const BYTE *)&val, sizeof(DWORD));
3089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3090
3091     /* LocalPackage type is REG_DWORD */
3092     sz = MAX_PATH;
3093     lstrcpyA(buf, "apple");
3094     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3096     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3097     ok(sz == 2, "Expected 2, got %d\n", sz);
3098
3099     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3101
3102     /* UrlInfoAbout value exists */
3103     sz = MAX_PATH;
3104     lstrcpyA(buf, "apple");
3105     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3106     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3107     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3108     ok(sz == 5, "Expected 5, got %d\n", sz);
3109
3110     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3111                          (const BYTE *)&val, sizeof(DWORD));
3112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3113
3114     /* UrlInfoAbout type is REG_DWORD */
3115     sz = MAX_PATH;
3116     lstrcpyA(buf, "apple");
3117     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3119     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3120     ok(sz == 2, "Expected 2, got %d\n", sz);
3121
3122     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3124
3125     /* UrlUpdateInfo value exists */
3126     sz = MAX_PATH;
3127     lstrcpyA(buf, "apple");
3128     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3130     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3131     ok(sz == 4, "Expected 4, got %d\n", sz);
3132
3133     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3134                          (const BYTE *)&val, sizeof(DWORD));
3135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3136
3137     /* UrlUpdateInfo type is REG_DWORD */
3138     sz = MAX_PATH;
3139     lstrcpyA(buf, "apple");
3140     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3142     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3143     ok(sz == 2, "Expected 2, got %d\n", sz);
3144
3145     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3146     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3147
3148     /* VersionMinor value exists */
3149     sz = MAX_PATH;
3150     lstrcpyA(buf, "apple");
3151     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3152     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3153     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3154     ok(sz == 1, "Expected 1, got %d\n", sz);
3155
3156     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3157                          (const BYTE *)&val, sizeof(DWORD));
3158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3159
3160     /* VersionMinor type is REG_DWORD */
3161     sz = MAX_PATH;
3162     lstrcpyA(buf, "apple");
3163     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3165     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3166     ok(sz == 2, "Expected 2, got %d\n", sz);
3167
3168     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3170
3171     /* VersionMajor value exists */
3172     sz = MAX_PATH;
3173     lstrcpyA(buf, "apple");
3174     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3175     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3176     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3177     ok(sz == 1, "Expected 1, got %d\n", sz);
3178
3179     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3180                          (const BYTE *)&val, sizeof(DWORD));
3181     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3182
3183     /* VersionMajor type is REG_DWORD */
3184     sz = MAX_PATH;
3185     lstrcpyA(buf, "apple");
3186     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3187     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3188     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3189     ok(sz == 2, "Expected 2, got %d\n", sz);
3190
3191     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3193
3194     /* ProductID value exists */
3195     sz = MAX_PATH;
3196     lstrcpyA(buf, "apple");
3197     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3198     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3199     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3200     ok(sz == 2, "Expected 2, got %d\n", sz);
3201
3202     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3203                          (const BYTE *)&val, sizeof(DWORD));
3204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3205
3206     /* ProductID type is REG_DWORD */
3207     sz = MAX_PATH;
3208     lstrcpyA(buf, "apple");
3209     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3211     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3212     ok(sz == 2, "Expected 2, got %d\n", sz);
3213
3214     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3216
3217     /* RegCompany value exists */
3218     sz = MAX_PATH;
3219     lstrcpyA(buf, "apple");
3220     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3222     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3223     ok(sz == 4, "Expected 4, got %d\n", sz);
3224
3225     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3226                          (const BYTE *)&val, sizeof(DWORD));
3227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3228
3229     /* RegCompany type is REG_DWORD */
3230     sz = MAX_PATH;
3231     lstrcpyA(buf, "apple");
3232     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3234     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3235     ok(sz == 2, "Expected 2, got %d\n", sz);
3236
3237     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3239
3240     /* RegOwner value exists */
3241     sz = MAX_PATH;
3242     lstrcpyA(buf, "apple");
3243     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3245     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3246     ok(sz == 3, "Expected 3, got %d\n", sz);
3247
3248     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3249                          (const BYTE *)&val, sizeof(DWORD));
3250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3251
3252     /* RegOwner type is REG_DWORD */
3253     sz = MAX_PATH;
3254     lstrcpyA(buf, "apple");
3255     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3257     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3258     ok(sz == 2, "Expected 2, got %d\n", sz);
3259
3260     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3262
3263     /* InstanceType value exists */
3264     sz = MAX_PATH;
3265     lstrcpyA(buf, "apple");
3266     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3267     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3268     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3269     ok(sz == 0, "Expected 0, got %d\n", sz);
3270
3271     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3272                          (const BYTE *)&val, sizeof(DWORD));
3273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3274
3275     /* InstanceType type is REG_DWORD */
3276     sz = MAX_PATH;
3277     lstrcpyA(buf, "apple");
3278     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3280     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3281     ok(sz == 0, "Expected 0, got %d\n", sz);
3282
3283     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3285
3286     /* InstanceType value exists */
3287     sz = MAX_PATH;
3288     lstrcpyA(buf, "apple");
3289     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3291     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3292     ok(sz == 4, "Expected 4, got %d\n", sz);
3293
3294     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3295                          (const BYTE *)&val, sizeof(DWORD));
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* InstanceType type is REG_DWORD */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3303     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3304     ok(sz == 2, "Expected 2, got %d\n", sz);
3305
3306     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3308
3309     /* Transforms value exists */
3310     sz = MAX_PATH;
3311     lstrcpyA(buf, "apple");
3312     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3314     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3315     ok(sz == 0, "Expected 0, got %d\n", sz);
3316
3317     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3318                          (const BYTE *)&val, sizeof(DWORD));
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* Transforms type is REG_DWORD */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3327     ok(sz == 0, "Expected 0, got %d\n", sz);
3328
3329     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3331
3332     /* Transforms value exists */
3333     sz = MAX_PATH;
3334     lstrcpyA(buf, "apple");
3335     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3337     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3338     ok(sz == 6, "Expected 6, got %d\n", sz);
3339
3340     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3341                          (const BYTE *)&val, sizeof(DWORD));
3342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3343
3344     /* Transforms type is REG_DWORD */
3345     sz = MAX_PATH;
3346     lstrcpyA(buf, "apple");
3347     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3349     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3350     ok(sz == 2, "Expected 2, got %d\n", sz);
3351
3352     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3354
3355     /* Language value exists */
3356     sz = MAX_PATH;
3357     lstrcpyA(buf, "apple");
3358     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3360     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3361     ok(sz == 0, "Expected 0, got %d\n", sz);
3362
3363     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3364                          (const BYTE *)&val, sizeof(DWORD));
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     /* Language type is REG_DWORD */
3368     sz = MAX_PATH;
3369     lstrcpyA(buf, "apple");
3370     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3373     ok(sz == 0, "Expected 0, got %d\n", sz);
3374
3375     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3377
3378     /* Language value exists */
3379     sz = MAX_PATH;
3380     lstrcpyA(buf, "apple");
3381     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3382     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3383     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3384     ok(sz == 4, "Expected 4, got %d\n", sz);
3385
3386     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3387                          (const BYTE *)&val, sizeof(DWORD));
3388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3389
3390     /* Language type is REG_DWORD */
3391     sz = MAX_PATH;
3392     lstrcpyA(buf, "apple");
3393     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3395     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3396     ok(sz == 2, "Expected 2, got %d\n", sz);
3397
3398     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3400
3401     /* ProductName value exists */
3402     sz = MAX_PATH;
3403     lstrcpyA(buf, "apple");
3404     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3405     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3406     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3407     ok(sz == 0, "Expected 0, got %d\n", sz);
3408
3409     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3410                          (const BYTE *)&val, sizeof(DWORD));
3411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3412
3413     /* ProductName type is REG_DWORD */
3414     sz = MAX_PATH;
3415     lstrcpyA(buf, "apple");
3416     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3419     ok(sz == 0, "Expected 0, got %d\n", sz);
3420
3421     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3423
3424     /* ProductName value exists */
3425     sz = MAX_PATH;
3426     lstrcpyA(buf, "apple");
3427     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3429     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3430     ok(sz == 4, "Expected 4, got %d\n", sz);
3431
3432     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3433                          (const BYTE *)&val, sizeof(DWORD));
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     /* ProductName type is REG_DWORD */
3437     sz = MAX_PATH;
3438     lstrcpyA(buf, "apple");
3439     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3441     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3442     ok(sz == 2, "Expected 2, got %d\n", sz);
3443
3444     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3446
3447     /* Assignment value exists */
3448     sz = MAX_PATH;
3449     lstrcpyA(buf, "apple");
3450     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3452     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3453     ok(sz == 0, "Expected 0, got %d\n", sz);
3454
3455     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3456                          (const BYTE *)&val, sizeof(DWORD));
3457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3458
3459     /* Assignment type is REG_DWORD */
3460     sz = MAX_PATH;
3461     lstrcpyA(buf, "apple");
3462     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3465     ok(sz == 0, "Expected 0, got %d\n", sz);
3466
3467     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3469
3470     /* Assignment value exists */
3471     sz = MAX_PATH;
3472     lstrcpyA(buf, "apple");
3473     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3474     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3475     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3476     ok(sz == 2, "Expected 2, got %d\n", sz);
3477
3478     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3479                          (const BYTE *)&val, sizeof(DWORD));
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481
3482     /* Assignment type is REG_DWORD */
3483     sz = MAX_PATH;
3484     lstrcpyA(buf, "apple");
3485     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3487     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3488     ok(sz == 2, "Expected 2, got %d\n", sz);
3489
3490     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3491     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3492
3493     /* PackageCode value exists */
3494     sz = MAX_PATH;
3495     lstrcpyA(buf, "apple");
3496     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3497     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3498     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3499     ok(sz == 0, "Expected 0, got %d\n", sz);
3500
3501     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3502                          (const BYTE *)&val, sizeof(DWORD));
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     /* PackageCode type is REG_DWORD */
3506     sz = MAX_PATH;
3507     lstrcpyA(buf, "apple");
3508     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3511     ok(sz == 0, "Expected 0, got %d\n", sz);
3512
3513     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3515
3516     /* PackageCode value exists */
3517     sz = MAX_PATH;
3518     lstrcpyA(buf, "apple");
3519     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3520     ok(r == ERROR_BAD_CONFIGURATION,
3521        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3522     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3523     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3524
3525     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3526                          (const BYTE *)&val, sizeof(DWORD));
3527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3528
3529     /* PackageCode type is REG_DWORD */
3530     sz = MAX_PATH;
3531     lstrcpyA(buf, "apple");
3532     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3533     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3534     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3535     ok(sz == 2, "Expected 2, got %d\n", sz);
3536
3537     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3539
3540     /* PackageCode value exists */
3541     sz = MAX_PATH;
3542     lstrcpyA(buf, "apple");
3543     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3545     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3546     ok(sz == 38, "Expected 38, got %d\n", sz);
3547
3548     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3550
3551     /* Version value exists */
3552     sz = MAX_PATH;
3553     lstrcpyA(buf, "apple");
3554     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3556     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3557     ok(sz == 0, "Expected 0, got %d\n", sz);
3558
3559     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3560                          (const BYTE *)&val, sizeof(DWORD));
3561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3562
3563     /* Version type is REG_DWORD */
3564     sz = MAX_PATH;
3565     lstrcpyA(buf, "apple");
3566     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3568     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3569     ok(sz == 0, "Expected 0, got %d\n", sz);
3570
3571     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3573
3574     /* Version value exists */
3575     sz = MAX_PATH;
3576     lstrcpyA(buf, "apple");
3577     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3579     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3580     ok(sz == 3, "Expected 3, got %d\n", sz);
3581
3582     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3583                          (const BYTE *)&val, sizeof(DWORD));
3584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3585
3586     /* Version type is REG_DWORD */
3587     sz = MAX_PATH;
3588     lstrcpyA(buf, "apple");
3589     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3591     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3592     ok(sz == 2, "Expected 2, got %d\n", sz);
3593
3594     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3596
3597     /* ProductIcon value exists */
3598     sz = MAX_PATH;
3599     lstrcpyA(buf, "apple");
3600     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3602     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3603     ok(sz == 0, "Expected 0, got %d\n", sz);
3604
3605     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3606                          (const BYTE *)&val, sizeof(DWORD));
3607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3608
3609     /* ProductIcon type is REG_DWORD */
3610     sz = MAX_PATH;
3611     lstrcpyA(buf, "apple");
3612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3614     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3615     ok(sz == 0, "Expected 0, got %d\n", sz);
3616
3617     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3619
3620     /* ProductIcon value exists */
3621     sz = MAX_PATH;
3622     lstrcpyA(buf, "apple");
3623     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3625     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3626     ok(sz == 3, "Expected 3, got %d\n", sz);
3627
3628     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3629                          (const BYTE *)&val, sizeof(DWORD));
3630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3631
3632     /* ProductIcon type is REG_DWORD */
3633     sz = MAX_PATH;
3634     lstrcpyA(buf, "apple");
3635     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3637     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3638     ok(sz == 2, "Expected 2, got %d\n", sz);
3639
3640     res = RegCreateKeyA(prodkey, "SourceList", &source);
3641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3642
3643     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3645
3646     sz = MAX_PATH;
3647     lstrcpyA(buf, "apple");
3648     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3649     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3650     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3651     ok(sz == 8, "Expected 8, got %d\n", sz);
3652
3653     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3654                          (const BYTE *)&val, sizeof(DWORD));
3655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3656
3657     /* PackageName type is REG_DWORD */
3658     sz = MAX_PATH;
3659     lstrcpyA(buf, "apple");
3660     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3662     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3663     ok(sz == 2, "Expected 2, got %d\n", sz);
3664
3665     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3667
3668     /* Authorized value exists */
3669     sz = MAX_PATH;
3670     lstrcpyA(buf, "apple");
3671     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3672     if (r != ERROR_UNKNOWN_PROPERTY)
3673     {
3674         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3675         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3676         ok(sz == 0, "Expected 0, got %d\n", sz);
3677     }
3678
3679     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3680                          (const BYTE *)&val, sizeof(DWORD));
3681     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3682
3683     /* AuthorizedLUAApp type is REG_DWORD */
3684     sz = MAX_PATH;
3685     lstrcpyA(buf, "apple");
3686     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3687     if (r != ERROR_UNKNOWN_PROPERTY)
3688     {
3689         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3690         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3691         ok(sz == 0, "Expected 0, got %d\n", sz);
3692     }
3693
3694     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3696
3697     /* Authorized value exists */
3698     sz = MAX_PATH;
3699     lstrcpyA(buf, "apple");
3700     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3701     if (r != ERROR_UNKNOWN_PROPERTY)
3702     {
3703         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3704         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3705         ok(sz == 4, "Expected 4, got %d\n", sz);
3706     }
3707
3708     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3709                          (const BYTE *)&val, sizeof(DWORD));
3710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3711
3712     /* AuthorizedLUAApp type is REG_DWORD */
3713     sz = MAX_PATH;
3714     lstrcpyA(buf, "apple");
3715     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3716     if (r != ERROR_UNKNOWN_PROPERTY)
3717     {
3718         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3719         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3720         ok(sz == 2, "Expected 2, got %d\n", sz);
3721     }
3722
3723     RegDeleteValueA(propkey, "HelpLink");
3724     RegDeleteValueA(propkey, "DisplayName");
3725     RegDeleteValueA(propkey, "DisplayVersion");
3726     RegDeleteValueA(propkey, "HelpTelephone");
3727     RegDeleteValueA(propkey, "InstallLocation");
3728     RegDeleteValueA(propkey, "InstallSource");
3729     RegDeleteValueA(propkey, "InstallDate");
3730     RegDeleteValueA(propkey, "Publisher");
3731     RegDeleteValueA(propkey, "LocalPackage");
3732     RegDeleteValueA(propkey, "UrlInfoAbout");
3733     RegDeleteValueA(propkey, "UrlUpdateInfo");
3734     RegDeleteValueA(propkey, "VersionMinor");
3735     RegDeleteValueA(propkey, "VersionMajor");
3736     RegDeleteValueA(propkey, "ProductID");
3737     RegDeleteValueA(propkey, "RegCompany");
3738     RegDeleteValueA(propkey, "RegOwner");
3739     RegDeleteValueA(propkey, "InstanceType");
3740     RegDeleteValueA(propkey, "Transforms");
3741     RegDeleteValueA(propkey, "Language");
3742     RegDeleteValueA(propkey, "ProductName");
3743     RegDeleteValueA(propkey, "Assignment");
3744     RegDeleteValueA(propkey, "PackageCode");
3745     RegDeleteValueA(propkey, "Version");
3746     RegDeleteValueA(propkey, "ProductIcon");
3747     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3748     RegDeleteKeyA(propkey, "");
3749     RegDeleteKeyA(localkey, "");
3750     RegDeleteValueA(prodkey, "InstanceType");
3751     RegDeleteValueA(prodkey, "Transforms");
3752     RegDeleteValueA(prodkey, "Language");
3753     RegDeleteValueA(prodkey, "ProductName");
3754     RegDeleteValueA(prodkey, "Assignment");
3755     RegDeleteValueA(prodkey, "PackageCode");
3756     RegDeleteValueA(prodkey, "Version");
3757     RegDeleteValueA(prodkey, "ProductIcon");
3758     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3759     RegDeleteValueA(source, "PackageName");
3760     RegDeleteKeyA(source, "");
3761     RegDeleteKeyA(prodkey, "");
3762     RegCloseKey(propkey);
3763     RegCloseKey(localkey);
3764     RegCloseKey(source);
3765     RegCloseKey(prodkey);
3766 }
3767
3768 static void test_MsiGetProductInfoEx(void)
3769 {
3770     UINT r;
3771     LONG res;
3772     HKEY propkey, userkey;
3773     HKEY prodkey, localkey;
3774     CHAR prodcode[MAX_PATH];
3775     CHAR prod_squashed[MAX_PATH];
3776     CHAR packcode[MAX_PATH];
3777     CHAR pack_squashed[MAX_PATH];
3778     CHAR buf[MAX_PATH];
3779     CHAR keypath[MAX_PATH];
3780     LPSTR usersid;
3781     DWORD sz;
3782
3783     if (!pMsiGetProductInfoExA)
3784     {
3785         skip("MsiGetProductInfoExA is not available\n");
3786         return;
3787     }
3788
3789     create_test_guid(prodcode, prod_squashed);
3790     create_test_guid(packcode, pack_squashed);
3791     get_user_sid(&usersid);
3792
3793     /* NULL szProductCode */
3794     sz = MAX_PATH;
3795     lstrcpyA(buf, "apple");
3796     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3797                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3798     ok(r == ERROR_INVALID_PARAMETER,
3799        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3800     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3801     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3802
3803     /* empty szProductCode */
3804     sz = MAX_PATH;
3805     lstrcpyA(buf, "apple");
3806     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3807                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3808     ok(r == ERROR_INVALID_PARAMETER,
3809        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3810     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3811     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3812
3813     /* garbage szProductCode */
3814     sz = MAX_PATH;
3815     lstrcpyA(buf, "apple");
3816     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3817                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3818     ok(r == ERROR_INVALID_PARAMETER,
3819        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3820     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3821     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3822
3823     /* guid without brackets */
3824     sz = MAX_PATH;
3825     lstrcpyA(buf, "apple");
3826     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3827                               MSIINSTALLCONTEXT_USERUNMANAGED,
3828                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3829     ok(r == ERROR_INVALID_PARAMETER,
3830        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3831     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3832     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3833
3834     /* guid with brackets */
3835     sz = MAX_PATH;
3836     lstrcpyA(buf, "apple");
3837     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3838                               MSIINSTALLCONTEXT_USERUNMANAGED,
3839                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3840     ok(r == ERROR_UNKNOWN_PRODUCT,
3841        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3842     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3843     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3844
3845     /* szValue is non-NULL while pcchValue is NULL */
3846     lstrcpyA(buf, "apple");
3847     r = pMsiGetProductInfoExA(prodcode, usersid,
3848                               MSIINSTALLCONTEXT_USERUNMANAGED,
3849                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3850     ok(r == ERROR_INVALID_PARAMETER,
3851        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3852     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3853
3854     /* dwContext is out of range */
3855     sz = MAX_PATH;
3856     lstrcpyA(buf, "apple");
3857     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3858                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3859     ok(r == ERROR_INVALID_PARAMETER,
3860        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3861     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3862     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3863
3864     /* szProperty is NULL */
3865     sz = MAX_PATH;
3866     lstrcpyA(buf, "apple");
3867     r = pMsiGetProductInfoExA(prodcode, usersid,
3868                               MSIINSTALLCONTEXT_USERUNMANAGED,
3869                               NULL, buf, &sz);
3870     ok(r == ERROR_INVALID_PARAMETER,
3871        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3872     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3873     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3874
3875     /* szProperty is empty */
3876     sz = MAX_PATH;
3877     lstrcpyA(buf, "apple");
3878     r = pMsiGetProductInfoExA(prodcode, usersid,
3879                               MSIINSTALLCONTEXT_USERUNMANAGED,
3880                               "", buf, &sz);
3881     ok(r == ERROR_INVALID_PARAMETER,
3882        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3883     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3884     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3885
3886     /* szProperty is not a valid property */
3887     sz = MAX_PATH;
3888     lstrcpyA(buf, "apple");
3889     r = pMsiGetProductInfoExA(prodcode, usersid,
3890                               MSIINSTALLCONTEXT_USERUNMANAGED,
3891                               "notvalid", buf, &sz);
3892     ok(r == ERROR_UNKNOWN_PRODUCT,
3893        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3894     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3895     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3896
3897     /* same length as guid, but random */
3898     sz = MAX_PATH;
3899     lstrcpyA(buf, "apple");
3900     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3901                               MSIINSTALLCONTEXT_USERUNMANAGED,
3902                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3903     ok(r == ERROR_INVALID_PARAMETER,
3904        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3905     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3906     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3907
3908     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3909
3910     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3911     lstrcatA(keypath, usersid);
3912     lstrcatA(keypath, "\\Products\\");
3913     lstrcatA(keypath, prod_squashed);
3914
3915     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3917
3918     /* local user product key exists */
3919     sz = MAX_PATH;
3920     lstrcpyA(buf, "apple");
3921     r = pMsiGetProductInfoExA(prodcode, usersid,
3922                               MSIINSTALLCONTEXT_USERUNMANAGED,
3923                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3924     ok(r == ERROR_UNKNOWN_PRODUCT,
3925        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3926     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3927     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3928
3929     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3931
3932     /* InstallProperties key exists */
3933     sz = MAX_PATH;
3934     lstrcpyA(buf, "apple");
3935     r = pMsiGetProductInfoExA(prodcode, usersid,
3936                               MSIINSTALLCONTEXT_USERUNMANAGED,
3937                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3938     ok(r == ERROR_UNKNOWN_PRODUCT,
3939        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3940     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3941     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3942
3943     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3945
3946     /* LocalPackage value exists */
3947     sz = MAX_PATH;
3948     lstrcpyA(buf, "apple");
3949     r = pMsiGetProductInfoExA(prodcode, usersid,
3950                               MSIINSTALLCONTEXT_USERUNMANAGED,
3951                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3953     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
3954     ok(sz == 1, "Expected 1, got %d\n", sz);
3955
3956     RegDeleteValueA(propkey, "LocalPackage");
3957
3958     /* LocalPackage value must exist */
3959     sz = MAX_PATH;
3960     lstrcpyA(buf, "apple");
3961     r = pMsiGetProductInfoExA(prodcode, usersid,
3962                               MSIINSTALLCONTEXT_USERUNMANAGED,
3963                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3964     ok(r == ERROR_UNKNOWN_PRODUCT,
3965        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3966     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3967     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3968
3969     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3971
3972     /* LocalPackage exists, but HelpLink does not exist */
3973     sz = MAX_PATH;
3974     lstrcpyA(buf, "apple");
3975     r = pMsiGetProductInfoExA(prodcode, usersid,
3976                               MSIINSTALLCONTEXT_USERUNMANAGED,
3977                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3978     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3979     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3980     ok(sz == 0, "Expected 0, got %d\n", sz);
3981
3982     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3984
3985     /* HelpLink value exists */
3986     sz = MAX_PATH;
3987     lstrcpyA(buf, "apple");
3988     r = pMsiGetProductInfoExA(prodcode, usersid,
3989                               MSIINSTALLCONTEXT_USERUNMANAGED,
3990                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3992     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3993     ok(sz == 4, "Expected 4, got %d\n", sz);
3994
3995     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
3996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3997
3998     /* HelpTelephone value exists */
3999     sz = MAX_PATH;
4000     lstrcpyA(buf, "apple");
4001     r = pMsiGetProductInfoExA(prodcode, usersid,
4002                               MSIINSTALLCONTEXT_USERUNMANAGED,
4003                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4005     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4006     ok(sz == 5, "Expected 5, got %d\n", sz);
4007
4008     /* szValue and pcchValue are NULL */
4009     r = pMsiGetProductInfoExA(prodcode, usersid,
4010                               MSIINSTALLCONTEXT_USERUNMANAGED,
4011                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4012     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4013
4014     /* pcchValue is exactly 5 */
4015     sz = 5;
4016     lstrcpyA(buf, "apple");
4017     r = pMsiGetProductInfoExA(prodcode, usersid,
4018                               MSIINSTALLCONTEXT_USERUNMANAGED,
4019                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4020     ok(r == ERROR_MORE_DATA,
4021        "Expected ERROR_MORE_DATA, got %d\n", r);
4022     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4023     ok(sz == 10, "Expected 10, got %d\n", sz);
4024
4025     /* szValue is NULL, pcchValue is exactly 5 */
4026     sz = 5;
4027     r = pMsiGetProductInfoExA(prodcode, usersid,
4028                               MSIINSTALLCONTEXT_USERUNMANAGED,
4029                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4031     ok(sz == 10, "Expected 10, got %d\n", sz);
4032
4033     /* szValue is NULL, pcchValue is MAX_PATH */
4034     sz = MAX_PATH;
4035     r = pMsiGetProductInfoExA(prodcode, usersid,
4036                               MSIINSTALLCONTEXT_USERUNMANAGED,
4037                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4039     ok(sz == 10, "Expected 10, got %d\n", sz);
4040
4041     /* pcchValue is exactly 0 */
4042     sz = 0;
4043     lstrcpyA(buf, "apple");
4044     r = pMsiGetProductInfoExA(prodcode, usersid,
4045                               MSIINSTALLCONTEXT_USERUNMANAGED,
4046                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4047     ok(r == ERROR_MORE_DATA,
4048        "Expected ERROR_MORE_DATA, got %d\n", r);
4049     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4050     ok(sz == 10, "Expected 10, got %d\n", sz);
4051
4052     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4054
4055     /* szProperty is not a valid property */
4056     sz = MAX_PATH;
4057     lstrcpyA(buf, "apple");
4058     r = pMsiGetProductInfoExA(prodcode, usersid,
4059                               MSIINSTALLCONTEXT_USERUNMANAGED,
4060                               "notvalid", buf, &sz);
4061     ok(r == ERROR_UNKNOWN_PROPERTY,
4062        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4063     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4064     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4065
4066     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4068
4069     /* InstallDate value exists */
4070     sz = MAX_PATH;
4071     lstrcpyA(buf, "apple");
4072     r = pMsiGetProductInfoExA(prodcode, usersid,
4073                               MSIINSTALLCONTEXT_USERUNMANAGED,
4074                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4076     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4077     ok(sz == 4, "Expected 4, got %d\n", sz);
4078
4079     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4081
4082     /* DisplayName value exists */
4083     sz = MAX_PATH;
4084     lstrcpyA(buf, "apple");
4085     r = pMsiGetProductInfoExA(prodcode, usersid,
4086                               MSIINSTALLCONTEXT_USERUNMANAGED,
4087                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4088     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4089     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4090     ok(sz == 4, "Expected 4, got %d\n", sz);
4091
4092     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4094
4095     /* InstallLocation value exists */
4096     sz = MAX_PATH;
4097     lstrcpyA(buf, "apple");
4098     r = pMsiGetProductInfoExA(prodcode, usersid,
4099                               MSIINSTALLCONTEXT_USERUNMANAGED,
4100                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4102     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4103     ok(sz == 3, "Expected 3, got %d\n", sz);
4104
4105     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4107
4108     /* InstallSource value exists */
4109     sz = MAX_PATH;
4110     lstrcpyA(buf, "apple");
4111     r = pMsiGetProductInfoExA(prodcode, usersid,
4112                               MSIINSTALLCONTEXT_USERUNMANAGED,
4113                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4116     ok(sz == 6, "Expected 6, got %d\n", sz);
4117
4118     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4120
4121     /* LocalPackage value exists */
4122     sz = MAX_PATH;
4123     lstrcpyA(buf, "apple");
4124     r = pMsiGetProductInfoExA(prodcode, usersid,
4125                               MSIINSTALLCONTEXT_USERUNMANAGED,
4126                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4128     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4129     ok(sz == 5, "Expected 5, got %d\n", sz);
4130
4131     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4133
4134     /* Publisher value exists */
4135     sz = MAX_PATH;
4136     lstrcpyA(buf, "apple");
4137     r = pMsiGetProductInfoExA(prodcode, usersid,
4138                               MSIINSTALLCONTEXT_USERUNMANAGED,
4139                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4140     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4141     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4142     ok(sz == 3, "Expected 3, got %d\n", sz);
4143
4144     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4146
4147     /* URLInfoAbout value exists */
4148     sz = MAX_PATH;
4149     lstrcpyA(buf, "apple");
4150     r = pMsiGetProductInfoExA(prodcode, usersid,
4151                               MSIINSTALLCONTEXT_USERUNMANAGED,
4152                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4154     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4155     ok(sz == 5, "Expected 5, got %d\n", sz);
4156
4157     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4159
4160     /* URLUpdateInfo value exists */
4161     sz = MAX_PATH;
4162     lstrcpyA(buf, "apple");
4163     r = pMsiGetProductInfoExA(prodcode, usersid,
4164                               MSIINSTALLCONTEXT_USERUNMANAGED,
4165                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4166     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4167     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4168     ok(sz == 6, "Expected 6, got %d\n", sz);
4169
4170     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4172
4173     /* VersionMinor value exists */
4174     sz = MAX_PATH;
4175     lstrcpyA(buf, "apple");
4176     r = pMsiGetProductInfoExA(prodcode, usersid,
4177                               MSIINSTALLCONTEXT_USERUNMANAGED,
4178                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4180     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4181     ok(sz == 1, "Expected 1, got %d\n", sz);
4182
4183     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4185
4186     /* VersionMajor value exists */
4187     sz = MAX_PATH;
4188     lstrcpyA(buf, "apple");
4189     r = pMsiGetProductInfoExA(prodcode, usersid,
4190                               MSIINSTALLCONTEXT_USERUNMANAGED,
4191                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4192     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4193     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4194     ok(sz == 1, "Expected 1, got %d\n", sz);
4195
4196     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4198
4199     /* DisplayVersion value exists */
4200     sz = MAX_PATH;
4201     lstrcpyA(buf, "apple");
4202     r = pMsiGetProductInfoExA(prodcode, usersid,
4203                               MSIINSTALLCONTEXT_USERUNMANAGED,
4204                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4205     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4206     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4207     ok(sz == 5, "Expected 5, got %d\n", sz);
4208
4209     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4211
4212     /* ProductID value exists */
4213     sz = MAX_PATH;
4214     lstrcpyA(buf, "apple");
4215     r = pMsiGetProductInfoExA(prodcode, usersid,
4216                               MSIINSTALLCONTEXT_USERUNMANAGED,
4217                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4219     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4220     ok(sz == 2, "Expected 2, got %d\n", sz);
4221
4222     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4224
4225     /* RegCompany value exists */
4226     sz = MAX_PATH;
4227     lstrcpyA(buf, "apple");
4228     r = pMsiGetProductInfoExA(prodcode, usersid,
4229                               MSIINSTALLCONTEXT_USERUNMANAGED,
4230                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4232     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4233     ok(sz == 4, "Expected 4, got %d\n", sz);
4234
4235     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4237
4238     /* RegOwner value exists */
4239     sz = MAX_PATH;
4240     lstrcpyA(buf, "apple");
4241     r = pMsiGetProductInfoExA(prodcode, usersid,
4242                               MSIINSTALLCONTEXT_USERUNMANAGED,
4243                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4245     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4246     ok(sz == 5, "Expected 5, got %d\n", sz);
4247
4248     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4249     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4250
4251     /* Transforms value exists */
4252     sz = MAX_PATH;
4253     lstrcpyA(buf, "apple");
4254     r = pMsiGetProductInfoExA(prodcode, usersid,
4255                               MSIINSTALLCONTEXT_USERUNMANAGED,
4256                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4257     ok(r == ERROR_UNKNOWN_PRODUCT,
4258        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4259     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4260     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4261
4262     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4264
4265     /* Language value exists */
4266     sz = MAX_PATH;
4267     lstrcpyA(buf, "apple");
4268     r = pMsiGetProductInfoExA(prodcode, usersid,
4269                               MSIINSTALLCONTEXT_USERUNMANAGED,
4270                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4271     ok(r == ERROR_UNKNOWN_PRODUCT,
4272        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4273     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4274     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4275
4276     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4278
4279     /* ProductName value exists */
4280     sz = MAX_PATH;
4281     lstrcpyA(buf, "apple");
4282     r = pMsiGetProductInfoExA(prodcode, usersid,
4283                               MSIINSTALLCONTEXT_USERUNMANAGED,
4284                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4285     ok(r == ERROR_UNKNOWN_PRODUCT,
4286        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4287     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4288     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4289
4290     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4292
4293     /* FIXME */
4294
4295     /* AssignmentType value exists */
4296     sz = MAX_PATH;
4297     lstrcpyA(buf, "apple");
4298     r = pMsiGetProductInfoExA(prodcode, usersid,
4299                               MSIINSTALLCONTEXT_USERUNMANAGED,
4300                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4301     ok(r == ERROR_UNKNOWN_PRODUCT,
4302        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4303     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4304     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4305
4306     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4308
4309     /* PackageCode value exists */
4310     sz = MAX_PATH;
4311     lstrcpyA(buf, "apple");
4312     r = pMsiGetProductInfoExA(prodcode, usersid,
4313                               MSIINSTALLCONTEXT_USERUNMANAGED,
4314                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4315     ok(r == ERROR_UNKNOWN_PRODUCT,
4316        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4317     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4318     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4319
4320     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4322
4323     /* Version value exists */
4324     sz = MAX_PATH;
4325     lstrcpyA(buf, "apple");
4326     r = pMsiGetProductInfoExA(prodcode, usersid,
4327                               MSIINSTALLCONTEXT_USERUNMANAGED,
4328                               INSTALLPROPERTY_VERSION, buf, &sz);
4329     ok(r == ERROR_UNKNOWN_PRODUCT,
4330        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4331     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4332     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4333
4334     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4336
4337     /* ProductIcon value exists */
4338     sz = MAX_PATH;
4339     lstrcpyA(buf, "apple");
4340     r = pMsiGetProductInfoExA(prodcode, usersid,
4341                               MSIINSTALLCONTEXT_USERUNMANAGED,
4342                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4343     ok(r == ERROR_UNKNOWN_PRODUCT,
4344        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4345     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4346     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4347
4348     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4350
4351     /* PackageName value exists */
4352     sz = MAX_PATH;
4353     lstrcpyA(buf, "apple");
4354     r = pMsiGetProductInfoExA(prodcode, usersid,
4355                               MSIINSTALLCONTEXT_USERUNMANAGED,
4356                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4357     ok(r == ERROR_UNKNOWN_PRODUCT,
4358        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4359     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4360     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4361
4362     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4364
4365     /* AuthorizedLUAApp value exists */
4366     sz = MAX_PATH;
4367     lstrcpyA(buf, "apple");
4368     r = pMsiGetProductInfoExA(prodcode, usersid,
4369                               MSIINSTALLCONTEXT_USERUNMANAGED,
4370                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4371     ok(r == ERROR_UNKNOWN_PRODUCT,
4372        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4373     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4374     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4375
4376     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4377     RegDeleteValueA(propkey, "PackageName");
4378     RegDeleteValueA(propkey, "ProductIcon");
4379     RegDeleteValueA(propkey, "Version");
4380     RegDeleteValueA(propkey, "PackageCode");
4381     RegDeleteValueA(propkey, "AssignmentType");
4382     RegDeleteValueA(propkey, "ProductName");
4383     RegDeleteValueA(propkey, "Language");
4384     RegDeleteValueA(propkey, "Transforms");
4385     RegDeleteValueA(propkey, "RegOwner");
4386     RegDeleteValueA(propkey, "RegCompany");
4387     RegDeleteValueA(propkey, "ProductID");
4388     RegDeleteValueA(propkey, "DisplayVersion");
4389     RegDeleteValueA(propkey, "VersionMajor");
4390     RegDeleteValueA(propkey, "VersionMinor");
4391     RegDeleteValueA(propkey, "URLUpdateInfo");
4392     RegDeleteValueA(propkey, "URLInfoAbout");
4393     RegDeleteValueA(propkey, "Publisher");
4394     RegDeleteValueA(propkey, "LocalPackage");
4395     RegDeleteValueA(propkey, "InstallSource");
4396     RegDeleteValueA(propkey, "InstallLocation");
4397     RegDeleteValueA(propkey, "DisplayName");
4398     RegDeleteValueA(propkey, "InstallDate");
4399     RegDeleteValueA(propkey, "HelpTelephone");
4400     RegDeleteValueA(propkey, "HelpLink");
4401     RegDeleteValueA(propkey, "LocalPackage");
4402     RegDeleteKeyA(propkey, "");
4403     RegCloseKey(propkey);
4404     RegDeleteKeyA(localkey, "");
4405     RegCloseKey(localkey);
4406
4407     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4408     lstrcatA(keypath, usersid);
4409     lstrcatA(keypath, "\\Installer\\Products\\");
4410     lstrcatA(keypath, prod_squashed);
4411
4412     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4413     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4414
4415     /* user product key exists */
4416     sz = MAX_PATH;
4417     lstrcpyA(buf, "apple");
4418     r = pMsiGetProductInfoExA(prodcode, usersid,
4419                               MSIINSTALLCONTEXT_USERUNMANAGED,
4420                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4421     ok(r == ERROR_UNKNOWN_PRODUCT,
4422        "Expected ERROR_UNKNOWN_PRODUCT, 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     RegDeleteKeyA(userkey, "");
4427     RegCloseKey(userkey);
4428
4429     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4430     lstrcatA(keypath, prod_squashed);
4431
4432     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4434
4435     sz = MAX_PATH;
4436     lstrcpyA(buf, "apple");
4437     r = pMsiGetProductInfoExA(prodcode, usersid,
4438                               MSIINSTALLCONTEXT_USERUNMANAGED,
4439                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4441     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4442     ok(sz == 1, "Expected 1, got %d\n", sz);
4443
4444     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4446
4447     /* HelpLink value exists */
4448     sz = MAX_PATH;
4449     lstrcpyA(buf, "apple");
4450     r = pMsiGetProductInfoExA(prodcode, usersid,
4451                               MSIINSTALLCONTEXT_USERUNMANAGED,
4452                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4453     ok(r == ERROR_UNKNOWN_PROPERTY,
4454        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4455     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4456     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4457
4458     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4460
4461     /* HelpTelephone value exists */
4462     sz = MAX_PATH;
4463     lstrcpyA(buf, "apple");
4464     r = pMsiGetProductInfoExA(prodcode, usersid,
4465                               MSIINSTALLCONTEXT_USERUNMANAGED,
4466                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4467     ok(r == ERROR_UNKNOWN_PROPERTY,
4468        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4469     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4470     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4471
4472     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4474
4475     /* InstallDate value exists */
4476     sz = MAX_PATH;
4477     lstrcpyA(buf, "apple");
4478     r = pMsiGetProductInfoExA(prodcode, usersid,
4479                               MSIINSTALLCONTEXT_USERUNMANAGED,
4480                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4481     ok(r == ERROR_UNKNOWN_PROPERTY,
4482        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4483     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4484     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4485
4486     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4488
4489     /* DisplayName value exists */
4490     sz = MAX_PATH;
4491     lstrcpyA(buf, "apple");
4492     r = pMsiGetProductInfoExA(prodcode, usersid,
4493                               MSIINSTALLCONTEXT_USERUNMANAGED,
4494                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4495     ok(r == ERROR_UNKNOWN_PROPERTY,
4496        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4497     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4498     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4499
4500     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4501     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4502
4503     /* InstallLocation value exists */
4504     sz = MAX_PATH;
4505     lstrcpyA(buf, "apple");
4506     r = pMsiGetProductInfoExA(prodcode, usersid,
4507                               MSIINSTALLCONTEXT_USERUNMANAGED,
4508                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4509     ok(r == ERROR_UNKNOWN_PROPERTY,
4510        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4511     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4512     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4513
4514     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4516
4517     /* InstallSource value exists */
4518     sz = MAX_PATH;
4519     lstrcpyA(buf, "apple");
4520     r = pMsiGetProductInfoExA(prodcode, usersid,
4521                               MSIINSTALLCONTEXT_USERUNMANAGED,
4522                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4523     ok(r == ERROR_UNKNOWN_PROPERTY,
4524        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4525     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4526     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4527
4528     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4530
4531     /* LocalPackage value exists */
4532     sz = MAX_PATH;
4533     lstrcpyA(buf, "apple");
4534     r = pMsiGetProductInfoExA(prodcode, usersid,
4535                               MSIINSTALLCONTEXT_USERUNMANAGED,
4536                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4537     ok(r == ERROR_UNKNOWN_PROPERTY,
4538        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4539     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4540     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4541
4542     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4543     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4544
4545     /* Publisher value exists */
4546     sz = MAX_PATH;
4547     lstrcpyA(buf, "apple");
4548     r = pMsiGetProductInfoExA(prodcode, usersid,
4549                               MSIINSTALLCONTEXT_USERUNMANAGED,
4550                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4551     ok(r == ERROR_UNKNOWN_PROPERTY,
4552        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4553     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4554     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4555
4556     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4558
4559     /* URLInfoAbout value exists */
4560     sz = MAX_PATH;
4561     lstrcpyA(buf, "apple");
4562     r = pMsiGetProductInfoExA(prodcode, usersid,
4563                               MSIINSTALLCONTEXT_USERUNMANAGED,
4564                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4565     ok(r == ERROR_UNKNOWN_PROPERTY,
4566        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4567     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4568     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4569
4570     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4572
4573     /* URLUpdateInfo value exists */
4574     sz = MAX_PATH;
4575     lstrcpyA(buf, "apple");
4576     r = pMsiGetProductInfoExA(prodcode, usersid,
4577                               MSIINSTALLCONTEXT_USERUNMANAGED,
4578                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4579     ok(r == ERROR_UNKNOWN_PROPERTY,
4580        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4581     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4582     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4583
4584     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4586
4587     /* VersionMinor value exists */
4588     sz = MAX_PATH;
4589     lstrcpyA(buf, "apple");
4590     r = pMsiGetProductInfoExA(prodcode, usersid,
4591                               MSIINSTALLCONTEXT_USERUNMANAGED,
4592                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4593     ok(r == ERROR_UNKNOWN_PROPERTY,
4594        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4595     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4596     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4597
4598     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4600
4601     /* VersionMajor value exists */
4602     sz = MAX_PATH;
4603     lstrcpyA(buf, "apple");
4604     r = pMsiGetProductInfoExA(prodcode, usersid,
4605                               MSIINSTALLCONTEXT_USERUNMANAGED,
4606                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4607     ok(r == ERROR_UNKNOWN_PROPERTY,
4608        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4609     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4610     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4611
4612     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4614
4615     /* DisplayVersion value exists */
4616     sz = MAX_PATH;
4617     lstrcpyA(buf, "apple");
4618     r = pMsiGetProductInfoExA(prodcode, usersid,
4619                               MSIINSTALLCONTEXT_USERUNMANAGED,
4620                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4621     ok(r == ERROR_UNKNOWN_PROPERTY,
4622        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4623     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4624     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4625
4626     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4628
4629     /* ProductID value exists */
4630     sz = MAX_PATH;
4631     lstrcpyA(buf, "apple");
4632     r = pMsiGetProductInfoExA(prodcode, usersid,
4633                               MSIINSTALLCONTEXT_USERUNMANAGED,
4634                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4635     ok(r == ERROR_UNKNOWN_PROPERTY,
4636        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4637     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4638     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4639
4640     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4642
4643     /* RegCompany value exists */
4644     sz = MAX_PATH;
4645     lstrcpyA(buf, "apple");
4646     r = pMsiGetProductInfoExA(prodcode, usersid,
4647                               MSIINSTALLCONTEXT_USERUNMANAGED,
4648                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4649     ok(r == ERROR_UNKNOWN_PROPERTY,
4650        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4651     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4652     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4653
4654     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4656
4657     /* RegOwner value exists */
4658     sz = MAX_PATH;
4659     lstrcpyA(buf, "apple");
4660     r = pMsiGetProductInfoExA(prodcode, usersid,
4661                               MSIINSTALLCONTEXT_USERUNMANAGED,
4662                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4663     ok(r == ERROR_UNKNOWN_PROPERTY,
4664        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4665     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4666     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4667
4668     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4670
4671     /* Transforms value exists */
4672     sz = MAX_PATH;
4673     lstrcpyA(buf, "apple");
4674     r = pMsiGetProductInfoExA(prodcode, usersid,
4675                               MSIINSTALLCONTEXT_USERUNMANAGED,
4676                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4678     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4679     ok(sz == 5, "Expected 5, got %d\n", sz);
4680
4681     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4683
4684     /* Language value exists */
4685     sz = MAX_PATH;
4686     lstrcpyA(buf, "apple");
4687     r = pMsiGetProductInfoExA(prodcode, usersid,
4688                               MSIINSTALLCONTEXT_USERUNMANAGED,
4689                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4691     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4692     ok(sz == 4, "Expected 4, got %d\n", sz);
4693
4694     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4696
4697     /* ProductName value exists */
4698     sz = MAX_PATH;
4699     lstrcpyA(buf, "apple");
4700     r = pMsiGetProductInfoExA(prodcode, usersid,
4701                               MSIINSTALLCONTEXT_USERUNMANAGED,
4702                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4703     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4704     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4705     ok(sz == 4, "Expected 4, got %d\n", sz);
4706
4707     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4709
4710     /* FIXME */
4711
4712     /* AssignmentType value exists */
4713     sz = MAX_PATH;
4714     lstrcpyA(buf, "apple");
4715     r = pMsiGetProductInfoExA(prodcode, usersid,
4716                               MSIINSTALLCONTEXT_USERUNMANAGED,
4717                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4718     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4719     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4720     ok(sz == 0, "Expected 0, got %d\n", sz);
4721
4722     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4723     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4724
4725     /* FIXME */
4726
4727     /* PackageCode value exists */
4728     sz = MAX_PATH;
4729     lstrcpyA(buf, "apple");
4730     r = pMsiGetProductInfoExA(prodcode, usersid,
4731                               MSIINSTALLCONTEXT_USERUNMANAGED,
4732                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4733     todo_wine
4734     {
4735         ok(r == ERROR_BAD_CONFIGURATION,
4736            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4737         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4738         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4739     }
4740
4741     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4743
4744     /* Version value exists */
4745     sz = MAX_PATH;
4746     lstrcpyA(buf, "apple");
4747     r = pMsiGetProductInfoExA(prodcode, usersid,
4748                               MSIINSTALLCONTEXT_USERUNMANAGED,
4749                               INSTALLPROPERTY_VERSION, buf, &sz);
4750     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4751     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4752     ok(sz == 3, "Expected 3, got %d\n", sz);
4753
4754     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4755     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4756
4757     /* ProductIcon value exists */
4758     sz = MAX_PATH;
4759     lstrcpyA(buf, "apple");
4760     r = pMsiGetProductInfoExA(prodcode, usersid,
4761                               MSIINSTALLCONTEXT_USERUNMANAGED,
4762                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4763     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4764     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4765     ok(sz == 4, "Expected 4, got %d\n", sz);
4766
4767     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4769
4770     /* PackageName value exists */
4771     sz = MAX_PATH;
4772     lstrcpyA(buf, "apple");
4773     r = pMsiGetProductInfoExA(prodcode, usersid,
4774                               MSIINSTALLCONTEXT_USERUNMANAGED,
4775                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4776     todo_wine
4777     {
4778         ok(r == ERROR_UNKNOWN_PRODUCT,
4779            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4780         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4781         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4782     }
4783
4784     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4786
4787     /* AuthorizedLUAApp value exists */
4788     sz = MAX_PATH;
4789     lstrcpyA(buf, "apple");
4790     r = pMsiGetProductInfoExA(prodcode, usersid,
4791                               MSIINSTALLCONTEXT_USERUNMANAGED,
4792                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4794     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4795     ok(sz == 4, "Expected 4, got %d\n", sz);
4796
4797     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4798     RegDeleteValueA(prodkey, "PackageName");
4799     RegDeleteValueA(prodkey, "ProductIcon");
4800     RegDeleteValueA(prodkey, "Version");
4801     RegDeleteValueA(prodkey, "PackageCode");
4802     RegDeleteValueA(prodkey, "AssignmentType");
4803     RegDeleteValueA(prodkey, "ProductName");
4804     RegDeleteValueA(prodkey, "Language");
4805     RegDeleteValueA(prodkey, "Transforms");
4806     RegDeleteValueA(prodkey, "RegOwner");
4807     RegDeleteValueA(prodkey, "RegCompany");
4808     RegDeleteValueA(prodkey, "ProductID");
4809     RegDeleteValueA(prodkey, "DisplayVersion");
4810     RegDeleteValueA(prodkey, "VersionMajor");
4811     RegDeleteValueA(prodkey, "VersionMinor");
4812     RegDeleteValueA(prodkey, "URLUpdateInfo");
4813     RegDeleteValueA(prodkey, "URLInfoAbout");
4814     RegDeleteValueA(prodkey, "Publisher");
4815     RegDeleteValueA(prodkey, "LocalPackage");
4816     RegDeleteValueA(prodkey, "InstallSource");
4817     RegDeleteValueA(prodkey, "InstallLocation");
4818     RegDeleteValueA(prodkey, "DisplayName");
4819     RegDeleteValueA(prodkey, "InstallDate");
4820     RegDeleteValueA(prodkey, "HelpTelephone");
4821     RegDeleteValueA(prodkey, "HelpLink");
4822     RegDeleteValueA(prodkey, "LocalPackage");
4823     RegDeleteKeyA(prodkey, "");
4824     RegCloseKey(prodkey);
4825
4826     /* MSIINSTALLCONTEXT_USERMANAGED */
4827
4828     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4829     lstrcatA(keypath, usersid);
4830     lstrcatA(keypath, "\\Products\\");
4831     lstrcatA(keypath, prod_squashed);
4832
4833     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4835
4836     /* local user product key exists */
4837     sz = MAX_PATH;
4838     lstrcpyA(buf, "apple");
4839     r = pMsiGetProductInfoExA(prodcode, usersid,
4840                               MSIINSTALLCONTEXT_USERMANAGED,
4841                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4842     ok(r == ERROR_UNKNOWN_PRODUCT,
4843        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4844     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4845     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4846
4847     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4849
4850     /* InstallProperties key exists */
4851     sz = MAX_PATH;
4852     lstrcpyA(buf, "apple");
4853     r = pMsiGetProductInfoExA(prodcode, usersid,
4854                               MSIINSTALLCONTEXT_USERMANAGED,
4855                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4856     ok(r == ERROR_UNKNOWN_PRODUCT,
4857        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4858     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4859     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4860
4861     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4863
4864     /* ManagedLocalPackage value exists */
4865     sz = MAX_PATH;
4866     lstrcpyA(buf, "apple");
4867     r = pMsiGetProductInfoExA(prodcode, usersid,
4868                               MSIINSTALLCONTEXT_USERMANAGED,
4869                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4871     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4872     ok(sz == 1, "Expected 1, got %d\n", sz);
4873
4874     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4876
4877     /* HelpLink value exists */
4878     sz = MAX_PATH;
4879     lstrcpyA(buf, "apple");
4880     r = pMsiGetProductInfoExA(prodcode, usersid,
4881                               MSIINSTALLCONTEXT_USERMANAGED,
4882                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4883     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4884     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4885     ok(sz == 4, "Expected 4, got %d\n", sz);
4886
4887     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4889
4890     /* HelpTelephone value exists */
4891     sz = MAX_PATH;
4892     lstrcpyA(buf, "apple");
4893     r = pMsiGetProductInfoExA(prodcode, usersid,
4894                               MSIINSTALLCONTEXT_USERMANAGED,
4895                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4897     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4898     ok(sz == 5, "Expected 5, got %d\n", sz);
4899
4900     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4902
4903     /* InstallDate value exists */
4904     sz = MAX_PATH;
4905     lstrcpyA(buf, "apple");
4906     r = pMsiGetProductInfoExA(prodcode, usersid,
4907                               MSIINSTALLCONTEXT_USERMANAGED,
4908                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4910     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4911     ok(sz == 4, "Expected 4, got %d\n", sz);
4912
4913     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4915
4916     /* DisplayName value exists */
4917     sz = MAX_PATH;
4918     lstrcpyA(buf, "apple");
4919     r = pMsiGetProductInfoExA(prodcode, usersid,
4920                               MSIINSTALLCONTEXT_USERMANAGED,
4921                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4922     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4923     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4924     ok(sz == 4, "Expected 4, got %d\n", sz);
4925
4926     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4928
4929     /* InstallLocation value exists */
4930     sz = MAX_PATH;
4931     lstrcpyA(buf, "apple");
4932     r = pMsiGetProductInfoExA(prodcode, usersid,
4933                               MSIINSTALLCONTEXT_USERMANAGED,
4934                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4936     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4937     ok(sz == 3, "Expected 3, got %d\n", sz);
4938
4939     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4941
4942     /* InstallSource value exists */
4943     sz = MAX_PATH;
4944     lstrcpyA(buf, "apple");
4945     r = pMsiGetProductInfoExA(prodcode, usersid,
4946                               MSIINSTALLCONTEXT_USERMANAGED,
4947                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4949     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4950     ok(sz == 6, "Expected 6, got %d\n", sz);
4951
4952     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4954
4955     /* LocalPackage value exists */
4956     sz = MAX_PATH;
4957     lstrcpyA(buf, "apple");
4958     r = pMsiGetProductInfoExA(prodcode, usersid,
4959                               MSIINSTALLCONTEXT_USERMANAGED,
4960                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4961     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4962     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4963     ok(sz == 5, "Expected 5, got %d\n", sz);
4964
4965     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4967
4968     /* Publisher value exists */
4969     sz = MAX_PATH;
4970     lstrcpyA(buf, "apple");
4971     r = pMsiGetProductInfoExA(prodcode, usersid,
4972                               MSIINSTALLCONTEXT_USERMANAGED,
4973                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4975     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4976     ok(sz == 3, "Expected 3, got %d\n", sz);
4977
4978     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4980
4981     /* URLInfoAbout value exists */
4982     sz = MAX_PATH;
4983     lstrcpyA(buf, "apple");
4984     r = pMsiGetProductInfoExA(prodcode, usersid,
4985                               MSIINSTALLCONTEXT_USERMANAGED,
4986                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4988     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4989     ok(sz == 5, "Expected 5, got %d\n", sz);
4990
4991     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4993
4994     /* URLUpdateInfo value exists */
4995     sz = MAX_PATH;
4996     lstrcpyA(buf, "apple");
4997     r = pMsiGetProductInfoExA(prodcode, usersid,
4998                               MSIINSTALLCONTEXT_USERMANAGED,
4999                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5001     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5002     ok(sz == 6, "Expected 6, got %d\n", sz);
5003
5004     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5006
5007     /* VersionMinor value exists */
5008     sz = MAX_PATH;
5009     lstrcpyA(buf, "apple");
5010     r = pMsiGetProductInfoExA(prodcode, usersid,
5011                               MSIINSTALLCONTEXT_USERMANAGED,
5012                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5014     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5015     ok(sz == 1, "Expected 1, got %d\n", sz);
5016
5017     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5019
5020     /* VersionMajor value exists */
5021     sz = MAX_PATH;
5022     lstrcpyA(buf, "apple");
5023     r = pMsiGetProductInfoExA(prodcode, usersid,
5024                               MSIINSTALLCONTEXT_USERMANAGED,
5025                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5027     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5028     ok(sz == 1, "Expected 1, got %d\n", sz);
5029
5030     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5032
5033     /* DisplayVersion value exists */
5034     sz = MAX_PATH;
5035     lstrcpyA(buf, "apple");
5036     r = pMsiGetProductInfoExA(prodcode, usersid,
5037                               MSIINSTALLCONTEXT_USERMANAGED,
5038                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5040     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5041     ok(sz == 5, "Expected 5, got %d\n", sz);
5042
5043     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5044     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5045
5046     /* ProductID value exists */
5047     sz = MAX_PATH;
5048     lstrcpyA(buf, "apple");
5049     r = pMsiGetProductInfoExA(prodcode, usersid,
5050                               MSIINSTALLCONTEXT_USERMANAGED,
5051                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5052     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5053     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5054     ok(sz == 2, "Expected 2, got %d\n", sz);
5055
5056     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5057     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5058
5059     /* RegCompany value exists */
5060     sz = MAX_PATH;
5061     lstrcpyA(buf, "apple");
5062     r = pMsiGetProductInfoExA(prodcode, usersid,
5063                               MSIINSTALLCONTEXT_USERMANAGED,
5064                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5066     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5067     ok(sz == 4, "Expected 4, got %d\n", sz);
5068
5069     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5071
5072     /* RegOwner value exists */
5073     sz = MAX_PATH;
5074     lstrcpyA(buf, "apple");
5075     r = pMsiGetProductInfoExA(prodcode, usersid,
5076                               MSIINSTALLCONTEXT_USERMANAGED,
5077                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5078     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5079     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5080     ok(sz == 5, "Expected 5, got %d\n", sz);
5081
5082     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5084
5085     /* Transforms value exists */
5086     sz = MAX_PATH;
5087     lstrcpyA(buf, "apple");
5088     r = pMsiGetProductInfoExA(prodcode, usersid,
5089                               MSIINSTALLCONTEXT_USERMANAGED,
5090                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5091     ok(r == ERROR_UNKNOWN_PRODUCT,
5092        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5093     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5094     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5095
5096     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5098
5099     /* Language value exists */
5100     sz = MAX_PATH;
5101     lstrcpyA(buf, "apple");
5102     r = pMsiGetProductInfoExA(prodcode, usersid,
5103                               MSIINSTALLCONTEXT_USERMANAGED,
5104                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5105     ok(r == ERROR_UNKNOWN_PRODUCT,
5106        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5107     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5108     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5109
5110     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5112
5113     /* ProductName value exists */
5114     sz = MAX_PATH;
5115     lstrcpyA(buf, "apple");
5116     r = pMsiGetProductInfoExA(prodcode, usersid,
5117                               MSIINSTALLCONTEXT_USERMANAGED,
5118                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5119     ok(r == ERROR_UNKNOWN_PRODUCT,
5120        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5121     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5122     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5123
5124     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5126
5127     /* FIXME */
5128
5129     /* AssignmentType value exists */
5130     sz = MAX_PATH;
5131     lstrcpyA(buf, "apple");
5132     r = pMsiGetProductInfoExA(prodcode, usersid,
5133                               MSIINSTALLCONTEXT_USERMANAGED,
5134                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5135     ok(r == ERROR_UNKNOWN_PRODUCT,
5136        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5137     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5138     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5139
5140     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5142
5143     /* PackageCode value exists */
5144     sz = MAX_PATH;
5145     lstrcpyA(buf, "apple");
5146     r = pMsiGetProductInfoExA(prodcode, usersid,
5147                               MSIINSTALLCONTEXT_USERMANAGED,
5148                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5149     ok(r == ERROR_UNKNOWN_PRODUCT,
5150        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5151     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5152     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5153
5154     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5156
5157     /* Version value exists */
5158     sz = MAX_PATH;
5159     lstrcpyA(buf, "apple");
5160     r = pMsiGetProductInfoExA(prodcode, usersid,
5161                               MSIINSTALLCONTEXT_USERMANAGED,
5162                               INSTALLPROPERTY_VERSION, buf, &sz);
5163     ok(r == ERROR_UNKNOWN_PRODUCT,
5164        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5165     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5166     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5167
5168     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5170
5171     /* ProductIcon value exists */
5172     sz = MAX_PATH;
5173     lstrcpyA(buf, "apple");
5174     r = pMsiGetProductInfoExA(prodcode, usersid,
5175                               MSIINSTALLCONTEXT_USERMANAGED,
5176                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5177     ok(r == ERROR_UNKNOWN_PRODUCT,
5178        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5179     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5180     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5181
5182     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5184
5185     /* PackageName value exists */
5186     sz = MAX_PATH;
5187     lstrcpyA(buf, "apple");
5188     r = pMsiGetProductInfoExA(prodcode, usersid,
5189                               MSIINSTALLCONTEXT_USERMANAGED,
5190                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5191     ok(r == ERROR_UNKNOWN_PRODUCT,
5192        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5193     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5194     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5195
5196     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5198
5199     /* AuthorizedLUAApp value exists */
5200     sz = MAX_PATH;
5201     lstrcpyA(buf, "apple");
5202     r = pMsiGetProductInfoExA(prodcode, usersid,
5203                               MSIINSTALLCONTEXT_USERMANAGED,
5204                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5205     ok(r == ERROR_UNKNOWN_PRODUCT,
5206        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5207     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5208     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5209
5210     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5211     RegDeleteValueA(propkey, "PackageName");
5212     RegDeleteValueA(propkey, "ProductIcon");
5213     RegDeleteValueA(propkey, "Version");
5214     RegDeleteValueA(propkey, "PackageCode");
5215     RegDeleteValueA(propkey, "AssignmentType");
5216     RegDeleteValueA(propkey, "ProductName");
5217     RegDeleteValueA(propkey, "Language");
5218     RegDeleteValueA(propkey, "Transforms");
5219     RegDeleteValueA(propkey, "RegOwner");
5220     RegDeleteValueA(propkey, "RegCompany");
5221     RegDeleteValueA(propkey, "ProductID");
5222     RegDeleteValueA(propkey, "DisplayVersion");
5223     RegDeleteValueA(propkey, "VersionMajor");
5224     RegDeleteValueA(propkey, "VersionMinor");
5225     RegDeleteValueA(propkey, "URLUpdateInfo");
5226     RegDeleteValueA(propkey, "URLInfoAbout");
5227     RegDeleteValueA(propkey, "Publisher");
5228     RegDeleteValueA(propkey, "LocalPackage");
5229     RegDeleteValueA(propkey, "InstallSource");
5230     RegDeleteValueA(propkey, "InstallLocation");
5231     RegDeleteValueA(propkey, "DisplayName");
5232     RegDeleteValueA(propkey, "InstallDate");
5233     RegDeleteValueA(propkey, "HelpTelephone");
5234     RegDeleteValueA(propkey, "HelpLink");
5235     RegDeleteValueA(propkey, "ManagedLocalPackage");
5236     RegDeleteKeyA(propkey, "");
5237     RegCloseKey(propkey);
5238     RegDeleteKeyA(localkey, "");
5239     RegCloseKey(localkey);
5240
5241     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5242     lstrcatA(keypath, usersid);
5243     lstrcatA(keypath, "\\Installer\\Products\\");
5244     lstrcatA(keypath, prod_squashed);
5245
5246     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5248
5249     /* user product key exists */
5250     sz = MAX_PATH;
5251     lstrcpyA(buf, "apple");
5252     r = pMsiGetProductInfoExA(prodcode, usersid,
5253                               MSIINSTALLCONTEXT_USERMANAGED,
5254                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5255     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5256     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5257     ok(sz == 1, "Expected 1, got %d\n", sz);
5258
5259     RegDeleteKeyA(userkey, "");
5260     RegCloseKey(userkey);
5261
5262     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5263     lstrcatA(keypath, prod_squashed);
5264
5265     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5267
5268     /* current user product key exists */
5269     sz = MAX_PATH;
5270     lstrcpyA(buf, "apple");
5271     r = pMsiGetProductInfoExA(prodcode, usersid,
5272                               MSIINSTALLCONTEXT_USERMANAGED,
5273                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5274     ok(r == ERROR_UNKNOWN_PRODUCT,
5275        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5276     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5277     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5278
5279     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5281
5282     /* HelpLink value exists, user product key does not exist */
5283     sz = MAX_PATH;
5284     lstrcpyA(buf, "apple");
5285     r = pMsiGetProductInfoExA(prodcode, usersid,
5286                               MSIINSTALLCONTEXT_USERMANAGED,
5287                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5288     ok(r == ERROR_UNKNOWN_PRODUCT,
5289        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5290     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5291     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5292
5293     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5294     lstrcatA(keypath, usersid);
5295     lstrcatA(keypath, "\\Installer\\Products\\");
5296     lstrcatA(keypath, prod_squashed);
5297
5298     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5300
5301     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5303
5304     /* HelpLink value exists, user product key does exist */
5305     sz = MAX_PATH;
5306     lstrcpyA(buf, "apple");
5307     r = pMsiGetProductInfoExA(prodcode, usersid,
5308                               MSIINSTALLCONTEXT_USERMANAGED,
5309                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5310     ok(r == ERROR_UNKNOWN_PROPERTY,
5311        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5312     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5313     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5314
5315     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5317
5318     /* HelpTelephone value exists */
5319     sz = MAX_PATH;
5320     lstrcpyA(buf, "apple");
5321     r = pMsiGetProductInfoExA(prodcode, usersid,
5322                               MSIINSTALLCONTEXT_USERMANAGED,
5323                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5324     ok(r == ERROR_UNKNOWN_PROPERTY,
5325        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5326     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5327     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5328
5329     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5331
5332     /* InstallDate value exists */
5333     sz = MAX_PATH;
5334     lstrcpyA(buf, "apple");
5335     r = pMsiGetProductInfoExA(prodcode, usersid,
5336                               MSIINSTALLCONTEXT_USERMANAGED,
5337                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5338     ok(r == ERROR_UNKNOWN_PROPERTY,
5339        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5340     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5341     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5342
5343     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5345
5346     /* DisplayName value exists */
5347     sz = MAX_PATH;
5348     lstrcpyA(buf, "apple");
5349     r = pMsiGetProductInfoExA(prodcode, usersid,
5350                               MSIINSTALLCONTEXT_USERMANAGED,
5351                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5352     ok(r == ERROR_UNKNOWN_PROPERTY,
5353        "Expected ERROR_UNKNOWN_PROPERTY, 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     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5359
5360     /* InstallLocation value exists */
5361     sz = MAX_PATH;
5362     lstrcpyA(buf, "apple");
5363     r = pMsiGetProductInfoExA(prodcode, usersid,
5364                               MSIINSTALLCONTEXT_USERMANAGED,
5365                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5366     ok(r == ERROR_UNKNOWN_PROPERTY,
5367        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5368     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5369     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5370
5371     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5373
5374     /* InstallSource value exists */
5375     sz = MAX_PATH;
5376     lstrcpyA(buf, "apple");
5377     r = pMsiGetProductInfoExA(prodcode, usersid,
5378                               MSIINSTALLCONTEXT_USERMANAGED,
5379                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5380     ok(r == ERROR_UNKNOWN_PROPERTY,
5381        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5382     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5383     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5384
5385     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5387
5388     /* LocalPackage value exists */
5389     sz = MAX_PATH;
5390     lstrcpyA(buf, "apple");
5391     r = pMsiGetProductInfoExA(prodcode, usersid,
5392                               MSIINSTALLCONTEXT_USERMANAGED,
5393                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5394     ok(r == ERROR_UNKNOWN_PROPERTY,
5395        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5396     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5397     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5398
5399     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5401
5402     /* Publisher value exists */
5403     sz = MAX_PATH;
5404     lstrcpyA(buf, "apple");
5405     r = pMsiGetProductInfoExA(prodcode, usersid,
5406                               MSIINSTALLCONTEXT_USERMANAGED,
5407                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5408     ok(r == ERROR_UNKNOWN_PROPERTY,
5409        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5410     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5411     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5412
5413     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5415
5416     /* URLInfoAbout value exists */
5417     sz = MAX_PATH;
5418     lstrcpyA(buf, "apple");
5419     r = pMsiGetProductInfoExA(prodcode, usersid,
5420                               MSIINSTALLCONTEXT_USERMANAGED,
5421                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5422     ok(r == ERROR_UNKNOWN_PROPERTY,
5423        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5424     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5425     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5426
5427     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5429
5430     /* URLUpdateInfo value exists */
5431     sz = MAX_PATH;
5432     lstrcpyA(buf, "apple");
5433     r = pMsiGetProductInfoExA(prodcode, usersid,
5434                               MSIINSTALLCONTEXT_USERMANAGED,
5435                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5436     ok(r == ERROR_UNKNOWN_PROPERTY,
5437        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5438     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5439     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5440
5441     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5443
5444     /* VersionMinor value exists */
5445     sz = MAX_PATH;
5446     lstrcpyA(buf, "apple");
5447     r = pMsiGetProductInfoExA(prodcode, usersid,
5448                               MSIINSTALLCONTEXT_USERMANAGED,
5449                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5450     ok(r == ERROR_UNKNOWN_PROPERTY,
5451        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5452     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5453     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5454
5455     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5457
5458     /* VersionMajor value exists */
5459     sz = MAX_PATH;
5460     lstrcpyA(buf, "apple");
5461     r = pMsiGetProductInfoExA(prodcode, usersid,
5462                               MSIINSTALLCONTEXT_USERMANAGED,
5463                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5464     ok(r == ERROR_UNKNOWN_PROPERTY,
5465        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5466     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5467     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5468
5469     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5471
5472     /* DisplayVersion value exists */
5473     sz = MAX_PATH;
5474     lstrcpyA(buf, "apple");
5475     r = pMsiGetProductInfoExA(prodcode, usersid,
5476                               MSIINSTALLCONTEXT_USERMANAGED,
5477                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5478     ok(r == ERROR_UNKNOWN_PROPERTY,
5479        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5480     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5481     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5482
5483     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5485
5486     /* ProductID value exists */
5487     sz = MAX_PATH;
5488     lstrcpyA(buf, "apple");
5489     r = pMsiGetProductInfoExA(prodcode, usersid,
5490                               MSIINSTALLCONTEXT_USERMANAGED,
5491                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5492     ok(r == ERROR_UNKNOWN_PROPERTY,
5493        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5494     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5495     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5496
5497     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5499
5500     /* RegCompany value exists */
5501     sz = MAX_PATH;
5502     lstrcpyA(buf, "apple");
5503     r = pMsiGetProductInfoExA(prodcode, usersid,
5504                               MSIINSTALLCONTEXT_USERMANAGED,
5505                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5506     ok(r == ERROR_UNKNOWN_PROPERTY,
5507        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5508     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5509     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5510
5511     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5513
5514     /* RegOwner value exists */
5515     sz = MAX_PATH;
5516     lstrcpyA(buf, "apple");
5517     r = pMsiGetProductInfoExA(prodcode, usersid,
5518                               MSIINSTALLCONTEXT_USERMANAGED,
5519                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5520     ok(r == ERROR_UNKNOWN_PROPERTY,
5521        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5522     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5523     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5524
5525     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5527
5528     /* Transforms value exists */
5529     sz = MAX_PATH;
5530     lstrcpyA(buf, "apple");
5531     r = pMsiGetProductInfoExA(prodcode, usersid,
5532                               MSIINSTALLCONTEXT_USERMANAGED,
5533                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5534     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5535     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5536     ok(sz == 5, "Expected 5, got %d\n", sz);
5537
5538     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5540
5541     /* Language value exists */
5542     sz = MAX_PATH;
5543     lstrcpyA(buf, "apple");
5544     r = pMsiGetProductInfoExA(prodcode, usersid,
5545                               MSIINSTALLCONTEXT_USERMANAGED,
5546                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5547     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5548     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5549     ok(sz == 4, "Expected 4, got %d\n", sz);
5550
5551     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5553
5554     /* ProductName value exists */
5555     sz = MAX_PATH;
5556     lstrcpyA(buf, "apple");
5557     r = pMsiGetProductInfoExA(prodcode, usersid,
5558                               MSIINSTALLCONTEXT_USERMANAGED,
5559                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5561     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5562     ok(sz == 4, "Expected 4, got %d\n", sz);
5563
5564     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5566
5567     /* FIXME */
5568
5569     /* AssignmentType value exists */
5570     sz = MAX_PATH;
5571     lstrcpyA(buf, "apple");
5572     r = pMsiGetProductInfoExA(prodcode, usersid,
5573                               MSIINSTALLCONTEXT_USERMANAGED,
5574                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5575     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5576     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5577     ok(sz == 0, "Expected 0, got %d\n", sz);
5578
5579     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5580     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5581
5582     /* FIXME */
5583
5584     /* PackageCode value exists */
5585     sz = MAX_PATH;
5586     lstrcpyA(buf, "apple");
5587     r = pMsiGetProductInfoExA(prodcode, usersid,
5588                               MSIINSTALLCONTEXT_USERMANAGED,
5589                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5590     todo_wine
5591     {
5592         ok(r == ERROR_BAD_CONFIGURATION,
5593            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5594         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5595         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5596     }
5597
5598     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5600
5601     /* Version value exists */
5602     sz = MAX_PATH;
5603     lstrcpyA(buf, "apple");
5604     r = pMsiGetProductInfoExA(prodcode, usersid,
5605                               MSIINSTALLCONTEXT_USERMANAGED,
5606                               INSTALLPROPERTY_VERSION, buf, &sz);
5607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5608     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5609     ok(sz == 3, "Expected 3, got %d\n", sz);
5610
5611     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5613
5614     /* ProductIcon value exists */
5615     sz = MAX_PATH;
5616     lstrcpyA(buf, "apple");
5617     r = pMsiGetProductInfoExA(prodcode, usersid,
5618                               MSIINSTALLCONTEXT_USERMANAGED,
5619                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5621     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5622     ok(sz == 4, "Expected 4, got %d\n", sz);
5623
5624     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5626
5627     /* PackageName value exists */
5628     sz = MAX_PATH;
5629     lstrcpyA(buf, "apple");
5630     r = pMsiGetProductInfoExA(prodcode, usersid,
5631                               MSIINSTALLCONTEXT_USERMANAGED,
5632                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5633     todo_wine
5634     {
5635         ok(r == ERROR_UNKNOWN_PRODUCT,
5636            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5637         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5638         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5639     }
5640
5641     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5643
5644     /* AuthorizedLUAApp value exists */
5645     sz = MAX_PATH;
5646     lstrcpyA(buf, "apple");
5647     r = pMsiGetProductInfoExA(prodcode, usersid,
5648                               MSIINSTALLCONTEXT_USERMANAGED,
5649                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5650     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5651     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5652     ok(sz == 4, "Expected 4, got %d\n", sz);
5653
5654     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5655     RegDeleteValueA(userkey, "PackageName");
5656     RegDeleteValueA(userkey, "ProductIcon");
5657     RegDeleteValueA(userkey, "Version");
5658     RegDeleteValueA(userkey, "PackageCode");
5659     RegDeleteValueA(userkey, "AssignmentType");
5660     RegDeleteValueA(userkey, "ProductName");
5661     RegDeleteValueA(userkey, "Language");
5662     RegDeleteValueA(userkey, "Transforms");
5663     RegDeleteValueA(userkey, "RegOwner");
5664     RegDeleteValueA(userkey, "RegCompany");
5665     RegDeleteValueA(userkey, "ProductID");
5666     RegDeleteValueA(userkey, "DisplayVersion");
5667     RegDeleteValueA(userkey, "VersionMajor");
5668     RegDeleteValueA(userkey, "VersionMinor");
5669     RegDeleteValueA(userkey, "URLUpdateInfo");
5670     RegDeleteValueA(userkey, "URLInfoAbout");
5671     RegDeleteValueA(userkey, "Publisher");
5672     RegDeleteValueA(userkey, "LocalPackage");
5673     RegDeleteValueA(userkey, "InstallSource");
5674     RegDeleteValueA(userkey, "InstallLocation");
5675     RegDeleteValueA(userkey, "DisplayName");
5676     RegDeleteValueA(userkey, "InstallDate");
5677     RegDeleteValueA(userkey, "HelpTelephone");
5678     RegDeleteValueA(userkey, "HelpLink");
5679     RegDeleteKeyA(userkey, "");
5680     RegCloseKey(userkey);
5681     RegDeleteKeyA(prodkey, "");
5682     RegCloseKey(prodkey);
5683
5684     /* MSIINSTALLCONTEXT_MACHINE */
5685
5686     /* szUserSid is non-NULL */
5687     sz = MAX_PATH;
5688     lstrcpyA(buf, "apple");
5689     r = pMsiGetProductInfoExA(prodcode, usersid,
5690                               MSIINSTALLCONTEXT_MACHINE,
5691                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5692     ok(r == ERROR_INVALID_PARAMETER,
5693        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5694     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5695     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5696
5697     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5698     lstrcatA(keypath, prod_squashed);
5699
5700     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5702
5703     /* local system product key exists */
5704     sz = MAX_PATH;
5705     lstrcpyA(buf, "apple");
5706     r = pMsiGetProductInfoExA(prodcode, NULL,
5707                               MSIINSTALLCONTEXT_MACHINE,
5708                               INSTALLPROPERTY_PRODUCTSTATE, 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 = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5716
5717     /* InstallProperties key exists */
5718     sz = MAX_PATH;
5719     lstrcpyA(buf, "apple");
5720     r = pMsiGetProductInfoExA(prodcode, NULL,
5721                               MSIINSTALLCONTEXT_MACHINE,
5722                               INSTALLPROPERTY_PRODUCTSTATE, 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, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5730
5731     /* LocalPackage value exists */
5732     sz = MAX_PATH;
5733     lstrcpyA(buf, "apple");
5734     r = pMsiGetProductInfoExA(prodcode, NULL,
5735                               MSIINSTALLCONTEXT_MACHINE,
5736                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5738     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5739     ok(sz == 1, "Expected 1, got %d\n", sz);
5740
5741     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5743
5744     /* HelpLink value exists */
5745     sz = MAX_PATH;
5746     lstrcpyA(buf, "apple");
5747     r = pMsiGetProductInfoExA(prodcode, NULL,
5748                               MSIINSTALLCONTEXT_MACHINE,
5749                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5750     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5751     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5752     ok(sz == 4, "Expected 4, got %d\n", sz);
5753
5754     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5755     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5756
5757     /* HelpTelephone value exists */
5758     sz = MAX_PATH;
5759     lstrcpyA(buf, "apple");
5760     r = pMsiGetProductInfoExA(prodcode, NULL,
5761                               MSIINSTALLCONTEXT_MACHINE,
5762                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5763     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5764     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5765     ok(sz == 5, "Expected 5, got %d\n", sz);
5766
5767     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5769
5770     /* InstallDate value exists */
5771     sz = MAX_PATH;
5772     lstrcpyA(buf, "apple");
5773     r = pMsiGetProductInfoExA(prodcode, NULL,
5774                               MSIINSTALLCONTEXT_MACHINE,
5775                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5777     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5778     ok(sz == 4, "Expected 4, got %d\n", sz);
5779
5780     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5782
5783     /* DisplayName value exists */
5784     sz = MAX_PATH;
5785     lstrcpyA(buf, "apple");
5786     r = pMsiGetProductInfoExA(prodcode, NULL,
5787                               MSIINSTALLCONTEXT_MACHINE,
5788                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5789     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5790     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5791     ok(sz == 4, "Expected 4, got %d\n", sz);
5792
5793     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5794     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5795
5796     /* InstallLocation value exists */
5797     sz = MAX_PATH;
5798     lstrcpyA(buf, "apple");
5799     r = pMsiGetProductInfoExA(prodcode, NULL,
5800                               MSIINSTALLCONTEXT_MACHINE,
5801                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5802     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5803     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5804     ok(sz == 3, "Expected 3, got %d\n", sz);
5805
5806     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5807     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5808
5809     /* InstallSource value exists */
5810     sz = MAX_PATH;
5811     lstrcpyA(buf, "apple");
5812     r = pMsiGetProductInfoExA(prodcode, NULL,
5813                               MSIINSTALLCONTEXT_MACHINE,
5814                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5815     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5816     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5817     ok(sz == 6, "Expected 6, got %d\n", sz);
5818
5819     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5821
5822     /* LocalPackage value exists */
5823     sz = MAX_PATH;
5824     lstrcpyA(buf, "apple");
5825     r = pMsiGetProductInfoExA(prodcode, NULL,
5826                               MSIINSTALLCONTEXT_MACHINE,
5827                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5829     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5830     ok(sz == 5, "Expected 5, got %d\n", sz);
5831
5832     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5833     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5834
5835     /* Publisher value exists */
5836     sz = MAX_PATH;
5837     lstrcpyA(buf, "apple");
5838     r = pMsiGetProductInfoExA(prodcode, NULL,
5839                               MSIINSTALLCONTEXT_MACHINE,
5840                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5841     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5842     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5843     ok(sz == 3, "Expected 3, got %d\n", sz);
5844
5845     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5846     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5847
5848     /* URLInfoAbout value exists */
5849     sz = MAX_PATH;
5850     lstrcpyA(buf, "apple");
5851     r = pMsiGetProductInfoExA(prodcode, NULL,
5852                               MSIINSTALLCONTEXT_MACHINE,
5853                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5854     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5855     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5856     ok(sz == 5, "Expected 5, got %d\n", sz);
5857
5858     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5860
5861     /* URLUpdateInfo value exists */
5862     sz = MAX_PATH;
5863     lstrcpyA(buf, "apple");
5864     r = pMsiGetProductInfoExA(prodcode, NULL,
5865                               MSIINSTALLCONTEXT_MACHINE,
5866                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5867     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5868     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5869     ok(sz == 6, "Expected 6, got %d\n", sz);
5870
5871     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5872     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5873
5874     /* VersionMinor value exists */
5875     sz = MAX_PATH;
5876     lstrcpyA(buf, "apple");
5877     r = pMsiGetProductInfoExA(prodcode, NULL,
5878                               MSIINSTALLCONTEXT_MACHINE,
5879                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5881     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5882     ok(sz == 1, "Expected 1, got %d\n", sz);
5883
5884     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5886
5887     /* VersionMajor value exists */
5888     sz = MAX_PATH;
5889     lstrcpyA(buf, "apple");
5890     r = pMsiGetProductInfoExA(prodcode, NULL,
5891                               MSIINSTALLCONTEXT_MACHINE,
5892                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5893     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5894     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5895     ok(sz == 1, "Expected 1, got %d\n", sz);
5896
5897     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5899
5900     /* DisplayVersion value exists */
5901     sz = MAX_PATH;
5902     lstrcpyA(buf, "apple");
5903     r = pMsiGetProductInfoExA(prodcode, NULL,
5904                               MSIINSTALLCONTEXT_MACHINE,
5905                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5906     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5907     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5908     ok(sz == 5, "Expected 5, got %d\n", sz);
5909
5910     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5911     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5912
5913     /* ProductID value exists */
5914     sz = MAX_PATH;
5915     lstrcpyA(buf, "apple");
5916     r = pMsiGetProductInfoExA(prodcode, NULL,
5917                               MSIINSTALLCONTEXT_MACHINE,
5918                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5919     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5920     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5921     ok(sz == 2, "Expected 2, got %d\n", sz);
5922
5923     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5925
5926     /* RegCompany value exists */
5927     sz = MAX_PATH;
5928     lstrcpyA(buf, "apple");
5929     r = pMsiGetProductInfoExA(prodcode, NULL,
5930                               MSIINSTALLCONTEXT_MACHINE,
5931                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5932     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5933     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5934     ok(sz == 4, "Expected 4, got %d\n", sz);
5935
5936     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5938
5939     /* RegOwner value exists */
5940     sz = MAX_PATH;
5941     lstrcpyA(buf, "apple");
5942     r = pMsiGetProductInfoExA(prodcode, NULL,
5943                               MSIINSTALLCONTEXT_MACHINE,
5944                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5945     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5946     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5947     ok(sz == 5, "Expected 5, got %d\n", sz);
5948
5949     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5951
5952     /* Transforms value exists */
5953     sz = MAX_PATH;
5954     lstrcpyA(buf, "apple");
5955     r = pMsiGetProductInfoExA(prodcode, NULL,
5956                               MSIINSTALLCONTEXT_MACHINE,
5957                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5958     ok(r == ERROR_UNKNOWN_PRODUCT,
5959        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5960     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5961     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5962
5963     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5965
5966     /* Language value exists */
5967     sz = MAX_PATH;
5968     lstrcpyA(buf, "apple");
5969     r = pMsiGetProductInfoExA(prodcode, NULL,
5970                               MSIINSTALLCONTEXT_MACHINE,
5971                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5972     ok(r == ERROR_UNKNOWN_PRODUCT,
5973        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5974     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5975     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5976
5977     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5978     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5979
5980     /* ProductName value exists */
5981     sz = MAX_PATH;
5982     lstrcpyA(buf, "apple");
5983     r = pMsiGetProductInfoExA(prodcode, NULL,
5984                               MSIINSTALLCONTEXT_MACHINE,
5985                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5986     ok(r == ERROR_UNKNOWN_PRODUCT,
5987        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5988     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5989     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5990
5991     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5993
5994     /* FIXME */
5995
5996     /* AssignmentType value exists */
5997     sz = MAX_PATH;
5998     lstrcpyA(buf, "apple");
5999     r = pMsiGetProductInfoExA(prodcode, NULL,
6000                               MSIINSTALLCONTEXT_MACHINE,
6001                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6002     ok(r == ERROR_UNKNOWN_PRODUCT,
6003        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6004     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6005     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6006
6007     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6009
6010     /* PackageCode value exists */
6011     sz = MAX_PATH;
6012     lstrcpyA(buf, "apple");
6013     r = pMsiGetProductInfoExA(prodcode, NULL,
6014                               MSIINSTALLCONTEXT_MACHINE,
6015                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6016     ok(r == ERROR_UNKNOWN_PRODUCT,
6017        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6018     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6019     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6020
6021     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6023
6024     /* Version value exists */
6025     sz = MAX_PATH;
6026     lstrcpyA(buf, "apple");
6027     r = pMsiGetProductInfoExA(prodcode, NULL,
6028                               MSIINSTALLCONTEXT_MACHINE,
6029                               INSTALLPROPERTY_VERSION, buf, &sz);
6030     ok(r == ERROR_UNKNOWN_PRODUCT,
6031        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6032     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6033     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6034
6035     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6036     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6037
6038     /* ProductIcon value exists */
6039     sz = MAX_PATH;
6040     lstrcpyA(buf, "apple");
6041     r = pMsiGetProductInfoExA(prodcode, NULL,
6042                               MSIINSTALLCONTEXT_MACHINE,
6043                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6044     ok(r == ERROR_UNKNOWN_PRODUCT,
6045        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6046     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6047     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6048
6049     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6051
6052     /* PackageName value exists */
6053     sz = MAX_PATH;
6054     lstrcpyA(buf, "apple");
6055     r = pMsiGetProductInfoExA(prodcode, NULL,
6056                               MSIINSTALLCONTEXT_MACHINE,
6057                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6058     ok(r == ERROR_UNKNOWN_PRODUCT,
6059        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6060     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6061     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6062
6063     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6065
6066     /* AuthorizedLUAApp value exists */
6067     sz = MAX_PATH;
6068     lstrcpyA(buf, "apple");
6069     r = pMsiGetProductInfoExA(prodcode, NULL,
6070                               MSIINSTALLCONTEXT_MACHINE,
6071                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6072     ok(r == ERROR_UNKNOWN_PRODUCT,
6073        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6074     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6075     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6076
6077     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6078     RegDeleteValueA(propkey, "PackageName");
6079     RegDeleteValueA(propkey, "ProductIcon");
6080     RegDeleteValueA(propkey, "Version");
6081     RegDeleteValueA(propkey, "PackageCode");
6082     RegDeleteValueA(propkey, "AssignmentType");
6083     RegDeleteValueA(propkey, "ProductName");
6084     RegDeleteValueA(propkey, "Language");
6085     RegDeleteValueA(propkey, "Transforms");
6086     RegDeleteValueA(propkey, "RegOwner");
6087     RegDeleteValueA(propkey, "RegCompany");
6088     RegDeleteValueA(propkey, "ProductID");
6089     RegDeleteValueA(propkey, "DisplayVersion");
6090     RegDeleteValueA(propkey, "VersionMajor");
6091     RegDeleteValueA(propkey, "VersionMinor");
6092     RegDeleteValueA(propkey, "URLUpdateInfo");
6093     RegDeleteValueA(propkey, "URLInfoAbout");
6094     RegDeleteValueA(propkey, "Publisher");
6095     RegDeleteValueA(propkey, "LocalPackage");
6096     RegDeleteValueA(propkey, "InstallSource");
6097     RegDeleteValueA(propkey, "InstallLocation");
6098     RegDeleteValueA(propkey, "DisplayName");
6099     RegDeleteValueA(propkey, "InstallDate");
6100     RegDeleteValueA(propkey, "HelpTelephone");
6101     RegDeleteValueA(propkey, "HelpLink");
6102     RegDeleteValueA(propkey, "LocalPackage");
6103     RegDeleteKeyA(propkey, "");
6104     RegCloseKey(propkey);
6105     RegDeleteKeyA(localkey, "");
6106     RegCloseKey(localkey);
6107
6108     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6109     lstrcatA(keypath, prod_squashed);
6110
6111     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6113
6114     /* local classes product key exists */
6115     sz = MAX_PATH;
6116     lstrcpyA(buf, "apple");
6117     r = pMsiGetProductInfoExA(prodcode, NULL,
6118                               MSIINSTALLCONTEXT_MACHINE,
6119                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6121     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6122     ok(sz == 1, "Expected 1, got %d\n", sz);
6123
6124     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6126
6127     /* HelpLink value exists */
6128     sz = MAX_PATH;
6129     lstrcpyA(buf, "apple");
6130     r = pMsiGetProductInfoExA(prodcode, NULL,
6131                               MSIINSTALLCONTEXT_MACHINE,
6132                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6133     ok(r == ERROR_UNKNOWN_PROPERTY,
6134        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6135     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6136     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6137
6138     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6140
6141     /* HelpTelephone value exists */
6142     sz = MAX_PATH;
6143     lstrcpyA(buf, "apple");
6144     r = pMsiGetProductInfoExA(prodcode, NULL,
6145                               MSIINSTALLCONTEXT_MACHINE,
6146                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6147     ok(r == ERROR_UNKNOWN_PROPERTY,
6148        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6149     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6150     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6151
6152     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6153     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6154
6155     /* InstallDate value exists */
6156     sz = MAX_PATH;
6157     lstrcpyA(buf, "apple");
6158     r = pMsiGetProductInfoExA(prodcode, NULL,
6159                               MSIINSTALLCONTEXT_MACHINE,
6160                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6161     ok(r == ERROR_UNKNOWN_PROPERTY,
6162        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6163     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6164     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6165
6166     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6168
6169     /* DisplayName value exists */
6170     sz = MAX_PATH;
6171     lstrcpyA(buf, "apple");
6172     r = pMsiGetProductInfoExA(prodcode, NULL,
6173                               MSIINSTALLCONTEXT_MACHINE,
6174                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6175     ok(r == ERROR_UNKNOWN_PROPERTY,
6176        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6177     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6178     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6179
6180     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6181     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6182
6183     /* InstallLocation value exists */
6184     sz = MAX_PATH;
6185     lstrcpyA(buf, "apple");
6186     r = pMsiGetProductInfoExA(prodcode, NULL,
6187                               MSIINSTALLCONTEXT_MACHINE,
6188                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6189     ok(r == ERROR_UNKNOWN_PROPERTY,
6190        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6191     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6192     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6193
6194     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6196
6197     /* InstallSource value exists */
6198     sz = MAX_PATH;
6199     lstrcpyA(buf, "apple");
6200     r = pMsiGetProductInfoExA(prodcode, NULL,
6201                               MSIINSTALLCONTEXT_MACHINE,
6202                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6203     ok(r == ERROR_UNKNOWN_PROPERTY,
6204        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6205     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6206     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6207
6208     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6210
6211     /* LocalPackage value exists */
6212     sz = MAX_PATH;
6213     lstrcpyA(buf, "apple");
6214     r = pMsiGetProductInfoExA(prodcode, NULL,
6215                               MSIINSTALLCONTEXT_MACHINE,
6216                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6217     ok(r == ERROR_UNKNOWN_PROPERTY,
6218        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6219     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6220     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6221
6222     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6224
6225     /* Publisher value exists */
6226     sz = MAX_PATH;
6227     lstrcpyA(buf, "apple");
6228     r = pMsiGetProductInfoExA(prodcode, NULL,
6229                               MSIINSTALLCONTEXT_MACHINE,
6230                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6231     ok(r == ERROR_UNKNOWN_PROPERTY,
6232        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6233     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6234     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6235
6236     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6238
6239     /* URLInfoAbout value exists */
6240     sz = MAX_PATH;
6241     lstrcpyA(buf, "apple");
6242     r = pMsiGetProductInfoExA(prodcode, NULL,
6243                               MSIINSTALLCONTEXT_MACHINE,
6244                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6245     ok(r == ERROR_UNKNOWN_PROPERTY,
6246        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6247     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6248     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6249
6250     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6252
6253     /* URLUpdateInfo value exists */
6254     sz = MAX_PATH;
6255     lstrcpyA(buf, "apple");
6256     r = pMsiGetProductInfoExA(prodcode, NULL,
6257                               MSIINSTALLCONTEXT_MACHINE,
6258                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6259     ok(r == ERROR_UNKNOWN_PROPERTY,
6260        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6261     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6262     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6263
6264     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6266
6267     /* VersionMinor value exists */
6268     sz = MAX_PATH;
6269     lstrcpyA(buf, "apple");
6270     r = pMsiGetProductInfoExA(prodcode, NULL,
6271                               MSIINSTALLCONTEXT_MACHINE,
6272                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6273     ok(r == ERROR_UNKNOWN_PROPERTY,
6274        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6275     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6276     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6277
6278     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6280
6281     /* VersionMajor value exists */
6282     sz = MAX_PATH;
6283     lstrcpyA(buf, "apple");
6284     r = pMsiGetProductInfoExA(prodcode, NULL,
6285                               MSIINSTALLCONTEXT_MACHINE,
6286                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6287     ok(r == ERROR_UNKNOWN_PROPERTY,
6288        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6289     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6290     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6291
6292     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6294
6295     /* DisplayVersion value exists */
6296     sz = MAX_PATH;
6297     lstrcpyA(buf, "apple");
6298     r = pMsiGetProductInfoExA(prodcode, NULL,
6299                               MSIINSTALLCONTEXT_MACHINE,
6300                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6301     ok(r == ERROR_UNKNOWN_PROPERTY,
6302        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6303     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6304     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6305
6306     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6308
6309     /* ProductID value exists */
6310     sz = MAX_PATH;
6311     lstrcpyA(buf, "apple");
6312     r = pMsiGetProductInfoExA(prodcode, NULL,
6313                               MSIINSTALLCONTEXT_MACHINE,
6314                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6315     ok(r == ERROR_UNKNOWN_PROPERTY,
6316        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6317     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6318     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6319
6320     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6322
6323     /* RegCompany value exists */
6324     sz = MAX_PATH;
6325     lstrcpyA(buf, "apple");
6326     r = pMsiGetProductInfoExA(prodcode, NULL,
6327                               MSIINSTALLCONTEXT_MACHINE,
6328                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6329     ok(r == ERROR_UNKNOWN_PROPERTY,
6330        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6331     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6332     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6333
6334     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6336
6337     /* RegOwner value exists */
6338     sz = MAX_PATH;
6339     lstrcpyA(buf, "apple");
6340     r = pMsiGetProductInfoExA(prodcode, NULL,
6341                               MSIINSTALLCONTEXT_MACHINE,
6342                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6343     ok(r == ERROR_UNKNOWN_PROPERTY,
6344        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6345     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6346     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6347
6348     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6350
6351     /* Transforms value exists */
6352     sz = MAX_PATH;
6353     lstrcpyA(buf, "apple");
6354     r = pMsiGetProductInfoExA(prodcode, NULL,
6355                               MSIINSTALLCONTEXT_MACHINE,
6356                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6358     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6359     ok(sz == 5, "Expected 5, got %d\n", sz);
6360
6361     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6363
6364     /* Language value exists */
6365     sz = MAX_PATH;
6366     lstrcpyA(buf, "apple");
6367     r = pMsiGetProductInfoExA(prodcode, NULL,
6368                               MSIINSTALLCONTEXT_MACHINE,
6369                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6371     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6372     ok(sz == 4, "Expected 4, got %d\n", sz);
6373
6374     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6376
6377     /* ProductName value exists */
6378     sz = MAX_PATH;
6379     lstrcpyA(buf, "apple");
6380     r = pMsiGetProductInfoExA(prodcode, NULL,
6381                               MSIINSTALLCONTEXT_MACHINE,
6382                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6384     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6385     ok(sz == 4, "Expected 4, got %d\n", sz);
6386
6387     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6389
6390     /* FIXME */
6391
6392     /* AssignmentType value exists */
6393     sz = MAX_PATH;
6394     lstrcpyA(buf, "apple");
6395     r = pMsiGetProductInfoExA(prodcode, NULL,
6396                               MSIINSTALLCONTEXT_MACHINE,
6397                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6398     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6399     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6400     ok(sz == 0, "Expected 0, got %d\n", sz);
6401
6402     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6404
6405     /* FIXME */
6406
6407     /* PackageCode value exists */
6408     sz = MAX_PATH;
6409     lstrcpyA(buf, "apple");
6410     r = pMsiGetProductInfoExA(prodcode, NULL,
6411                               MSIINSTALLCONTEXT_MACHINE,
6412                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6413     todo_wine
6414     {
6415         ok(r == ERROR_BAD_CONFIGURATION,
6416            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6417         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6418         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6419     }
6420
6421     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6423
6424     /* Version value exists */
6425     sz = MAX_PATH;
6426     lstrcpyA(buf, "apple");
6427     r = pMsiGetProductInfoExA(prodcode, NULL,
6428                               MSIINSTALLCONTEXT_MACHINE,
6429                               INSTALLPROPERTY_VERSION, buf, &sz);
6430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6431     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6432     ok(sz == 3, "Expected 3, got %d\n", sz);
6433
6434     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6436
6437     /* ProductIcon value exists */
6438     sz = MAX_PATH;
6439     lstrcpyA(buf, "apple");
6440     r = pMsiGetProductInfoExA(prodcode, NULL,
6441                               MSIINSTALLCONTEXT_MACHINE,
6442                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6444     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6445     ok(sz == 4, "Expected 4, got %d\n", sz);
6446
6447     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6449
6450     /* PackageName value exists */
6451     sz = MAX_PATH;
6452     lstrcpyA(buf, "apple");
6453     r = pMsiGetProductInfoExA(prodcode, NULL,
6454                               MSIINSTALLCONTEXT_MACHINE,
6455                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6456     todo_wine
6457     {
6458         ok(r == ERROR_UNKNOWN_PRODUCT,
6459            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6460         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6461         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6462     }
6463
6464     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6465     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6466
6467     /* AuthorizedLUAApp value exists */
6468     sz = MAX_PATH;
6469     lstrcpyA(buf, "apple");
6470     r = pMsiGetProductInfoExA(prodcode, NULL,
6471                               MSIINSTALLCONTEXT_MACHINE,
6472                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6474     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6475     ok(sz == 4, "Expected 4, got %d\n", sz);
6476
6477     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6478     RegDeleteValueA(prodkey, "PackageName");
6479     RegDeleteValueA(prodkey, "ProductIcon");
6480     RegDeleteValueA(prodkey, "Version");
6481     RegDeleteValueA(prodkey, "PackageCode");
6482     RegDeleteValueA(prodkey, "AssignmentType");
6483     RegDeleteValueA(prodkey, "ProductName");
6484     RegDeleteValueA(prodkey, "Language");
6485     RegDeleteValueA(prodkey, "Transforms");
6486     RegDeleteValueA(prodkey, "RegOwner");
6487     RegDeleteValueA(prodkey, "RegCompany");
6488     RegDeleteValueA(prodkey, "ProductID");
6489     RegDeleteValueA(prodkey, "DisplayVersion");
6490     RegDeleteValueA(prodkey, "VersionMajor");
6491     RegDeleteValueA(prodkey, "VersionMinor");
6492     RegDeleteValueA(prodkey, "URLUpdateInfo");
6493     RegDeleteValueA(prodkey, "URLInfoAbout");
6494     RegDeleteValueA(prodkey, "Publisher");
6495     RegDeleteValueA(prodkey, "LocalPackage");
6496     RegDeleteValueA(prodkey, "InstallSource");
6497     RegDeleteValueA(prodkey, "InstallLocation");
6498     RegDeleteValueA(prodkey, "DisplayName");
6499     RegDeleteValueA(prodkey, "InstallDate");
6500     RegDeleteValueA(prodkey, "HelpTelephone");
6501     RegDeleteValueA(prodkey, "HelpLink");
6502     RegDeleteKeyA(prodkey, "");
6503     RegCloseKey(prodkey);
6504 }
6505
6506 #define INIT_USERINFO() \
6507     lstrcpyA(user, "apple"); \
6508     lstrcpyA(org, "orange"); \
6509     lstrcpyA(serial, "banana"); \
6510     usersz = orgsz = serialsz = MAX_PATH;
6511
6512 static void test_MsiGetUserInfo(void)
6513 {
6514     USERINFOSTATE state;
6515     CHAR user[MAX_PATH];
6516     CHAR org[MAX_PATH];
6517     CHAR serial[MAX_PATH];
6518     DWORD usersz, orgsz, serialsz;
6519     CHAR keypath[MAX_PATH * 2];
6520     CHAR prodcode[MAX_PATH];
6521     CHAR prod_squashed[MAX_PATH];
6522     HKEY prodkey, userprod, props;
6523     LPSTR usersid;
6524     LONG res;
6525
6526     create_test_guid(prodcode, prod_squashed);
6527     get_user_sid(&usersid);
6528
6529     /* NULL szProduct */
6530     INIT_USERINFO();
6531     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6532     ok(state == USERINFOSTATE_INVALIDARG,
6533        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6534     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6535     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6536     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6537     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6538     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6539     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6540
6541     /* empty szProductCode */
6542     INIT_USERINFO();
6543     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6544     ok(state == USERINFOSTATE_INVALIDARG,
6545        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6546     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6547     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6548     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6549     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6550     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6551     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6552
6553     /* garbage szProductCode */
6554     INIT_USERINFO();
6555     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6556     ok(state == USERINFOSTATE_INVALIDARG,
6557        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6558     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6559     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6560     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6561     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6562     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6563     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6564
6565     /* guid without brackets */
6566     INIT_USERINFO();
6567     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6568                             user, &usersz, org, &orgsz, serial, &serialsz);
6569     ok(state == USERINFOSTATE_INVALIDARG,
6570        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6571     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6572     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6573     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6574     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6575     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6576     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6577
6578     /* guid with brackets */
6579     INIT_USERINFO();
6580     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6581                             user, &usersz, org, &orgsz, serial, &serialsz);
6582     ok(state == USERINFOSTATE_UNKNOWN,
6583        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6584     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6585     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6586     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6587     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6588     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6589     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6590
6591     /* NULL lpUserNameBuf */
6592     INIT_USERINFO();
6593     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6594     ok(state == USERINFOSTATE_UNKNOWN,
6595        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6596     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6597     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6598     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6599     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6600     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6601
6602     /* NULL pcchUserNameBuf */
6603     INIT_USERINFO();
6604     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6605     ok(state == USERINFOSTATE_INVALIDARG,
6606        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6607     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6608     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6609     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6610     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6611     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6612
6613     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6614     INIT_USERINFO();
6615     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6616     ok(state == USERINFOSTATE_UNKNOWN,
6617        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6618     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6619     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6620     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6621     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6622
6623     /* NULL lpOrgNameBuf */
6624     INIT_USERINFO();
6625     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6626     ok(state == USERINFOSTATE_UNKNOWN,
6627        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6628     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6629     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6630     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6631     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6632     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6633
6634     /* NULL pcchOrgNameBuf */
6635     INIT_USERINFO();
6636     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6637     ok(state == USERINFOSTATE_INVALIDARG,
6638        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6639     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6640     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6641     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6642     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6643     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6644
6645     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6646     INIT_USERINFO();
6647     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6648     ok(state == USERINFOSTATE_UNKNOWN,
6649        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6650     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6651     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6652     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6653     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6654
6655     /* NULL lpSerialBuf */
6656     INIT_USERINFO();
6657     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6658     ok(state == USERINFOSTATE_UNKNOWN,
6659        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6660     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6661     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6662     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6663     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6664     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6665
6666     /* NULL pcchSerialBuf */
6667     INIT_USERINFO();
6668     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6669     ok(state == USERINFOSTATE_INVALIDARG,
6670        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6671     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6672     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6673     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6674     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6675     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6676
6677     /* both lpSerialBuf and pcchSerialBuf NULL */
6678     INIT_USERINFO();
6679     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6680     ok(state == USERINFOSTATE_UNKNOWN,
6681        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6682     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6683     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6684     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6685     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6686
6687     /* MSIINSTALLCONTEXT_USERMANAGED */
6688
6689     /* create local system product key */
6690     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6691     lstrcatA(keypath, usersid);
6692     lstrcatA(keypath, "\\Installer\\Products\\");
6693     lstrcatA(keypath, prod_squashed);
6694
6695     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6697
6698     /* managed product key exists */
6699     INIT_USERINFO();
6700     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6701     ok(state == USERINFOSTATE_ABSENT,
6702        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6703     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6704     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6705     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6706     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6707     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6708     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6709
6710     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6711     lstrcatA(keypath, "Installer\\UserData\\");
6712     lstrcatA(keypath, usersid);
6713     lstrcatA(keypath, "\\Products\\");
6714     lstrcatA(keypath, prod_squashed);
6715
6716     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6717     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6718
6719     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6721
6722     /* InstallProperties key exists */
6723     INIT_USERINFO();
6724     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6725     ok(state == USERINFOSTATE_ABSENT,
6726        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6727     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6728     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6729     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6730     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6731     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6732     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6733
6734     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6735     INIT_USERINFO();
6736     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6737     ok(state == USERINFOSTATE_ABSENT,
6738        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6739     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6740     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6741     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6742     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6743
6744     /* RegOwner, RegCompany don't exist, out params are NULL */
6745     INIT_USERINFO();
6746     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6747     ok(state == USERINFOSTATE_ABSENT,
6748        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6749     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6750     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6751
6752     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6754
6755     /* RegOwner value exists */
6756     INIT_USERINFO();
6757     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6758     ok(state == USERINFOSTATE_ABSENT,
6759        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6760     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6761     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6762     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6763     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6764     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6765     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6766
6767     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6769
6770     /* RegCompany value exists */
6771     INIT_USERINFO();
6772     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6773     ok(state == USERINFOSTATE_ABSENT,
6774        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6775     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6776     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6777     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6778     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6779     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6780     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6781
6782     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6784
6785     /* ProductID value exists */
6786     INIT_USERINFO();
6787     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6788     ok(state == USERINFOSTATE_PRESENT,
6789        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6790     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6791     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6792     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6793     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6794     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6795     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6796
6797     /* pcchUserNameBuf is too small */
6798     INIT_USERINFO();
6799     usersz = 0;
6800     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6801     ok(state == USERINFOSTATE_MOREDATA,
6802        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6803     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6804     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6805     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6806     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6807     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6808     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6809
6810     /* pcchUserNameBuf has no room for NULL terminator */
6811     INIT_USERINFO();
6812     usersz = 5;
6813     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6814     ok(state == USERINFOSTATE_MOREDATA,
6815        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6816     todo_wine
6817     {
6818         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6819     }
6820     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6821     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6822     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6823     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6824     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6825
6826     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6827     INIT_USERINFO();
6828     usersz = 0;
6829     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6830     ok(state == USERINFOSTATE_PRESENT,
6831        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6832     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6833     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6834     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6835     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6836     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6837     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6838
6839     RegDeleteValueA(props, "ProductID");
6840     RegDeleteValueA(props, "RegCompany");
6841     RegDeleteValueA(props, "RegOwner");
6842     RegDeleteKeyA(props, "");
6843     RegCloseKey(props);
6844     RegDeleteKeyA(userprod, "");
6845     RegCloseKey(userprod);
6846     RegDeleteKeyA(prodkey, "");
6847     RegCloseKey(prodkey);
6848
6849     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6850
6851     /* create local system product key */
6852     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6853     lstrcatA(keypath, prod_squashed);
6854
6855     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6856     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6857
6858     /* product key exists */
6859     INIT_USERINFO();
6860     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6861     ok(state == USERINFOSTATE_ABSENT,
6862        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6863     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6864     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6865     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6866     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6867     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6868     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6869
6870     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6871     lstrcatA(keypath, "Installer\\UserData\\");
6872     lstrcatA(keypath, usersid);
6873     lstrcatA(keypath, "\\Products\\");
6874     lstrcatA(keypath, prod_squashed);
6875
6876     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6878
6879     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6880     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6881
6882     /* InstallProperties key exists */
6883     INIT_USERINFO();
6884     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6885     ok(state == USERINFOSTATE_ABSENT,
6886        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6887     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6888     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6889     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6890     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6891     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6892     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6893
6894     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6895     INIT_USERINFO();
6896     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6897     ok(state == USERINFOSTATE_ABSENT,
6898        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6899     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6900     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6901     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6902     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6903
6904     /* RegOwner, RegCompany don't exist, out params are NULL */
6905     INIT_USERINFO();
6906     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6907     ok(state == USERINFOSTATE_ABSENT,
6908        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6909     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6910     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6911
6912     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6914
6915     /* RegOwner value exists */
6916     INIT_USERINFO();
6917     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6918     ok(state == USERINFOSTATE_ABSENT,
6919        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6920     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6921     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6922     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6923     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6924     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6925     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6926
6927     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6929
6930     /* RegCompany value exists */
6931     INIT_USERINFO();
6932     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6933     ok(state == USERINFOSTATE_ABSENT,
6934        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6935     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6936     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6937     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6938     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6939     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6940     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6941
6942     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6944
6945     /* ProductID value exists */
6946     INIT_USERINFO();
6947     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6948     ok(state == USERINFOSTATE_PRESENT,
6949        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6950     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6951     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6952     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6953     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6954     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6955     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6956
6957     RegDeleteValueA(props, "ProductID");
6958     RegDeleteValueA(props, "RegCompany");
6959     RegDeleteValueA(props, "RegOwner");
6960     RegDeleteKeyA(props, "");
6961     RegCloseKey(props);
6962     RegDeleteKeyA(userprod, "");
6963     RegCloseKey(userprod);
6964     RegDeleteKeyA(prodkey, "");
6965     RegCloseKey(prodkey);
6966
6967     /* MSIINSTALLCONTEXT_MACHINE */
6968
6969     /* create local system product key */
6970     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6971     lstrcatA(keypath, prod_squashed);
6972
6973     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6975
6976     /* product key exists */
6977     INIT_USERINFO();
6978     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6979     ok(state == USERINFOSTATE_ABSENT,
6980        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6981     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6982     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6983     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6984     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6985     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6986     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6987
6988     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6989     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
6990     lstrcatA(keypath, "\\Products\\");
6991     lstrcatA(keypath, prod_squashed);
6992
6993     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6995
6996     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6998
6999     /* InstallProperties key exists */
7000     INIT_USERINFO();
7001     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7002     ok(state == USERINFOSTATE_ABSENT,
7003        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7004     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7005     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7006     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7007     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7008     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7009     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7010
7011     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7012     INIT_USERINFO();
7013     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7014     ok(state == USERINFOSTATE_ABSENT,
7015        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7016     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7017     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7018     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7019     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7020
7021     /* RegOwner, RegCompany don't exist, out params are NULL */
7022     INIT_USERINFO();
7023     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7024     ok(state == USERINFOSTATE_ABSENT,
7025        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7026     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7027     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7028
7029     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7030     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7031
7032     /* RegOwner value exists */
7033     INIT_USERINFO();
7034     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7035     ok(state == USERINFOSTATE_ABSENT,
7036        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7037     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7038     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7039     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7040     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7041     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7042     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7043
7044     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7046
7047     /* RegCompany value exists */
7048     INIT_USERINFO();
7049     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7050     ok(state == USERINFOSTATE_ABSENT,
7051        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7052     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7053     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7054     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7055     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7056     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7057     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7058
7059     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7061
7062     /* ProductID value exists */
7063     INIT_USERINFO();
7064     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7065     ok(state == USERINFOSTATE_PRESENT,
7066        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7067     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7068     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7069     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7070     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7071     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7072     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7073
7074     RegDeleteValueA(props, "ProductID");
7075     RegDeleteValueA(props, "RegCompany");
7076     RegDeleteValueA(props, "RegOwner");
7077     RegDeleteKeyA(props, "");
7078     RegCloseKey(props);
7079     RegDeleteKeyA(userprod, "");
7080     RegCloseKey(userprod);
7081     RegDeleteKeyA(prodkey, "");
7082     RegCloseKey(prodkey);
7083 }
7084
7085 static void test_MsiOpenProduct(void)
7086 {
7087     MSIHANDLE hprod, hdb;
7088     CHAR val[MAX_PATH];
7089     CHAR path[MAX_PATH];
7090     CHAR keypath[MAX_PATH*2];
7091     CHAR prodcode[MAX_PATH];
7092     CHAR prod_squashed[MAX_PATH];
7093     HKEY prodkey, userkey, props;
7094     LPSTR usersid;
7095     DWORD size;
7096     LONG res;
7097     UINT r;
7098
7099     GetCurrentDirectoryA(MAX_PATH, path);
7100     lstrcatA(path, "\\");
7101
7102     create_test_guid(prodcode, prod_squashed);
7103     get_user_sid(&usersid);
7104
7105     hdb = create_package_db(prodcode);
7106     MsiCloseHandle(hdb);
7107
7108     /* NULL szProduct */
7109     hprod = 0xdeadbeef;
7110     r = MsiOpenProductA(NULL, &hprod);
7111     ok(r == ERROR_INVALID_PARAMETER,
7112        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7113     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7114
7115     /* empty szProduct */
7116     hprod = 0xdeadbeef;
7117     r = MsiOpenProductA("", &hprod);
7118     ok(r == ERROR_INVALID_PARAMETER,
7119        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7120     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7121
7122     /* garbage szProduct */
7123     hprod = 0xdeadbeef;
7124     r = MsiOpenProductA("garbage", &hprod);
7125     ok(r == ERROR_INVALID_PARAMETER,
7126        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7127     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7128
7129     /* guid without brackets */
7130     hprod = 0xdeadbeef;
7131     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7132     ok(r == ERROR_INVALID_PARAMETER,
7133        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7134     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7135
7136     /* guid with brackets */
7137     hprod = 0xdeadbeef;
7138     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7139     ok(r == ERROR_UNKNOWN_PRODUCT,
7140        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7141     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7142
7143     /* same length as guid, but random */
7144     hprod = 0xdeadbeef;
7145     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7146     ok(r == ERROR_INVALID_PARAMETER,
7147        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7148     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7149
7150     /* hProduct is NULL */
7151     hprod = 0xdeadbeef;
7152     r = MsiOpenProductA(prodcode, NULL);
7153     ok(r == ERROR_INVALID_PARAMETER,
7154        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7155     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7156
7157     /* MSIINSTALLCONTEXT_USERMANAGED */
7158
7159     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7160     lstrcatA(keypath, "Installer\\Managed\\");
7161     lstrcatA(keypath, usersid);
7162     lstrcatA(keypath, "\\Installer\\Products\\");
7163     lstrcatA(keypath, prod_squashed);
7164
7165     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7166     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7167
7168     /* managed product key exists */
7169     hprod = 0xdeadbeef;
7170     r = MsiOpenProductA(prodcode, &hprod);
7171     ok(r == ERROR_UNKNOWN_PRODUCT,
7172        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7173     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7174
7175     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7176     lstrcatA(keypath, "Installer\\UserData\\");
7177     lstrcatA(keypath, usersid);
7178     lstrcatA(keypath, "\\Products\\");
7179     lstrcatA(keypath, prod_squashed);
7180
7181     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7183
7184     /* user product key exists */
7185     hprod = 0xdeadbeef;
7186     r = MsiOpenProductA(prodcode, &hprod);
7187     ok(r == ERROR_UNKNOWN_PRODUCT,
7188        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7189     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7190
7191     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7193
7194     /* InstallProperties key exists */
7195     hprod = 0xdeadbeef;
7196     r = MsiOpenProductA(prodcode, &hprod);
7197     ok(r == ERROR_UNKNOWN_PRODUCT,
7198        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7199     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7200
7201     lstrcpyA(val, path);
7202     lstrcatA(val, "\\winetest.msi");
7203     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7204                          (const BYTE *)val, lstrlenA(val) + 1);
7205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7206
7207     /* ManagedLocalPackage value exists */
7208     hprod = 0xdeadbeef;
7209     r = MsiOpenProductA(prodcode, &hprod);
7210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7211     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7212
7213     size = MAX_PATH;
7214     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7216     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7217     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7218
7219     MsiCloseHandle(hprod);
7220
7221     RegDeleteValueA(props, "ManagedLocalPackage");
7222     RegDeleteKeyA(props, "");
7223     RegCloseKey(props);
7224     RegDeleteKeyA(userkey, "");
7225     RegCloseKey(userkey);
7226     RegDeleteKeyA(prodkey, "");
7227     RegCloseKey(prodkey);
7228
7229     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7230
7231     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7232     lstrcatA(keypath, prod_squashed);
7233
7234     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7236
7237     /* unmanaged product key exists */
7238     hprod = 0xdeadbeef;
7239     r = MsiOpenProductA(prodcode, &hprod);
7240     ok(r == ERROR_UNKNOWN_PRODUCT,
7241        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7242     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7243
7244     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7245     lstrcatA(keypath, "Installer\\UserData\\");
7246     lstrcatA(keypath, usersid);
7247     lstrcatA(keypath, "\\Products\\");
7248     lstrcatA(keypath, prod_squashed);
7249
7250     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7252
7253     /* user product key exists */
7254     hprod = 0xdeadbeef;
7255     r = MsiOpenProductA(prodcode, &hprod);
7256     ok(r == ERROR_UNKNOWN_PRODUCT,
7257        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7258     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7259
7260     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7262
7263     /* InstallProperties key exists */
7264     hprod = 0xdeadbeef;
7265     r = MsiOpenProductA(prodcode, &hprod);
7266     ok(r == ERROR_UNKNOWN_PRODUCT,
7267        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7268     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7269
7270     lstrcpyA(val, path);
7271     lstrcatA(val, "\\winetest.msi");
7272     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7273                          (const BYTE *)val, lstrlenA(val) + 1);
7274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7275
7276     /* LocalPackage value exists */
7277     hprod = 0xdeadbeef;
7278     r = MsiOpenProductA(prodcode, &hprod);
7279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7280     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7281
7282     size = MAX_PATH;
7283     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7284     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7285     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7286     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7287
7288     MsiCloseHandle(hprod);
7289
7290     RegDeleteValueA(props, "LocalPackage");
7291     RegDeleteKeyA(props, "");
7292     RegCloseKey(props);
7293     RegDeleteKeyA(userkey, "");
7294     RegCloseKey(userkey);
7295     RegDeleteKeyA(prodkey, "");
7296     RegCloseKey(prodkey);
7297
7298     /* MSIINSTALLCONTEXT_MACHINE */
7299
7300     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7301     lstrcatA(keypath, prod_squashed);
7302
7303     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7305
7306     /* managed product key exists */
7307     hprod = 0xdeadbeef;
7308     r = MsiOpenProductA(prodcode, &hprod);
7309     ok(r == ERROR_UNKNOWN_PRODUCT,
7310        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7311     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7312
7313     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7314     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7315     lstrcatA(keypath, prod_squashed);
7316
7317     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7319
7320     /* user product key exists */
7321     hprod = 0xdeadbeef;
7322     r = MsiOpenProductA(prodcode, &hprod);
7323     ok(r == ERROR_UNKNOWN_PRODUCT,
7324        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7325     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7326
7327     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7329
7330     /* InstallProperties key exists */
7331     hprod = 0xdeadbeef;
7332     r = MsiOpenProductA(prodcode, &hprod);
7333     ok(r == ERROR_UNKNOWN_PRODUCT,
7334        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7335     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7336
7337     lstrcpyA(val, path);
7338     lstrcatA(val, "\\winetest.msi");
7339     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7340                          (const BYTE *)val, lstrlenA(val) + 1);
7341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7342
7343     /* LocalPackage value exists */
7344     hprod = 0xdeadbeef;
7345     r = MsiOpenProductA(prodcode, &hprod);
7346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7347     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7348
7349     size = MAX_PATH;
7350     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7351     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7352     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7353     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7354
7355     MsiCloseHandle(hprod);
7356
7357     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7358                          (const BYTE *)"winetest.msi", 13);
7359     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7360
7361     /* LocalPackage has just the package name */
7362     hprod = 0xdeadbeef;
7363     r = MsiOpenProductA(prodcode, &hprod);
7364     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED,
7365        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED, got %d\n", r);
7366     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7367
7368     lstrcpyA(val, path);
7369     lstrcatA(val, "\\winetest.msi");
7370     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7371                          (const BYTE *)val, lstrlenA(val) + 1);
7372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7373
7374     DeleteFileA(msifile);
7375
7376     /* local package does not exist */
7377     hprod = 0xdeadbeef;
7378     r = MsiOpenProductA(prodcode, &hprod);
7379     ok(r == ERROR_UNKNOWN_PRODUCT,
7380        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7381     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7382
7383     RegDeleteValueA(props, "LocalPackage");
7384     RegDeleteKeyA(props, "");
7385     RegCloseKey(props);
7386     RegDeleteKeyA(userkey, "");
7387     RegCloseKey(userkey);
7388     RegDeleteKeyA(prodkey, "");
7389     RegCloseKey(prodkey);
7390
7391     DeleteFileA(msifile);
7392 }
7393
7394 START_TEST(msi)
7395 {
7396     init_functionpointers();
7397
7398     test_usefeature();
7399     test_null();
7400     test_getcomponentpath();
7401     test_MsiGetFileHash();
7402
7403     if (!pConvertSidToStringSidA)
7404         skip("ConvertSidToStringSidA not implemented\n");
7405     else
7406     {
7407         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
7408         test_MsiQueryProductState();
7409         test_MsiQueryFeatureState();
7410         test_MsiQueryComponentState();
7411         test_MsiGetComponentPath();
7412         test_MsiGetProductCode();
7413         test_MsiEnumClients();
7414         test_MsiGetProductInfo();
7415         test_MsiGetProductInfoEx();
7416         test_MsiGetUserInfo();
7417         test_MsiOpenProduct();
7418     }
7419
7420     test_MsiGetFileVersion();
7421 }