[MSI_WINETEST]
[reactos.git] / rostests / winetests / msi / msi.c
1 /*
2 * tests for Microsoft Installer functionality
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static BOOL is_wow64;
33 static const char msifile[] = "winetest.msi";
34
35 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
36 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
37 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
38
39 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
40 (LPCSTR, LPCSTR, LPSTR, DWORD*);
41 static UINT (WINAPI *pMsiGetFileHashA)
42 (LPCSTR, DWORD, PMSIFILEHASHINFO);
43 static UINT (WINAPI *pMsiGetProductInfoExA)
44 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
45 static UINT (WINAPI *pMsiOpenPackageExA)
46 (LPCSTR, DWORD, MSIHANDLE*);
47 static UINT (WINAPI *pMsiOpenPackageExW)
48 (LPCWSTR, DWORD, MSIHANDLE*);
49 static UINT (WINAPI *pMsiEnumPatchesExA)
50 (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
51 MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
52 static UINT (WINAPI *pMsiQueryComponentStateA)
53 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
54 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
55 (LPCSTR, LPCSTR ,DWORD, DWORD);
56 static UINT (WINAPI *pMsiGetPatchInfoExA)
57 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
58 static UINT (WINAPI *pMsiEnumProductsExA)
59 (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
60 static UINT (WINAPI *pMsiEnumComponentsExA)
61 (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
62
63 static void init_functionpointers(void)
64 {
65 HMODULE hmsi = GetModuleHandleA("msi.dll");
66 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
67 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
68
69 #define GET_PROC(dll, func) \
70 p ## func = (void *)GetProcAddress(dll, #func); \
71 if(!p ## func) \
72 trace("GetProcAddress(%s) failed\n", #func);
73
74 GET_PROC(hmsi, MsiGetComponentPathA)
75 GET_PROC(hmsi, MsiGetFileHashA)
76 GET_PROC(hmsi, MsiGetProductInfoExA)
77 GET_PROC(hmsi, MsiOpenPackageExA)
78 GET_PROC(hmsi, MsiOpenPackageExW)
79 GET_PROC(hmsi, MsiEnumPatchesExA)
80 GET_PROC(hmsi, MsiQueryComponentStateA)
81 GET_PROC(hmsi, MsiUseFeatureExA)
82 GET_PROC(hmsi, MsiGetPatchInfoExA)
83 GET_PROC(hmsi, MsiEnumProductsExA)
84 GET_PROC(hmsi, MsiEnumComponentsExA)
85
86 GET_PROC(hadvapi32, ConvertSidToStringSidA)
87 GET_PROC(hadvapi32, RegDeleteKeyExA)
88 GET_PROC(hkernel32, IsWow64Process)
89
90 #undef GET_PROC
91 }
92
93 static UINT run_query(MSIHANDLE hdb, const char *query)
94 {
95 MSIHANDLE hview = 0;
96 UINT r;
97
98 r = MsiDatabaseOpenView(hdb, query, &hview);
99 if (r != ERROR_SUCCESS)
100 return r;
101
102 r = MsiViewExecute(hview, 0);
103 if (r == ERROR_SUCCESS)
104 r = MsiViewClose(hview);
105 MsiCloseHandle(hview);
106 return r;
107 }
108
109 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
110 {
111 UINT res;
112 MSIHANDLE suminfo;
113
114 /* build summary info */
115 res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
116 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
117
118 res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
119 "Installation Database");
120 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
121
122 res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
123 "Installation Database");
124 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
125
126 res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
127 "Wine Hackers");
128 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
129
130 res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
131 ";1033");
132 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
133
134 res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
135 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
136 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
137
138 res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
139 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
140
141 res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
142 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
143
144 res = MsiSummaryInfoPersist(suminfo);
145 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
146
147 res = MsiCloseHandle(suminfo);
148 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
149
150 return res;
151 }
152
153 static MSIHANDLE create_package_db(LPSTR prodcode)
154 {
155 MSIHANDLE hdb = 0;
156 CHAR query[MAX_PATH];
157 UINT res;
158
159 DeleteFile(msifile);
160
161 /* create an empty database */
162 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
163 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
164 if (res != ERROR_SUCCESS)
165 return hdb;
166
167 res = MsiDatabaseCommit(hdb);
168 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
169
170 set_summary_info(hdb, prodcode);
171
172 res = run_query(hdb,
173 "CREATE TABLE `Directory` ( "
174 "`Directory` CHAR(255) NOT NULL, "
175 "`Directory_Parent` CHAR(255), "
176 "`DefaultDir` CHAR(255) NOT NULL "
177 "PRIMARY KEY `Directory`)");
178 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
179
180 res = run_query(hdb,
181 "CREATE TABLE `Property` ( "
182 "`Property` CHAR(72) NOT NULL, "
183 "`Value` CHAR(255) "
184 "PRIMARY KEY `Property`)");
185 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
186
187 sprintf(query, "INSERT INTO `Property` "
188 "(`Property`, `Value`) "
189 "VALUES( 'ProductCode', '%s' )", prodcode);
190 res = run_query(hdb, query);
191 ok(res == ERROR_SUCCESS , "Failed\n");
192
193 res = MsiDatabaseCommit(hdb);
194 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
195
196 return hdb;
197 }
198
199 static void test_usefeature(void)
200 {
201 INSTALLSTATE r;
202
203 if (!pMsiUseFeatureExA)
204 {
205 win_skip("MsiUseFeatureExA not implemented\n");
206 return;
207 }
208
209 r = MsiQueryFeatureState(NULL,NULL);
210 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
211
212 r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
213 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
214
215 r = pMsiUseFeatureExA(NULL,NULL,0,0);
216 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
217
218 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
219 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
220
221 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
222 NULL, -2, 0 );
223 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
224
225 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
226 "WORDVIEWFiles", -2, 0 );
227 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
228
229 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
230 "WORDVIEWFiles", -2, 0 );
231 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
232
233 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
234 "WORDVIEWFiles", -2, 1 );
235 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
236 }
237
238 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
239 {
240 if (pRegDeleteKeyExA)
241 return pRegDeleteKeyExA( key, subkey, access, 0 );
242 return RegDeleteKeyA( key, subkey );
243 }
244
245 static void test_null(void)
246 {
247 MSIHANDLE hpkg;
248 UINT r;
249 HKEY hkey;
250 DWORD dwType, cbData;
251 LPBYTE lpData = NULL;
252 INSTALLSTATE state;
253 REGSAM access = KEY_ALL_ACCESS;
254
255 if (is_wow64)
256 access |= KEY_WOW64_64KEY;
257
258 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
259 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
260
261 state = MsiQueryProductStateW(NULL);
262 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
263
264 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
265 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
266
267 r = MsiConfigureFeatureW(NULL, NULL, 0);
268 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
269
270 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
271 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
272
273 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
274 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
275
276 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
277 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
278
279 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
280 * necessary registry values */
281
282 /* empty product string */
283 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
284 if (r == ERROR_ACCESS_DENIED)
285 {
286 skip("Not enough rights to perform tests\n");
287 return;
288 }
289 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
290
291 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
292 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
293 if ( r == ERROR_SUCCESS )
294 {
295 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
296 if (!lpData)
297 skip("Out of memory\n");
298 else
299 {
300 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
301 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
302 }
303 }
304
305 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
306 if (r == ERROR_ACCESS_DENIED)
307 {
308 skip("Not enough rights to perform tests\n");
309 HeapFree(GetProcessHeap(), 0, lpData);
310 RegCloseKey(hkey);
311 return;
312 }
313 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
314
315 r = MsiGetProductInfoA("", "", NULL, NULL);
316 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
317
318 if (lpData)
319 {
320 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
321 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
322
323 HeapFree(GetProcessHeap(), 0, lpData);
324 }
325 else
326 {
327 r = RegDeleteValueA(hkey, NULL);
328 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
329 }
330
331 r = RegCloseKey(hkey);
332 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
333
334 /* empty attribute */
335 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
336 0, NULL, 0, access, NULL, &hkey, NULL);
337 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
338
339 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
340 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
341
342 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
343 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
344
345 r = RegCloseKey(hkey);
346 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
347
348 r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
349 access & KEY_WOW64_64KEY);
350 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
351 }
352
353 static void test_getcomponentpath(void)
354 {
355 INSTALLSTATE r;
356 char buffer[0x100];
357 DWORD sz;
358
359 if(!pMsiGetComponentPathA)
360 return;
361
362 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
363 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
364
365 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
366 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
367
368 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
369 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
370
371 sz = sizeof buffer;
372 buffer[0]=0;
373 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
374 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
375
376 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
377 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
378 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
379
380 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
381 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
382 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
383
384 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
385 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
386 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
387
388 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
389 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
390 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
391 }
392
393 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
394 {
395 HANDLE file;
396 DWORD written;
397
398 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
399 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
400 WriteFile(file, data, strlen(data), &written, NULL);
401
402 if (size)
403 {
404 SetFilePointer(file, size, NULL, FILE_BEGIN);
405 SetEndOfFile(file);
406 }
407
408 CloseHandle(file);
409 }
410
411 #define HASHSIZE sizeof(MSIFILEHASHINFO)
412
413 static const struct
414 {
415 LPCSTR data;
416 DWORD size;
417 MSIFILEHASHINFO hash;
418 } hash_data[] =
419 {
420 { "", 0,
421 { HASHSIZE,
422 { 0, 0, 0, 0 },
423 },
424 },
425
426 { "abc", 0,
427 { HASHSIZE,
428 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
429 },
430 },
431
432 { "C:\\Program Files\\msitest\\caesar\n", 0,
433 { HASHSIZE,
434 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
435 },
436 },
437
438 { "C:\\Program Files\\msitest\\caesar\n", 500,
439 { HASHSIZE,
440 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
441 },
442 },
443 };
444
445 static void test_MsiGetFileHash(void)
446 {
447 const char name[] = "msitest.bin";
448 UINT r;
449 MSIFILEHASHINFO hash;
450 DWORD i;
451
452 if (!pMsiGetFileHashA)
453 {
454 win_skip("MsiGetFileHash not implemented\n");
455 return;
456 }
457
458 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
459
460 /* szFilePath is NULL */
461 r = pMsiGetFileHashA(NULL, 0, &hash);
462 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
463
464 /* szFilePath is empty */
465 r = pMsiGetFileHashA("", 0, &hash);
466 ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
467 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
468
469 /* szFilePath is nonexistent */
470 r = pMsiGetFileHashA(name, 0, &hash);
471 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
472
473 /* dwOptions is non-zero */
474 r = pMsiGetFileHashA(name, 1, &hash);
475 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
476
477 /* pHash.dwFileHashInfoSize is not correct */
478 hash.dwFileHashInfoSize = 0;
479 r = pMsiGetFileHashA(name, 0, &hash);
480 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
481
482 /* pHash is NULL */
483 r = pMsiGetFileHashA(name, 0, NULL);
484 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
485
486 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
487 {
488 int ret;
489
490 create_file(name, hash_data[i].data, hash_data[i].size);
491
492 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
493 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
494
495 r = pMsiGetFileHashA(name, 0, &hash);
496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
497
498 ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
499 ok(!ret, "Hash incorrect\n");
500
501 DeleteFile(name);
502 }
503 }
504
505 /* copied from dlls/msi/registry.c */
506 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
507 {
508 DWORD i,n=1;
509 GUID guid;
510
511 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
512 return FALSE;
513
514 for(i=0; i<8; i++)
515 out[7-i] = in[n++];
516 n++;
517 for(i=0; i<4; i++)
518 out[11-i] = in[n++];
519 n++;
520 for(i=0; i<4; i++)
521 out[15-i] = in[n++];
522 n++;
523 for(i=0; i<2; i++)
524 {
525 out[17+i*2] = in[n++];
526 out[16+i*2] = in[n++];
527 }
528 n++;
529 for( ; i<8; i++)
530 {
531 out[17+i*2] = in[n++];
532 out[16+i*2] = in[n++];
533 }
534 out[32]=0;
535 return TRUE;
536 }
537
538 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
539 {
540 WCHAR guidW[MAX_PATH];
541 WCHAR squashedW[MAX_PATH];
542 GUID guid;
543 HRESULT hr;
544 int size;
545
546 hr = CoCreateGuid(&guid);
547 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
548
549 size = StringFromGUID2(&guid, guidW, MAX_PATH);
550 ok(size == 39, "Expected 39, got %d\n", hr);
551
552 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
553 if (squashed)
554 {
555 squash_guid(guidW, squashedW);
556 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
557 }
558 }
559
560 static char *get_user_sid(void)
561 {
562 HANDLE token;
563 DWORD size = 0;
564 TOKEN_USER *user;
565 char *usersid = NULL;
566
567 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
568 GetTokenInformation(token, TokenUser, NULL, size, &size);
569
570 user = HeapAlloc(GetProcessHeap(), 0, size);
571 GetTokenInformation(token, TokenUser, user, size, &size);
572 pConvertSidToStringSidA(user->User.Sid, &usersid);
573 HeapFree(GetProcessHeap(), 0, user);
574
575 CloseHandle(token);
576 return usersid;
577 }
578
579 static void test_MsiQueryProductState(void)
580 {
581 CHAR prodcode[MAX_PATH];
582 CHAR prod_squashed[MAX_PATH];
583 CHAR keypath[MAX_PATH*2];
584 LPSTR usersid;
585 INSTALLSTATE state;
586 LONG res;
587 HKEY userkey, localkey, props;
588 HKEY prodkey;
589 DWORD data, error;
590 REGSAM access = KEY_ALL_ACCESS;
591
592 create_test_guid(prodcode, prod_squashed);
593 usersid = get_user_sid();
594
595 if (is_wow64)
596 access |= KEY_WOW64_64KEY;
597
598 /* NULL prodcode */
599 SetLastError(0xdeadbeef);
600 state = MsiQueryProductStateA(NULL);
601 error = GetLastError();
602 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
603 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
604
605 /* empty prodcode */
606 SetLastError(0xdeadbeef);
607 state = MsiQueryProductStateA("");
608 error = GetLastError();
609 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
610 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
611
612 /* garbage prodcode */
613 SetLastError(0xdeadbeef);
614 state = MsiQueryProductStateA("garbage");
615 error = GetLastError();
616 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
617 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
618
619 /* guid without brackets */
620 SetLastError(0xdeadbeef);
621 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
622 error = GetLastError();
623 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
624 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
625
626 /* guid with brackets */
627 SetLastError(0xdeadbeef);
628 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
629 error = GetLastError();
630 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
631 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
632 "expected ERROR_SUCCESS, got %u\n", error);
633
634 /* same length as guid, but random */
635 SetLastError(0xdeadbeef);
636 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
637 error = GetLastError();
638 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
639 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
640
641 /* MSIINSTALLCONTEXT_USERUNMANAGED */
642
643 SetLastError(0xdeadbeef);
644 state = MsiQueryProductStateA(prodcode);
645 error = GetLastError();
646 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
647 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
648 "expected ERROR_SUCCESS, got %u\n", error);
649
650 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
651 lstrcatA(keypath, prod_squashed);
652
653 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
654 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
655
656 /* user product key exists */
657 SetLastError(0xdeadbeef);
658 state = MsiQueryProductStateA(prodcode);
659 error = GetLastError();
660 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
661 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
662 "expected ERROR_SUCCESS, got %u\n", error);
663
664 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
665 lstrcatA(keypath, prodcode);
666
667 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
668 if (res == ERROR_ACCESS_DENIED)
669 {
670 skip("Not enough rights to perform tests\n");
671 RegDeleteKeyA(userkey, "");
672 LocalFree(usersid);
673 return;
674 }
675 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
676
677 /* local uninstall key exists */
678 SetLastError(0xdeadbeef);
679 state = MsiQueryProductStateA(prodcode);
680 error = GetLastError();
681 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
682 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
683 "expected ERROR_SUCCESS, got %u\n", error);
684
685 data = 1;
686 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
687 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
688
689 /* WindowsInstaller value exists */
690 SetLastError(0xdeadbeef);
691 state = MsiQueryProductStateA(prodcode);
692 error = GetLastError();
693 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
694 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
695 "expected ERROR_SUCCESS, got %u\n", error);
696
697 RegDeleteValueA(localkey, "WindowsInstaller");
698 delete_key(localkey, "", access & KEY_WOW64_64KEY);
699
700 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
701 lstrcatA(keypath, usersid);
702 lstrcatA(keypath, "\\Products\\");
703 lstrcatA(keypath, prod_squashed);
704
705 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
706 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
707
708 /* local product key exists */
709 SetLastError(0xdeadbeef);
710 state = MsiQueryProductStateA(prodcode);
711 error = GetLastError();
712 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
713 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
714 "expected ERROR_SUCCESS, got %u\n", error);
715
716 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
717 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
718
719 /* install properties key exists */
720 SetLastError(0xdeadbeef);
721 state = MsiQueryProductStateA(prodcode);
722 error = GetLastError();
723 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
724 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
725 "expected ERROR_SUCCESS, got %u\n", error);
726
727 data = 1;
728 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
729 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
730
731 /* WindowsInstaller value exists */
732 SetLastError(0xdeadbeef);
733 state = MsiQueryProductStateA(prodcode);
734 error = GetLastError();
735 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
736 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
737 "expected ERROR_SUCCESS, got %u\n", error);
738
739 data = 2;
740 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
741 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
742
743 /* WindowsInstaller value is not 1 */
744 SetLastError(0xdeadbeef);
745 state = MsiQueryProductStateA(prodcode);
746 error = GetLastError();
747 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
748 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
749 "expected ERROR_SUCCESS, got %u\n", error);
750
751 RegDeleteKeyA(userkey, "");
752
753 /* user product key does not exist */
754 SetLastError(0xdeadbeef);
755 state = MsiQueryProductStateA(prodcode);
756 error = GetLastError();
757 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
758 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
759 "expected ERROR_SUCCESS, got %u\n", error);
760
761 RegDeleteValueA(props, "WindowsInstaller");
762 delete_key(props, "", access & KEY_WOW64_64KEY);
763 RegCloseKey(props);
764 delete_key(localkey, "", access & KEY_WOW64_64KEY);
765 RegCloseKey(localkey);
766 RegDeleteKeyA(userkey, "");
767 RegCloseKey(userkey);
768
769 /* MSIINSTALLCONTEXT_USERMANAGED */
770
771 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
772 lstrcatA(keypath, usersid);
773 lstrcatA(keypath, "\\Installer\\Products\\");
774 lstrcatA(keypath, prod_squashed);
775
776 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
777 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
778
779 state = MsiQueryProductStateA(prodcode);
780 ok(state == INSTALLSTATE_ADVERTISED,
781 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
782
783 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
784 lstrcatA(keypath, usersid);
785 lstrcatA(keypath, "\\Products\\");
786 lstrcatA(keypath, prod_squashed);
787
788 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
789 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
790
791 state = MsiQueryProductStateA(prodcode);
792 ok(state == INSTALLSTATE_ADVERTISED,
793 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
794
795 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
796 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
797
798 state = MsiQueryProductStateA(prodcode);
799 ok(state == INSTALLSTATE_ADVERTISED,
800 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
801
802 data = 1;
803 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
804 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
805
806 /* WindowsInstaller value exists */
807 state = MsiQueryProductStateA(prodcode);
808 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
809
810 RegDeleteValueA(props, "WindowsInstaller");
811 delete_key(props, "", access & KEY_WOW64_64KEY);
812 RegCloseKey(props);
813 delete_key(localkey, "", access & KEY_WOW64_64KEY);
814 RegCloseKey(localkey);
815 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
816 RegCloseKey(prodkey);
817
818 /* MSIINSTALLCONTEXT_MACHINE */
819
820 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
821 lstrcatA(keypath, prod_squashed);
822
823 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
824 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
825
826 state = MsiQueryProductStateA(prodcode);
827 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
828
829 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
830 lstrcatA(keypath, "S-1-5-18\\Products\\");
831 lstrcatA(keypath, prod_squashed);
832
833 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
834 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
835
836 state = MsiQueryProductStateA(prodcode);
837 ok(state == INSTALLSTATE_ADVERTISED,
838 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
839
840 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
841 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
842
843 state = MsiQueryProductStateA(prodcode);
844 ok(state == INSTALLSTATE_ADVERTISED,
845 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
846
847 data = 1;
848 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
849 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
850
851 /* WindowsInstaller value exists */
852 state = MsiQueryProductStateA(prodcode);
853 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
854
855 RegDeleteValueA(props, "WindowsInstaller");
856 delete_key(props, "", access & KEY_WOW64_64KEY);
857 RegCloseKey(props);
858 delete_key(localkey, "", access & KEY_WOW64_64KEY);
859 RegCloseKey(localkey);
860 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
861 RegCloseKey(prodkey);
862
863 LocalFree(usersid);
864 }
865
866 static const char table_enc85[] =
867 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
868 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
869 "yz{}~";
870
871 /*
872 * Encodes a base85 guid given a GUID pointer
873 * Caller should provide a 21 character buffer for the encoded string.
874 */
875 static void encode_base85_guid( GUID *guid, LPWSTR str )
876 {
877 unsigned int x, *p, i;
878
879 p = (unsigned int*) guid;
880 for( i=0; i<4; i++ )
881 {
882 x = p[i];
883 *str++ = table_enc85[x%85];
884 x = x/85;
885 *str++ = table_enc85[x%85];
886 x = x/85;
887 *str++ = table_enc85[x%85];
888 x = x/85;
889 *str++ = table_enc85[x%85];
890 x = x/85;
891 *str++ = table_enc85[x%85];
892 }
893 *str = 0;
894 }
895
896 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
897 {
898 WCHAR guidW[MAX_PATH];
899 WCHAR base85W[MAX_PATH];
900 WCHAR squashedW[MAX_PATH];
901 GUID guid;
902 HRESULT hr;
903 int size;
904
905 hr = CoCreateGuid(&guid);
906 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
907
908 size = StringFromGUID2(&guid, guidW, MAX_PATH);
909 ok(size == 39, "Expected 39, got %d\n", hr);
910
911 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
912 encode_base85_guid(&guid, base85W);
913 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
914 squash_guid(guidW, squashedW);
915 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
916 }
917
918 static void test_MsiQueryFeatureState(void)
919 {
920 HKEY userkey, localkey, compkey, compkey2;
921 CHAR prodcode[MAX_PATH];
922 CHAR prod_squashed[MAX_PATH];
923 CHAR component[MAX_PATH];
924 CHAR comp_base85[MAX_PATH];
925 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
926 CHAR keypath[MAX_PATH*2];
927 INSTALLSTATE state;
928 LPSTR usersid;
929 LONG res;
930 REGSAM access = KEY_ALL_ACCESS;
931 DWORD error;
932
933 create_test_guid(prodcode, prod_squashed);
934 compose_base85_guid(component, comp_base85, comp_squashed);
935 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
936 usersid = get_user_sid();
937
938 if (is_wow64)
939 access |= KEY_WOW64_64KEY;
940
941 /* NULL prodcode */
942 SetLastError(0xdeadbeef);
943 state = MsiQueryFeatureStateA(NULL, "feature");
944 error = GetLastError();
945 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
946 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
947
948 /* empty prodcode */
949 SetLastError(0xdeadbeef);
950 state = MsiQueryFeatureStateA("", "feature");
951 error = GetLastError();
952 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
953 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
954
955 /* garbage prodcode */
956 SetLastError(0xdeadbeef);
957 state = MsiQueryFeatureStateA("garbage", "feature");
958 error = GetLastError();
959 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
960 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
961
962 /* guid without brackets */
963 SetLastError(0xdeadbeef);
964 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
965 error = GetLastError();
966 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
967 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
968
969 /* guid with brackets */
970 SetLastError(0xdeadbeef);
971 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
972 error = GetLastError();
973 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
974 ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
975 "expected ERROR_SUCCESS, got %u\n", error);
976
977 /* same length as guid, but random */
978 SetLastError(0xdeadbeef);
979 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
980 error = GetLastError();
981 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
982 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
983
984 /* NULL szFeature */
985 SetLastError(0xdeadbeef);
986 state = MsiQueryFeatureStateA(prodcode, NULL);
987 error = GetLastError();
988 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
989 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
990
991 /* empty szFeature */
992 SetLastError(0xdeadbeef);
993 state = MsiQueryFeatureStateA(prodcode, "");
994 error = GetLastError();
995 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
996 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
997 "expected ERROR_SUCCESS, got %u\n", error);
998
999 /* feature key does not exist yet */
1000 SetLastError(0xdeadbeef);
1001 state = MsiQueryFeatureStateA(prodcode, "feature");
1002 error = GetLastError();
1003 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1004 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1005 "expected ERROR_SUCCESS, got %u\n", error);
1006
1007 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1008
1009 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
1010 lstrcatA(keypath, prod_squashed);
1011
1012 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1013 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1014
1015 /* feature key exists */
1016 SetLastError(0xdeadbeef);
1017 state = MsiQueryFeatureStateA(prodcode, "feature");
1018 error = GetLastError();
1019 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1020 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1021 "expected ERROR_SUCCESS, got %u\n", error);
1022
1023 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1024 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1025
1026 /* feature value exists */
1027 SetLastError(0xdeadbeef);
1028 state = MsiQueryFeatureStateA(prodcode, "feature");
1029 error = GetLastError();
1030 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1031 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1032 "expected ERROR_SUCCESS, got %u\n", error);
1033
1034 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1035 lstrcatA(keypath, usersid);
1036 lstrcatA(keypath, "\\Products\\");
1037 lstrcatA(keypath, prod_squashed);
1038 lstrcatA(keypath, "\\Features");
1039
1040 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1041 if (res == ERROR_ACCESS_DENIED)
1042 {
1043 skip("Not enough rights to perform tests\n");
1044 RegDeleteKeyA(userkey, "");
1045 RegCloseKey(userkey);
1046 LocalFree(usersid);
1047 return;
1048 }
1049 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1050
1051 /* userdata features key exists */
1052 SetLastError(0xdeadbeef);
1053 state = MsiQueryFeatureStateA(prodcode, "feature");
1054 error = GetLastError();
1055 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1056 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1057 "expected ERROR_SUCCESS, got %u\n", error);
1058
1059 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1060 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1061
1062 SetLastError(0xdeadbeef);
1063 state = MsiQueryFeatureStateA(prodcode, "feature");
1064 error = GetLastError();
1065 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1066 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1067 "expected ERROR_SUCCESS, got %u\n", error);
1068
1069 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1070 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1071
1072 SetLastError(0xdeadbeef);
1073 state = MsiQueryFeatureStateA(prodcode, "feature");
1074 error = GetLastError();
1075 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1076 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1077 "expected ERROR_SUCCESS, got %u\n", error);
1078
1079 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1080 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082 SetLastError(0xdeadbeef);
1083 state = MsiQueryFeatureStateA(prodcode, "feature");
1084 error = GetLastError();
1085 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1086 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1087 "expected ERROR_SUCCESS, got %u\n", error);
1088
1089 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1090 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1091
1092 SetLastError(0xdeadbeef);
1093 state = MsiQueryFeatureStateA(prodcode, "feature");
1094 error = GetLastError();
1095 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1096 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1097 "expected ERROR_SUCCESS, got %u\n", error);
1098
1099 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1100 lstrcatA(keypath, usersid);
1101 lstrcatA(keypath, "\\Components\\");
1102 lstrcatA(keypath, comp_squashed);
1103
1104 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1105 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1106
1107 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1108 lstrcatA(keypath, usersid);
1109 lstrcatA(keypath, "\\Components\\");
1110 lstrcatA(keypath, comp_squashed2);
1111
1112 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1113 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1114
1115 SetLastError(0xdeadbeef);
1116 state = MsiQueryFeatureStateA(prodcode, "feature");
1117 error = GetLastError();
1118 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1119 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1120 "expected ERROR_SUCCESS, got %u\n", error);
1121
1122 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1123 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1124
1125 SetLastError(0xdeadbeef);
1126 state = MsiQueryFeatureStateA(prodcode, "feature");
1127 error = GetLastError();
1128 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1129 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1130 "expected ERROR_SUCCESS, got %u\n", error);
1131
1132 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1133 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1134
1135 SetLastError(0xdeadbeef);
1136 state = MsiQueryFeatureStateA(prodcode, "feature");
1137 error = GetLastError();
1138 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1139 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1140 "expected ERROR_SUCCESS, got %u\n", error);
1141
1142 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1143 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1144
1145 /* INSTALLSTATE_LOCAL */
1146 SetLastError(0xdeadbeef);
1147 state = MsiQueryFeatureStateA(prodcode, "feature");
1148 error = GetLastError();
1149 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1150 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1151 "expected ERROR_SUCCESS, got %u\n", error);
1152
1153 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1154 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1155
1156 /* INSTALLSTATE_SOURCE */
1157 SetLastError(0xdeadbeef);
1158 state = MsiQueryFeatureStateA(prodcode, "feature");
1159 error = GetLastError();
1160 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1161 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1162 "expected ERROR_SUCCESS, got %u\n", error);
1163
1164 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1165 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1166
1167 /* bad INSTALLSTATE_SOURCE */
1168 SetLastError(0xdeadbeef);
1169 state = MsiQueryFeatureStateA(prodcode, "feature");
1170 error = GetLastError();
1171 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1172 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1173 "expected ERROR_SUCCESS, got %u\n", error);
1174
1175 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1176 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1177
1178 /* INSTALLSTATE_SOURCE */
1179 SetLastError(0xdeadbeef);
1180 state = MsiQueryFeatureStateA(prodcode, "feature");
1181 error = GetLastError();
1182 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1183 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1184 "expected ERROR_SUCCESS, got %u\n", error);
1185
1186 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1187 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1188
1189 /* bad INSTALLSTATE_SOURCE */
1190 SetLastError(0xdeadbeef);
1191 state = MsiQueryFeatureStateA(prodcode, "feature");
1192 error = GetLastError();
1193 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1194 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1195 "expected ERROR_SUCCESS, got %u\n", error);
1196
1197 RegDeleteValueA(compkey, prod_squashed);
1198 RegDeleteValueA(compkey2, prod_squashed);
1199 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1200 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1201 RegDeleteValueA(localkey, "feature");
1202 RegDeleteValueA(userkey, "feature");
1203 RegDeleteKeyA(userkey, "");
1204 RegCloseKey(compkey);
1205 RegCloseKey(compkey2);
1206 RegCloseKey(localkey);
1207 RegCloseKey(userkey);
1208
1209 /* MSIINSTALLCONTEXT_USERMANAGED */
1210
1211 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1212 lstrcatA(keypath, usersid);
1213 lstrcatA(keypath, "\\Installer\\Features\\");
1214 lstrcatA(keypath, prod_squashed);
1215
1216 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1217 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1218
1219 /* feature key exists */
1220 state = MsiQueryFeatureStateA(prodcode, "feature");
1221 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1222
1223 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1224 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1225
1226 /* feature value exists */
1227 state = MsiQueryFeatureStateA(prodcode, "feature");
1228 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1229
1230 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1231 lstrcatA(keypath, usersid);
1232 lstrcatA(keypath, "\\Products\\");
1233 lstrcatA(keypath, prod_squashed);
1234 lstrcatA(keypath, "\\Features");
1235
1236 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1238
1239 /* userdata features key exists */
1240 state = MsiQueryFeatureStateA(prodcode, "feature");
1241 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1242
1243 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1244 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1245
1246 state = MsiQueryFeatureStateA(prodcode, "feature");
1247 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1248
1249 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1251
1252 state = MsiQueryFeatureStateA(prodcode, "feature");
1253 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1254
1255 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1256 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1257
1258 state = MsiQueryFeatureStateA(prodcode, "feature");
1259 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1260
1261 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1262 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1263
1264 state = MsiQueryFeatureStateA(prodcode, "feature");
1265 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1266
1267 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1268 lstrcatA(keypath, usersid);
1269 lstrcatA(keypath, "\\Components\\");
1270 lstrcatA(keypath, comp_squashed);
1271
1272 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1273 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1274
1275 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1276 lstrcatA(keypath, usersid);
1277 lstrcatA(keypath, "\\Components\\");
1278 lstrcatA(keypath, comp_squashed2);
1279
1280 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1282
1283 state = MsiQueryFeatureStateA(prodcode, "feature");
1284 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1285
1286 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1288
1289 state = MsiQueryFeatureStateA(prodcode, "feature");
1290 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1291
1292 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1293 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1294
1295 state = MsiQueryFeatureStateA(prodcode, "feature");
1296 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1297
1298 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1299 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1300
1301 state = MsiQueryFeatureStateA(prodcode, "feature");
1302 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1303
1304 RegDeleteValueA(compkey, prod_squashed);
1305 RegDeleteValueA(compkey2, prod_squashed);
1306 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1307 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1308 RegDeleteValueA(localkey, "feature");
1309 RegDeleteValueA(userkey, "feature");
1310 delete_key(userkey, "", access & KEY_WOW64_64KEY);
1311 RegCloseKey(compkey);
1312 RegCloseKey(compkey2);
1313 RegCloseKey(localkey);
1314 RegCloseKey(userkey);
1315
1316 /* MSIINSTALLCONTEXT_MACHINE */
1317
1318 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1319 lstrcatA(keypath, prod_squashed);
1320
1321 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1322 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1323
1324 /* feature key exists */
1325 state = MsiQueryFeatureStateA(prodcode, "feature");
1326 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1327
1328 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1330
1331 /* feature value exists */
1332 state = MsiQueryFeatureStateA(prodcode, "feature");
1333 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1334
1335 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1336 lstrcatA(keypath, "S-1-5-18\\Products\\");
1337 lstrcatA(keypath, prod_squashed);
1338 lstrcatA(keypath, "\\Features");
1339
1340 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1341 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1342
1343 /* userdata features key exists */
1344 state = MsiQueryFeatureStateA(prodcode, "feature");
1345 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1346
1347 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1349
1350 state = MsiQueryFeatureStateA(prodcode, "feature");
1351 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1352
1353 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1354 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1355
1356 state = MsiQueryFeatureStateA(prodcode, "feature");
1357 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1358
1359 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1361
1362 state = MsiQueryFeatureStateA(prodcode, "feature");
1363 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1364
1365 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1366 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1367
1368 state = MsiQueryFeatureStateA(prodcode, "feature");
1369 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1370
1371 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1372 lstrcatA(keypath, "S-1-5-18\\Components\\");
1373 lstrcatA(keypath, comp_squashed);
1374
1375 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1376 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1377
1378 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1379 lstrcatA(keypath, "S-1-5-18\\Components\\");
1380 lstrcatA(keypath, comp_squashed2);
1381
1382 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1383 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1384
1385 state = MsiQueryFeatureStateA(prodcode, "feature");
1386 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1387
1388 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1390
1391 state = MsiQueryFeatureStateA(prodcode, "feature");
1392 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1393
1394 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1395 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1396
1397 state = MsiQueryFeatureStateA(prodcode, "feature");
1398 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1399
1400 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1401 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1402
1403 state = MsiQueryFeatureStateA(prodcode, "feature");
1404 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1405
1406 RegDeleteValueA(compkey, prod_squashed);
1407 RegDeleteValueA(compkey2, prod_squashed);
1408 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1409 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1410 RegDeleteValueA(localkey, "feature");
1411 RegDeleteValueA(userkey, "feature");
1412 delete_key(userkey, "", access & KEY_WOW64_64KEY);
1413 RegCloseKey(compkey);
1414 RegCloseKey(compkey2);
1415 RegCloseKey(localkey);
1416 RegCloseKey(userkey);
1417 LocalFree(usersid);
1418 }
1419
1420 static void test_MsiQueryComponentState(void)
1421 {
1422 HKEY compkey, prodkey;
1423 CHAR prodcode[MAX_PATH];
1424 CHAR prod_squashed[MAX_PATH];
1425 CHAR component[MAX_PATH];
1426 CHAR comp_base85[MAX_PATH];
1427 CHAR comp_squashed[MAX_PATH];
1428 CHAR keypath[MAX_PATH];
1429 INSTALLSTATE state;
1430 LPSTR usersid;
1431 LONG res;
1432 UINT r;
1433 REGSAM access = KEY_ALL_ACCESS;
1434 DWORD error;
1435
1436 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1437
1438 if (!pMsiQueryComponentStateA)
1439 {
1440 win_skip("MsiQueryComponentStateA not implemented\n");
1441 return;
1442 }
1443
1444 create_test_guid(prodcode, prod_squashed);
1445 compose_base85_guid(component, comp_base85, comp_squashed);
1446 usersid = get_user_sid();
1447
1448 if (is_wow64)
1449 access |= KEY_WOW64_64KEY;
1450
1451 /* NULL szProductCode */
1452 state = MAGIC_ERROR;
1453 SetLastError(0xdeadbeef);
1454 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1455 error = GetLastError();
1456 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1457 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1458 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1459
1460 /* empty szProductCode */
1461 state = MAGIC_ERROR;
1462 SetLastError(0xdeadbeef);
1463 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1464 error = GetLastError();
1465 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1466 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1467 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1468
1469 /* random szProductCode */
1470 state = MAGIC_ERROR;
1471 SetLastError(0xdeadbeef);
1472 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1473 error = GetLastError();
1474 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1475 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1476 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1477
1478 /* GUID-length szProductCode */
1479 state = MAGIC_ERROR;
1480 SetLastError(0xdeadbeef);
1481 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1482 error = GetLastError();
1483 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1484 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1485 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1486
1487 /* GUID-length with brackets */
1488 state = MAGIC_ERROR;
1489 SetLastError(0xdeadbeef);
1490 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1491 error = GetLastError();
1492 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1493 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1494 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1495
1496 /* actual GUID */
1497 state = MAGIC_ERROR;
1498 SetLastError(0xdeadbeef);
1499 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1500 error = GetLastError();
1501 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1502 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1503 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1504
1505 state = MAGIC_ERROR;
1506 SetLastError(0xdeadbeef);
1507 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1508 error = GetLastError();
1509 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1510 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1511 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1512
1513 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1514 lstrcatA(keypath, prod_squashed);
1515
1516 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1517 if (res == ERROR_ACCESS_DENIED)
1518 {
1519 skip("Not enough rights to perform tests\n");
1520 LocalFree(usersid);
1521 return;
1522 }
1523 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1524
1525 state = MAGIC_ERROR;
1526 SetLastError(0xdeadbeef);
1527 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1528 error = GetLastError();
1529 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1530 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1531 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1532
1533 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1534 RegCloseKey(prodkey);
1535
1536 /* create local system product key */
1537 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1538 lstrcatA(keypath, prod_squashed);
1539 lstrcatA(keypath, "\\InstallProperties");
1540
1541 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1542 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1543
1544 /* local system product key exists */
1545 state = MAGIC_ERROR;
1546 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1547 error = GetLastError();
1548 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1549 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1550 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1551
1552 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1553 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1554
1555 /* LocalPackage value exists */
1556 state = MAGIC_ERROR;
1557 SetLastError(0xdeadbeef);
1558 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1559 error = GetLastError();
1560 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1561 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1562 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1563
1564 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1565 lstrcatA(keypath, comp_squashed);
1566
1567 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1568 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1569
1570 /* component key exists */
1571 state = MAGIC_ERROR;
1572 SetLastError(0xdeadbeef);
1573 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1574 error = GetLastError();
1575 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1576 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1577 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1578
1579 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1580 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1581
1582 /* component\product exists */
1583 state = MAGIC_ERROR;
1584 SetLastError(0xdeadbeef);
1585 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1586 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1587 error = GetLastError();
1588 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1589 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1590 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1591
1592 /* NULL component, product exists */
1593 state = MAGIC_ERROR;
1594 SetLastError(0xdeadbeef);
1595 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1596 error = GetLastError();
1597 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1598 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1599 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1600
1601 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1603
1604 /* INSTALLSTATE_LOCAL */
1605 state = MAGIC_ERROR;
1606 SetLastError(0xdeadbeef);
1607 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1608 error = GetLastError();
1609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1610 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1611 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1612
1613 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1614 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1615
1616 /* INSTALLSTATE_SOURCE */
1617 state = MAGIC_ERROR;
1618 SetLastError(0xdeadbeef);
1619 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1620 error = GetLastError();
1621 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1622 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1623 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1624
1625 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1626 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1627
1628 /* bad INSTALLSTATE_SOURCE */
1629 state = MAGIC_ERROR;
1630 SetLastError(0xdeadbeef);
1631 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1632 error = GetLastError();
1633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1634 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1635 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1636
1637 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1638 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1639
1640 /* INSTALLSTATE_SOURCE */
1641 state = MAGIC_ERROR;
1642 SetLastError(0xdeadbeef);
1643 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1644 error = GetLastError();
1645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1646 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1647 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1648
1649 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
1650 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1651
1652 /* registry component */
1653 state = MAGIC_ERROR;
1654 SetLastError(0xdeadbeef);
1655 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1656 error = GetLastError();
1657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1658 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1659 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1660
1661 RegDeleteValueA(prodkey, "LocalPackage");
1662 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1663 RegDeleteValueA(compkey, prod_squashed);
1664 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1665 RegCloseKey(prodkey);
1666 RegCloseKey(compkey);
1667
1668 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1669
1670 state = MAGIC_ERROR;
1671 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1672 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1673 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1674
1675 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1676 lstrcatA(keypath, prod_squashed);
1677
1678 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1679 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1680
1681 state = MAGIC_ERROR;
1682 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1683 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1684 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1685
1686 RegDeleteKeyA(prodkey, "");
1687 RegCloseKey(prodkey);
1688
1689 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1690 lstrcatA(keypath, usersid);
1691 lstrcatA(keypath, "\\Products\\");
1692 lstrcatA(keypath, prod_squashed);
1693 lstrcatA(keypath, "\\InstallProperties");
1694
1695 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1696 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1697
1698 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1699 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1700
1701 RegCloseKey(prodkey);
1702
1703 state = MAGIC_ERROR;
1704 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1705 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1706 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1707
1708 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1709 lstrcatA(keypath, usersid);
1710 lstrcatA(keypath, "\\Components\\");
1711 lstrcatA(keypath, comp_squashed);
1712
1713 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1714 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1715
1716 /* component key exists */
1717 state = MAGIC_ERROR;
1718 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1719 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1720 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1721
1722 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1724
1725 /* component\product exists */
1726 state = MAGIC_ERROR;
1727 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1729 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1730 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1731
1732 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1734
1735 state = MAGIC_ERROR;
1736 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1738 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1739
1740 /* MSIINSTALLCONTEXT_USERMANAGED */
1741
1742 state = MAGIC_ERROR;
1743 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1744 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1745 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1746
1747 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1748 lstrcatA(keypath, prod_squashed);
1749
1750 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1751 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1752
1753 state = MAGIC_ERROR;
1754 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1755 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1756 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1757
1758 RegDeleteKeyA(prodkey, "");
1759 RegCloseKey(prodkey);
1760
1761 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1762 lstrcatA(keypath, usersid);
1763 lstrcatA(keypath, "\\Installer\\Products\\");
1764 lstrcatA(keypath, prod_squashed);
1765
1766 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1767 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1768
1769 state = MAGIC_ERROR;
1770 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1771 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1772 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1773
1774 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1775 RegCloseKey(prodkey);
1776
1777 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1778 lstrcatA(keypath, usersid);
1779 lstrcatA(keypath, "\\Products\\");
1780 lstrcatA(keypath, prod_squashed);
1781 lstrcatA(keypath, "\\InstallProperties");
1782
1783 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1784 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1785
1786 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1787 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1788
1789 state = MAGIC_ERROR;
1790 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1792 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1793
1794 RegDeleteValueA(prodkey, "LocalPackage");
1795 RegDeleteValueA(prodkey, "ManagedLocalPackage");
1796 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1797 RegDeleteValueA(compkey, prod_squashed);
1798 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1799 RegCloseKey(prodkey);
1800 RegCloseKey(compkey);
1801 LocalFree(usersid);
1802 }
1803
1804 static void test_MsiGetComponentPath(void)
1805 {
1806 HKEY compkey, prodkey, installprop;
1807 CHAR prodcode[MAX_PATH];
1808 CHAR prod_squashed[MAX_PATH];
1809 CHAR component[MAX_PATH];
1810 CHAR comp_base85[MAX_PATH];
1811 CHAR comp_squashed[MAX_PATH];
1812 CHAR keypath[MAX_PATH];
1813 CHAR path[MAX_PATH];
1814 INSTALLSTATE state;
1815 LPSTR usersid;
1816 DWORD size, val;
1817 REGSAM access = KEY_ALL_ACCESS;
1818 LONG res;
1819
1820 create_test_guid(prodcode, prod_squashed);
1821 compose_base85_guid(component, comp_base85, comp_squashed);
1822 usersid = get_user_sid();
1823
1824 if (is_wow64)
1825 access |= KEY_WOW64_64KEY;
1826
1827 /* NULL szProduct */
1828 size = MAX_PATH;
1829 state = MsiGetComponentPathA(NULL, component, path, &size);
1830 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1831 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1832
1833 /* NULL szComponent */
1834 size = MAX_PATH;
1835 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1836 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1837 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1838
1839 size = MAX_PATH;
1840 state = MsiLocateComponentA(NULL, path, &size);
1841 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1842 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1843
1844 /* NULL lpPathBuf */
1845 size = MAX_PATH;
1846 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1847 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1848 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1849
1850 size = MAX_PATH;
1851 state = MsiLocateComponentA(component, NULL, &size);
1852 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1853 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1854
1855 /* NULL pcchBuf */
1856 size = MAX_PATH;
1857 state = MsiGetComponentPathA(prodcode, component, path, NULL);
1858 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1859 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1860
1861 size = MAX_PATH;
1862 state = MsiLocateComponentA(component, path, NULL);
1863 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1864 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1865
1866 /* all params valid */
1867 size = MAX_PATH;
1868 state = MsiGetComponentPathA(prodcode, component, path, &size);
1869 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1870 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1871
1872 size = MAX_PATH;
1873 state = MsiLocateComponentA(component, path, &size);
1874 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1875 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1876
1877 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1878 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1879 lstrcatA(keypath, comp_squashed);
1880
1881 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1882 if (res == ERROR_ACCESS_DENIED)
1883 {
1884 skip("Not enough rights to perform tests\n");
1885 LocalFree(usersid);
1886 return;
1887 }
1888 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1889
1890 /* local system component key exists */
1891 size = MAX_PATH;
1892 state = MsiGetComponentPathA(prodcode, component, path, &size);
1893 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1894 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1895
1896 size = MAX_PATH;
1897 state = MsiLocateComponentA(component, path, &size);
1898 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1899 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1900
1901 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1902 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1903
1904 /* product value exists */
1905 path[0] = 0;
1906 size = MAX_PATH;
1907 state = MsiGetComponentPathA(prodcode, component, path, &size);
1908 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1909 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1910 ok(size == 10, "Expected 10, got %d\n", size);
1911
1912 path[0] = 0;
1913 size = MAX_PATH;
1914 state = MsiLocateComponentA(component, path, &size);
1915 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1916 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1917 ok(size == 10, "Expected 10, got %d\n", size);
1918
1919 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1920 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1921 lstrcatA(keypath, prod_squashed);
1922 lstrcatA(keypath, "\\InstallProperties");
1923
1924 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1925 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1926
1927 val = 1;
1928 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1929 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1930
1931 /* install properties key exists */
1932 path[0] = 0;
1933 size = MAX_PATH;
1934 state = MsiGetComponentPathA(prodcode, component, path, &size);
1935 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1936 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1937 ok(size == 10, "Expected 10, got %d\n", size);
1938
1939 path[0] = 0;
1940 size = MAX_PATH;
1941 state = MsiLocateComponentA(component, path, &size);
1942 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1943 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1944 ok(size == 10, "Expected 10, got %d\n", size);
1945
1946 create_file("C:\\imapath", "C:\\imapath", 11);
1947
1948 /* file exists */
1949 path[0] = 0;
1950 size = MAX_PATH;
1951 state = MsiGetComponentPathA(prodcode, component, path, &size);
1952 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1953 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1954 ok(size == 10, "Expected 10, got %d\n", size);
1955
1956 path[0] = 0;
1957 size = MAX_PATH;
1958 state = MsiLocateComponentA(component, path, &size);
1959 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1960 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1961 ok(size == 10, "Expected 10, got %d\n", size);
1962
1963 RegDeleteValueA(compkey, prod_squashed);
1964 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1965 RegDeleteValueA(installprop, "WindowsInstaller");
1966 delete_key(installprop, "", access & KEY_WOW64_64KEY);
1967 RegCloseKey(compkey);
1968 RegCloseKey(installprop);
1969 DeleteFileA("C:\\imapath");
1970
1971 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1972 lstrcatA(keypath, "Installer\\UserData\\");
1973 lstrcatA(keypath, usersid);
1974 lstrcatA(keypath, "\\Components\\");
1975 lstrcatA(keypath, comp_squashed);
1976
1977 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1979
1980 /* user managed component key exists */
1981 size = MAX_PATH;
1982 state = MsiGetComponentPathA(prodcode, component, path, &size);
1983 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1984 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1985
1986 size = MAX_PATH;
1987 state = MsiLocateComponentA(component, path, &size);
1988 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1989 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1990
1991 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1992 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1993
1994 /* product value exists */
1995 path[0] = 0;
1996 size = MAX_PATH;
1997 state = MsiGetComponentPathA(prodcode, component, path, &size);
1998 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1999 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2000 ok(size == 10, "Expected 10, got %d\n", size);
2001
2002 path[0] = 0;
2003 size = MAX_PATH;
2004 state = MsiLocateComponentA(component, path, &size);
2005 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2006 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2007 ok(size == 10, "Expected 10, got %d\n", size);
2008
2009 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2010 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2011 lstrcatA(keypath, prod_squashed);
2012 lstrcatA(keypath, "\\InstallProperties");
2013
2014 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2015 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2016
2017 val = 1;
2018 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2019 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2020
2021 /* install properties key exists */
2022 path[0] = 0;
2023 size = MAX_PATH;
2024 state = MsiGetComponentPathA(prodcode, component, path, &size);
2025 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2026 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2027 ok(size == 10, "Expected 10, got %d\n", size);
2028
2029 path[0] = 0;
2030 size = MAX_PATH;
2031 state = MsiLocateComponentA(component, path, &size);
2032 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2033 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2034 ok(size == 10, "Expected 10, got %d\n", size);
2035
2036 create_file("C:\\imapath", "C:\\imapath", 11);
2037
2038 /* file exists */
2039 path[0] = 0;
2040 size = MAX_PATH;
2041 state = MsiGetComponentPathA(prodcode, component, path, &size);
2042 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2043 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2044 ok(size == 10, "Expected 10, got %d\n", size);
2045
2046 path[0] = 0;
2047 size = MAX_PATH;
2048 state = MsiLocateComponentA(component, path, &size);
2049 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2050 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2051 ok(size == 10, "Expected 10, got %d\n", size);
2052
2053 RegDeleteValueA(compkey, prod_squashed);
2054 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2055 RegDeleteValueA(installprop, "WindowsInstaller");
2056 delete_key(installprop, "", access & KEY_WOW64_64KEY);
2057 RegCloseKey(compkey);
2058 RegCloseKey(installprop);
2059 DeleteFileA("C:\\imapath");
2060
2061 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2062 lstrcatA(keypath, "Installer\\Managed\\");
2063 lstrcatA(keypath, usersid);
2064 lstrcatA(keypath, "\\Installer\\Products\\");
2065 lstrcatA(keypath, prod_squashed);
2066
2067 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2068 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2069
2070 /* user managed product key exists */
2071 size = MAX_PATH;
2072 state = MsiGetComponentPathA(prodcode, component, path, &size);
2073 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2074 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2075
2076 size = MAX_PATH;
2077 state = MsiLocateComponentA(component, path, &size);
2078 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2079 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2080
2081 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2082 lstrcatA(keypath, "Installer\\UserData\\");
2083 lstrcatA(keypath, usersid);
2084 lstrcatA(keypath, "\\Components\\");
2085 lstrcatA(keypath, comp_squashed);
2086
2087 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2088 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2089
2090 /* user managed component key exists */
2091 size = MAX_PATH;
2092 state = MsiGetComponentPathA(prodcode, component, path, &size);
2093 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2094 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2095
2096 size = MAX_PATH;
2097 state = MsiLocateComponentA(component, path, &size);
2098 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2099 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2100
2101 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2103
2104 /* product value exists */
2105 path[0] = 0;
2106 size = MAX_PATH;
2107 state = MsiGetComponentPathA(prodcode, component, path, &size);
2108 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2109 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2110 ok(size == 10, "Expected 10, got %d\n", size);
2111
2112 path[0] = 0;
2113 size = MAX_PATH;
2114 state = MsiLocateComponentA(component, path, &size);
2115 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2116 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2117 ok(size == 10, "Expected 10, got %d\n", size);
2118
2119 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2120 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2121 lstrcatA(keypath, prod_squashed);
2122 lstrcatA(keypath, "\\InstallProperties");
2123
2124 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2125 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2126
2127 val = 1;
2128 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2129 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2130
2131 /* install properties key exists */
2132 path[0] = 0;
2133 size = MAX_PATH;
2134 state = MsiGetComponentPathA(prodcode, component, path, &size);
2135 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2136 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2137 ok(size == 10, "Expected 10, got %d\n", size);
2138
2139 path[0] = 0;
2140 size = MAX_PATH;
2141 state = MsiLocateComponentA(component, path, &size);
2142 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2143 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2144 ok(size == 10, "Expected 10, got %d\n", size);
2145
2146 create_file("C:\\imapath", "C:\\imapath", 11);
2147
2148 /* file exists */
2149 path[0] = 0;
2150 size = MAX_PATH;
2151 state = MsiGetComponentPathA(prodcode, component, path, &size);
2152 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2153 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2154 ok(size == 10, "Expected 10, got %d\n", size);
2155
2156 path[0] = 0;
2157 size = MAX_PATH;
2158 state = MsiLocateComponentA(component, path, &size);
2159 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2160 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2161 ok(size == 10, "Expected 10, got %d\n", size);
2162
2163 RegDeleteValueA(compkey, prod_squashed);
2164 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2165 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2166 RegDeleteValueA(installprop, "WindowsInstaller");
2167 delete_key(installprop, "", access & KEY_WOW64_64KEY);
2168 RegCloseKey(prodkey);
2169 RegCloseKey(compkey);
2170 RegCloseKey(installprop);
2171 DeleteFileA("C:\\imapath");
2172
2173 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2174 lstrcatA(keypath, prod_squashed);
2175
2176 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2177 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2178
2179 /* user unmanaged product key exists */
2180 size = MAX_PATH;
2181 state = MsiGetComponentPathA(prodcode, component, path, &size);
2182 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2183 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2184
2185 size = MAX_PATH;
2186 state = MsiLocateComponentA(component, path, &size);
2187 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2188 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2189
2190 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2191 lstrcatA(keypath, "Installer\\UserData\\");
2192 lstrcatA(keypath, usersid);
2193 lstrcatA(keypath, "\\Components\\");
2194 lstrcatA(keypath, comp_squashed);
2195
2196 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2197 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2198
2199 /* user unmanaged component key exists */
2200 size = MAX_PATH;
2201 state = MsiGetComponentPathA(prodcode, component, path, &size);
2202 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2203 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2204
2205 size = MAX_PATH;
2206 state = MsiLocateComponentA(component, path, &size);
2207 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2208 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2209
2210 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2211 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2212
2213 /* product value exists */
2214 path[0] = 0;
2215 size = MAX_PATH;
2216 state = MsiGetComponentPathA(prodcode, component, path, &size);
2217 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2218 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2219 ok(size == 10, "Expected 10, got %d\n", size);
2220
2221 path[0] = 0;
2222 size = MAX_PATH;
2223 state = MsiLocateComponentA(component, path, &size);
2224 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2225 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2226 ok(size == 10, "Expected 10, got %d\n", size);
2227
2228 create_file("C:\\imapath", "C:\\imapath", 11);
2229
2230 /* file exists */
2231 path[0] = 0;
2232 size = MAX_PATH;
2233 state = MsiGetComponentPathA(prodcode, component, path, &size);
2234 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2235 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2236 ok(size == 10, "Expected 10, got %d\n", size);
2237
2238 path[0] = 0;
2239 size = MAX_PATH;
2240 state = MsiLocateComponentA(component, path, &size);
2241 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2242 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2243 ok(size == 10, "Expected 10, got %d\n", size);
2244
2245 RegDeleteValueA(compkey, prod_squashed);
2246 RegDeleteKeyA(prodkey, "");
2247 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2248 RegCloseKey(prodkey);
2249 RegCloseKey(compkey);
2250 DeleteFileA("C:\\imapath");
2251
2252 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2253 lstrcatA(keypath, prod_squashed);
2254
2255 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2256 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2257
2258 /* local classes product key exists */
2259 size = MAX_PATH;
2260 state = MsiGetComponentPathA(prodcode, component, path, &size);
2261 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2262 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2263
2264 size = MAX_PATH;
2265 state = MsiLocateComponentA(component, path, &size);
2266 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2267 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2268
2269 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2270 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2271 lstrcatA(keypath, comp_squashed);
2272
2273 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2274 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2275
2276 /* local user component key exists */
2277 size = MAX_PATH;
2278 state = MsiGetComponentPathA(prodcode, component, path, &size);
2279 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2280 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2281
2282 size = MAX_PATH;
2283 state = MsiLocateComponentA(component, path, &size);
2284 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2285 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2286
2287 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2289
2290 /* product value exists */
2291 path[0] = 0;
2292 size = MAX_PATH;
2293 state = MsiGetComponentPathA(prodcode, component, path, &size);
2294 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2295 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2296 ok(size == 10, "Expected 10, got %d\n", size);
2297
2298 path[0] = 0;
2299 size = MAX_PATH;
2300 state = MsiLocateComponentA(component, path, &size);
2301 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2302 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2303 ok(size == 10, "Expected 10, got %d\n", size);
2304
2305 create_file("C:\\imapath", "C:\\imapath", 11);
2306
2307 /* file exists */
2308 path[0] = 0;
2309 size = MAX_PATH;
2310 state = MsiGetComponentPathA(prodcode, component, path, &size);
2311 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2312 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2313 ok(size == 10, "Expected 10, got %d\n", size);
2314
2315 path[0] = 0;
2316 size = MAX_PATH;
2317 state = MsiLocateComponentA(component, path, &size);
2318 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2319 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2320 ok(size == 10, "Expected 10, got %d\n", size);
2321
2322 RegDeleteValueA(compkey, prod_squashed);
2323 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2324 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2325 RegCloseKey(prodkey);
2326 RegCloseKey(compkey);
2327 DeleteFileA("C:\\imapath");
2328 LocalFree(usersid);
2329 }
2330
2331 static void test_MsiGetProductCode(void)
2332 {
2333 HKEY compkey, prodkey;
2334 CHAR prodcode[MAX_PATH];
2335 CHAR prod_squashed[MAX_PATH];
2336 CHAR prodcode2[MAX_PATH];
2337 CHAR prod2_squashed[MAX_PATH];
2338 CHAR component[MAX_PATH];
2339 CHAR comp_base85[MAX_PATH];
2340 CHAR comp_squashed[MAX_PATH];
2341 CHAR keypath[MAX_PATH];
2342 CHAR product[MAX_PATH];
2343 LPSTR usersid;
2344 LONG res;
2345 UINT r;
2346 REGSAM access = KEY_ALL_ACCESS;
2347
2348 create_test_guid(prodcode, prod_squashed);
2349 create_test_guid(prodcode2, prod2_squashed);
2350 compose_base85_guid(component, comp_base85, comp_squashed);
2351 usersid = get_user_sid();
2352
2353 if (is_wow64)
2354 access |= KEY_WOW64_64KEY;
2355
2356 /* szComponent is NULL */
2357 lstrcpyA(product, "prod");
2358 r = MsiGetProductCodeA(NULL, product);
2359 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2360 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2361
2362 /* szComponent is empty */
2363 lstrcpyA(product, "prod");
2364 r = MsiGetProductCodeA("", product);
2365 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2366 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2367
2368 /* garbage szComponent */
2369 lstrcpyA(product, "prod");
2370 r = MsiGetProductCodeA("garbage", product);
2371 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2372 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2373
2374 /* guid without brackets */
2375 lstrcpyA(product, "prod");
2376 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2377 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2378 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2379
2380 /* guid with brackets */
2381 lstrcpyA(product, "prod");
2382 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2383 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2384 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2385
2386 /* same length as guid, but random */
2387 lstrcpyA(product, "prod");
2388 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2389 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2390 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2391
2392 /* all params correct, szComponent not published */
2393 lstrcpyA(product, "prod");
2394 r = MsiGetProductCodeA(component, product);
2395 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2396 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2397
2398 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2399 lstrcatA(keypath, "Installer\\UserData\\");
2400 lstrcatA(keypath, usersid);
2401 lstrcatA(keypath, "\\Components\\");
2402 lstrcatA(keypath, comp_squashed);
2403
2404 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2405 if (res == ERROR_ACCESS_DENIED)
2406 {
2407 skip("Not enough rights to perform tests\n");
2408 LocalFree(usersid);
2409 return;
2410 }
2411 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2412
2413 /* user unmanaged component key exists */
2414 lstrcpyA(product, "prod");
2415 r = MsiGetProductCodeA(component, product);
2416 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2417 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2418
2419 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2421
2422 /* product value exists */
2423 lstrcpyA(product, "prod");
2424 r = MsiGetProductCodeA(component, product);
2425 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2426 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2427
2428 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2429 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2430
2431 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2432 lstrcatA(keypath, "Installer\\Managed\\");
2433 lstrcatA(keypath, usersid);
2434 lstrcatA(keypath, "\\Installer\\Products\\");
2435 lstrcatA(keypath, prod_squashed);
2436
2437 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2438 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2439
2440 /* user managed product key of first product exists */
2441 lstrcpyA(product, "prod");
2442 r = MsiGetProductCodeA(component, product);
2443 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2444 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2445
2446 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2447 RegCloseKey(prodkey);
2448
2449 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2450 lstrcatA(keypath, prod_squashed);
2451
2452 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2453 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2454
2455 /* user unmanaged product key exists */
2456 lstrcpyA(product, "prod");
2457 r = MsiGetProductCodeA(component, product);
2458 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2459 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2460
2461 RegDeleteKeyA(prodkey, "");
2462 RegCloseKey(prodkey);
2463
2464 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2465 lstrcatA(keypath, prod_squashed);
2466
2467 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2469
2470 /* local classes product key exists */
2471 lstrcpyA(product, "prod");
2472 r = MsiGetProductCodeA(component, product);
2473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2474 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2475
2476 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2477 RegCloseKey(prodkey);
2478
2479 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2480 lstrcatA(keypath, "Installer\\Managed\\");
2481 lstrcatA(keypath, usersid);
2482 lstrcatA(keypath, "\\Installer\\Products\\");
2483 lstrcatA(keypath, prod2_squashed);
2484
2485 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2486 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2487
2488 /* user managed product key of second product exists */
2489 lstrcpyA(product, "prod");
2490 r = MsiGetProductCodeA(component, product);
2491 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2492 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2493
2494 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2495 RegCloseKey(prodkey);
2496 RegDeleteValueA(compkey, prod_squashed);
2497 RegDeleteValueA(compkey, prod2_squashed);
2498 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2499 RegCloseKey(compkey);
2500
2501 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2502 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2503 lstrcatA(keypath, comp_squashed);
2504
2505 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2506 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2507
2508 /* local user component key exists */
2509 lstrcpyA(product, "prod");
2510 r = MsiGetProductCodeA(component, product);
2511 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2512 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2513
2514 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2515 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2516
2517 /* product value exists */
2518 lstrcpyA(product, "prod");
2519 r = MsiGetProductCodeA(component, product);
2520 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2521 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2522
2523 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2524 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2525
2526 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2527 lstrcatA(keypath, "Installer\\Managed\\");
2528 lstrcatA(keypath, usersid);
2529 lstrcatA(keypath, "\\Installer\\Products\\");
2530 lstrcatA(keypath, prod_squashed);
2531
2532 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2533 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2534
2535 /* user managed product key of first product exists */
2536 lstrcpyA(product, "prod");
2537 r = MsiGetProductCodeA(component, product);
2538 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2539 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2540
2541 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2542 RegCloseKey(prodkey);
2543
2544 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2545 lstrcatA(keypath, prod_squashed);
2546
2547 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2548 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2549
2550 /* user unmanaged product key exists */
2551 lstrcpyA(product, "prod");
2552 r = MsiGetProductCodeA(component, product);
2553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2554 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2555
2556 RegDeleteKeyA(prodkey, "");
2557 RegCloseKey(prodkey);
2558
2559 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2560 lstrcatA(keypath, prod_squashed);
2561
2562 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2563 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2564
2565 /* local classes product key exists */
2566 lstrcpyA(product, "prod");
2567 r = MsiGetProductCodeA(component, product);
2568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2569 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2570
2571 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2572 RegCloseKey(prodkey);
2573
2574 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2575 lstrcatA(keypath, "Installer\\Managed\\");
2576 lstrcatA(keypath, usersid);
2577 lstrcatA(keypath, "\\Installer\\Products\\");
2578 lstrcatA(keypath, prod2_squashed);
2579
2580 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2581 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2582
2583 /* user managed product key of second product exists */
2584 lstrcpyA(product, "prod");
2585 r = MsiGetProductCodeA(component, product);
2586 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2587 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2588
2589 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2590 RegCloseKey(prodkey);
2591 RegDeleteValueA(compkey, prod_squashed);
2592 RegDeleteValueA(compkey, prod2_squashed);
2593 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2594 RegCloseKey(compkey);
2595 LocalFree(usersid);
2596 }
2597
2598 static void test_MsiEnumClients(void)
2599 {
2600 HKEY compkey;
2601 CHAR prodcode[MAX_PATH];
2602 CHAR prod_squashed[MAX_PATH];
2603 CHAR prodcode2[MAX_PATH];
2604 CHAR prod2_squashed[MAX_PATH];
2605 CHAR component[MAX_PATH];
2606 CHAR comp_base85[MAX_PATH];
2607 CHAR comp_squashed[MAX_PATH];
2608 CHAR product[MAX_PATH];
2609 CHAR keypath[MAX_PATH];
2610 LPSTR usersid;
2611 LONG res;
2612 UINT r;
2613 REGSAM access = KEY_ALL_ACCESS;
2614
2615 create_test_guid(prodcode, prod_squashed);
2616 create_test_guid(prodcode2, prod2_squashed);
2617 compose_base85_guid(component, comp_base85, comp_squashed);
2618 usersid = get_user_sid();
2619
2620 if (is_wow64)
2621 access |= KEY_WOW64_64KEY;
2622
2623 /* NULL szComponent */
2624 product[0] = '\0';
2625 r = MsiEnumClientsA(NULL, 0, product);
2626 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2627 ok(!lstrcmpA(product, ""