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 pMsiSourceListGetInfoA = (void*)GetProcAddress(hmsi, "MsiSourceListGetInfoA");
45 pMsiSourceListAddSourceExA = (void*)GetProcAddress(hmsi, "MsiSourceListAddSourceExA");
46 pConvertSidToStringSidA = (void*)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
49 /* copied from dlls/msi/registry.c */
50 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
55 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
69 out[17+i*2] = in[n++];
70 out[16+i*2] = in[n++];
75 out[17+i*2] = in[n++];
76 out[16+i*2] = in[n++];
82 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
84 WCHAR guidW[MAX_PATH];
85 WCHAR squashedW[MAX_PATH];
90 hr = CoCreateGuid(&guid);
91 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
93 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
94 ok(size == 39, "Expected 39, got %d\n", hr);
96 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
97 squash_guid(guidW, squashedW);
98 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
101 static void get_user_sid(LPSTR *usersid)
108 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
110 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
111 user = (PTOKEN_USER)buf;
112 pConvertSidToStringSidA(user->User.Sid, usersid);
115 static void test_MsiSourceListGetInfo(void)
117 CHAR prodcode[MAX_PATH];
118 CHAR prod_squashed[MAX_PATH];
119 CHAR keypath[MAX_PATH*2];
120 CHAR value[MAX_PATH];
128 create_test_guid(prodcode, prod_squashed);
129 get_user_sid(&usersid);
131 /* NULL szProductCodeOrPatchCode */
132 r = pMsiSourceListGetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
133 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
134 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
136 /* empty szProductCodeOrPatchCode */
137 r = pMsiSourceListGetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
138 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
139 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
141 /* garbage szProductCodeOrPatchCode */
142 r = pMsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
143 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
144 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
146 /* szProductCodeOrPatchCode */
147 r = pMsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
148 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
149 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
151 /* guid without brackets */
152 r = pMsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
153 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
154 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
156 /* guid with brackets */
157 r = pMsiSourceListGetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
158 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
159 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
161 /* same length as guid, but random */
162 r = pMsiSourceListGetInfoA("ADKD-2KSDFF2-DKK1KNFJASD9GLKWME-1I3KAD", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
163 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
164 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
166 /* invalid context */
167 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_NONE,
168 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
169 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
171 /* another invalid context */
172 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALLUSERMANAGED,
173 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
174 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
176 /* yet another invalid context */
177 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALL,
178 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
179 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
181 /* mix two valid contexts */
182 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED,
183 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
184 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
187 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
188 4, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
189 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
192 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
193 MSICODE_PRODUCT, NULL, NULL, NULL);
194 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
197 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
198 MSICODE_PRODUCT, "", NULL, NULL);
199 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
201 /* value is non-NULL while size is NULL */
202 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
203 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, NULL);
204 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
206 /* size is non-NULL while value is NULL */
207 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
208 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
209 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
211 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
212 lstrcatA(keypath, prod_squashed);
214 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
215 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
217 /* user product key exists */
218 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
219 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
220 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
222 res = RegCreateKeyA(userkey, "SourceList", &hkey);
223 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
225 /* SourceList key exists */
227 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
228 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
230 ok(size == 0, "Expected 0, got %d\n", size);
232 data = "msitest.msi";
233 res = RegSetValueExA(hkey, "PackageName", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
234 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
236 /* PackageName value exists */
238 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
239 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
240 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
241 ok(size == 11, "Expected 11, got %d\n", size);
243 /* read the value, don't change size */
244 lstrcpyA(value, "aaa");
245 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
246 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
247 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
248 ok(!lstrcmpA(value, "aaa"), "Expected 'aaa', got %s\n", value);
249 ok(size == 11, "Expected 11, got %d\n", size);
251 /* read the value, fix size */
253 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
254 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
255 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
256 ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
257 ok(size == 11, "Expected 11, got %d\n", size);
259 /* empty property now that product key exists */
261 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
262 MSICODE_PRODUCT, "", NULL, &size);
263 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
264 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
266 /* nonexistent property now that product key exists */
268 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
269 MSICODE_PRODUCT, "nonexistent", NULL, &size);
270 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
271 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
274 res = RegSetValueExA(hkey, "nonexistent", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
275 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
277 /* nonexistent property now that nonexistent value exists */
279 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
280 MSICODE_PRODUCT, "nonexistent", NULL, &size);
281 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
282 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
284 /* invalid option now that product key exists */
286 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
287 4, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
289 ok(size == 11, "Expected 11, got %d\n", size);
291 RegDeleteValueA(hkey, "nonexistent");
292 RegDeleteValueA(hkey, "PackageName");
293 RegDeleteKeyA(hkey, "");
294 RegDeleteKeyA(userkey, "");
296 RegCloseKey(userkey);
300 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
301 MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
302 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
303 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
305 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\");
306 lstrcatA(keypath, prod_squashed);
308 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
309 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
312 * NOTE: using prodcode guid, but it really doesn't matter
315 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
316 MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
317 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
318 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
320 res = RegCreateKeyA(userkey, "SourceList", &hkey);
321 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
323 /* SourceList key exists */
325 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
326 MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
328 ok(size == 0, "Expected 0, got %d\n", size);
330 RegDeleteKeyA(hkey, "");
331 RegDeleteKeyA(userkey, "");
333 RegCloseKey(userkey);
336 static void test_MsiSourceListAddSourceEx(void)
338 CHAR prodcode[MAX_PATH];
339 CHAR prod_squashed[MAX_PATH];
340 CHAR keypath[MAX_PATH*2];
341 CHAR value[MAX_PATH];
345 HKEY prodkey, userkey, hkey;
349 if (!pMsiSourceListAddSourceExA)
351 skip("Skipping MsiSourceListAddSourceEx tests\n");
355 create_test_guid(prodcode, prod_squashed);
356 get_user_sid(&usersid);
358 /* GetLastError is not set by the function */
360 /* NULL szProductCodeOrPatchCode */
361 r = pMsiSourceListAddSourceExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
362 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
363 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
365 /* empty szProductCodeOrPatchCode */
366 r = pMsiSourceListAddSourceExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
367 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
368 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
370 /* garbage szProductCodeOrPatchCode */
371 r = pMsiSourceListAddSourceExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
372 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
373 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
375 /* guid without brackets */
376 r = pMsiSourceListAddSourceExA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid,
377 MSIINSTALLCONTEXT_USERUNMANAGED,
378 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
379 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
381 /* guid with brackets */
382 r = pMsiSourceListAddSourceExA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid,
383 MSIINSTALLCONTEXT_USERUNMANAGED,
384 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
385 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
387 /* MSIINSTALLCONTEXT_USERUNMANAGED */
389 r = pMsiSourceListAddSourceExA(prodcode, usersid,
390 MSIINSTALLCONTEXT_USERUNMANAGED,
391 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
392 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
394 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
395 lstrcatA(keypath, prod_squashed);
397 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
398 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
400 /* user product key exists */
401 r = pMsiSourceListAddSourceExA(prodcode, usersid,
402 MSIINSTALLCONTEXT_USERUNMANAGED,
403 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
404 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
406 res = RegCreateKeyA(userkey, "SourceList", &url);
407 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
410 /* SourceList key exists */
411 r = pMsiSourceListAddSourceExA(prodcode, usersid,
412 MSIINSTALLCONTEXT_USERUNMANAGED,
413 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
414 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
416 res = RegOpenKeyA(userkey, "SourceList\\URL", &url);
417 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
420 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
421 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
422 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
423 ok(size == 11, "Expected 11, got %d\n", size);
425 /* add another source, index 0 */
426 r = pMsiSourceListAddSourceExA(prodcode, usersid,
427 MSIINSTALLCONTEXT_USERUNMANAGED,
428 MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
432 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
434 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
435 ok(size == 11, "Expected 11, got %d\n", size);
438 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
440 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
441 ok(size == 9, "Expected 9, got %d\n", size);
443 /* add another source, index 1 */
444 r = pMsiSourceListAddSourceExA(prodcode, usersid,
445 MSIINSTALLCONTEXT_USERUNMANAGED,
446 MSICODE_PRODUCT | MSISOURCETYPE_URL, "third/", 1);
447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
450 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
451 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
452 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
453 ok(size == 7, "Expected 7, got %d\n", size);
456 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
458 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
459 ok(size == 11, "Expected 11, got %d\n", size);
462 res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
463 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
464 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
465 ok(size == 9, "Expected 9, got %d\n", size);
467 /* add another source, index > N */
468 r = pMsiSourceListAddSourceExA(prodcode, usersid,
469 MSIINSTALLCONTEXT_USERUNMANAGED,
470 MSICODE_PRODUCT | MSISOURCETYPE_URL, "last/", 5);
471 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
474 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
475 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
476 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
477 ok(size == 7, "Expected 7, got %d\n", size);
480 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
481 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
482 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
483 ok(size == 11, "Expected 11, got %d\n", size);
486 res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
487 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
488 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
489 ok(size == 9, "Expected 9, got %d\n", size);
492 res = RegQueryValueExA(url, "4", NULL, NULL, (LPBYTE)value, &size);
493 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
494 ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
495 ok(size == 6, "Expected 6, got %d\n", size);
497 /* just MSISOURCETYPE_NETWORK */
498 r = pMsiSourceListAddSourceExA(prodcode, usersid,
499 MSIINSTALLCONTEXT_USERUNMANAGED,
500 MSISOURCETYPE_NETWORK, "source", 0);
501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
503 res = RegOpenKeyA(userkey, "SourceList\\Net", &net);
504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
507 res = RegQueryValueExA(net, "1", NULL, NULL, (LPBYTE)value, &size);
508 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
509 ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
510 ok(size == 8, "Expected 8, got %d\n", size);
512 /* just MSISOURCETYPE_URL */
513 r = pMsiSourceListAddSourceExA(prodcode, usersid,
514 MSIINSTALLCONTEXT_USERUNMANAGED,
515 MSISOURCETYPE_URL, "source", 0);
516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
519 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
520 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
521 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
522 ok(size == 7, "Expected 7, got %d\n", size);
525 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
526 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
527 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
528 ok(size == 11, "Expected 11, got %d\n", size);
531 res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
532 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
533 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
534 ok(size == 9, "Expected 9, got %d\n", size);
537 res = RegQueryValueExA(url, "4", NULL, NULL, (LPBYTE)value, &size);
538 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
539 ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
540 ok(size == 6, "Expected 6, got %d\n", size);
543 res = RegQueryValueExA(url, "5", NULL, NULL, (LPBYTE)value, &size);
544 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
545 ok(!lstrcmpA(value, "source/"), "Expected 'source/', got %s\n", value);
546 ok(size == 8, "Expected 8, got %d\n", size);
549 r = pMsiSourceListAddSourceExA(prodcode, NULL,
550 MSIINSTALLCONTEXT_USERUNMANAGED,
551 MSISOURCETYPE_NETWORK, "nousersid", 0);
552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
555 res = RegQueryValueExA(net, "1", NULL, NULL, (LPBYTE)value, &size);
556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
557 ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
558 ok(size == 8, "Expected 8, got %d\n", size);
561 res = RegQueryValueExA(net, "2", NULL, NULL, (LPBYTE)value, &size);
562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
563 ok(!lstrcmpA(value, "nousersid\\"), "Expected 'nousersid\\', got %s\n", value);
564 ok(size == 11, "Expected 11, got %d\n", size);
566 /* invalid options, must have source type */
567 r = pMsiSourceListAddSourceExA(prodcode, usersid,
568 MSIINSTALLCONTEXT_USERUNMANAGED,
569 MSICODE_PRODUCT, "source", 0);
570 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
572 r = pMsiSourceListAddSourceExA(prodcode, usersid,
573 MSIINSTALLCONTEXT_USERUNMANAGED,
574 MSICODE_PATCH, "source", 0);
575 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
578 r = pMsiSourceListAddSourceExA(prodcode, usersid,
579 MSIINSTALLCONTEXT_USERUNMANAGED,
580 MSISOURCETYPE_URL, NULL, 1);
581 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
584 r = pMsiSourceListAddSourceExA(prodcode, usersid,
585 MSIINSTALLCONTEXT_USERUNMANAGED,
586 MSISOURCETYPE_URL, "", 1);
587 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
589 /* MSIINSTALLCONTEXT_USERMANAGED, non-NULL szUserSid */
591 r = pMsiSourceListAddSourceExA(prodcode, usersid,
592 MSIINSTALLCONTEXT_USERMANAGED,
593 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
594 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
596 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
597 lstrcatA(keypath, usersid);
598 lstrcatA(keypath, "\\Installer\\Products\\");
599 lstrcatA(keypath, prod_squashed);
601 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
604 /* product key exists */
605 r = pMsiSourceListAddSourceExA(prodcode, usersid,
606 MSIINSTALLCONTEXT_USERMANAGED,
607 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
608 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
610 res = RegCreateKeyA(prodkey, "SourceList", &hkey);
611 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
614 /* SourceList exists */
615 r = pMsiSourceListAddSourceExA(prodcode, usersid,
616 MSIINSTALLCONTEXT_USERMANAGED,
617 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
618 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
620 res = RegOpenKeyA(prodkey, "SourceList\\URL", &url);
621 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
624 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
625 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
626 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
627 ok(size == 11, "Expected 11, got %d\n", size);
631 /* MSIINSTALLCONTEXT_USERMANAGED, NULL szUserSid */
633 r = pMsiSourceListAddSourceExA(prodcode, NULL,
634 MSIINSTALLCONTEXT_USERMANAGED,
635 MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
638 res = RegOpenKeyA(prodkey, "SourceList\\URL", &url);
639 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
642 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
643 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
644 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
645 ok(size == 11, "Expected 11, got %d\n", size);
648 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
649 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
650 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
651 ok(size == 9, "Expected 9, got %d\n", size);
654 RegCloseKey(prodkey);
656 /* MSIINSTALLCONTEXT_MACHINE */
658 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
659 r = pMsiSourceListAddSourceExA(prodcode, usersid,
660 MSIINSTALLCONTEXT_MACHINE,
661 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
662 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
664 r = pMsiSourceListAddSourceExA(prodcode, NULL,
665 MSIINSTALLCONTEXT_MACHINE,
666 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
667 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
669 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
670 lstrcatA(keypath, prod_squashed);
672 res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
673 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
675 /* product key exists */
676 r = pMsiSourceListAddSourceExA(prodcode, NULL,
677 MSIINSTALLCONTEXT_MACHINE,
678 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
679 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
681 res = RegCreateKeyA(prodkey, "SourceList", &hkey);
682 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
685 /* SourceList exists */
686 r = pMsiSourceListAddSourceExA(prodcode, NULL,
687 MSIINSTALLCONTEXT_MACHINE,
688 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
691 res = RegOpenKeyA(prodkey, "SourceList\\URL", &url);
692 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
695 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
696 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
697 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
698 ok(size == 11, "Expected 11, got %d\n", size);
701 RegCloseKey(prodkey);
702 HeapFree(GetProcessHeap(), 0, usersid);
707 init_functionpointers();
709 test_MsiSourceListGetInfo();
710 test_MsiSourceListAddSourceEx();