msi: Reimplement MsiGetComponentPath.
[wine/wine-kai.git] / dlls / msi / tests / msi.c
blob975d722a3e142d212dd7c09a0482cdbb13b386e0
1 /*
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
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <sddl.h>
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 pMsiGetComponentPathA = (void*)GetProcAddress(hmsi, "MsiGetComponentPathA");
52 pMsiGetFileHashA = (void*)GetProcAddress(hmsi, "MsiGetFileHashA");
53 pMsiOpenPackageExA = (void*)GetProcAddress(hmsi, "MsiOpenPackageExA");
54 pMsiOpenPackageExW = (void*)GetProcAddress(hmsi, "MsiOpenPackageExW");
55 pMsiQueryComponentStateA = (void*)GetProcAddress(hmsi, "MsiQueryComponentStateA");
56 pMsiUseFeatureExA = (void*)GetProcAddress(hmsi, "MsiUseFeatureExA");
58 pConvertSidToStringSidA = (void*)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
61 static void test_usefeature(void)
63 INSTALLSTATE r;
65 if (!pMsiUseFeatureExA)
66 return;
68 r = MsiQueryFeatureState(NULL,NULL);
69 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
71 r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
72 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
74 r = pMsiUseFeatureExA(NULL,NULL,0,0);
75 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
77 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
78 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
80 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
81 NULL, -2, 0 );
82 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
84 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
85 "WORDVIEWFiles", -2, 0 );
86 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
88 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
89 "WORDVIEWFiles", -2, 0 );
90 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
92 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
93 "WORDVIEWFiles", -2, 1 );
94 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
97 static void test_null(void)
99 MSIHANDLE hpkg;
100 UINT r;
101 HKEY hkey;
102 DWORD dwType, cbData;
103 LPBYTE lpData = NULL;
104 INSTALLSTATE state;
106 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
107 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
109 state = MsiQueryProductStateW(NULL);
110 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
112 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
113 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
115 r = MsiConfigureFeatureW(NULL, NULL, 0);
116 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
118 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
119 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
121 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
122 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
124 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
125 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
127 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
128 * necessary registry values */
130 /* empty product string */
131 r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
132 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
134 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
135 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
136 if ( r == ERROR_SUCCESS )
138 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
139 if (!lpData)
140 skip("Out of memory\n");
141 else
143 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
144 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
148 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
149 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
151 r = MsiGetProductInfoA("", "", NULL, NULL);
152 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
154 if (lpData)
156 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
157 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
159 HeapFree(GetProcessHeap(), 0, lpData);
161 else
163 r = RegDeleteValueA(hkey, NULL);
164 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
167 r = RegCloseKey(hkey);
168 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
170 /* empty attribute */
171 r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
172 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
174 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
175 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
177 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
178 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
180 r = RegCloseKey(hkey);
181 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
183 r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
184 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
187 static void test_getcomponentpath(void)
189 INSTALLSTATE r;
190 char buffer[0x100];
191 DWORD sz;
193 if(!pMsiGetComponentPathA)
194 return;
196 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
197 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
199 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
200 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
202 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
203 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
205 sz = sizeof buffer;
206 buffer[0]=0;
207 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
208 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
210 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
211 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
212 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
214 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
215 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
216 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
218 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
219 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
220 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
222 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
223 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
224 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
227 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
229 HANDLE file;
230 DWORD written;
232 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
233 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
234 WriteFile(file, data, strlen(data), &written, NULL);
236 if (size)
238 SetFilePointer(file, size, NULL, FILE_BEGIN);
239 SetEndOfFile(file);
242 CloseHandle(file);
245 #define HASHSIZE sizeof(MSIFILEHASHINFO)
247 static const struct
249 LPCSTR data;
250 DWORD size;
251 MSIFILEHASHINFO hash;
252 } hash_data[] =
254 { "abc", 0,
255 { HASHSIZE,
256 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
260 { "C:\\Program Files\\msitest\\caesar\n", 0,
261 { HASHSIZE,
262 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
266 { "C:\\Program Files\\msitest\\caesar\n", 500,
267 { HASHSIZE,
268 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
273 static void test_MsiGetFileHash(void)
275 const char name[] = "msitest.bin";
276 UINT r;
277 MSIFILEHASHINFO hash;
278 DWORD i;
280 if (!pMsiGetFileHashA)
282 skip("MsiGetFileHash not implemented.");
283 return;
286 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
288 /* szFilePath is NULL */
289 r = pMsiGetFileHashA(NULL, 0, &hash);
290 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
292 /* szFilePath is empty */
293 r = pMsiGetFileHashA("", 0, &hash);
294 ok(r == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", r);
296 /* szFilePath is nonexistent */
297 r = pMsiGetFileHashA(name, 0, &hash);
298 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
300 /* dwOptions is non-zero */
301 r = pMsiGetFileHashA(name, 1, &hash);
302 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
304 /* pHash.dwFileHashInfoSize is not correct */
305 hash.dwFileHashInfoSize = 0;
306 r = pMsiGetFileHashA(name, 0, &hash);
307 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
309 /* pHash is NULL */
310 r = pMsiGetFileHashA(name, 0, NULL);
311 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
313 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
315 create_file(name, hash_data[i].data, hash_data[i].size);
317 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
318 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
320 r = pMsiGetFileHashA(name, 0, &hash);
321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
322 ok(!memcmp(&hash, &hash_data[i].hash, HASHSIZE), "Hash incorrect\n");
324 DeleteFile(name);
328 /* copied from dlls/msi/registry.c */
329 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
331 DWORD i,n=1;
332 GUID guid;
334 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
335 return FALSE;
337 for(i=0; i<8; i++)
338 out[7-i] = in[n++];
339 n++;
340 for(i=0; i<4; i++)
341 out[11-i] = in[n++];
342 n++;
343 for(i=0; i<4; i++)
344 out[15-i] = in[n++];
345 n++;
346 for(i=0; i<2; i++)
348 out[17+i*2] = in[n++];
349 out[16+i*2] = in[n++];
351 n++;
352 for( ; i<8; i++)
354 out[17+i*2] = in[n++];
355 out[16+i*2] = in[n++];
357 out[32]=0;
358 return TRUE;
361 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
363 WCHAR guidW[MAX_PATH];
364 WCHAR squashedW[MAX_PATH];
365 GUID guid;
366 HRESULT hr;
367 int size;
369 hr = CoCreateGuid(&guid);
370 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
372 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
373 ok(size == 39, "Expected 39, got %d\n", hr);
375 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
376 squash_guid(guidW, squashedW);
377 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
380 static void get_user_sid(LPSTR *usersid)
382 HANDLE token;
383 BYTE buf[1024];
384 DWORD size;
385 PTOKEN_USER user;
387 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
388 size = sizeof(buf);
389 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
390 user = (PTOKEN_USER)buf;
391 pConvertSidToStringSidA(user->User.Sid, usersid);
394 static void test_MsiQueryProductState(void)
396 CHAR prodcode[MAX_PATH];
397 CHAR prod_squashed[MAX_PATH];
398 CHAR keypath[MAX_PATH*2];
399 LPSTR usersid;
400 INSTALLSTATE state;
401 LONG res;
402 HKEY userkey, localkey, props;
403 DWORD data;
405 create_test_guid(prodcode, prod_squashed);
406 get_user_sid(&usersid);
408 /* NULL prodcode */
409 state = MsiQueryProductStateA(NULL);
410 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
412 /* empty prodcode */
413 state = MsiQueryProductStateA("");
414 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
416 /* garbage prodcode */
417 state = MsiQueryProductStateA("garbage");
418 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
420 /* guid without brackets */
421 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
422 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
424 /* guid with brackets */
425 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
426 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
428 /* same length as guid, but random */
429 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
430 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
432 /* created guid cannot possibly be an installed product code */
433 state = MsiQueryProductStateA(prodcode);
434 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
436 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
437 lstrcatA(keypath, prod_squashed);
439 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
440 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
442 /* user product key exists */
443 state = MsiQueryProductStateA(prodcode);
444 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
446 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
447 lstrcatA(keypath, prodcode);
449 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
450 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
452 /* local uninstall key exists */
453 state = MsiQueryProductStateA(prodcode);
454 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
456 data = 1;
457 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
458 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
460 /* WindowsInstaller value exists */
461 state = MsiQueryProductStateA(prodcode);
462 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
464 RegDeleteValueA(localkey, "WindowsInstaller");
465 RegDeleteKeyA(localkey, "");
467 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
468 lstrcatA(keypath, usersid);
469 lstrcatA(keypath, "\\Products\\");
470 lstrcatA(keypath, prod_squashed);
472 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
473 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
475 /* local product key exists */
476 state = MsiQueryProductStateA(prodcode);
477 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
479 res = RegCreateKeyA(localkey, "InstallProperties", &props);
480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
482 /* install properties key exists */
483 state = MsiQueryProductStateA(prodcode);
484 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
486 data = 1;
487 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
488 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
490 /* WindowsInstaller value exists */
491 state = MsiQueryProductStateA(prodcode);
492 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
494 data = 2;
495 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
496 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
498 /* WindowsInstaller value is not 1 */
499 state = MsiQueryProductStateA(prodcode);
500 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
502 RegDeleteKeyA(userkey, "");
504 /* user product key does not exist */
505 state = MsiQueryProductStateA(prodcode);
506 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
508 LocalFree(usersid);
509 RegDeleteValueA(props, "WindowsInstaller");
510 RegDeleteKeyA(props, "");
511 RegDeleteKeyA(localkey, "");
512 RegCloseKey(userkey);
513 RegCloseKey(localkey);
514 RegCloseKey(props);
517 static const char table_enc85[] =
518 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
519 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
520 "yz{}~";
523 * Encodes a base85 guid given a GUID pointer
524 * Caller should provide a 21 character buffer for the encoded string.
526 * returns TRUE if successful, FALSE if not
528 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
530 unsigned int x, *p, i;
532 p = (unsigned int*) guid;
533 for( i=0; i<4; i++ )
535 x = p[i];
536 *str++ = table_enc85[x%85];
537 x = x/85;
538 *str++ = table_enc85[x%85];
539 x = x/85;
540 *str++ = table_enc85[x%85];
541 x = x/85;
542 *str++ = table_enc85[x%85];
543 x = x/85;
544 *str++ = table_enc85[x%85];
546 *str = 0;
548 return TRUE;
551 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
553 WCHAR guidW[MAX_PATH];
554 WCHAR base85W[MAX_PATH];
555 WCHAR squashedW[MAX_PATH];
556 GUID guid;
557 HRESULT hr;
558 int size;
560 hr = CoCreateGuid(&guid);
561 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
563 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
564 ok(size == 39, "Expected 39, got %d\n", hr);
566 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
567 encode_base85_guid(&guid, base85W);
568 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
569 squash_guid(guidW, squashedW);
570 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
573 static void test_MsiQueryFeatureState(void)
575 HKEY userkey, localkey, compkey;
576 CHAR prodcode[MAX_PATH];
577 CHAR prod_squashed[MAX_PATH];
578 CHAR component[MAX_PATH];
579 CHAR comp_base85[MAX_PATH];
580 CHAR comp_squashed[MAX_PATH];
581 CHAR keypath[MAX_PATH*2];
582 INSTALLSTATE state;
583 LPSTR usersid;
584 LONG res;
586 create_test_guid(prodcode, prod_squashed);
587 compose_base85_guid(component, comp_base85, comp_squashed);
588 get_user_sid(&usersid);
590 /* NULL prodcode */
591 state = MsiQueryFeatureStateA(NULL, "feature");
592 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
594 /* empty prodcode */
595 state = MsiQueryFeatureStateA("", "feature");
596 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
598 /* garbage prodcode */
599 state = MsiQueryFeatureStateA("garbage", "feature");
600 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
602 /* guid without brackets */
603 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
604 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
606 /* guid with brackets */
607 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
608 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
610 /* same length as guid, but random */
611 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
612 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
614 /* NULL szFeature */
615 state = MsiQueryFeatureStateA(prodcode, NULL);
616 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
618 /* empty szFeature */
619 state = MsiQueryFeatureStateA(prodcode, "");
620 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
622 /* feature key does not exist yet */
623 state = MsiQueryFeatureStateA(prodcode, "feature");
624 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
626 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
627 lstrcatA(keypath, prod_squashed);
629 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
630 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
632 /* feature key exists */
633 state = MsiQueryFeatureStateA(prodcode, "feature");
634 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
636 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 8);
637 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
639 state = MsiQueryFeatureStateA(prodcode, "feature");
640 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
642 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
643 lstrcatA(keypath, usersid);
644 lstrcatA(keypath, "\\Products\\");
645 lstrcatA(keypath, prod_squashed);
646 lstrcatA(keypath, "\\Features");
648 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
649 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
651 state = MsiQueryFeatureStateA(prodcode, "feature");
652 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
654 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
655 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
657 state = MsiQueryFeatureStateA(prodcode, "feature");
658 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
660 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
661 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
663 state = MsiQueryFeatureStateA(prodcode, "feature");
664 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
666 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
667 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
669 state = MsiQueryFeatureStateA(prodcode, "feature");
670 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
672 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
673 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
675 state = MsiQueryFeatureStateA(prodcode, "feature");
676 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
678 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
679 lstrcatA(keypath, usersid);
680 lstrcatA(keypath, "\\Components\\");
681 lstrcatA(keypath, comp_squashed);
683 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
686 state = MsiQueryFeatureStateA(prodcode, "feature");
687 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
689 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
690 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
692 state = MsiQueryFeatureStateA(prodcode, "feature");
693 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
695 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
696 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
698 state = MsiQueryFeatureStateA(prodcode, "feature");
699 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
701 RegDeleteValueA(compkey, prod_squashed);
702 RegDeleteValueA(compkey, "");
703 RegDeleteValueA(localkey, "feature");
704 RegDeleteValueA(userkey, "feature");
705 RegDeleteKeyA(userkey, "");
706 RegCloseKey(compkey);
707 RegCloseKey(localkey);
708 RegCloseKey(userkey);
711 static void test_MsiQueryComponentState(void)
713 HKEY compkey, prodkey;
714 CHAR prodcode[MAX_PATH];
715 CHAR prod_squashed[MAX_PATH];
716 CHAR component[MAX_PATH];
717 CHAR comp_base85[MAX_PATH];
718 CHAR comp_squashed[MAX_PATH];
719 CHAR keypath[MAX_PATH];
720 INSTALLSTATE state;
721 LPSTR usersid;
722 LONG res;
723 UINT r;
725 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
727 create_test_guid(prodcode, prod_squashed);
728 compose_base85_guid(component, comp_base85, comp_squashed);
729 get_user_sid(&usersid);
731 /* NULL szProductCode */
732 state = MAGIC_ERROR;
733 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
734 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
735 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
737 /* empty szProductCode */
738 state = MAGIC_ERROR;
739 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);\
740 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
741 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
743 /* random szProductCode */
744 state = MAGIC_ERROR;
745 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
746 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
747 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
749 /* GUID-length szProductCode */
750 state = MAGIC_ERROR;
751 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
752 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
753 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
755 /* GUID-length with brackets */
756 state = MAGIC_ERROR;
757 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
758 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
759 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
761 /* actual GUID */
762 state = MAGIC_ERROR;
763 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
764 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
765 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
767 state = MAGIC_ERROR;
768 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
769 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
770 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
772 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
773 lstrcatA(keypath, prod_squashed);
775 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
776 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
778 state = MAGIC_ERROR;
779 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
780 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
781 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
783 RegDeleteKeyA(prodkey, "");
784 RegCloseKey(prodkey);
786 /* create local system product key */
787 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
788 lstrcatA(keypath, prod_squashed);
789 lstrcatA(keypath, "\\InstallProperties");
791 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
792 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
794 /* local system product key exists */
795 state = MAGIC_ERROR;
796 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
797 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
798 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
800 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
803 /* LocalPackage value exists */
804 state = MAGIC_ERROR;
805 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
806 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
807 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
809 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
810 lstrcatA(keypath, comp_squashed);
812 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
813 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
815 /* component key exists */
816 state = MAGIC_ERROR;
817 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, 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 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
822 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
824 /* component\product exists */
825 state = MAGIC_ERROR;
826 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
828 ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
830 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
833 state = MAGIC_ERROR;
834 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
836 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
838 RegDeleteValueA(prodkey, "LocalPackage");
839 RegDeleteKeyA(prodkey, "");
840 RegDeleteValueA(compkey, prod_squashed);
841 RegDeleteKeyA(prodkey, "");
842 RegCloseKey(prodkey);
843 RegCloseKey(compkey);
845 /* MSIINSTALLCONTEXT_USERUNMANAGED */
847 state = MAGIC_ERROR;
848 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
849 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
850 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
852 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
853 lstrcatA(keypath, prod_squashed);
855 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
858 state = MAGIC_ERROR;
859 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
860 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
861 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
863 RegDeleteKeyA(prodkey, "");
864 RegCloseKey(prodkey);
866 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
867 lstrcatA(keypath, usersid);
868 lstrcatA(keypath, "\\Products\\");
869 lstrcatA(keypath, prod_squashed);
870 lstrcatA(keypath, "\\InstallProperties");
872 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
873 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
875 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
876 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
878 RegCloseKey(prodkey);
880 state = MAGIC_ERROR;
881 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
882 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
883 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
885 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
886 lstrcatA(keypath, usersid);
887 lstrcatA(keypath, "\\Components\\");
888 lstrcatA(keypath, comp_squashed);
890 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
891 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
893 /* component key exists */
894 state = MAGIC_ERROR;
895 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
896 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
897 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
899 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
900 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
902 /* component\product exists */
903 state = MAGIC_ERROR;
904 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
905 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
906 ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
908 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
909 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
911 state = MAGIC_ERROR;
912 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
914 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
916 /* MSIINSTALLCONTEXT_USERMANAGED */
918 state = MAGIC_ERROR;
919 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
920 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
921 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
923 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
924 lstrcatA(keypath, prod_squashed);
926 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
927 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
929 state = MAGIC_ERROR;
930 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
931 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
932 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
934 RegDeleteKeyA(prodkey, "");
935 RegCloseKey(prodkey);
937 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
938 lstrcatA(keypath, usersid);
939 lstrcatA(keypath, "\\Installer\\Products\\");
940 lstrcatA(keypath, prod_squashed);
942 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
943 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
945 state = MAGIC_ERROR;
946 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
947 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
948 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
950 RegDeleteKeyA(prodkey, "");
951 RegCloseKey(prodkey);
953 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
954 lstrcatA(keypath, usersid);
955 lstrcatA(keypath, "\\Products\\");
956 lstrcatA(keypath, prod_squashed);
957 lstrcatA(keypath, "\\InstallProperties");
959 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
960 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
962 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
963 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
965 state = MAGIC_ERROR;
966 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
968 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
970 RegDeleteValueA(prodkey, "LocalPackage");
971 RegDeleteValueA(prodkey, "ManagedLocalPackage");
972 RegDeleteKeyA(prodkey, "");
973 RegDeleteValueA(compkey, prod_squashed);
974 RegDeleteKeyA(compkey, "");
975 RegCloseKey(prodkey);
976 RegCloseKey(compkey);
979 static void test_MsiGetComponentPath(void)
981 HKEY compkey, prodkey, installprop;
982 CHAR prodcode[MAX_PATH];
983 CHAR prod_squashed[MAX_PATH];
984 CHAR component[MAX_PATH];
985 CHAR comp_base85[MAX_PATH];
986 CHAR comp_squashed[MAX_PATH];
987 CHAR keypath[MAX_PATH];
988 CHAR path[MAX_PATH];
989 INSTALLSTATE state;
990 LPSTR usersid;
991 DWORD size, val;
992 LONG res;
994 create_test_guid(prodcode, prod_squashed);
995 compose_base85_guid(component, comp_base85, comp_squashed);
996 get_user_sid(&usersid);
998 /* NULL szProduct */
999 size = MAX_PATH;
1000 state = MsiGetComponentPathA(NULL, component, path, &size);
1001 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1002 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1004 /* NULL szComponent */
1005 size = MAX_PATH;
1006 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1007 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1008 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1010 /* NULL lpPathBuf */
1011 size = MAX_PATH;
1012 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1013 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1014 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1016 /* NULL pcchBuf */
1017 size = MAX_PATH;
1018 state = MsiGetComponentPathA(prodcode, component, path, NULL);
1019 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1020 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1022 /* all params valid */
1023 size = MAX_PATH;
1024 state = MsiGetComponentPathA(prodcode, component, path, &size);
1025 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1026 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1028 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1029 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1030 lstrcatA(keypath, comp_squashed);
1032 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1033 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1035 /* local system component key exists */
1036 size = MAX_PATH;
1037 state = MsiGetComponentPathA(prodcode, component, path, &size);
1038 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1039 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1041 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1042 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1044 /* product value exists */
1045 size = MAX_PATH;
1046 state = MsiGetComponentPathA(prodcode, component, path, &size);
1047 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1048 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1049 ok(size == 10, "Expected 10, got %d\n", size);
1051 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1052 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1053 lstrcatA(keypath, prod_squashed);
1054 lstrcatA(keypath, "\\InstallProperties");
1056 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1057 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1059 val = 1;
1060 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1061 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1063 /* install properties key exists */
1064 size = MAX_PATH;
1065 state = MsiGetComponentPathA(prodcode, component, path, &size);
1066 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1067 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1068 ok(size == 10, "Expected 10, got %d\n", size);
1070 create_file("C:\\imapath", "C:\\imapath", 11);
1072 /* file exists */
1073 size = MAX_PATH;
1074 state = MsiGetComponentPathA(prodcode, component, path, &size);
1075 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1076 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1077 ok(size == 10, "Expected 10, got %d\n", size);
1079 RegDeleteValueA(compkey, prod_squashed);
1080 RegDeleteKeyA(compkey, "");
1081 RegDeleteValueA(installprop, "WindowsInstaller");
1082 RegDeleteKeyA(installprop, "");
1083 RegCloseKey(compkey);
1084 RegCloseKey(installprop);
1085 DeleteFileA("C:\\imapath");
1087 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1088 lstrcatA(keypath, "Installer\\UserData\\");
1089 lstrcatA(keypath, usersid);
1090 lstrcatA(keypath, "\\Components\\");
1091 lstrcatA(keypath, comp_squashed);
1093 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1094 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1096 /* user managed component key exists */
1097 size = MAX_PATH;
1098 state = MsiGetComponentPathA(prodcode, component, path, &size);
1099 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1100 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1102 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1103 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1105 /* product value exists */
1106 size = MAX_PATH;
1107 state = MsiGetComponentPathA(prodcode, component, path, &size);
1108 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1109 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1110 ok(size == 10, "Expected 10, got %d\n", size);
1112 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1113 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1114 lstrcatA(keypath, prod_squashed);
1115 lstrcatA(keypath, "\\InstallProperties");
1117 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1118 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1120 val = 1;
1121 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1122 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1124 /* install properties key exists */
1125 size = MAX_PATH;
1126 state = MsiGetComponentPathA(prodcode, component, path, &size);
1127 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1128 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1129 ok(size == 10, "Expected 10, got %d\n", size);
1131 create_file("C:\\imapath", "C:\\imapath", 11);
1133 /* file exists */
1134 size = MAX_PATH;
1135 state = MsiGetComponentPathA(prodcode, component, path, &size);
1136 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1137 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1138 ok(size == 10, "Expected 10, got %d\n", size);
1140 RegDeleteValueA(compkey, prod_squashed);
1141 RegDeleteKeyA(compkey, "");
1142 RegDeleteValueA(installprop, "WindowsInstaller");
1143 RegDeleteKeyA(installprop, "");
1144 RegCloseKey(compkey);
1145 RegCloseKey(installprop);
1146 DeleteFileA("C:\\imapath");
1148 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1149 lstrcatA(keypath, "Installer\\Managed\\");
1150 lstrcatA(keypath, usersid);
1151 lstrcatA(keypath, "\\Installer\\Products\\");
1152 lstrcatA(keypath, prod_squashed);
1154 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1155 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1157 /* user managed product key exists */
1158 size = MAX_PATH;
1159 state = MsiGetComponentPathA(prodcode, component, path, &size);
1160 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1161 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1163 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1164 lstrcatA(keypath, "Installer\\UserData\\");
1165 lstrcatA(keypath, usersid);
1166 lstrcatA(keypath, "\\Components\\");
1167 lstrcatA(keypath, comp_squashed);
1169 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1170 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1172 /* user managed component key exists */
1173 size = MAX_PATH;
1174 state = MsiGetComponentPathA(prodcode, component, path, &size);
1175 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1176 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1178 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1179 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1181 /* product value exists */
1182 size = MAX_PATH;
1183 state = MsiGetComponentPathA(prodcode, component, path, &size);
1184 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1185 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1186 ok(size == 10, "Expected 10, got %d\n", size);
1188 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1189 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1190 lstrcatA(keypath, prod_squashed);
1191 lstrcatA(keypath, "\\InstallProperties");
1193 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1196 val = 1;
1197 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1198 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1200 /* install properties key exists */
1201 size = MAX_PATH;
1202 state = MsiGetComponentPathA(prodcode, component, path, &size);
1203 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1204 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1205 ok(size == 10, "Expected 10, got %d\n", size);
1207 create_file("C:\\imapath", "C:\\imapath", 11);
1209 /* file exists */
1210 size = MAX_PATH;
1211 state = MsiGetComponentPathA(prodcode, component, path, &size);
1212 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1213 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1214 ok(size == 10, "Expected 10, got %d\n", size);
1216 RegDeleteValueA(compkey, prod_squashed);
1217 RegDeleteKeyA(prodkey, "");
1218 RegDeleteKeyA(compkey, "");
1219 RegDeleteValueA(installprop, "WindowsInstaller");
1220 RegDeleteKeyA(installprop, "");
1221 RegCloseKey(prodkey);
1222 RegCloseKey(compkey);
1223 RegCloseKey(installprop);
1224 DeleteFileA("C:\\imapath");
1226 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1227 lstrcatA(keypath, prod_squashed);
1229 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1232 /* user unmanaged product key exists */
1233 size = MAX_PATH;
1234 state = MsiGetComponentPathA(prodcode, component, path, &size);
1235 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1236 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1238 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1239 lstrcatA(keypath, "Installer\\UserData\\");
1240 lstrcatA(keypath, usersid);
1241 lstrcatA(keypath, "\\Components\\");
1242 lstrcatA(keypath, comp_squashed);
1244 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1245 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1247 /* user unmanaged component key exists */
1248 size = MAX_PATH;
1249 state = MsiGetComponentPathA(prodcode, component, path, &size);
1250 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1251 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1253 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1254 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1256 /* product value exists */
1257 size = MAX_PATH;
1258 state = MsiGetComponentPathA(prodcode, component, path, &size);
1259 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1260 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1261 ok(size == 10, "Expected 10, got %d\n", size);
1263 create_file("C:\\imapath", "C:\\imapath", 11);
1265 /* file exists */
1266 size = MAX_PATH;
1267 state = MsiGetComponentPathA(prodcode, component, path, &size);
1268 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1269 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1270 ok(size == 10, "Expected 10, got %d\n", size);
1272 RegDeleteValueA(compkey, prod_squashed);
1273 RegDeleteKeyA(prodkey, "");
1274 RegDeleteKeyA(compkey, "");
1275 RegCloseKey(prodkey);
1276 RegCloseKey(compkey);
1277 RegCloseKey(installprop);
1278 DeleteFileA("C:\\imapath");
1280 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1281 lstrcatA(keypath, prod_squashed);
1283 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1284 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1286 /* local classes product key exists */
1287 size = MAX_PATH;
1288 state = MsiGetComponentPathA(prodcode, component, path, &size);
1289 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1290 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1292 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1293 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1294 lstrcatA(keypath, comp_squashed);
1296 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1297 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1299 /* local user component key exists */
1300 size = MAX_PATH;
1301 state = MsiGetComponentPathA(prodcode, component, path, &size);
1302 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1303 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1305 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1306 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1308 /* product value exists */
1309 size = MAX_PATH;
1310 state = MsiGetComponentPathA(prodcode, component, path, &size);
1311 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1312 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1313 ok(size == 10, "Expected 10, got %d\n", size);
1315 create_file("C:\\imapath", "C:\\imapath", 11);
1317 /* file exists */
1318 size = MAX_PATH;
1319 state = MsiGetComponentPathA(prodcode, component, path, &size);
1320 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1321 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1322 ok(size == 10, "Expected 10, got %d\n", size);
1324 RegDeleteValueA(compkey, prod_squashed);
1325 RegDeleteKeyA(prodkey, "");
1326 RegDeleteKeyA(compkey, "");
1327 RegCloseKey(prodkey);
1328 RegCloseKey(compkey);
1329 DeleteFileA("C:\\imapath");
1332 START_TEST(msi)
1334 init_functionpointers();
1336 test_usefeature();
1337 test_null();
1338 test_getcomponentpath();
1339 test_MsiGetFileHash();
1340 test_MsiQueryProductState();
1341 test_MsiQueryFeatureState();
1342 test_MsiQueryComponentState();
1343 test_MsiGetComponentPath();