push e57f4907e24f93b118c5a715e9cf13b17e600a1f
[wine/hacks.git] / dlls / msi / tests / msi.c
bloba2149c8ef7a82ba095dabdc1fcaa32db2e466233
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 #define GET_PROC(dll, func) \
52 p ## func = (void *)GetProcAddress(dll, #func); \
53 if(!p ## 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)
65 #undef GET_PROC
68 static void test_usefeature(void)
70 INSTALLSTATE r;
72 if (!pMsiUseFeatureExA)
74 skip("MsiUseFeatureExA not implemented\n");
75 return;
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}",
91 NULL, -2, 0 );
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)
109 MSIHANDLE hpkg;
110 UINT r;
111 HKEY hkey;
112 DWORD dwType, cbData;
113 LPBYTE lpData = NULL;
114 INSTALLSTATE state;
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);
149 if (!lpData)
150 skip("Out of memory\n");
151 else
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);
164 if (lpData)
166 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
167 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
169 HeapFree(GetProcessHeap(), 0, lpData);
171 else
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)
199 INSTALLSTATE r;
200 char buffer[0x100];
201 DWORD sz;
203 if(!pMsiGetComponentPathA)
204 return;
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");
215 sz = sizeof buffer;
216 buffer[0]=0;
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)
239 HANDLE file;
240 DWORD written;
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);
246 if (size)
248 SetFilePointer(file, size, NULL, FILE_BEGIN);
249 SetEndOfFile(file);
252 CloseHandle(file);
255 #define HASHSIZE sizeof(MSIFILEHASHINFO)
257 static const struct
259 LPCSTR data;
260 DWORD size;
261 MSIFILEHASHINFO hash;
262 } hash_data[] =
264 { "abc", 0,
265 { HASHSIZE,
266 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
270 { "C:\\Program Files\\msitest\\caesar\n", 0,
271 { HASHSIZE,
272 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
276 { "C:\\Program Files\\msitest\\caesar\n", 500,
277 { HASHSIZE,
278 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
283 static void test_MsiGetFileHash(void)
285 const char name[] = "msitest.bin";
286 UINT r;
287 MSIFILEHASHINFO hash;
288 DWORD i;
290 if (!pMsiGetFileHashA)
292 skip("MsiGetFileHash not implemented\n");
293 return;
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);
319 /* pHash is NULL */
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");
334 DeleteFile(name);
338 /* copied from dlls/msi/registry.c */
339 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
341 DWORD i,n=1;
342 GUID guid;
344 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
345 return FALSE;
347 for(i=0; i<8; i++)
348 out[7-i] = in[n++];
349 n++;
350 for(i=0; i<4; i++)
351 out[11-i] = in[n++];
352 n++;
353 for(i=0; i<4; i++)
354 out[15-i] = in[n++];
355 n++;
356 for(i=0; i<2; i++)
358 out[17+i*2] = in[n++];
359 out[16+i*2] = in[n++];
361 n++;
362 for( ; i<8; i++)
364 out[17+i*2] = in[n++];
365 out[16+i*2] = in[n++];
367 out[32]=0;
368 return TRUE;
371 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
373 WCHAR guidW[MAX_PATH];
374 WCHAR squashedW[MAX_PATH];
375 GUID guid;
376 HRESULT hr;
377 int size;
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)
392 HANDLE token;
393 BYTE buf[1024];
394 DWORD size;
395 PTOKEN_USER user;
397 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
398 size = sizeof(buf);
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];
409 LPSTR usersid;
410 INSTALLSTATE state;
411 LONG res;
412 HKEY userkey, localkey, props;
413 DWORD data;
415 create_test_guid(prodcode, prod_squashed);
416 get_user_sid(&usersid);
418 /* NULL prodcode */
419 state = MsiQueryProductStateA(NULL);
420 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
422 /* empty prodcode */
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);
466 data = 1;
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);
496 data = 1;
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);
504 data = 2;
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);
518 LocalFree(usersid);
519 RegDeleteValueA(props, "WindowsInstaller");
520 RegDeleteKeyA(props, "");
521 RegDeleteKeyA(localkey, "");
522 RegCloseKey(userkey);
523 RegCloseKey(localkey);
524 RegCloseKey(props);
527 static const char table_enc85[] =
528 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
529 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
530 "yz{}~";
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;
543 for( i=0; i<4; i++ )
545 x = p[i];
546 *str++ = table_enc85[x%85];
547 x = x/85;
548 *str++ = table_enc85[x%85];
549 x = x/85;
550 *str++ = table_enc85[x%85];
551 x = x/85;
552 *str++ = table_enc85[x%85];
553 x = x/85;
554 *str++ = table_enc85[x%85];
556 *str = 0;
558 return TRUE;
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];
566 GUID guid;
567 HRESULT hr;
568 int size;
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];
592 INSTALLSTATE state;
593 LPSTR usersid;
594 LONG res;
596 create_test_guid(prodcode, prod_squashed);
597 compose_base85_guid(component, comp_base85, comp_squashed);
598 get_user_sid(&usersid);
600 /* NULL prodcode */
601 state = MsiQueryFeatureStateA(NULL, "feature");
602 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
604 /* empty prodcode */
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);
624 /* NULL szFeature */
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];
730 INSTALLSTATE state;
731 LPSTR usersid;
732 LONG res;
733 UINT r;
735 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
737 if (!pMsiQueryComponentStateA)
739 skip("MsiQueryComponentStateA not implemented\n");
740 return;
743 create_test_guid(prodcode, prod_squashed);
744 compose_base85_guid(component, comp_base85, comp_squashed);
745 get_user_sid(&usersid);
747 /* NULL szProductCode */
748 state = MAGIC_ERROR;
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 */
754 state = MAGIC_ERROR;
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 */
760 state = MAGIC_ERROR;
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 */
766 state = MAGIC_ERROR;
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 */
772 state = MAGIC_ERROR;
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);
777 /* actual GUID */
778 state = MAGIC_ERROR;
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);
783 state = MAGIC_ERROR;
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);
794 state = MAGIC_ERROR;
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 */
811 state = MAGIC_ERROR;
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 */
820 state = MAGIC_ERROR;
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 */
832 state = MAGIC_ERROR;
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 */
841 state = MAGIC_ERROR;
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);
849 state = MAGIC_ERROR;
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 */
863 state = MAGIC_ERROR;
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);
874 state = MAGIC_ERROR;
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);
896 state = MAGIC_ERROR;
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 */
910 state = MAGIC_ERROR;
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 */
919 state = MAGIC_ERROR;
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);
927 state = MAGIC_ERROR;
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 */
934 state = MAGIC_ERROR;
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);
945 state = MAGIC_ERROR;
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);
961 state = MAGIC_ERROR;
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);
981 state = MAGIC_ERROR;
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];
1005 INSTALLSTATE state;
1006 LPSTR usersid;
1007 DWORD size, val;
1008 LONG res;
1010 create_test_guid(prodcode, prod_squashed);
1011 compose_base85_guid(component, comp_base85, comp_squashed);
1012 get_user_sid(&usersid);
1014 /* NULL szProduct */
1015 size = MAX_PATH;
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 */
1021 size = MAX_PATH;
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 */
1027 size = MAX_PATH;
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);
1032 /* NULL pcchBuf */
1033 size = MAX_PATH;
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 */
1039 size = MAX_PATH;
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 */
1052 size = MAX_PATH;
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 */
1061 size = MAX_PATH;
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);
1075 val = 1;
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 */
1080 size = MAX_PATH;
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);
1088 /* file exists */
1089 size = MAX_PATH;
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 */
1113 size = MAX_PATH;
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 */
1122 size = MAX_PATH;
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);
1136 val = 1;
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 */
1141 size = MAX_PATH;
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);
1149 /* file exists */
1150 size = MAX_PATH;
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 */
1174 size = MAX_PATH;
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 */
1189 size = MAX_PATH;
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 */
1198 size = MAX_PATH;
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);
1212 val = 1;
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 */
1217 size = MAX_PATH;
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);
1225 /* file exists */
1226 size = MAX_PATH;
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 */
1249 size = MAX_PATH;
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 */
1264 size = MAX_PATH;
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 */
1273 size = MAX_PATH;
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);
1281 /* file exists */
1282 size = MAX_PATH;
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 */
1303 size = MAX_PATH;
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 */
1316 size = MAX_PATH;
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 */
1325 size = MAX_PATH;
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);
1333 /* file exists */
1334 size = MAX_PATH;
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];
1360 LPSTR usersid;
1361 LONG res;
1362 UINT r;
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)
1609 HKEY compkey;
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];
1619 LPSTR usersid;
1620 LONG res;
1621 UINT r;
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 */
1629 product[0] = '\0';
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 */
1635 product[0] = '\0';
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 */
1645 product[0] = '\0';
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 */
1660 product[0] = '\0';
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 */
1666 product[0] = '\0';
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 */
1680 product[0] = '\0';
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 */
1686 product[0] = '\0';
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 */
1695 product[0] = '\0';
1696 r = MsiEnumClientsA(component, 1, product);
1697 todo_wine
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 */
1704 product[0] = '\0';
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 */
1711 product[0] = '\0';
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 */
1730 product[0] = '\0';
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 */
1736 product[0] = '\0';
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 */
1745 product[0] = '\0';
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 */
1751 product[0] = '\0';
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 */
1756 product[0] = '\0';
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 */
1765 product[0] = '\0';
1766 r = MsiEnumClientsA(component, 1, product);
1767 todo_wine
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 */
1774 product[0] = '\0';
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 */
1781 product[0] = '\0';
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);
1793 START_TEST(msi)
1795 init_functionpointers();
1797 test_usefeature();
1798 test_null();
1799 test_getcomponentpath();
1800 test_MsiGetFileHash();
1802 if (!pConvertSidToStringSidA)
1803 skip("ConvertSidToStringSidA not implemented\n");
1804 else
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();