2 * Tests for MSI Source functions
4 * Copyright (C) 2006 James Hawkins
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
31 #include "wine/test.h"
33 static BOOL (WINAPI
*pConvertSidToStringSidA
)(PSID
, LPSTR
*);
34 static UINT (WINAPI
*pMsiSourceListGetInfoA
)
35 (LPCSTR
, LPCSTR
, MSIINSTALLCONTEXT
, DWORD
, LPCSTR
, LPSTR
, LPDWORD
);
36 static UINT (WINAPI
*pMsiSourceListAddSourceExA
)
37 (LPCSTR
, LPCSTR
, MSIINSTALLCONTEXT
, DWORD
, LPCSTR
, DWORD
);
39 static void init_functionpointers(void)
41 HMODULE hmsi
= GetModuleHandleA("msi.dll");
42 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
44 #define GET_PROC(dll, func) \
45 p ## func = (void *)GetProcAddress(dll, #func); \
47 trace("GetProcAddress(%s) failed\n", #func);
49 GET_PROC(hmsi
, MsiSourceListAddSourceExA
)
50 GET_PROC(hmsi
, MsiSourceListGetInfoA
)
52 GET_PROC(hadvapi32
, ConvertSidToStringSidA
)
57 /* copied from dlls/msi/registry.c */
58 static BOOL
squash_guid(LPCWSTR in
, LPWSTR out
)
63 if (FAILED(CLSIDFromString((LPOLESTR
)in
, &guid
)))
77 out
[17+i
*2] = in
[n
++];
78 out
[16+i
*2] = in
[n
++];
83 out
[17+i
*2] = in
[n
++];
84 out
[16+i
*2] = in
[n
++];
90 static void create_test_guid(LPSTR prodcode
, LPSTR squashed
)
92 WCHAR guidW
[MAX_PATH
];
93 WCHAR squashedW
[MAX_PATH
];
98 hr
= CoCreateGuid(&guid
);
99 ok(hr
== S_OK
, "Expected S_OK, got %d\n", hr
);
101 size
= StringFromGUID2(&guid
, (LPOLESTR
)guidW
, MAX_PATH
);
102 ok(size
== 39, "Expected 39, got %d\n", hr
);
104 WideCharToMultiByte(CP_ACP
, 0, guidW
, size
, prodcode
, MAX_PATH
, NULL
, NULL
);
105 squash_guid(guidW
, squashedW
);
106 WideCharToMultiByte(CP_ACP
, 0, squashedW
, -1, squashed
, MAX_PATH
, NULL
, NULL
);
109 static void get_user_sid(LPSTR
*usersid
)
116 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &token
);
118 GetTokenInformation(token
, TokenUser
, (void *)buf
, size
, &size
);
119 user
= (PTOKEN_USER
)buf
;
120 pConvertSidToStringSidA(user
->User
.Sid
, usersid
);
123 static void test_MsiSourceListGetInfo(void)
125 CHAR prodcode
[MAX_PATH
];
126 CHAR prod_squashed
[MAX_PATH
];
127 CHAR keypath
[MAX_PATH
*2];
128 CHAR value
[MAX_PATH
];
136 if (!pMsiSourceListGetInfoA
)
138 skip("Skipping MsiSourceListGetInfoA tests\n");
142 create_test_guid(prodcode
, prod_squashed
);
143 get_user_sid(&usersid
);
145 /* NULL szProductCodeOrPatchCode */
146 r
= pMsiSourceListGetInfoA(NULL
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
147 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
148 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
150 /* empty szProductCodeOrPatchCode */
151 r
= pMsiSourceListGetInfoA("", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
152 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
153 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
155 /* garbage szProductCodeOrPatchCode */
156 r
= pMsiSourceListGetInfoA("garbage", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
157 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
158 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
160 /* szProductCodeOrPatchCode */
161 r
= pMsiSourceListGetInfoA("garbage", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
162 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
163 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
165 /* guid without brackets */
166 r
= pMsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
167 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
168 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
170 /* guid with brackets */
171 r
= pMsiSourceListGetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
172 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
173 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
175 /* same length as guid, but random */
176 r
= pMsiSourceListGetInfoA("ADKD-2KSDFF2-DKK1KNFJASD9GLKWME-1I3KAD", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
177 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
178 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
180 /* invalid context */
181 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_NONE
,
182 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
183 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
185 /* another invalid context */
186 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_ALLUSERMANAGED
,
187 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
188 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
190 /* yet another invalid context */
191 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_ALL
,
192 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
193 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
195 /* mix two valid contexts */
196 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERMANAGED
| MSIINSTALLCONTEXT_USERUNMANAGED
,
197 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
198 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
201 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
202 4, INSTALLPROPERTY_PACKAGENAME
, NULL
, NULL
);
203 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
206 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
207 MSICODE_PRODUCT
, NULL
, NULL
, NULL
);
208 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
211 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
212 MSICODE_PRODUCT
, "", NULL
, NULL
);
213 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
215 /* value is non-NULL while size is NULL */
216 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
217 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, value
, NULL
);
218 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
220 /* size is non-NULL while value is NULL */
221 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
222 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
223 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
225 lstrcpyA(keypath
, "Software\\Microsoft\\Installer\\Products\\");
226 lstrcatA(keypath
, prod_squashed
);
228 res
= RegCreateKeyA(HKEY_CURRENT_USER
, keypath
, &userkey
);
229 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
231 /* user product key exists */
232 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
233 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
234 ok(r
== ERROR_BAD_CONFIGURATION
, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r
);
236 res
= RegCreateKeyA(userkey
, "SourceList", &hkey
);
237 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
239 /* SourceList key exists */
241 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
242 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
243 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
244 ok(size
== 0, "Expected 0, got %d\n", size
);
246 data
= "msitest.msi";
247 res
= RegSetValueExA(hkey
, "PackageName", 0, REG_SZ
, (const BYTE
*)data
, lstrlenA(data
) + 1);
248 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
250 /* PackageName value exists */
252 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
253 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
254 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
255 ok(size
== 11, "Expected 11, got %d\n", size
);
257 /* read the value, don't change size */
258 lstrcpyA(value
, "aaa");
259 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
260 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, value
, &size
);
261 ok(r
== ERROR_MORE_DATA
, "Expected ERROR_MORE_DATA, got %d\n", r
);
262 ok(!lstrcmpA(value
, "aaa"), "Expected 'aaa', got %s\n", value
);
263 ok(size
== 11, "Expected 11, got %d\n", size
);
265 /* read the value, fix size */
267 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
268 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAME
, value
, &size
);
269 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
270 ok(!lstrcmpA(value
, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value
);
271 ok(size
== 11, "Expected 11, got %d\n", size
);
273 /* empty property now that product key exists */
275 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
276 MSICODE_PRODUCT
, "", NULL
, &size
);
277 ok(r
== ERROR_UNKNOWN_PROPERTY
, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r
);
278 ok(size
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size
);
280 /* nonexistent property now that product key exists */
282 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
283 MSICODE_PRODUCT
, "nonexistent", NULL
, &size
);
284 ok(r
== ERROR_UNKNOWN_PROPERTY
, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r
);
285 ok(size
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size
);
288 res
= RegSetValueExA(hkey
, "nonexistent", 0, REG_SZ
, (const BYTE
*)data
, lstrlenA(data
) + 1);
289 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
291 /* nonexistent property now that nonexistent value exists */
293 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
294 MSICODE_PRODUCT
, "nonexistent", NULL
, &size
);
295 ok(r
== ERROR_UNKNOWN_PROPERTY
, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r
);
296 ok(size
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size
);
298 /* invalid option now that product key exists */
300 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
301 4, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
302 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
303 ok(size
== 11, "Expected 11, got %d\n", size
);
305 RegDeleteValueA(hkey
, "nonexistent");
306 RegDeleteValueA(hkey
, "PackageName");
307 RegDeleteKeyA(hkey
, "");
308 RegDeleteKeyA(userkey
, "");
310 RegCloseKey(userkey
);
314 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
315 MSICODE_PATCH
, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
316 ok(r
== ERROR_UNKNOWN_PATCH
, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r
);
317 ok(size
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size
);
319 lstrcpyA(keypath
, "Software\\Microsoft\\Installer\\Patches\\");
320 lstrcatA(keypath
, prod_squashed
);
322 res
= RegCreateKeyA(HKEY_CURRENT_USER
, keypath
, &userkey
);
323 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
326 * NOTE: using prodcode guid, but it really doesn't matter
329 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
330 MSICODE_PATCH
, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
331 ok(r
== ERROR_BAD_CONFIGURATION
, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r
);
332 ok(size
== 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size
);
334 res
= RegCreateKeyA(userkey
, "SourceList", &hkey
);
335 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
337 /* SourceList key exists */
339 r
= pMsiSourceListGetInfoA(prodcode
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
340 MSICODE_PATCH
, INSTALLPROPERTY_PACKAGENAME
, NULL
, &size
);
341 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
342 ok(size
== 0, "Expected 0, got %d\n", size
);
344 RegDeleteKeyA(hkey
, "");
345 RegDeleteKeyA(userkey
, "");
347 RegCloseKey(userkey
);
350 static void test_MsiSourceListAddSourceEx(void)
352 CHAR prodcode
[MAX_PATH
];
353 CHAR prod_squashed
[MAX_PATH
];
354 CHAR keypath
[MAX_PATH
*2];
355 CHAR value
[MAX_PATH
];
359 HKEY prodkey
, userkey
, hkey
;
363 if (!pMsiSourceListAddSourceExA
)
365 skip("Skipping MsiSourceListAddSourceExA tests\n");
369 create_test_guid(prodcode
, prod_squashed
);
370 get_user_sid(&usersid
);
372 /* GetLastError is not set by the function */
374 /* NULL szProductCodeOrPatchCode */
375 r
= pMsiSourceListAddSourceExA(NULL
, usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
376 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
377 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
379 /* empty szProductCodeOrPatchCode */
380 r
= pMsiSourceListAddSourceExA("", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
381 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
382 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
384 /* garbage szProductCodeOrPatchCode */
385 r
= pMsiSourceListAddSourceExA("garbage", usersid
, MSIINSTALLCONTEXT_USERUNMANAGED
,
386 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
387 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
389 /* guid without brackets */
390 r
= pMsiSourceListAddSourceExA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid
,
391 MSIINSTALLCONTEXT_USERUNMANAGED
,
392 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
393 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
395 /* guid with brackets */
396 r
= pMsiSourceListAddSourceExA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid
,
397 MSIINSTALLCONTEXT_USERUNMANAGED
,
398 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
399 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
401 /* MSIINSTALLCONTEXT_USERUNMANAGED */
403 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
404 MSIINSTALLCONTEXT_USERUNMANAGED
,
405 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
406 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
408 lstrcpyA(keypath
, "Software\\Microsoft\\Installer\\Products\\");
409 lstrcatA(keypath
, prod_squashed
);
411 res
= RegCreateKeyA(HKEY_CURRENT_USER
, keypath
, &userkey
);
412 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
414 /* user product key exists */
415 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
416 MSIINSTALLCONTEXT_USERUNMANAGED
,
417 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
418 ok(r
== ERROR_BAD_CONFIGURATION
, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r
);
420 res
= RegCreateKeyA(userkey
, "SourceList", &url
);
421 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
424 /* SourceList key exists */
425 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
426 MSIINSTALLCONTEXT_USERUNMANAGED
,
427 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
428 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
430 res
= RegOpenKeyA(userkey
, "SourceList\\URL", &url
);
431 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
434 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
435 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
436 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
437 ok(size
== 11, "Expected 11, got %d\n", size
);
439 /* add another source, index 0 */
440 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
441 MSIINSTALLCONTEXT_USERUNMANAGED
,
442 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "another", 0);
443 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
446 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
447 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
448 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
449 ok(size
== 11, "Expected 11, got %d\n", size
);
452 res
= RegQueryValueExA(url
, "2", NULL
, NULL
, (LPBYTE
)value
, &size
);
453 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
454 ok(!lstrcmpA(value
, "another/"), "Expected 'another/', got %s\n", value
);
455 ok(size
== 9, "Expected 9, got %d\n", size
);
457 /* add another source, index 1 */
458 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
459 MSIINSTALLCONTEXT_USERUNMANAGED
,
460 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "third/", 1);
461 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
464 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
465 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
466 ok(!lstrcmpA(value
, "third/"), "Expected 'third/', got %s\n", value
);
467 ok(size
== 7, "Expected 7, got %d\n", size
);
470 res
= RegQueryValueExA(url
, "2", NULL
, NULL
, (LPBYTE
)value
, &size
);
471 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
472 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
473 ok(size
== 11, "Expected 11, got %d\n", size
);
476 res
= RegQueryValueExA(url
, "3", NULL
, NULL
, (LPBYTE
)value
, &size
);
477 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
478 ok(!lstrcmpA(value
, "another/"), "Expected 'another/', got %s\n", value
);
479 ok(size
== 9, "Expected 9, got %d\n", size
);
481 /* add another source, index > N */
482 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
483 MSIINSTALLCONTEXT_USERUNMANAGED
,
484 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "last/", 5);
485 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
488 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
489 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
490 ok(!lstrcmpA(value
, "third/"), "Expected 'third/', got %s\n", value
);
491 ok(size
== 7, "Expected 7, got %d\n", size
);
494 res
= RegQueryValueExA(url
, "2", NULL
, NULL
, (LPBYTE
)value
, &size
);
495 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
496 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
497 ok(size
== 11, "Expected 11, got %d\n", size
);
500 res
= RegQueryValueExA(url
, "3", NULL
, NULL
, (LPBYTE
)value
, &size
);
501 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
502 ok(!lstrcmpA(value
, "another/"), "Expected 'another/', got %s\n", value
);
503 ok(size
== 9, "Expected 9, got %d\n", size
);
506 res
= RegQueryValueExA(url
, "4", NULL
, NULL
, (LPBYTE
)value
, &size
);
507 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
508 ok(!lstrcmpA(value
, "last/"), "Expected 'last/', got %s\n", value
);
509 ok(size
== 6, "Expected 6, got %d\n", size
);
511 /* just MSISOURCETYPE_NETWORK */
512 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
513 MSIINSTALLCONTEXT_USERUNMANAGED
,
514 MSISOURCETYPE_NETWORK
, "source", 0);
515 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
517 res
= RegOpenKeyA(userkey
, "SourceList\\Net", &net
);
518 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
521 res
= RegQueryValueExA(net
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
522 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
523 ok(!lstrcmpA(value
, "source\\"), "Expected 'source\\', got %s\n", value
);
524 ok(size
== 8, "Expected 8, got %d\n", size
);
526 /* just MSISOURCETYPE_URL */
527 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
528 MSIINSTALLCONTEXT_USERUNMANAGED
,
529 MSISOURCETYPE_URL
, "source", 0);
530 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
533 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
534 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
535 ok(!lstrcmpA(value
, "third/"), "Expected 'third/', got %s\n", value
);
536 ok(size
== 7, "Expected 7, got %d\n", size
);
539 res
= RegQueryValueExA(url
, "2", NULL
, NULL
, (LPBYTE
)value
, &size
);
540 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
541 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
542 ok(size
== 11, "Expected 11, got %d\n", size
);
545 res
= RegQueryValueExA(url
, "3", NULL
, NULL
, (LPBYTE
)value
, &size
);
546 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
547 ok(!lstrcmpA(value
, "another/"), "Expected 'another/', got %s\n", value
);
548 ok(size
== 9, "Expected 9, got %d\n", size
);
551 res
= RegQueryValueExA(url
, "4", NULL
, NULL
, (LPBYTE
)value
, &size
);
552 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
553 ok(!lstrcmpA(value
, "last/"), "Expected 'last/', got %s\n", value
);
554 ok(size
== 6, "Expected 6, got %d\n", size
);
557 res
= RegQueryValueExA(url
, "5", NULL
, NULL
, (LPBYTE
)value
, &size
);
558 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
559 ok(!lstrcmpA(value
, "source/"), "Expected 'source/', got %s\n", value
);
560 ok(size
== 8, "Expected 8, got %d\n", size
);
563 r
= pMsiSourceListAddSourceExA(prodcode
, NULL
,
564 MSIINSTALLCONTEXT_USERUNMANAGED
,
565 MSISOURCETYPE_NETWORK
, "nousersid", 0);
566 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
569 res
= RegQueryValueExA(net
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
570 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
571 ok(!lstrcmpA(value
, "source\\"), "Expected 'source\\', got %s\n", value
);
572 ok(size
== 8, "Expected 8, got %d\n", size
);
575 res
= RegQueryValueExA(net
, "2", NULL
, NULL
, (LPBYTE
)value
, &size
);
576 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
577 ok(!lstrcmpA(value
, "nousersid\\"), "Expected 'nousersid\\', got %s\n", value
);
578 ok(size
== 11, "Expected 11, got %d\n", size
);
580 /* invalid options, must have source type */
581 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
582 MSIINSTALLCONTEXT_USERUNMANAGED
,
583 MSICODE_PRODUCT
, "source", 0);
584 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
586 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
587 MSIINSTALLCONTEXT_USERUNMANAGED
,
588 MSICODE_PATCH
, "source", 0);
589 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
592 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
593 MSIINSTALLCONTEXT_USERUNMANAGED
,
594 MSISOURCETYPE_URL
, NULL
, 1);
595 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
598 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
599 MSIINSTALLCONTEXT_USERUNMANAGED
,
600 MSISOURCETYPE_URL
, "", 1);
601 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
603 /* MSIINSTALLCONTEXT_USERMANAGED, non-NULL szUserSid */
605 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
606 MSIINSTALLCONTEXT_USERMANAGED
,
607 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
608 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r
);
610 lstrcpyA(keypath
, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
611 lstrcatA(keypath
, usersid
);
612 lstrcatA(keypath
, "\\Installer\\Products\\");
613 lstrcatA(keypath
, prod_squashed
);
615 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
616 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
618 /* product key exists */
619 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
620 MSIINSTALLCONTEXT_USERMANAGED
,
621 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
622 ok(r
== ERROR_BAD_CONFIGURATION
, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r
);
624 res
= RegCreateKeyA(prodkey
, "SourceList", &hkey
);
625 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
628 /* SourceList exists */
629 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
630 MSIINSTALLCONTEXT_USERMANAGED
,
631 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
632 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
634 res
= RegOpenKeyA(prodkey
, "SourceList\\URL", &url
);
635 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
638 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
639 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
640 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
641 ok(size
== 11, "Expected 11, got %d\n", size
);
645 /* MSIINSTALLCONTEXT_USERMANAGED, NULL szUserSid */
647 r
= pMsiSourceListAddSourceExA(prodcode
, NULL
,
648 MSIINSTALLCONTEXT_USERMANAGED
,
649 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "another", 0);
650 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
652 res
= RegOpenKeyA(prodkey
, "SourceList\\URL", &url
);
653 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
656 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
657 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
658 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
659 ok(size
== 11, "Expected 11, got %d\n", size
);
662 res
= RegQueryValueExA(url
, "2", NULL
, NULL
, (LPBYTE
)value
, &size
);
663 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
664 ok(!lstrcmpA(value
, "another/"), "Expected 'another/', got %s\n", value
);
665 ok(size
== 9, "Expected 9, got %d\n", size
);
668 RegCloseKey(prodkey
);
670 /* MSIINSTALLCONTEXT_MACHINE */
672 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
673 r
= pMsiSourceListAddSourceExA(prodcode
, usersid
,
674 MSIINSTALLCONTEXT_MACHINE
,
675 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
676 ok(r
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
678 r
= pMsiSourceListAddSourceExA(prodcode
, NULL
,
679 MSIINSTALLCONTEXT_MACHINE
,
680 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
681 ok(r
== ERROR_UNKNOWN_PRODUCT
, "Expected ERROR_INVALID_PARAMETER, got %d\n", r
);
683 lstrcpyA(keypath
, "Software\\Classes\\Installer\\Products\\");
684 lstrcatA(keypath
, prod_squashed
);
686 res
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, keypath
, &prodkey
);
687 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
689 /* product key exists */
690 r
= pMsiSourceListAddSourceExA(prodcode
, NULL
,
691 MSIINSTALLCONTEXT_MACHINE
,
692 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
693 ok(r
== ERROR_BAD_CONFIGURATION
, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r
);
695 res
= RegCreateKeyA(prodkey
, "SourceList", &hkey
);
696 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
699 /* SourceList exists */
700 r
= pMsiSourceListAddSourceExA(prodcode
, NULL
,
701 MSIINSTALLCONTEXT_MACHINE
,
702 MSICODE_PRODUCT
| MSISOURCETYPE_URL
, "C:\\source", 0);
703 ok(r
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", r
);
705 res
= RegOpenKeyA(prodkey
, "SourceList\\URL", &url
);
706 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
709 res
= RegQueryValueExA(url
, "1", NULL
, NULL
, (LPBYTE
)value
, &size
);
710 ok(res
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", res
);
711 ok(!lstrcmpA(value
, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value
);
712 ok(size
== 11, "Expected 11, got %d\n", size
);
715 RegCloseKey(prodkey
);
716 HeapFree(GetProcessHeap(), 0, usersid
);
721 init_functionpointers();
723 test_MsiSourceListGetInfo();
724 test_MsiSourceListAddSourceEx();