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