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 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
33 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
34 (LPCSTR, LPCSTR, LPSTR, DWORD*);
35 static UINT (WINAPI *pMsiGetFileHashA)
36 (LPCSTR, DWORD, PMSIFILEHASHINFO);
37 static UINT (WINAPI *pMsiOpenPackageExA)
38 (LPCSTR, DWORD, MSIHANDLE*);
39 static UINT (WINAPI *pMsiOpenPackageExW)
40 (LPCWSTR, DWORD, MSIHANDLE*);
41 static UINT (WINAPI *pMsiQueryComponentStateA)
42 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
43 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
44 (LPCSTR, LPCSTR ,DWORD, DWORD );
46 static void init_functionpointers(void)
48 HMODULE hmsi = GetModuleHandleA("msi.dll");
49 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
51 #define GET_PROC(dll, func) \
52 p ## func = (void *)GetProcAddress(dll, #func); \
54 trace("GetProcAddress(%s) failed\n", #func);
56 GET_PROC(hmsi, MsiGetComponentPathA)
57 GET_PROC(hmsi, MsiGetFileHashA)
58 GET_PROC(hmsi, MsiOpenPackageExA)
59 GET_PROC(hmsi, MsiOpenPackageExW)
60 GET_PROC(hmsi, MsiQueryComponentStateA)
61 GET_PROC(hmsi, MsiUseFeatureExA)
63 GET_PROC(hadvapi32, ConvertSidToStringSidA)
68 static void test_usefeature(void)
72 if (!pMsiUseFeatureExA)
74 skip("MsiUseFeatureExA not implemented\n");
78 r = MsiQueryFeatureState(NULL,NULL);
79 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
81 r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
82 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
84 r = pMsiUseFeatureExA(NULL,NULL,0,0);
85 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
87 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
88 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
90 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
92 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
94 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
95 "WORDVIEWFiles", -2, 0 );
96 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
98 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
99 "WORDVIEWFiles", -2, 0 );
100 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
102 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
103 "WORDVIEWFiles", -2, 1 );
104 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
107 static void test_null(void)
112 DWORD dwType, cbData;
113 LPBYTE lpData = NULL;
116 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
117 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
119 state = MsiQueryProductStateW(NULL);
120 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
122 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
123 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
125 r = MsiConfigureFeatureW(NULL, NULL, 0);
126 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
128 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
129 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
131 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
132 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
134 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
135 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
137 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
138 * necessary registry values */
140 /* empty product string */
141 r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
142 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
144 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
145 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
146 if ( r == ERROR_SUCCESS )
148 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
150 skip("Out of memory\n");
153 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
154 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
158 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
159 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
161 r = MsiGetProductInfoA("", "", NULL, NULL);
162 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
166 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
167 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
169 HeapFree(GetProcessHeap(), 0, lpData);
173 r = RegDeleteValueA(hkey, NULL);
174 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
177 r = RegCloseKey(hkey);
178 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
180 /* empty attribute */
181 r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
182 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
184 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
185 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
187 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
188 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
190 r = RegCloseKey(hkey);
191 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
193 r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
194 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
197 static void test_getcomponentpath(void)
203 if(!pMsiGetComponentPathA)
206 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
207 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
209 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
210 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
212 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
213 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
217 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
218 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
220 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
221 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
222 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
224 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
225 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
226 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
228 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
229 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
230 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
232 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
233 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
234 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
237 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
242 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
243 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
244 WriteFile(file, data, strlen(data), &written, NULL);
248 SetFilePointer(file, size, NULL, FILE_BEGIN);
255 #define HASHSIZE sizeof(MSIFILEHASHINFO)
261 MSIFILEHASHINFO hash;
266 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
270 { "C:\\Program Files\\msitest\\caesar\n", 0,
272 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
276 { "C:\\Program Files\\msitest\\caesar\n", 500,
278 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
283 static void test_MsiGetFileHash(void)
285 const char name[] = "msitest.bin";
287 MSIFILEHASHINFO hash;
290 if (!pMsiGetFileHashA)
292 skip("MsiGetFileHash not implemented\n");
296 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
298 /* szFilePath is NULL */
299 r = pMsiGetFileHashA(NULL, 0, &hash);
300 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
302 /* szFilePath is empty */
303 r = pMsiGetFileHashA("", 0, &hash);
304 ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
306 /* szFilePath is nonexistent */
307 r = pMsiGetFileHashA(name, 0, &hash);
308 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
310 /* dwOptions is non-zero */
311 r = pMsiGetFileHashA(name, 1, &hash);
312 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
314 /* pHash.dwFileHashInfoSize is not correct */
315 hash.dwFileHashInfoSize = 0;
316 r = pMsiGetFileHashA(name, 0, &hash);
317 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
320 r = pMsiGetFileHashA(name, 0, NULL);
321 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
323 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
325 create_file(name, hash_data[i].data, hash_data[i].size);
327 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
328 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
330 r = pMsiGetFileHashA(name, 0, &hash);
331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
332 ok(!memcmp(&hash, &hash_data[i].hash, HASHSIZE), "Hash incorrect\n");
338 /* copied from dlls/msi/registry.c */
339 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
344 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
358 out[17+i*2] = in[n++];
359 out[16+i*2] = in[n++];
364 out[17+i*2] = in[n++];
365 out[16+i*2] = in[n++];
371 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
373 WCHAR guidW[MAX_PATH];
374 WCHAR squashedW[MAX_PATH];
379 hr = CoCreateGuid(&guid);
380 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
382 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
383 ok(size == 39, "Expected 39, got %d\n", hr);
385 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
386 squash_guid(guidW, squashedW);
387 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
390 static void get_user_sid(LPSTR *usersid)
397 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
399 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
400 user = (PTOKEN_USER)buf;
401 pConvertSidToStringSidA(user->User.Sid, usersid);
404 static void test_MsiQueryProductState(void)
406 CHAR prodcode[MAX_PATH];
407 CHAR prod_squashed[MAX_PATH];
408 CHAR keypath[MAX_PATH*2];
412 HKEY userkey, localkey, props;
415 create_test_guid(prodcode, prod_squashed);
416 get_user_sid(&usersid);
419 state = MsiQueryProductStateA(NULL);
420 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
423 state = MsiQueryProductStateA("");
424 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
426 /* garbage prodcode */
427 state = MsiQueryProductStateA("garbage");
428 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
430 /* guid without brackets */
431 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
432 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
434 /* guid with brackets */
435 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
436 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
438 /* same length as guid, but random */
439 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
440 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
442 /* created guid cannot possibly be an installed product code */
443 state = MsiQueryProductStateA(prodcode);
444 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
446 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
447 lstrcatA(keypath, prod_squashed);
449 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
450 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
452 /* user product key exists */
453 state = MsiQueryProductStateA(prodcode);
454 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
456 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
457 lstrcatA(keypath, prodcode);
459 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
460 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
462 /* local uninstall key exists */
463 state = MsiQueryProductStateA(prodcode);
464 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
467 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
470 /* WindowsInstaller value exists */
471 state = MsiQueryProductStateA(prodcode);
472 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
474 RegDeleteValueA(localkey, "WindowsInstaller");
475 RegDeleteKeyA(localkey, "");
477 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
478 lstrcatA(keypath, usersid);
479 lstrcatA(keypath, "\\Products\\");
480 lstrcatA(keypath, prod_squashed);
482 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
483 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
485 /* local product key exists */
486 state = MsiQueryProductStateA(prodcode);
487 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
489 res = RegCreateKeyA(localkey, "InstallProperties", &props);
490 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
492 /* install properties key exists */
493 state = MsiQueryProductStateA(prodcode);
494 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
497 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
498 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
500 /* WindowsInstaller value exists */
501 state = MsiQueryProductStateA(prodcode);
502 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
505 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
506 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
508 /* WindowsInstaller value is not 1 */
509 state = MsiQueryProductStateA(prodcode);
510 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
512 RegDeleteKeyA(userkey, "");
514 /* user product key does not exist */
515 state = MsiQueryProductStateA(prodcode);
516 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
519 RegDeleteValueA(props, "WindowsInstaller");
520 RegDeleteKeyA(props, "");
521 RegDeleteKeyA(localkey, "");
522 RegCloseKey(userkey);
523 RegCloseKey(localkey);
527 static const char table_enc85[] =
528 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
529 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
533 * Encodes a base85 guid given a GUID pointer
534 * Caller should provide a 21 character buffer for the encoded string.
536 * returns TRUE if successful, FALSE if not
538 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
540 unsigned int x, *p, i;
542 p = (unsigned int*) guid;
546 *str++ = table_enc85[x%85];
548 *str++ = table_enc85[x%85];
550 *str++ = table_enc85[x%85];
552 *str++ = table_enc85[x%85];
554 *str++ = table_enc85[x%85];
561 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
563 WCHAR guidW[MAX_PATH];
564 WCHAR base85W[MAX_PATH];
565 WCHAR squashedW[MAX_PATH];
570 hr = CoCreateGuid(&guid);
571 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
573 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
574 ok(size == 39, "Expected 39, got %d\n", hr);
576 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
577 encode_base85_guid(&guid, base85W);
578 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
579 squash_guid(guidW, squashedW);
580 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
583 static void test_MsiQueryFeatureState(void)
585 HKEY userkey, localkey, compkey;
586 CHAR prodcode[MAX_PATH];
587 CHAR prod_squashed[MAX_PATH];
588 CHAR component[MAX_PATH];
589 CHAR comp_base85[MAX_PATH];
590 CHAR comp_squashed[MAX_PATH];
591 CHAR keypath[MAX_PATH*2];
596 create_test_guid(prodcode, prod_squashed);
597 compose_base85_guid(component, comp_base85, comp_squashed);
598 get_user_sid(&usersid);
601 state = MsiQueryFeatureStateA(NULL, "feature");
602 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
605 state = MsiQueryFeatureStateA("", "feature");
606 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
608 /* garbage prodcode */
609 state = MsiQueryFeatureStateA("garbage", "feature");
610 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
612 /* guid without brackets */
613 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
614 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
616 /* guid with brackets */
617 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
618 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
620 /* same length as guid, but random */
621 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
622 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
625 state = MsiQueryFeatureStateA(prodcode, NULL);
626 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
628 /* empty szFeature */
629 state = MsiQueryFeatureStateA(prodcode, "");
630 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
632 /* feature key does not exist yet */
633 state = MsiQueryFeatureStateA(prodcode, "feature");
634 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
636 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
637 lstrcatA(keypath, prod_squashed);
639 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
640 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
642 /* feature key exists */
643 state = MsiQueryFeatureStateA(prodcode, "feature");
644 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
646 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 8);
647 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
649 state = MsiQueryFeatureStateA(prodcode, "feature");
650 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
652 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
653 lstrcatA(keypath, usersid);
654 lstrcatA(keypath, "\\Products\\");
655 lstrcatA(keypath, prod_squashed);
656 lstrcatA(keypath, "\\Features");
658 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
659 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
661 state = MsiQueryFeatureStateA(prodcode, "feature");
662 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
664 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
667 state = MsiQueryFeatureStateA(prodcode, "feature");
668 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
670 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
671 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
673 state = MsiQueryFeatureStateA(prodcode, "feature");
674 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
676 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
677 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
679 state = MsiQueryFeatureStateA(prodcode, "feature");
680 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
682 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
685 state = MsiQueryFeatureStateA(prodcode, "feature");
686 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
688 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
689 lstrcatA(keypath, usersid);
690 lstrcatA(keypath, "\\Components\\");
691 lstrcatA(keypath, comp_squashed);
693 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
696 state = MsiQueryFeatureStateA(prodcode, "feature");
697 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
699 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
700 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
702 state = MsiQueryFeatureStateA(prodcode, "feature");
703 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
705 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
706 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
708 state = MsiQueryFeatureStateA(prodcode, "feature");
709 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
711 RegDeleteValueA(compkey, prod_squashed);
712 RegDeleteValueA(compkey, "");
713 RegDeleteValueA(localkey, "feature");
714 RegDeleteValueA(userkey, "feature");
715 RegDeleteKeyA(userkey, "");
716 RegCloseKey(compkey);
717 RegCloseKey(localkey);
718 RegCloseKey(userkey);
721 static void test_MsiQueryComponentState(void)
723 HKEY compkey, prodkey;
724 CHAR prodcode[MAX_PATH];
725 CHAR prod_squashed[MAX_PATH];
726 CHAR component[MAX_PATH];
727 CHAR comp_base85[MAX_PATH];
728 CHAR comp_squashed[MAX_PATH];
729 CHAR keypath[MAX_PATH];
735 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
737 if (!pMsiQueryComponentStateA)
739 skip("MsiQueryComponentStateA not implemented\n");
743 create_test_guid(prodcode, prod_squashed);
744 compose_base85_guid(component, comp_base85, comp_squashed);
745 get_user_sid(&usersid);
747 /* NULL szProductCode */
749 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
750 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
751 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
753 /* empty szProductCode */
755 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
756 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
757 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
759 /* random szProductCode */
761 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
762 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
763 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
765 /* GUID-length szProductCode */
767 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
768 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
769 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
771 /* GUID-length with brackets */
773 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
774 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
775 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
779 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
780 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
781 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
784 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
785 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
786 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
788 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
789 lstrcatA(keypath, prod_squashed);
791 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
792 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
795 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
796 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
797 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
799 RegDeleteKeyA(prodkey, "");
800 RegCloseKey(prodkey);
802 /* create local system product key */
803 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
804 lstrcatA(keypath, prod_squashed);
805 lstrcatA(keypath, "\\InstallProperties");
807 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
808 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
810 /* local system product key exists */
812 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
813 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
814 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
816 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
817 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
819 /* LocalPackage value exists */
821 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
822 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
823 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
825 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
826 lstrcatA(keypath, comp_squashed);
828 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
829 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
831 /* component key exists */
833 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
834 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
835 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
837 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
838 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
840 /* component\product exists */
842 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
843 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
844 ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
846 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
847 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
850 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
851 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
852 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
854 RegDeleteValueA(prodkey, "LocalPackage");
855 RegDeleteKeyA(prodkey, "");
856 RegDeleteValueA(compkey, prod_squashed);
857 RegDeleteKeyA(prodkey, "");
858 RegCloseKey(prodkey);
859 RegCloseKey(compkey);
861 /* MSIINSTALLCONTEXT_USERUNMANAGED */
864 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
865 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
866 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
868 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
869 lstrcatA(keypath, prod_squashed);
871 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
872 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
875 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
876 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
877 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
879 RegDeleteKeyA(prodkey, "");
880 RegCloseKey(prodkey);
882 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
883 lstrcatA(keypath, usersid);
884 lstrcatA(keypath, "\\Products\\");
885 lstrcatA(keypath, prod_squashed);
886 lstrcatA(keypath, "\\InstallProperties");
888 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
891 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
894 RegCloseKey(prodkey);
897 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
898 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
899 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
901 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
902 lstrcatA(keypath, usersid);
903 lstrcatA(keypath, "\\Components\\");
904 lstrcatA(keypath, comp_squashed);
906 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
907 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
909 /* component key exists */
911 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
912 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
913 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
915 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
916 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
918 /* component\product exists */
920 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
921 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
922 ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
924 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
925 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
928 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
930 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
932 /* MSIINSTALLCONTEXT_USERMANAGED */
935 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
936 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
937 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
939 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
940 lstrcatA(keypath, prod_squashed);
942 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
943 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
946 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
947 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
948 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
950 RegDeleteKeyA(prodkey, "");
951 RegCloseKey(prodkey);
953 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
954 lstrcatA(keypath, usersid);
955 lstrcatA(keypath, "\\Installer\\Products\\");
956 lstrcatA(keypath, prod_squashed);
958 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
959 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
962 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
963 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
964 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
966 RegDeleteKeyA(prodkey, "");
967 RegCloseKey(prodkey);
969 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
970 lstrcatA(keypath, usersid);
971 lstrcatA(keypath, "\\Products\\");
972 lstrcatA(keypath, prod_squashed);
973 lstrcatA(keypath, "\\InstallProperties");
975 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
978 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
979 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
982 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
984 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
986 RegDeleteValueA(prodkey, "LocalPackage");
987 RegDeleteValueA(prodkey, "ManagedLocalPackage");
988 RegDeleteKeyA(prodkey, "");
989 RegDeleteValueA(compkey, prod_squashed);
990 RegDeleteKeyA(compkey, "");
991 RegCloseKey(prodkey);
992 RegCloseKey(compkey);
995 static void test_MsiGetComponentPath(void)
997 HKEY compkey, prodkey, installprop;
998 CHAR prodcode[MAX_PATH];
999 CHAR prod_squashed[MAX_PATH];
1000 CHAR component[MAX_PATH];
1001 CHAR comp_base85[MAX_PATH];
1002 CHAR comp_squashed[MAX_PATH];
1003 CHAR keypath[MAX_PATH];
1004 CHAR path[MAX_PATH];
1010 create_test_guid(prodcode, prod_squashed);
1011 compose_base85_guid(component, comp_base85, comp_squashed);
1012 get_user_sid(&usersid);
1014 /* NULL szProduct */
1016 state = MsiGetComponentPathA(NULL, component, path, &size);
1017 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1018 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1020 /* NULL szComponent */
1022 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1023 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1024 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1026 /* NULL lpPathBuf */
1028 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1029 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1030 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1034 state = MsiGetComponentPathA(prodcode, component, path, NULL);
1035 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1036 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1038 /* all params valid */
1040 state = MsiGetComponentPathA(prodcode, component, path, &size);
1041 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1042 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1044 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1045 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1046 lstrcatA(keypath, comp_squashed);
1048 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1049 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1051 /* local system component key exists */
1053 state = MsiGetComponentPathA(prodcode, component, path, &size);
1054 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1055 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1057 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1058 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1060 /* product value exists */
1062 state = MsiGetComponentPathA(prodcode, component, path, &size);
1063 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1064 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1065 ok(size == 10, "Expected 10, got %d\n", size);
1067 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1068 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1069 lstrcatA(keypath, prod_squashed);
1070 lstrcatA(keypath, "\\InstallProperties");
1072 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1073 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1076 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1077 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1079 /* install properties key exists */
1081 state = MsiGetComponentPathA(prodcode, component, path, &size);
1082 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1083 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1084 ok(size == 10, "Expected 10, got %d\n", size);
1086 create_file("C:\\imapath", "C:\\imapath", 11);
1090 state = MsiGetComponentPathA(prodcode, component, path, &size);
1091 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1092 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1093 ok(size == 10, "Expected 10, got %d\n", size);
1095 RegDeleteValueA(compkey, prod_squashed);
1096 RegDeleteKeyA(compkey, "");
1097 RegDeleteValueA(installprop, "WindowsInstaller");
1098 RegDeleteKeyA(installprop, "");
1099 RegCloseKey(compkey);
1100 RegCloseKey(installprop);
1101 DeleteFileA("C:\\imapath");
1103 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1104 lstrcatA(keypath, "Installer\\UserData\\");
1105 lstrcatA(keypath, usersid);
1106 lstrcatA(keypath, "\\Components\\");
1107 lstrcatA(keypath, comp_squashed);
1109 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1110 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1112 /* user managed component key exists */
1114 state = MsiGetComponentPathA(prodcode, component, path, &size);
1115 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1116 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1118 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1121 /* product value exists */
1123 state = MsiGetComponentPathA(prodcode, component, path, &size);
1124 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1125 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1126 ok(size == 10, "Expected 10, got %d\n", size);
1128 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1129 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1130 lstrcatA(keypath, prod_squashed);
1131 lstrcatA(keypath, "\\InstallProperties");
1133 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1134 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1137 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1138 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1140 /* install properties key exists */
1142 state = MsiGetComponentPathA(prodcode, component, path, &size);
1143 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1144 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1145 ok(size == 10, "Expected 10, got %d\n", size);
1147 create_file("C:\\imapath", "C:\\imapath", 11);
1151 state = MsiGetComponentPathA(prodcode, component, path, &size);
1152 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1153 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1154 ok(size == 10, "Expected 10, got %d\n", size);
1156 RegDeleteValueA(compkey, prod_squashed);
1157 RegDeleteKeyA(compkey, "");
1158 RegDeleteValueA(installprop, "WindowsInstaller");
1159 RegDeleteKeyA(installprop, "");
1160 RegCloseKey(compkey);
1161 RegCloseKey(installprop);
1162 DeleteFileA("C:\\imapath");
1164 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1165 lstrcatA(keypath, "Installer\\Managed\\");
1166 lstrcatA(keypath, usersid);
1167 lstrcatA(keypath, "\\Installer\\Products\\");
1168 lstrcatA(keypath, prod_squashed);
1170 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1173 /* user managed product key exists */
1175 state = MsiGetComponentPathA(prodcode, component, path, &size);
1176 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1177 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1179 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1180 lstrcatA(keypath, "Installer\\UserData\\");
1181 lstrcatA(keypath, usersid);
1182 lstrcatA(keypath, "\\Components\\");
1183 lstrcatA(keypath, comp_squashed);
1185 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1186 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1188 /* user managed component key exists */
1190 state = MsiGetComponentPathA(prodcode, component, path, &size);
1191 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1192 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1194 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1195 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1197 /* product value exists */
1199 state = MsiGetComponentPathA(prodcode, component, path, &size);
1200 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1201 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1202 ok(size == 10, "Expected 10, got %d\n", size);
1204 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1205 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1206 lstrcatA(keypath, prod_squashed);
1207 lstrcatA(keypath, "\\InstallProperties");
1209 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1210 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1213 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1214 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1216 /* install properties key exists */
1218 state = MsiGetComponentPathA(prodcode, component, path, &size);
1219 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1220 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1221 ok(size == 10, "Expected 10, got %d\n", size);
1223 create_file("C:\\imapath", "C:\\imapath", 11);
1227 state = MsiGetComponentPathA(prodcode, component, path, &size);
1228 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1229 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1230 ok(size == 10, "Expected 10, got %d\n", size);
1232 RegDeleteValueA(compkey, prod_squashed);
1233 RegDeleteKeyA(prodkey, "");
1234 RegDeleteKeyA(compkey, "");
1235 RegDeleteValueA(installprop, "WindowsInstaller");
1236 RegDeleteKeyA(installprop, "");
1237 RegCloseKey(prodkey);
1238 RegCloseKey(compkey);
1239 RegCloseKey(installprop);
1240 DeleteFileA("C:\\imapath");
1242 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1243 lstrcatA(keypath, prod_squashed);
1245 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1246 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1248 /* user unmanaged product key exists */
1250 state = MsiGetComponentPathA(prodcode, component, path, &size);
1251 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1252 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1254 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1255 lstrcatA(keypath, "Installer\\UserData\\");
1256 lstrcatA(keypath, usersid);
1257 lstrcatA(keypath, "\\Components\\");
1258 lstrcatA(keypath, comp_squashed);
1260 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1261 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1263 /* user unmanaged component key exists */
1265 state = MsiGetComponentPathA(prodcode, component, path, &size);
1266 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1267 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1269 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1270 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1272 /* product value exists */
1274 state = MsiGetComponentPathA(prodcode, component, path, &size);
1275 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1276 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1277 ok(size == 10, "Expected 10, got %d\n", size);
1279 create_file("C:\\imapath", "C:\\imapath", 11);
1283 state = MsiGetComponentPathA(prodcode, component, path, &size);
1284 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1285 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1286 ok(size == 10, "Expected 10, got %d\n", size);
1288 RegDeleteValueA(compkey, prod_squashed);
1289 RegDeleteKeyA(prodkey, "");
1290 RegDeleteKeyA(compkey, "");
1291 RegCloseKey(prodkey);
1292 RegCloseKey(compkey);
1293 RegCloseKey(installprop);
1294 DeleteFileA("C:\\imapath");
1296 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1297 lstrcatA(keypath, prod_squashed);
1299 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1302 /* local classes product key exists */
1304 state = MsiGetComponentPathA(prodcode, component, path, &size);
1305 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1306 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1308 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1309 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1310 lstrcatA(keypath, comp_squashed);
1312 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1313 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1315 /* local user component key exists */
1317 state = MsiGetComponentPathA(prodcode, component, path, &size);
1318 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1319 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1321 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1322 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1324 /* product value exists */
1326 state = MsiGetComponentPathA(prodcode, component, path, &size);
1327 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1328 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1329 ok(size == 10, "Expected 10, got %d\n", size);
1331 create_file("C:\\imapath", "C:\\imapath", 11);
1335 state = MsiGetComponentPathA(prodcode, component, path, &size);
1336 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1337 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1338 ok(size == 10, "Expected 10, got %d\n", size);
1340 RegDeleteValueA(compkey, prod_squashed);
1341 RegDeleteKeyA(prodkey, "");
1342 RegDeleteKeyA(compkey, "");
1343 RegCloseKey(prodkey);
1344 RegCloseKey(compkey);
1345 DeleteFileA("C:\\imapath");
1348 static void test_MsiGetProductCode(void)
1350 HKEY compkey, prodkey;
1351 CHAR prodcode[MAX_PATH];
1352 CHAR prod_squashed[MAX_PATH];
1353 CHAR prodcode2[MAX_PATH];
1354 CHAR prod2_squashed[MAX_PATH];
1355 CHAR component[MAX_PATH];
1356 CHAR comp_base85[MAX_PATH];
1357 CHAR comp_squashed[MAX_PATH];
1358 CHAR keypath[MAX_PATH];
1359 CHAR product[MAX_PATH];
1364 create_test_guid(prodcode, prod_squashed);
1365 create_test_guid(prodcode2, prod2_squashed);
1366 compose_base85_guid(component, comp_base85, comp_squashed);
1367 get_user_sid(&usersid);
1369 /* szComponent is NULL */
1370 lstrcpyA(product, "prod");
1371 r = MsiGetProductCodeA(NULL, product);
1372 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1373 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1375 /* szComponent is empty */
1376 lstrcpyA(product, "prod");
1377 r = MsiGetProductCodeA("", product);
1378 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1379 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1381 /* garbage szComponent */
1382 lstrcpyA(product, "prod");
1383 r = MsiGetProductCodeA("garbage", product);
1384 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1385 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1387 /* guid without brackets */
1388 lstrcpyA(product, "prod");
1389 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1390 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1391 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1393 /* guid with brackets */
1394 lstrcpyA(product, "prod");
1395 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1396 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1397 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1399 /* same length as guid, but random */
1400 lstrcpyA(product, "prod");
1401 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1402 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1403 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1405 /* all params correct, szComponent not published */
1406 lstrcpyA(product, "prod");
1407 r = MsiGetProductCodeA(component, product);
1408 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1409 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1411 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1412 lstrcatA(keypath, "Installer\\UserData\\");
1413 lstrcatA(keypath, usersid);
1414 lstrcatA(keypath, "\\Components\\");
1415 lstrcatA(keypath, comp_squashed);
1417 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1418 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1420 /* user unmanaged component key exists */
1421 lstrcpyA(product, "prod");
1422 r = MsiGetProductCodeA(component, product);
1423 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1424 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1426 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1429 /* product value exists */
1430 lstrcpyA(product, "prod");
1431 r = MsiGetProductCodeA(component, product);
1432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1433 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1435 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1436 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1438 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1439 lstrcatA(keypath, "Installer\\Managed\\");
1440 lstrcatA(keypath, usersid);
1441 lstrcatA(keypath, "\\Installer\\Products\\");
1442 lstrcatA(keypath, prod_squashed);
1444 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1445 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1447 /* user managed product key of first product exists */
1448 lstrcpyA(product, "prod");
1449 r = MsiGetProductCodeA(component, product);
1450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1451 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1453 RegDeleteKeyA(prodkey, "");
1454 RegCloseKey(prodkey);
1456 RegDeleteKeyA(prodkey, "");
1457 RegCloseKey(prodkey);
1459 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1460 lstrcatA(keypath, prod_squashed);
1462 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1463 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1465 /* user unmanaged product key exists */
1466 lstrcpyA(product, "prod");
1467 r = MsiGetProductCodeA(component, product);
1468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1469 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1471 RegDeleteKeyA(prodkey, "");
1472 RegCloseKey(prodkey);
1474 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1475 lstrcatA(keypath, prod_squashed);
1477 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1478 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1480 /* local classes product key exists */
1481 lstrcpyA(product, "prod");
1482 r = MsiGetProductCodeA(component, product);
1483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1484 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1486 RegDeleteKeyA(prodkey, "");
1487 RegCloseKey(prodkey);
1489 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1490 lstrcatA(keypath, "Installer\\Managed\\");
1491 lstrcatA(keypath, usersid);
1492 lstrcatA(keypath, "\\Installer\\Products\\");
1493 lstrcatA(keypath, prod2_squashed);
1495 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1496 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1498 /* user managed product key of second product exists */
1499 lstrcpyA(product, "prod");
1500 r = MsiGetProductCodeA(component, product);
1501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1502 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1504 RegDeleteKeyA(prodkey, "");
1505 RegCloseKey(prodkey);
1506 RegDeleteValueA(compkey, prod_squashed);
1507 RegDeleteValueA(compkey, prod2_squashed);
1508 RegDeleteKeyA(compkey, "");
1509 RegCloseKey(compkey);
1511 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1512 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1513 lstrcatA(keypath, comp_squashed);
1515 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1516 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1518 /* local user component key exists */
1519 lstrcpyA(product, "prod");
1520 r = MsiGetProductCodeA(component, product);
1521 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1522 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1524 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1527 /* product value exists */
1528 lstrcpyA(product, "prod");
1529 r = MsiGetProductCodeA(component, product);
1530 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1531 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1533 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1534 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1536 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1537 lstrcatA(keypath, "Installer\\Managed\\");
1538 lstrcatA(keypath, usersid);
1539 lstrcatA(keypath, "\\Installer\\Products\\");
1540 lstrcatA(keypath, prod_squashed);
1542 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1543 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1545 /* user managed product key of first product exists */
1546 lstrcpyA(product, "prod");
1547 r = MsiGetProductCodeA(component, product);
1548 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1549 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1551 RegDeleteKeyA(prodkey, "");
1552 RegCloseKey(prodkey);
1554 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1555 lstrcatA(keypath, prod_squashed);
1557 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1558 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1560 /* user unmanaged product key exists */
1561 lstrcpyA(product, "prod");
1562 r = MsiGetProductCodeA(component, product);
1563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1564 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1566 RegDeleteKeyA(prodkey, "");
1567 RegCloseKey(prodkey);
1569 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1570 lstrcatA(keypath, prod_squashed);
1572 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1573 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1575 /* local classes product key exists */
1576 lstrcpyA(product, "prod");
1577 r = MsiGetProductCodeA(component, product);
1578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1579 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1581 RegDeleteKeyA(prodkey, "");
1582 RegCloseKey(prodkey);
1584 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1585 lstrcatA(keypath, "Installer\\Managed\\");
1586 lstrcatA(keypath, usersid);
1587 lstrcatA(keypath, "\\Installer\\Products\\");
1588 lstrcatA(keypath, prod2_squashed);
1590 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1591 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1593 /* user managed product key of second product exists */
1594 lstrcpyA(product, "prod");
1595 r = MsiGetProductCodeA(component, product);
1596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1597 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1599 RegDeleteKeyA(prodkey, "");
1600 RegCloseKey(prodkey);
1601 RegDeleteValueA(compkey, prod_squashed);
1602 RegDeleteValueA(compkey, prod2_squashed);
1603 RegDeleteKeyA(compkey, "");
1604 RegCloseKey(compkey);
1607 static void test_MsiEnumClients(void)
1610 CHAR prodcode[MAX_PATH];
1611 CHAR prod_squashed[MAX_PATH];
1612 CHAR prodcode2[MAX_PATH];
1613 CHAR prod2_squashed[MAX_PATH];
1614 CHAR component[MAX_PATH];
1615 CHAR comp_base85[MAX_PATH];
1616 CHAR comp_squashed[MAX_PATH];
1617 CHAR product[MAX_PATH];
1618 CHAR keypath[MAX_PATH];
1623 create_test_guid(prodcode, prod_squashed);
1624 create_test_guid(prodcode2, prod2_squashed);
1625 compose_base85_guid(component, comp_base85, comp_squashed);
1626 get_user_sid(&usersid);
1628 /* NULL szComponent */
1630 r = MsiEnumClientsA(NULL, 0, product);
1631 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1632 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1634 /* empty szComponent */
1636 r = MsiEnumClientsA("", 0, product);
1637 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1638 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1640 /* NULL lpProductBuf */
1641 r = MsiEnumClientsA(component, 0, NULL);
1642 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1644 /* all params correct, component missing */
1646 r = MsiEnumClientsA(component, 0, product);
1647 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1648 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1650 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1651 lstrcatA(keypath, "Installer\\UserData\\");
1652 lstrcatA(keypath, usersid);
1653 lstrcatA(keypath, "\\Components\\");
1654 lstrcatA(keypath, comp_squashed);
1656 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1657 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1659 /* user unmanaged component key exists */
1661 r = MsiEnumClientsA(component, 0, product);
1662 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1663 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1665 /* index > 0, no products exist */
1667 r = MsiEnumClientsA(component, 1, product);
1668 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1669 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1671 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1672 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1674 /* product value exists */
1675 r = MsiEnumClientsA(component, 0, product);
1676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1677 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1679 /* try index 0 again */
1681 r = MsiEnumClientsA(component, 0, product);
1682 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1683 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1685 /* try index 1, second product value does not exist */
1687 r = MsiEnumClientsA(component, 1, product);
1688 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1689 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1691 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1692 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1694 /* try index 1, second product value does exist */
1696 r = MsiEnumClientsA(component, 1, product);
1699 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1700 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1703 /* start the enumeration over */
1705 r = MsiEnumClientsA(component, 0, product);
1706 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1707 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
1708 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
1710 /* correctly query second product */
1712 r = MsiEnumClientsA(component, 1, product);
1713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1714 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
1715 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
1717 RegDeleteValueA(compkey, prod_squashed);
1718 RegDeleteValueA(compkey, prod2_squashed);
1719 RegDeleteKeyA(compkey, "");
1720 RegCloseKey(compkey);
1722 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1723 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1724 lstrcatA(keypath, comp_squashed);
1726 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1727 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1729 /* user local component key exists */
1731 r = MsiEnumClientsA(component, 0, product);
1732 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1733 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1735 /* index > 0, no products exist */
1737 r = MsiEnumClientsA(component, 1, product);
1738 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1739 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1741 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1742 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1744 /* product value exists */
1746 r = MsiEnumClientsA(component, 0, product);
1747 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1748 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1750 /* try index 0 again */
1752 r = MsiEnumClientsA(component, 0, product);
1753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1755 /* try index 1, second product value does not exist */
1757 r = MsiEnumClientsA(component, 1, product);
1758 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1759 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1761 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1762 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1764 /* try index 1, second product value does exist */
1766 r = MsiEnumClientsA(component, 1, product);
1769 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1770 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
1773 /* start the enumeration over */
1775 r = MsiEnumClientsA(component, 0, product);
1776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1777 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
1778 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
1780 /* correctly query second product */
1782 r = MsiEnumClientsA(component, 1, product);
1783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1784 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
1785 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
1787 RegDeleteValueA(compkey, prod_squashed);
1788 RegDeleteValueA(compkey, prod2_squashed);
1789 RegDeleteKeyA(compkey, "");
1790 RegCloseKey(compkey);
1795 init_functionpointers();
1799 test_getcomponentpath();
1800 test_MsiGetFileHash();
1802 if (!pConvertSidToStringSidA)
1803 skip("ConvertSidToStringSidA not implemented\n");
1806 /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
1807 test_MsiQueryProductState();
1808 test_MsiQueryFeatureState();
1809 test_MsiQueryComponentState();
1810 test_MsiGetComponentPath();
1811 test_MsiGetProductCode();
1812 test_MsiEnumClients();