push b59ba84f7e04af9ef068bd4c6e96701941f0256e
[wine/hacks.git] / dlls / msi / tests / source.c
blob7407f5b874807e06aa5e7da508b212263bbf0660
1 /*
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
23 #include <stdio.h>
25 #include <windows.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <msi.h>
29 #include <sddl.h>
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); \
46 if(!p ## func) \
47 trace("GetProcAddress(%s) failed\n", #func);
49 GET_PROC(hmsi, MsiSourceListAddSourceExA)
50 GET_PROC(hmsi, MsiSourceListGetInfoA)
52 GET_PROC(hadvapi32, ConvertSidToStringSidA)
54 #undef GET_PROC
57 /* copied from dlls/msi/registry.c */
58 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
60 DWORD i,n=1;
61 GUID guid;
63 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
64 return FALSE;
66 for(i=0; i<8; i++)
67 out[7-i] = in[n++];
68 n++;
69 for(i=0; i<4; i++)
70 out[11-i] = in[n++];
71 n++;
72 for(i=0; i<4; i++)
73 out[15-i] = in[n++];
74 n++;
75 for(i=0; i<2; i++)
77 out[17+i*2] = in[n++];
78 out[16+i*2] = in[n++];
80 n++;
81 for( ; i<8; i++)
83 out[17+i*2] = in[n++];
84 out[16+i*2] = in[n++];
86 out[32]=0;
87 return TRUE;
90 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
92 WCHAR guidW[MAX_PATH];
93 WCHAR squashedW[MAX_PATH];
94 GUID guid;
95 HRESULT hr;
96 int size;
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)
111 HANDLE token;
112 BYTE buf[1024];
113 DWORD size;
114 PTOKEN_USER user;
116 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
117 size = sizeof(buf);
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];
129 LPSTR usersid;
130 LPCSTR data;
131 LONG res;
132 UINT r;
133 HKEY userkey, hkey;
134 DWORD size;
136 if (!pMsiSourceListGetInfoA)
138 skip("Skipping MsiSourceListGetInfoA tests\n");
139 return;
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);
200 /* invalid option */
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);
205 /* NULL property */
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);
210 /* empty property */
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 */
240 size = 0xdeadbeef;
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 */
251 size = 0xdeadbeef;
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 */
266 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 */
274 size = 0xdeadbeef;
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 */
281 size = 0xdeadbeef;
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);
287 data = "tester";
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 */
292 size = 0xdeadbeef;
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 */
299 size = 0xdeadbeef;
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, "");
309 RegCloseKey(hkey);
310 RegCloseKey(userkey);
312 /* try a patch */
313 size = 0xdeadbeef;
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);
325 /* patch key exists
326 * NOTE: using prodcode guid, but it really doesn't matter
328 size = 0xdeadbeef;
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 */
338 size = 0xdeadbeef;
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, "");
346 RegCloseKey(hkey);
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];
356 LPSTR usersid;
357 LONG res;
358 UINT r;
359 HKEY prodkey, userkey, hkey;
360 HKEY url, net;
361 DWORD size;
363 if (!pMsiSourceListAddSourceExA)
365 skip("Skipping MsiSourceListAddSourceExA tests\n");
366 return;
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);
422 RegCloseKey(url);
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);
433 size = MAX_PATH;
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);
445 size = MAX_PATH;
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);
451 size = MAX_PATH;
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);
463 size = MAX_PATH;
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);
469 size = MAX_PATH;
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);
475 size = MAX_PATH;
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);
487 size = MAX_PATH;
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);
493 size = MAX_PATH;
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);
499 size = MAX_PATH;
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);
505 size = MAX_PATH;
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);
520 size = MAX_PATH;
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);
532 size = MAX_PATH;
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);
538 size = MAX_PATH;
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);
544 size = MAX_PATH;
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);
550 size = MAX_PATH;
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);
556 size = MAX_PATH;
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);
562 /* NULL szUserSid */
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);
568 size = MAX_PATH;
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);
574 size = MAX_PATH;
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);
591 /* NULL szSource */
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);
597 /* empty szSource */
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);
626 RegCloseKey(hkey);
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);
637 size = MAX_PATH;
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);
643 RegCloseKey(url);
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);
655 size = MAX_PATH;
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);
661 size = MAX_PATH;
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);
667 RegCloseKey(url);
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);
697 RegCloseKey(hkey);
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);
708 size = MAX_PATH;
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);
714 RegCloseKey(url);
715 RegCloseKey(prodkey);
716 HeapFree(GetProcessHeap(), 0, usersid);
719 START_TEST(source)
721 init_functionpointers();
723 test_MsiSourceListGetInfo();
724 test_MsiSourceListAddSourceEx();