2 * tests for Microsoft Installer functionality
4 * Copyright 2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define _WIN32_MSI 300
29 #include "wine/test.h"
31 static BOOL (WINAPI
*pConvertSidToStringSidA
)(PSID
, LPSTR
*);
33 static INSTALLSTATE (WINAPI
*pMsiGetComponentPathA
)
34 (LPCSTR
, LPCSTR
, LPSTR
, DWORD
*);
35 static UINT (WINAPI
*pMsiGetFileHashA
)
36 (LPCSTR
, DWORD
, PMSIFILEHASHINFO
);
37 static UINT (WINAPI
*pMsiOpenPackageExA
)
38 (LPCSTR
, DWORD
, MSIHANDLE
*);
39 static UINT (WINAPI
*pMsiOpenPackageExW
)
40 (LPCWSTR
, DWORD
, MSIHANDLE
*);
41 static UINT (WINAPI
*pMsiQueryComponentStateA
)
42 (LPCSTR
, LPCSTR
, MSIINSTALLCONTEXT
, LPCSTR
, INSTALLSTATE
*);
43 static INSTALLSTATE (WINAPI
*pMsiUseFeatureExA
)
44 (LPCSTR
, LPCSTR
,DWORD
, DWORD
);
46 static void init_functionpointers(void)
48 HMODULE hmsi
= GetModuleHandleA("msi.dll");
49 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
51 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)
65 if (!pMsiUseFeatureExA
)
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}",
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)
102 DWORD dwType
, cbData
;
103 LPBYTE lpData
= NULL
;
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
);
140 skip("Out of memory\n");
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
);
156 r
= RegSetValueExA(hkey
, NULL
, 0, dwType
, lpData
, cbData
);
157 ok ( r
== ERROR_SUCCESS
, "wrong error %d\n", r
);
159 HeapFree(GetProcessHeap(), 0, lpData
);
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)
193 if(!pMsiGetComponentPathA
)
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");
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
)
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
);
238 SetFilePointer(file
, size
, NULL
, FILE_BEGIN
);
245 #define HASHSIZE sizeof(MSIFILEHASHINFO)
251 MSIFILEHASHINFO hash
;
256 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
260 { "C:\\Program Files\\msitest\\caesar\n", 0,
262 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
266 { "C:\\Program Files\\msitest\\caesar\n", 500,
268 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
273 static void test_MsiGetFileHash(void)
275 const char name
[] = "msitest.bin";
277 MSIFILEHASHINFO hash
;
280 if (!pMsiGetFileHashA
)
282 skip("MsiGetFileHash not implemented.");
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
);
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");
328 /* copied from dlls/msi/registry.c */
329 static BOOL
squash_guid(LPCWSTR in
, LPWSTR out
)
334 if (FAILED(CLSIDFromString((LPOLESTR
)in
, &guid
)))
348 out
[17+i
*2] = in
[n
++];
349 out
[16+i
*2] = in
[n
++];
354 out
[17+i
*2] = in
[n
++];
355 out
[16+i
*2] = in
[n
++];
361 static void create_test_guid(LPSTR prodcode
, LPSTR squashed
)
363 WCHAR guidW
[MAX_PATH
];
364 WCHAR squashedW
[MAX_PATH
];
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
)
387 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &token
);
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];
402 HKEY userkey
, localkey
, props
;
405 create_test_guid(prodcode
, prod_squashed
);
406 get_user_sid(&usersid
);
409 state
= MsiQueryProductStateA(NULL
);
410 ok(state
== INSTALLSTATE_INVALIDARG
, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state
);
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
);
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
);
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
);
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
);
509 RegDeleteValueA(props
, "WindowsInstaller");
510 RegDeleteKeyA(props
, "");
511 RegDeleteKeyA(localkey
, "");
512 RegCloseKey(userkey
);
513 RegCloseKey(localkey
);
517 static const char table_enc85
[] =
518 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
519 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
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
;
536 *str
++ = table_enc85
[x
%85];
538 *str
++ = table_enc85
[x
%85];
540 *str
++ = table_enc85
[x
%85];
542 *str
++ = table_enc85
[x
%85];
544 *str
++ = table_enc85
[x
%85];
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
];
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];
586 create_test_guid(prodcode
, prod_squashed
);
587 compose_base85_guid(component
, comp_base85
, comp_squashed
);
588 get_user_sid(&usersid
);
591 state
= MsiQueryFeatureStateA(NULL
, "feature");
592 ok(state
== INSTALLSTATE_INVALIDARG
, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state
);
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
);
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
];
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 */
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 */
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 */
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 */
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 */
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
);
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
);
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
);
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 */
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 */
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 */
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 */
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
);
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 */
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
);
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
);
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 */
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 */
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
);
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 */
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
);
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
);
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
);
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
];
994 create_test_guid(prodcode
, prod_squashed
);
995 compose_base85_guid(component
, comp_base85
, comp_squashed
);
996 get_user_sid(&usersid
);
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 */
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 */
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
);
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 */
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 */
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 */
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
);
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 */
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);
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 */
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 */
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
);
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 */
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);
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 */
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 */
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 */
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
);
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 */
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);
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 */
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 */
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 */
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);
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 */
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 */
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 */
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);
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 static void test_MsiGetProductCode(void)
1334 HKEY compkey
, prodkey
;
1335 CHAR prodcode
[MAX_PATH
];
1336 CHAR prod_squashed
[MAX_PATH
];
1337 CHAR prodcode2
[MAX_PATH
];
1338 CHAR prod2_squashed
[MAX_PATH
];
1339 CHAR component
[MAX_PATH
];
1340 CHAR comp_base85
[MAX_PATH
];
1341 CHAR comp_squashed
[MAX_PATH
];
1342 CHAR keypath
[MAX_PATH
];
1343 CHAR product
[MAX_PATH
];
1348 create_test_guid(prodcode
, prod_squashed
);
1349 create_test_guid(prodcode2
, prod2_squashed
);
1350 compose_base85_guid(component
, comp_base85
, comp_squashed
);
1351 get_user_sid(&usersid
);
1353 /* szComponent is NULL */
1354 lstrcpyA(product
, "prod");
1355 r
= MsiGetProductCodeA(NULL
, product
);
1356 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1357 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1359 /* szComponent is empty */
1360 lstrcpyA(product
, "prod");
1361 r
= MsiGetProductCodeA("", product
);
1362 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1363 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1365 /* garbage szComponent */
1366 lstrcpyA(product
, "prod");
1367 r
= MsiGetProductCodeA("garbage", product
);
1368 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1369 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1371 /* guid without brackets */
1372 lstrcpyA(product
, "prod");
1373 r
= MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product
);
1374 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1375 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1377 /* guid with brackets */
1378 lstrcpyA(product
, "prod");
1379 r
= MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product
);
1380 ok(r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r
);
1381 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1383 /* same length as guid, but random */
1384 lstrcpyA(product
, "prod");
1385 r
= MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product
);
1386 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1387 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1389 /* all params correct, szComponent not published */
1390 lstrcpyA(product
, "prod");
1391 r
= MsiGetProductCodeA(component
, product
);
1392 ok(r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r
);
1393 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1395 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1396 lstrcatA(keypath
, "Installer\\UserData\\");
1397 lstrcatA(keypath
, usersid
);
1398 lstrcatA(keypath
, "\\Components\\");
1399 lstrcatA(keypath
, comp_squashed
);
1401 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &compkey
);
1402 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1404 /* user unmanaged component key exists */
1405 lstrcpyA(product
, "prod");
1406 r
= MsiGetProductCodeA(component
, product
);
1407 ok(r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r
);
1408 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1410 res
= RegSetValueExA(compkey
, prod_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\imapath", 10);
1411 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1413 /* product value exists */
1414 lstrcpyA(product
, "prod");
1415 r
= MsiGetProductCodeA(component
, product
);
1416 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1417 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1419 res
= RegSetValueExA(compkey
, prod2_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\another", 10);
1420 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1422 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1423 lstrcatA(keypath
, "Installer\\Managed\\");
1424 lstrcatA(keypath
, usersid
);
1425 lstrcatA(keypath
, "\\Installer\\Products\\");
1426 lstrcatA(keypath
, prod_squashed
);
1428 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
1429 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1431 /* user managed product key of first product exists */
1432 lstrcpyA(product
, "prod");
1433 r
= MsiGetProductCodeA(component
, product
);
1434 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1435 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1437 RegDeleteKeyA(prodkey
, "");
1438 RegCloseKey(prodkey
);
1440 RegDeleteKeyA(prodkey
, "");
1441 RegCloseKey(prodkey
);
1443 lstrcpyA(keypath
, "Software\\Microsoft\\Installer\\Products\\");
1444 lstrcatA(keypath
, prod_squashed
);
1446 res
= RegCreateKeyA(HKEY_CURRENT_USER
, keypath
, &prodkey
);
1447 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1449 /* user unmanaged product key exists */
1450 lstrcpyA(product
, "prod");
1451 r
= MsiGetProductCodeA(component
, product
);
1452 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1453 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1455 RegDeleteKeyA(prodkey
, "");
1456 RegCloseKey(prodkey
);
1458 lstrcpyA(keypath
, "Software\\Classes\\Installer\\Products\\");
1459 lstrcatA(keypath
, prod_squashed
);
1461 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
1462 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1464 /* local classes product key exists */
1465 lstrcpyA(product
, "prod");
1466 r
= MsiGetProductCodeA(component
, product
);
1467 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1468 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1470 RegDeleteKeyA(prodkey
, "");
1471 RegCloseKey(prodkey
);
1473 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1474 lstrcatA(keypath
, "Installer\\Managed\\");
1475 lstrcatA(keypath
, usersid
);
1476 lstrcatA(keypath
, "\\Installer\\Products\\");
1477 lstrcatA(keypath
, prod2_squashed
);
1479 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
1480 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1482 /* user managed product key of second product exists */
1483 lstrcpyA(product
, "prod");
1484 r
= MsiGetProductCodeA(component
, product
);
1485 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1486 ok(!lstrcmpA(product
, prodcode2
), "Expected %s, got %s\n", prodcode2
, product
);
1488 RegDeleteKeyA(prodkey
, "");
1489 RegCloseKey(prodkey
);
1490 RegDeleteValueA(compkey
, prod_squashed
);
1491 RegDeleteValueA(compkey
, prod2_squashed
);
1492 RegDeleteKeyA(compkey
, "");
1493 RegCloseKey(compkey
);
1495 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1496 lstrcatA(keypath
, "Installer\\UserData\\S-1-5-18\\Components\\");
1497 lstrcatA(keypath
, comp_squashed
);
1499 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &compkey
);
1500 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1502 /* local user component key exists */
1503 lstrcpyA(product
, "prod");
1504 r
= MsiGetProductCodeA(component
, product
);
1505 ok(r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r
);
1506 ok(!lstrcmpA(product
, "prod"), "Expected product to be unchanged, got %s\n", product
);
1508 res
= RegSetValueExA(compkey
, prod_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\imapath", 10);
1509 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1511 /* product value exists */
1512 lstrcpyA(product
, "prod");
1513 r
= MsiGetProductCodeA(component
, product
);
1514 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1515 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1517 res
= RegSetValueExA(compkey
, prod2_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\another", 10);
1518 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1520 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1521 lstrcatA(keypath
, "Installer\\Managed\\");
1522 lstrcatA(keypath
, usersid
);
1523 lstrcatA(keypath
, "\\Installer\\Products\\");
1524 lstrcatA(keypath
, prod_squashed
);
1526 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
1527 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1529 /* user managed product key of first product exists */
1530 lstrcpyA(product
, "prod");
1531 r
= MsiGetProductCodeA(component
, product
);
1532 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1533 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1535 RegDeleteKeyA(prodkey
, "");
1536 RegCloseKey(prodkey
);
1538 lstrcpyA(keypath
, "Software\\Microsoft\\Installer\\Products\\");
1539 lstrcatA(keypath
, prod_squashed
);
1541 res
= RegCreateKeyA(HKEY_CURRENT_USER
, keypath
, &prodkey
);
1542 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1544 /* user unmanaged product key exists */
1545 lstrcpyA(product
, "prod");
1546 r
= MsiGetProductCodeA(component
, product
);
1547 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1548 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1550 RegDeleteKeyA(prodkey
, "");
1551 RegCloseKey(prodkey
);
1553 lstrcpyA(keypath
, "Software\\Classes\\Installer\\Products\\");
1554 lstrcatA(keypath
, prod_squashed
);
1556 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
1557 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1559 /* local classes product key exists */
1560 lstrcpyA(product
, "prod");
1561 r
= MsiGetProductCodeA(component
, product
);
1562 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1563 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1565 RegDeleteKeyA(prodkey
, "");
1566 RegCloseKey(prodkey
);
1568 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1569 lstrcatA(keypath
, "Installer\\Managed\\");
1570 lstrcatA(keypath
, usersid
);
1571 lstrcatA(keypath
, "\\Installer\\Products\\");
1572 lstrcatA(keypath
, prod2_squashed
);
1574 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
1575 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1577 /* user managed product key of second product exists */
1578 lstrcpyA(product
, "prod");
1579 r
= MsiGetProductCodeA(component
, product
);
1580 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1581 ok(!lstrcmpA(product
, prodcode2
), "Expected %s, got %s\n", prodcode2
, product
);
1583 RegDeleteKeyA(prodkey
, "");
1584 RegCloseKey(prodkey
);
1585 RegDeleteValueA(compkey
, prod_squashed
);
1586 RegDeleteValueA(compkey
, prod2_squashed
);
1587 RegDeleteKeyA(compkey
, "");
1588 RegCloseKey(compkey
);
1591 static void test_MsiEnumClients(void)
1594 CHAR prodcode
[MAX_PATH
];
1595 CHAR prod_squashed
[MAX_PATH
];
1596 CHAR prodcode2
[MAX_PATH
];
1597 CHAR prod2_squashed
[MAX_PATH
];
1598 CHAR component
[MAX_PATH
];
1599 CHAR comp_base85
[MAX_PATH
];
1600 CHAR comp_squashed
[MAX_PATH
];
1601 CHAR product
[MAX_PATH
];
1602 CHAR keypath
[MAX_PATH
];
1607 create_test_guid(prodcode
, prod_squashed
);
1608 create_test_guid(prodcode2
, prod2_squashed
);
1609 compose_base85_guid(component
, comp_base85
, comp_squashed
);
1610 get_user_sid(&usersid
);
1612 /* NULL szComponent */
1614 r
= MsiEnumClientsA(NULL
, 0, product
);
1615 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1616 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1618 /* empty szComponent */
1620 r
= MsiEnumClientsA("", 0, product
);
1621 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1622 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1624 /* NULL lpProductBuf */
1625 r
= MsiEnumClientsA(component
, 0, NULL
);
1626 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1628 /* all params correct, component missing */
1630 r
= MsiEnumClientsA(component
, 0, product
);
1631 ok(r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r
);
1632 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1634 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1635 lstrcatA(keypath
, "Installer\\UserData\\");
1636 lstrcatA(keypath
, usersid
);
1637 lstrcatA(keypath
, "\\Components\\");
1638 lstrcatA(keypath
, comp_squashed
);
1640 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &compkey
);
1641 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1643 /* user unmanaged component key exists */
1645 r
= MsiEnumClientsA(component
, 0, product
);
1646 ok(r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r
);
1647 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1649 /* index > 0, no products exist */
1651 r
= MsiEnumClientsA(component
, 1, product
);
1652 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1653 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1655 res
= RegSetValueExA(compkey
, prod_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\imapath", 10);
1656 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1658 /* product value exists */
1659 r
= MsiEnumClientsA(component
, 0, product
);
1660 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1661 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1663 /* try index 0 again */
1665 r
= MsiEnumClientsA(component
, 0, product
);
1666 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1667 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1669 /* try index 1, second product value does not exist */
1671 r
= MsiEnumClientsA(component
, 1, product
);
1672 ok(r
== ERROR_NO_MORE_ITEMS
, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r
);
1673 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1675 res
= RegSetValueExA(compkey
, prod2_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\another", 10);
1676 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1678 /* try index 1, second product value does exist */
1680 r
= MsiEnumClientsA(component
, 1, product
);
1683 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1684 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1687 /* start the enumeration over */
1689 r
= MsiEnumClientsA(component
, 0, product
);
1690 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1691 ok(!lstrcmpA(product
, prodcode
) || !lstrcmpA(product
, prodcode2
),
1692 "Expected %s or %s, got %s\n", prodcode
, prodcode2
, product
);
1694 /* correctly query second product */
1696 r
= MsiEnumClientsA(component
, 1, product
);
1697 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1698 ok(!lstrcmpA(product
, prodcode
) || !lstrcmpA(product
, prodcode2
),
1699 "Expected %s or %s, got %s\n", prodcode
, prodcode2
, product
);
1701 RegDeleteValueA(compkey
, prod_squashed
);
1702 RegDeleteValueA(compkey
, prod2_squashed
);
1703 RegDeleteKeyA(compkey
, "");
1704 RegCloseKey(compkey
);
1706 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1707 lstrcatA(keypath
, "Installer\\UserData\\S-1-5-18\\Components\\");
1708 lstrcatA(keypath
, comp_squashed
);
1710 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &compkey
);
1711 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1713 /* user local component key exists */
1715 r
= MsiEnumClientsA(component
, 0, product
);
1716 ok(r
== ERROR_UNKNOWN_COMPONENT
, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r
);
1717 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1719 /* index > 0, no products exist */
1721 r
= MsiEnumClientsA(component
, 1, product
);
1722 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1723 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1725 res
= RegSetValueExA(compkey
, prod_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\imapath", 10);
1726 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1728 /* product value exists */
1730 r
= MsiEnumClientsA(component
, 0, product
);
1731 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1732 ok(!lstrcmpA(product
, prodcode
), "Expected %s, got %s\n", prodcode
, product
);
1734 /* try index 0 again */
1736 r
= MsiEnumClientsA(component
, 0, product
);
1737 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1739 /* try index 1, second product value does not exist */
1741 r
= MsiEnumClientsA(component
, 1, product
);
1742 ok(r
== ERROR_NO_MORE_ITEMS
, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r
);
1743 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1745 res
= RegSetValueExA(compkey
, prod2_squashed
, 0, REG_SZ
, (const BYTE
*)"C:\\another", 10);
1746 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
1748 /* try index 1, second product value does exist */
1750 r
= MsiEnumClientsA(component
, 1, product
);
1753 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
1754 ok(!lstrcmpA(product
, ""), "Expected product to be unchanged, got %s\n", product
);
1757 /* start the enumeration over */
1759 r
= MsiEnumClientsA(component
, 0, product
);
1760 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1761 ok(!lstrcmpA(product
, prodcode
) || !lstrcmpA(product
, prodcode2
),
1762 "Expected %s or %s, got %s\n", prodcode
, prodcode2
, product
);
1764 /* correctly query second product */
1766 r
= MsiEnumClientsA(component
, 1, product
);
1767 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
1768 ok(!lstrcmpA(product
, prodcode
) || !lstrcmpA(product
, prodcode2
),
1769 "Expected %s or %s, got %s\n", prodcode
, prodcode2
, product
);
1771 RegDeleteValueA(compkey
, prod_squashed
);
1772 RegDeleteValueA(compkey
, prod2_squashed
);
1773 RegDeleteKeyA(compkey
, "");
1774 RegCloseKey(compkey
);
1779 init_functionpointers();
1783 test_getcomponentpath();
1784 test_MsiGetFileHash();
1785 test_MsiQueryProductState();
1786 test_MsiQueryFeatureState();
1787 test_MsiQueryComponentState();
1788 test_MsiGetComponentPath();
1789 test_MsiGetProductCode();
1790 test_MsiEnumClients();