2 * tests for Microsoft Installer functionality
4 * Copyright 2005 Mike McCormack for CodeWeavers
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.
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.
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
21 #define _WIN32_MSI 300
29 #include "wine/test.h"
31 typedef struct test_MSIFILEHASHINFO {
32 ULONG dwFileHashInfoSize;
34 } test_MSIFILEHASHINFO, *test_PMSIFILEHASHINFO;
36 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
38 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
39 (LPCSTR, LPCSTR, LPSTR, DWORD*);
40 static UINT (WINAPI *pMsiGetFileHashA)
41 (LPCSTR, DWORD, test_PMSIFILEHASHINFO);
42 static UINT (WINAPI *pMsiOpenPackageExA)
43 (LPCSTR, DWORD, MSIHANDLE*);
44 static UINT (WINAPI *pMsiOpenPackageExW)
45 (LPCWSTR, DWORD, MSIHANDLE*);
46 static UINT (WINAPI *pMsiQueryComponentStateA)
47 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
48 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
49 (LPCSTR, LPCSTR ,DWORD, DWORD );
51 static void init_functionpointers(void)
53 HMODULE hmsi = GetModuleHandleA("msi.dll");
54 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
56 pMsiGetComponentPathA = (void*)GetProcAddress(hmsi, "MsiGetComponentPathA");
57 pMsiGetFileHashA = (void*)GetProcAddress(hmsi, "MsiGetFileHashA");
58 pMsiOpenPackageExA = (void*)GetProcAddress(hmsi, "MsiOpenPackageExA");
59 pMsiOpenPackageExW = (void*)GetProcAddress(hmsi, "MsiOpenPackageExW");
60 pMsiQueryComponentStateA = (void*)GetProcAddress(hmsi, "MsiQueryComponentStateA");
61 pMsiUseFeatureExA = (void*)GetProcAddress(hmsi, "MsiUseFeatureExA");
63 pConvertSidToStringSidA = (void*)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
66 static void test_usefeature(void)
70 if (!pMsiUseFeatureExA)
73 r = MsiQueryFeatureState(NULL,NULL);
74 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
76 r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
77 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
79 r = pMsiUseFeatureExA(NULL,NULL,0,0);
80 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
82 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
83 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
85 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
87 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
89 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
90 "WORDVIEWFiles", -2, 0 );
91 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
93 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
94 "WORDVIEWFiles", -2, 0 );
95 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
97 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
98 "WORDVIEWFiles", -2, 1 );
99 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
102 static void test_null(void)
107 DWORD dwType, cbData;
108 LPBYTE lpData = NULL;
111 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
112 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
114 state = MsiQueryProductStateW(NULL);
115 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
117 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
118 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
120 r = MsiConfigureFeatureW(NULL, NULL, 0);
121 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
123 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
124 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
126 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
127 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
129 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
130 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
132 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
133 * necessary registry values */
135 /* empty product string */
136 r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
137 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
139 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
140 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
141 if ( r == ERROR_SUCCESS )
143 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
145 skip("Out of memory\n");
148 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
149 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
153 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
154 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
156 r = MsiGetProductInfoA("", "", NULL, NULL);
157 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
161 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
162 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
164 HeapFree(GetProcessHeap(), 0, lpData);
168 r = RegDeleteValueA(hkey, NULL);
169 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
172 r = RegCloseKey(hkey);
173 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
175 /* empty attribute */
176 r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
177 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
179 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
180 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
182 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
183 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
185 r = RegCloseKey(hkey);
186 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
188 r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
189 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
192 static void test_getcomponentpath(void)
198 if(!pMsiGetComponentPathA)
201 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
202 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
204 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
205 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
207 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
208 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
212 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
213 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
215 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
216 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
217 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
219 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
220 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
221 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
223 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
224 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
225 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
227 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
228 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
229 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
232 static void test_filehash(void)
234 const char name[] = "msitest.bin";
235 const char data[] = {'a','b','c'};
238 test_MSIFILEHASHINFO hash;
241 if (!pMsiGetFileHashA)
246 memset(&hash, 0, sizeof hash);
247 r = pMsiGetFileHashA(name, 0, &hash);
248 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
250 r = pMsiGetFileHashA(name, 0, NULL);
251 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
253 memset(&hash, 0, sizeof hash);
254 hash.dwFileHashInfoSize = sizeof hash;
255 r = pMsiGetFileHashA(name, 0, &hash);
256 ok( r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
258 handle = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, NULL,
259 CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
260 ok(handle != INVALID_HANDLE_VALUE, "failed to create file\n");
262 WriteFile(handle, data, sizeof data, &count, NULL);
265 memset(&hash, 0, sizeof hash);
266 r = pMsiGetFileHashA(name, 0, &hash);
267 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
269 memset(&hash, 0, sizeof hash);
270 hash.dwFileHashInfoSize = sizeof hash;
271 r = pMsiGetFileHashA(name, 1, &hash);
272 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
274 r = pMsiGetFileHashA(name, 0, &hash);
275 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
277 ok(hash.dwFileHashInfoSize == sizeof hash, "hash size changed\n");
278 ok(hash.dwData[0] == 0x98500190 &&
279 hash.dwData[1] == 0xb04fd23c &&
280 hash.dwData[2] == 0x7d3f96d6 &&
281 hash.dwData[3] == 0x727fe128, "hash of abc incorrect\n");
286 /* copied from dlls/msi/registry.c */
287 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
292 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
306 out[17+i*2] = in[n++];
307 out[16+i*2] = in[n++];
312 out[17+i*2] = in[n++];
313 out[16+i*2] = in[n++];
319 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
321 WCHAR guidW[MAX_PATH];
322 WCHAR squashedW[MAX_PATH];
327 hr = CoCreateGuid(&guid);
328 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
330 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
331 ok(size == 39, "Expected 39, got %d\n", hr);
333 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
334 squash_guid(guidW, squashedW);
335 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
338 static void get_user_sid(LPSTR *usersid)
345 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
347 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
348 user = (PTOKEN_USER)buf;
349 pConvertSidToStringSidA(user->User.Sid, usersid);
352 static void test_MsiQueryProductState(void)
354 CHAR prodcode[MAX_PATH];
355 CHAR prod_squashed[MAX_PATH];
356 CHAR keypath[MAX_PATH*2];
360 HKEY userkey, localkey, props;
363 create_test_guid(prodcode, prod_squashed);
364 get_user_sid(&usersid);
367 state = MsiQueryProductStateA(NULL);
368 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
371 state = MsiQueryProductStateA("");
372 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
374 /* garbage prodcode */
375 state = MsiQueryProductStateA("garbage");
376 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
378 /* guid without brackets */
379 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
380 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
382 /* guid with brackets */
383 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
384 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
386 /* same length as guid, but random */
387 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
388 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
390 /* created guid cannot possibly be an installed product code */
391 state = MsiQueryProductStateA(prodcode);
392 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
394 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
395 lstrcatA(keypath, prod_squashed);
397 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
398 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
400 /* user product key exists */
401 state = MsiQueryProductStateA(prodcode);
402 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
404 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
405 lstrcatA(keypath, prodcode);
407 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
408 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
410 /* local uninstall key exists */
411 state = MsiQueryProductStateA(prodcode);
412 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
415 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
416 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
418 /* WindowsInstaller value exists */
419 state = MsiQueryProductStateA(prodcode);
420 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
422 RegDeleteValueA(localkey, "WindowsInstaller");
423 RegDeleteKeyA(localkey, "");
425 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
426 lstrcatA(keypath, usersid);
427 lstrcatA(keypath, "\\Products\\");
428 lstrcatA(keypath, prod_squashed);
430 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
431 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
433 /* local product key exists */
434 state = MsiQueryProductStateA(prodcode);
435 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
437 res = RegCreateKeyA(localkey, "InstallProperties", &props);
438 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
440 /* install properties key exists */
441 state = MsiQueryProductStateA(prodcode);
442 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
445 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
448 /* WindowsInstaller value exists */
449 state = MsiQueryProductStateA(prodcode);
450 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
453 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
454 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
456 /* WindowsInstaller value is not 1 */
457 state = MsiQueryProductStateA(prodcode);
458 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
460 RegDeleteKeyA(userkey, "");
462 /* user product key does not exist */
463 state = MsiQueryProductStateA(prodcode);
464 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
467 RegDeleteValueA(props, "WindowsInstaller");
468 RegDeleteKeyA(props, "");
469 RegDeleteKeyA(localkey, "");
470 RegCloseKey(userkey);
471 RegCloseKey(localkey);
475 static const char table_enc85[] =
476 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
477 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
481 * Encodes a base85 guid given a GUID pointer
482 * Caller should provide a 21 character buffer for the encoded string.
484 * returns TRUE if successful, FALSE if not
486 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
488 unsigned int x, *p, i;
490 p = (unsigned int*) guid;
494 *str++ = table_enc85[x%85];
496 *str++ = table_enc85[x%85];
498 *str++ = table_enc85[x%85];
500 *str++ = table_enc85[x%85];
502 *str++ = table_enc85[x%85];
509 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
511 WCHAR guidW[MAX_PATH];
512 WCHAR base85W[MAX_PATH];
513 WCHAR squashedW[MAX_PATH];
518 hr = CoCreateGuid(&guid);
519 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
521 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
522 ok(size == 39, "Expected 39, got %d\n", hr);
524 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
525 encode_base85_guid(&guid, base85W);
526 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
527 squash_guid(guidW, squashedW);
528 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
531 static void test_MsiQueryFeatureState(void)
533 HKEY userkey, localkey, compkey;
534 CHAR prodcode[MAX_PATH];
535 CHAR prod_squashed[MAX_PATH];
536 CHAR component[MAX_PATH];
537 CHAR comp_base85[MAX_PATH];
538 CHAR comp_squashed[MAX_PATH];
539 CHAR keypath[MAX_PATH*2];
544 create_test_guid(prodcode, prod_squashed);
545 compose_base85_guid(component, comp_base85, comp_squashed);
546 get_user_sid(&usersid);
549 state = MsiQueryFeatureStateA(NULL, "feature");
550 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
553 state = MsiQueryFeatureStateA("", "feature");
554 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
556 /* garbage prodcode */
557 state = MsiQueryFeatureStateA("garbage", "feature");
558 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
560 /* guid without brackets */
561 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
562 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
564 /* guid with brackets */
565 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
566 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
568 /* same length as guid, but random */
569 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
570 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
573 state = MsiQueryFeatureStateA(prodcode, NULL);
574 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
576 /* empty szFeature */
577 state = MsiQueryFeatureStateA(prodcode, "");
578 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
580 /* feature key does not exist yet */
581 state = MsiQueryFeatureStateA(prodcode, "feature");
582 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
584 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
585 lstrcatA(keypath, prod_squashed);
587 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
588 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
590 /* feature key exists */
591 state = MsiQueryFeatureStateA(prodcode, "feature");
592 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
594 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 8);
595 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
597 state = MsiQueryFeatureStateA(prodcode, "feature");
598 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
600 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
601 lstrcatA(keypath, usersid);
602 lstrcatA(keypath, "\\Products\\");
603 lstrcatA(keypath, prod_squashed);
604 lstrcatA(keypath, "\\Features");
606 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
607 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
609 state = MsiQueryFeatureStateA(prodcode, "feature");
610 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
612 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
613 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
615 state = MsiQueryFeatureStateA(prodcode, "feature");
616 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
618 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
619 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
621 state = MsiQueryFeatureStateA(prodcode, "feature");
622 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
624 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
625 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
627 state = MsiQueryFeatureStateA(prodcode, "feature");
628 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
630 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
631 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
633 state = MsiQueryFeatureStateA(prodcode, "feature");
634 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
636 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
637 lstrcatA(keypath, usersid);
638 lstrcatA(keypath, "\\Components\\");
639 lstrcatA(keypath, comp_squashed);
641 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
642 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
644 state = MsiQueryFeatureStateA(prodcode, "feature");
645 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
647 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
648 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
650 state = MsiQueryFeatureStateA(prodcode, "feature");
651 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
653 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
654 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
656 state = MsiQueryFeatureStateA(prodcode, "feature");
657 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
659 RegDeleteValueA(compkey, prod_squashed);
660 RegDeleteValueA(compkey, "");
661 RegDeleteValueA(localkey, "feature");
662 RegDeleteValueA(userkey, "feature");
663 RegDeleteKeyA(userkey, "");
664 RegCloseKey(compkey);
665 RegCloseKey(localkey);
666 RegCloseKey(userkey);
669 static void test_MsiQueryComponentState(void)
671 HKEY compkey, prodkey;
672 CHAR prodcode[MAX_PATH];
673 CHAR prod_squashed[MAX_PATH];
674 CHAR component[MAX_PATH];
675 CHAR comp_base85[MAX_PATH];
676 CHAR comp_squashed[MAX_PATH];
677 CHAR keypath[MAX_PATH];
683 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
685 create_test_guid(prodcode, prod_squashed);
686 compose_base85_guid(component, comp_base85, comp_squashed);
687 get_user_sid(&usersid);
689 /* NULL szProductCode */
691 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
692 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
693 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
695 /* empty szProductCode */
697 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);\
698 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
699 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
701 /* random szProductCode */
703 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
704 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
705 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
707 /* GUID-length szProductCode */
709 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
710 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
711 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
713 /* GUID-length with brackets */
715 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
716 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
717 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
721 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
722 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
723 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
726 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
727 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
728 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
730 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
731 lstrcatA(keypath, prod_squashed);
733 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
734 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
737 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
738 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
739 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
741 RegDeleteKeyA(prodkey, "");
742 RegCloseKey(prodkey);
744 /* create local system product key */
745 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
746 lstrcatA(keypath, prod_squashed);
747 lstrcatA(keypath, "\\InstallProperties");
749 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
750 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
752 /* local system product key exists */
754 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
755 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
756 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
758 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
759 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
761 /* LocalPackage value exists */
763 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
764 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
765 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
767 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
768 lstrcatA(keypath, comp_squashed);
770 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
771 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
773 /* component key exists */
775 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
776 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
777 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
779 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
780 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
782 /* component\product exists */
784 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
786 ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
788 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
789 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
792 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
793 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
794 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
796 RegDeleteValueA(prodkey, "LocalPackage");
797 RegDeleteKeyA(prodkey, "");
798 RegDeleteValueA(compkey, prod_squashed);
799 RegDeleteKeyA(prodkey, "");
800 RegCloseKey(prodkey);
801 RegCloseKey(compkey);
803 /* MSIINSTALLCONTEXT_USERUNMANAGED */
806 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
807 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
808 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
810 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
811 lstrcatA(keypath, prod_squashed);
813 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
814 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
817 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
818 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
819 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
821 RegDeleteKeyA(prodkey, "");
822 RegCloseKey(prodkey);
824 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
825 lstrcatA(keypath, usersid);
826 lstrcatA(keypath, "\\Products\\");
827 lstrcatA(keypath, prod_squashed);
828 lstrcatA(keypath, "\\InstallProperties");
830 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
833 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
834 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
836 RegCloseKey(prodkey);
839 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
840 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
841 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
843 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
844 lstrcatA(keypath, usersid);
845 lstrcatA(keypath, "\\Components\\");
846 lstrcatA(keypath, comp_squashed);
848 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
849 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
851 /* component key exists */
853 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
854 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
855 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
857 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
858 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
860 /* component\product exists */
862 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
864 ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
866 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
867 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
870 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
872 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
874 /* MSIINSTALLCONTEXT_USERMANAGED */
877 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
878 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
879 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
881 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
882 lstrcatA(keypath, prod_squashed);
884 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
885 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
888 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
889 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
890 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
892 RegDeleteKeyA(prodkey, "");
893 RegCloseKey(prodkey);
895 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
896 lstrcatA(keypath, usersid);
897 lstrcatA(keypath, "\\Installer\\Products\\");
898 lstrcatA(keypath, prod_squashed);
900 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
901 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
904 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
905 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
906 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
908 RegDeleteKeyA(prodkey, "");
909 RegCloseKey(prodkey);
911 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
912 lstrcatA(keypath, usersid);
913 lstrcatA(keypath, "\\Products\\");
914 lstrcatA(keypath, prod_squashed);
915 lstrcatA(keypath, "\\InstallProperties");
917 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
918 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
920 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
921 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
924 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
926 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
928 RegDeleteValueA(prodkey, "LocalPackage");
929 RegDeleteValueA(prodkey, "ManagedLocalPackage");
930 RegDeleteKeyA(prodkey, "");
931 RegDeleteValueA(compkey, prod_squashed);
932 RegDeleteKeyA(compkey, "");
933 RegCloseKey(prodkey);
934 RegCloseKey(compkey);
939 init_functionpointers();
943 test_getcomponentpath();
945 test_MsiQueryProductState();
946 test_MsiQueryFeatureState();
947 test_MsiQueryComponentState();