mf/session: Forward more events to the application.
[wine/zf.git] / dlls / msi / tests / source.c
blob32b5621e3bf43a53a2f3b74c25afda322c5c1146
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>
30 #include <secext.h>
31 #include <objbase.h>
33 #include "wine/test.h"
34 #include "utils.h"
36 static BOOL is_wow64;
38 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
39 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
41 static UINT (WINAPI *pMsiSourceListAddMediaDiskA)
42 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPCSTR, LPCSTR);
43 static UINT (WINAPI *pMsiSourceListAddSourceExA)
44 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, DWORD);
45 static UINT (WINAPI *pMsiSourceListEnumMediaDisksA)
46 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPDWORD, LPSTR,
47 LPDWORD, LPSTR, LPDWORD);
48 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
49 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
50 static UINT (WINAPI *pMsiSourceListGetInfoA)
51 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
52 static UINT (WINAPI *pMsiSourceListGetInfoW)
53 (LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR, LPWSTR, LPDWORD);
54 static UINT (WINAPI *pMsiSourceListSetInfoA)
55 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD,LPCSTR, LPCSTR);
56 static UINT (WINAPI *pMsiSourceListAddSourceA)
57 (LPCSTR, LPCSTR, DWORD, LPCSTR);
59 static void init_functionpointers(void)
61 HMODULE hmsi = GetModuleHandleA("msi.dll");
62 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
63 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
65 #define GET_PROC(dll, func) \
66 p ## func = (void *)GetProcAddress(dll, #func); \
67 if(!p ## func) \
68 trace("GetProcAddress(%s) failed\n", #func);
70 GET_PROC(hmsi, MsiSourceListAddMediaDiskA)
71 GET_PROC(hmsi, MsiSourceListAddSourceExA)
72 GET_PROC(hmsi, MsiSourceListEnumMediaDisksA)
73 GET_PROC(hmsi, MsiSourceListEnumSourcesA)
74 GET_PROC(hmsi, MsiSourceListGetInfoA)
75 GET_PROC(hmsi, MsiSourceListGetInfoW)
76 GET_PROC(hmsi, MsiSourceListSetInfoA)
77 GET_PROC(hmsi, MsiSourceListAddSourceA)
79 GET_PROC(hadvapi32, RegDeleteKeyExA)
80 GET_PROC(hkernel32, IsWow64Process)
82 #undef GET_PROC
85 /* copied from dlls/msi/registry.c */
86 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
88 DWORD i,n=1;
89 GUID guid;
91 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
92 return FALSE;
94 for(i=0; i<8; i++)
95 out[7-i] = in[n++];
96 n++;
97 for(i=0; i<4; i++)
98 out[11-i] = in[n++];
99 n++;
100 for(i=0; i<4; i++)
101 out[15-i] = in[n++];
102 n++;
103 for(i=0; i<2; i++)
105 out[17+i*2] = in[n++];
106 out[16+i*2] = in[n++];
108 n++;
109 for( ; i<8; i++)
111 out[17+i*2] = in[n++];
112 out[16+i*2] = in[n++];
114 out[32]=0;
115 return TRUE;
118 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
120 WCHAR guidW[MAX_PATH];
121 WCHAR squashedW[MAX_PATH];
122 GUID guid;
123 HRESULT hr;
124 int size;
126 hr = CoCreateGuid(&guid);
127 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
129 size = StringFromGUID2(&guid, guidW, MAX_PATH);
130 ok(size == 39, "Expected 39, got %d\n", hr);
132 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
133 squash_guid(guidW, squashedW);
134 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
137 static char *get_user_sid(void)
139 HANDLE token;
140 DWORD size = 0;
141 TOKEN_USER *user;
142 char *usersid = NULL;
144 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
145 GetTokenInformation(token, TokenUser, NULL, size, &size);
147 user = HeapAlloc(GetProcessHeap(), 0, size);
148 GetTokenInformation(token, TokenUser, user, size, &size);
149 ConvertSidToStringSidA(user->User.Sid, &usersid);
150 HeapFree(GetProcessHeap(), 0, user);
152 CloseHandle(token);
153 return usersid;
156 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
158 char val[MAX_PATH];
159 DWORD size, type;
160 LONG res;
162 size = MAX_PATH;
163 val[0] = '\0';
164 res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
166 if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
168 ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
169 return;
172 if (!expected)
173 ok_(__FILE__, line)(!val[0], "Expected empty string, got %s\n", val);
174 else
176 if (bcase)
177 ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
178 else
179 ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
183 #define CHECK_REG_STR(prodkey, name, expected) \
184 check_reg_str(prodkey, name, expected, TRUE, __LINE__);
186 static inline WCHAR *strdupAW( const char *str )
188 int len;
189 WCHAR *ret;
190 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
191 if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
192 MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
193 return ret;
196 static void test_MsiSourceListGetInfo(void)
198 char prodcode[MAX_PATH], prod_squashed[MAX_PATH], keypath[MAX_PATH * 2], value[MAX_PATH], *usersid;
199 WCHAR valueW[MAX_PATH], *usersidW, *prodcodeW;
200 const char *data;
201 LONG res;
202 UINT r;
203 HKEY userkey, hkey, media;
204 DWORD size;
206 if (!pMsiSourceListGetInfoA)
208 win_skip("Skipping MsiSourceListGetInfoA tests\n");
209 return;
212 create_test_guid(prodcode, prod_squashed);
213 if (!(usersid = get_user_sid()))
215 skip("User SID not available -> skipping MsiSourceListGetInfoA tests\n");
216 return;
219 /* NULL szProductCodeOrPatchCode */
220 r = pMsiSourceListGetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
221 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
222 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
224 /* empty szProductCodeOrPatchCode */
225 r = pMsiSourceListGetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
226 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
227 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
229 /* garbage szProductCodeOrPatchCode */
230 r = pMsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
231 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
232 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
234 /* guid without brackets */
235 r = pMsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
236 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
237 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
239 /* guid with brackets */
240 r = pMsiSourceListGetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
241 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
242 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
244 /* same length as guid, but random */
245 r = pMsiSourceListGetInfoA("ADKD-2KSDFF2-DKK1KNFJASD9GLKWME-1I3KAD", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
246 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
247 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
249 /* invalid context */
250 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_NONE,
251 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
252 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
254 /* another invalid context */
255 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALLUSERMANAGED,
256 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
257 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
259 /* yet another invalid context */
260 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALL,
261 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
262 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
264 /* mix two valid contexts */
265 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED,
266 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
267 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
269 /* invalid option */
270 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
271 4, INSTALLPROPERTY_PACKAGENAMEA, NULL, NULL);
272 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
274 /* NULL property */
275 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
276 MSICODE_PRODUCT, NULL, NULL, NULL);
277 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
279 /* empty property */
280 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
281 MSICODE_PRODUCT, "", NULL, NULL);
282 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
284 /* value is non-NULL while size is NULL */
285 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
286 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, NULL);
287 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
289 /* size is non-NULL while value is NULL */
290 size = MAX_PATH;
291 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
292 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, &size);
293 ok(r == ERROR_UNKNOWN_PRODUCT || r == ERROR_INVALID_PARAMETER,
294 "Expected ERROR_UNKNOWN_PRODUCT or ERROR_INVALID_PARAMETER, got %d\n", r);
296 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
297 lstrcatA(keypath, prod_squashed);
299 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
302 /* user product key exists */
303 size = MAX_PATH;
304 lstrcpyA(value, "aaa");
305 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
306 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
307 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
308 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
310 res = RegCreateKeyA(userkey, "SourceList", &hkey);
311 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
313 /* SourceList key exists */
314 size = MAX_PATH;
315 lstrcpyA(value, "aaa");
316 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
317 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
319 ok(size == 0, "Expected 0, got %d\n", size);
320 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
322 data = "msitest.msi";
323 res = RegSetValueExA(hkey, "PackageName", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
324 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
326 /* PackageName value exists */
327 size = 0xdeadbeef;
328 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
329 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, NULL, &size);
330 ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER,
331 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
332 ok(size == 11 || r != ERROR_SUCCESS, "Expected 11, got %d\n", size);
334 /* read the value, don't change size */
335 size = 11;
336 lstrcpyA(value, "aaa");
337 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
338 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
339 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
340 ok(!lstrcmpA(value, "aaa"), "Expected 'aaa', got %s\n", value);
341 ok(size == 11, "Expected 11, got %d\n", size);
343 /* read the value, fix size */
344 size++;
345 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
346 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
348 ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
349 ok(size == 11, "Expected 11, got %d\n", size);
351 /* empty property now that product key exists */
352 size = MAX_PATH;
353 lstrcpyA(value, "aaa");
354 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
355 MSICODE_PRODUCT, "", value, &size);
356 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
357 ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
358 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
360 /* nonexistent property now that product key exists */
361 size = MAX_PATH;
362 lstrcpyA(value, "aaa");
363 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
364 MSICODE_PRODUCT, "nonexistent", value, &size);
365 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
366 ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
367 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
369 data = "tester";
370 res = RegSetValueExA(hkey, "nonexistent", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
373 /* nonexistent property now that nonexistent value exists */
374 size = MAX_PATH;
375 lstrcpyA(value, "aaa");
376 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
377 MSICODE_PRODUCT, "nonexistent", value, &size);
378 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
379 ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
380 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
382 /* invalid option now that product key exists */
383 size = MAX_PATH;
384 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
385 4, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
387 ok(size == 11, "Expected 11, got %d\n", size);
389 /* INSTALLPROPERTY_MEDIAPACKAGEPATH, media key does not exist */
390 size = MAX_PATH;
391 lstrcpyA(value, "aaa");
392 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
393 MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATHA,
394 value, &size);
395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
396 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
397 ok(size == 0, "Expected 0, got %d\n", size);
399 res = RegCreateKeyA(hkey, "Media", &media);
400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
402 data = "path";
403 res = RegSetValueExA(media, "MediaPackage", 0, REG_SZ,
404 (const BYTE *)data, lstrlenA(data) + 1);
405 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
407 /* INSTALLPROPERTY_MEDIAPACKAGEPATH */
408 size = MAX_PATH;
409 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
410 MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATHA,
411 value, &size);
412 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
413 ok(!lstrcmpA(value, "path"), "Expected \"path\", got \"%s\"\n", value);
414 ok(size == 4, "Expected 4, got %d\n", size);
416 /* INSTALLPROPERTY_DISKPROMPT */
417 data = "prompt";
418 res = RegSetValueExA(media, "DiskPrompt", 0, REG_SZ,
419 (const BYTE *)data, lstrlenA(data) + 1);
420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
422 size = MAX_PATH;
423 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
424 MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPTA,
425 value, &size);
426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
427 ok(!lstrcmpA(value, "prompt"), "Expected \"prompt\", got \"%s\"\n", value);
428 ok(size == 6, "Expected 6, got %d\n", size);
430 /* LastUsedSource value doesn't exist */
431 RegDeleteValueA(hkey, "LastUsedSource");
432 size = MAX_PATH;
433 memset(value, 0x55, sizeof(value));
434 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
435 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA,
436 value, &size);
437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
438 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
439 ok(size == 0, "Expected 0, got %d\n", size);
441 size = MAX_PATH;
442 usersidW = strdupAW(usersid);
443 prodcodeW = strdupAW(prodcode);
444 memset(valueW, 0x55, sizeof(valueW));
445 r = pMsiSourceListGetInfoW(prodcodeW, usersidW, MSIINSTALLCONTEXT_USERUNMANAGED,
446 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW,
447 valueW, &size);
448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
449 ok(!valueW[0], "Expected \"\"");
450 ok(size == 0, "Expected 0, got %d\n", size);
451 HeapFree(GetProcessHeap(), 0, usersidW);
452 HeapFree(GetProcessHeap(), 0, prodcodeW);
454 data = "";
455 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
456 (const BYTE *)data, lstrlenA(data) + 1);
457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
459 /* INSTALLPROPERTY_LASTUSEDSOURCE, source is empty */
460 size = MAX_PATH;
461 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
462 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA,
463 value, &size);
464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
465 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
466 ok(size == 0, "Expected 0, got %d\n", size);
468 data = "source";
469 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
470 (const BYTE *)data, lstrlenA(data) + 1);
471 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
473 /* INSTALLPROPERTY_LASTUSEDSOURCE */
474 size = MAX_PATH;
475 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
476 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA,
477 value, &size);
478 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
479 ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value);
480 ok(size == 6, "Expected 6, got %d\n", size);
482 /* INSTALLPROPERTY_LASTUSEDSOURCE, size is too short */
483 size = 4;
484 lstrcpyA(value, "aaa");
485 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
486 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA,
487 value, &size);
488 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
489 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value);
490 ok(size == 6, "Expected 6, got %d\n", size);
492 /* INSTALLPROPERTY_LASTUSEDSOURCE, size is exactly 6 */
493 size = 6;
494 lstrcpyA(value, "aaa");
495 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
496 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA,
497 value, &size);
498 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
499 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value);
500 ok(size == 6, "Expected 6, got %d\n", size);
502 data = "a;source";
503 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
504 (const BYTE *)data, lstrlenA(data) + 1);
505 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
507 /* INSTALLPROPERTY_LASTUSEDSOURCE, one semi-colon */
508 size = MAX_PATH;
509 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
510 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA,
511 value, &size);
512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
513 ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value);
514 ok(size == 6, "Expected 6, got %d\n", size);
516 data = "a:source";
517 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
518 (const BYTE *)data, lstrlenA(data) + 1);
519 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
521 /* INSTALLPROPERTY_LASTUSEDSOURCE, one colon */
522 size = MAX_PATH;
523 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
524 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA,
525 value, &size);
526 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
527 ok(!lstrcmpA(value, "a:source"), "Expected \"a:source\", got \"%s\"\n", value);
528 ok(size == 8, "Expected 8, got %d\n", size);
530 /* INSTALLPROPERTY_LASTUSEDTYPE, invalid source format */
531 size = MAX_PATH;
532 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
533 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA,
534 value, &size);
535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
536 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
537 ok(size == 0, "Expected 0, got %d\n", size);
539 data = "x;y;z";
540 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
541 (const BYTE *)data, lstrlenA(data) + 1);
542 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
544 /* INSTALLPROPERTY_LASTUSEDTYPE, invalid source format */
545 size = MAX_PATH;
546 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
547 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA,
548 value, &size);
549 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
550 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
551 ok(size == 0, "Expected 0, got %d\n", size);
553 data = "n;y;z";
554 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
555 (const BYTE *)data, lstrlenA(data) + 1);
556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
558 /* INSTALLPROPERTY_LASTUSEDTYPE */
559 size = MAX_PATH;
560 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
561 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA,
562 value, &size);
563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
564 ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
565 ok(size == 1, "Expected 1, got %d\n", size);
567 data = "negatory";
568 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
569 (const BYTE *)data, lstrlenA(data) + 1);
570 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
572 /* INSTALLPROPERTY_LASTUSEDTYPE */
573 size = MAX_PATH;
574 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
575 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA,
576 value, &size);
577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
578 ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
579 ok(size == 1, "Expected 1, got %d\n", size);
581 data = "megatron";
582 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
583 (const BYTE *)data, lstrlenA(data) + 1);
584 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
586 /* INSTALLPROPERTY_LASTUSEDTYPE */
587 size = MAX_PATH;
588 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
589 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA,
590 value, &size);
591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
592 ok(!lstrcmpA(value, "m"), "Expected \"m\", got \"%s\"\n", value);
593 ok(size == 1, "Expected 1, got %d\n", size);
595 data = "useless";
596 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
597 (const BYTE *)data, lstrlenA(data) + 1);
598 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
600 /* INSTALLPROPERTY_LASTUSEDTYPE */
601 size = MAX_PATH;
602 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
603 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA,
604 value, &size);
605 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
606 ok(!lstrcmpA(value, "u"), "Expected \"u\", got \"%s\"\n", value);
607 ok(size == 1, "Expected 1, got %d\n", size);
609 RegDeleteValueA(media, "MediaPackage");
610 RegDeleteValueA(media, "DiskPrompt");
611 RegDeleteKeyA(media, "");
612 RegDeleteValueA(hkey, "LastUsedSource");
613 RegDeleteValueA(hkey, "nonexistent");
614 RegDeleteValueA(hkey, "PackageName");
615 RegDeleteKeyA(hkey, "");
616 RegDeleteKeyA(userkey, "");
617 RegCloseKey(hkey);
618 RegCloseKey(userkey);
620 /* try a patch */
621 size = MAX_PATH;
622 lstrcpyA(value, "aaa");
623 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
624 MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
625 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
626 ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
627 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
629 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\");
630 lstrcatA(keypath, prod_squashed);
632 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
633 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
635 /* patch key exists
636 * NOTE: using prodcode guid, but it really doesn't matter
638 size = MAX_PATH;
639 lstrcpyA(value, "aaa");
640 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
641 MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
642 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
643 ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
644 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
646 res = RegCreateKeyA(userkey, "SourceList", &hkey);
647 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
649 /* SourceList key exists */
650 size = MAX_PATH;
651 lstrcpyA(value, "aaa");
652 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
653 MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
655 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
656 ok(size == 0, "Expected 0, got %d\n", size);
658 RegDeleteKeyA(hkey, "");
659 RegDeleteKeyA(userkey, "");
660 RegCloseKey(hkey);
661 RegCloseKey(userkey);
662 LocalFree(usersid);
665 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
667 if (pRegDeleteKeyExA)
668 return pRegDeleteKeyExA( key, subkey, access, 0 );
669 return RegDeleteKeyA( key, subkey );
672 static void test_MsiSourceListAddSourceEx(void)
674 CHAR prodcode[MAX_PATH];
675 CHAR prod_squashed[MAX_PATH];
676 CHAR keypath[MAX_PATH*2];
677 CHAR value[MAX_PATH];
678 LPSTR usersid;
679 LONG res;
680 UINT r;
681 HKEY prodkey, userkey, hkey, url, net;
682 DWORD size;
683 REGSAM access = KEY_ALL_ACCESS;
685 if (!pMsiSourceListAddSourceExA)
687 win_skip("Skipping MsiSourceListAddSourceExA tests\n");
688 return;
690 if (is_process_limited())
692 skip("process is limited\n");
693 return;
696 create_test_guid(prodcode, prod_squashed);
697 if (!(usersid = get_user_sid()))
699 skip("User SID not available -> skipping MsiSourceListAddSourceExA tests\n");
700 return;
703 if (is_wow64)
704 access |= KEY_WOW64_64KEY;
706 /* GetLastError is not set by the function */
708 /* NULL szProductCodeOrPatchCode */
709 r = pMsiSourceListAddSourceExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
710 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
711 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
713 /* empty szProductCodeOrPatchCode */
714 r = pMsiSourceListAddSourceExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
715 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
716 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
718 /* garbage szProductCodeOrPatchCode */
719 r = pMsiSourceListAddSourceExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
720 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
721 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
723 /* guid without brackets */
724 r = pMsiSourceListAddSourceExA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid,
725 MSIINSTALLCONTEXT_USERUNMANAGED,
726 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
727 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
729 /* guid with brackets */
730 r = pMsiSourceListAddSourceExA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid,
731 MSIINSTALLCONTEXT_USERUNMANAGED,
732 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
733 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
735 /* MSIINSTALLCONTEXT_USERUNMANAGED */
737 r = pMsiSourceListAddSourceExA(prodcode, usersid,
738 MSIINSTALLCONTEXT_USERUNMANAGED,
739 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
740 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
742 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
743 lstrcatA(keypath, prod_squashed);
745 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
748 /* user product key exists */
749 r = pMsiSourceListAddSourceExA(prodcode, usersid,
750 MSIINSTALLCONTEXT_USERUNMANAGED,
751 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
752 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
754 res = RegCreateKeyA(userkey, "SourceList", &url);
755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
756 RegCloseKey(url);
758 /* SourceList key exists */
759 r = pMsiSourceListAddSourceExA(prodcode, usersid,
760 MSIINSTALLCONTEXT_USERUNMANAGED,
761 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
764 res = RegOpenKeyA(userkey, "SourceList\\URL", &url);
765 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
767 size = MAX_PATH;
768 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
770 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
771 ok(size == 11, "Expected 11, got %d\n", size);
773 /* add another source, index 0 */
774 r = pMsiSourceListAddSourceExA(prodcode, usersid,
775 MSIINSTALLCONTEXT_USERUNMANAGED,
776 MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
777 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
779 size = MAX_PATH;
780 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
782 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
783 ok(size == 11, "Expected 11, got %d\n", size);
785 size = MAX_PATH;
786 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
787 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
788 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
789 ok(size == 9, "Expected 9, got %d\n", size);
791 /* add another source, index 1 */
792 r = pMsiSourceListAddSourceExA(prodcode, usersid,
793 MSIINSTALLCONTEXT_USERUNMANAGED,
794 MSICODE_PRODUCT | MSISOURCETYPE_URL, "third/", 1);
795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
797 size = MAX_PATH;
798 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
799 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
800 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
801 ok(size == 7, "Expected 7, got %d\n", size);
803 size = MAX_PATH;
804 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
805 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
806 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
807 ok(size == 11, "Expected 11, got %d\n", size);
809 size = MAX_PATH;
810 res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
812 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
813 ok(size == 9, "Expected 9, got %d\n", size);
815 /* add another source, index > N */
816 r = pMsiSourceListAddSourceExA(prodcode, usersid,
817 MSIINSTALLCONTEXT_USERUNMANAGED,
818 MSICODE_PRODUCT | MSISOURCETYPE_URL, "last/", 5);
819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
821 size = MAX_PATH;
822 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
823 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
824 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
825 ok(size == 7, "Expected 7, got %d\n", size);
827 size = MAX_PATH;
828 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
829 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
830 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
831 ok(size == 11, "Expected 11, got %d\n", size);
833 size = MAX_PATH;
834 res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
835 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
836 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
837 ok(size == 9, "Expected 9, got %d\n", size);
839 size = MAX_PATH;
840 res = RegQueryValueExA(url, "4", NULL, NULL, (LPBYTE)value, &size);
841 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
842 ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
843 ok(size == 6, "Expected 6, got %d\n", size);
845 /* just MSISOURCETYPE_NETWORK */
846 r = pMsiSourceListAddSourceExA(prodcode, usersid,
847 MSIINSTALLCONTEXT_USERUNMANAGED,
848 MSISOURCETYPE_NETWORK, "source", 0);
849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
851 res = RegOpenKeyA(userkey, "SourceList\\Net", &net);
852 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
854 size = MAX_PATH;
855 res = RegQueryValueExA(net, "1", NULL, NULL, (LPBYTE)value, &size);
856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
857 ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
858 ok(size == 8, "Expected 8, got %d\n", size);
860 /* just MSISOURCETYPE_URL */
861 r = pMsiSourceListAddSourceExA(prodcode, usersid,
862 MSIINSTALLCONTEXT_USERUNMANAGED,
863 MSISOURCETYPE_URL, "source", 0);
864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
866 size = MAX_PATH;
867 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
869 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
870 ok(size == 7, "Expected 7, got %d\n", size);
872 size = MAX_PATH;
873 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
875 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
876 ok(size == 11, "Expected 11, got %d\n", size);
878 size = MAX_PATH;
879 res = RegQueryValueExA(url, "3", NULL, NULL, (LPBYTE)value, &size);
880 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
881 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
882 ok(size == 9, "Expected 9, got %d\n", size);
884 size = MAX_PATH;
885 res = RegQueryValueExA(url, "4", NULL, NULL, (LPBYTE)value, &size);
886 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
887 ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
888 ok(size == 6, "Expected 6, got %d\n", size);
890 size = MAX_PATH;
891 res = RegQueryValueExA(url, "5", NULL, NULL, (LPBYTE)value, &size);
892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
893 ok(!lstrcmpA(value, "source/"), "Expected 'source/', got %s\n", value);
894 ok(size == 8, "Expected 8, got %d\n", size);
896 /* NULL szUserSid */
897 r = pMsiSourceListAddSourceExA(prodcode, NULL,
898 MSIINSTALLCONTEXT_USERUNMANAGED,
899 MSISOURCETYPE_NETWORK, "nousersid", 0);
900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
902 size = MAX_PATH;
903 res = RegQueryValueExA(net, "1", NULL, NULL, (LPBYTE)value, &size);
904 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
905 ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
906 ok(size == 8, "Expected 8, got %d\n", size);
908 size = MAX_PATH;
909 res = RegQueryValueExA(net, "2", NULL, NULL, (LPBYTE)value, &size);
910 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
911 ok(!lstrcmpA(value, "nousersid\\"), "Expected 'nousersid\\', got %s\n", value);
912 ok(size == 11, "Expected 11, got %d\n", size);
914 /* invalid options, must have source type */
915 r = pMsiSourceListAddSourceExA(prodcode, usersid,
916 MSIINSTALLCONTEXT_USERUNMANAGED,
917 MSICODE_PRODUCT, "source", 0);
918 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
920 r = pMsiSourceListAddSourceExA(prodcode, usersid,
921 MSIINSTALLCONTEXT_USERUNMANAGED,
922 MSICODE_PATCH, "source", 0);
923 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
925 /* NULL szSource */
926 r = pMsiSourceListAddSourceExA(prodcode, usersid,
927 MSIINSTALLCONTEXT_USERUNMANAGED,
928 MSISOURCETYPE_URL, NULL, 1);
929 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
931 /* empty szSource */
932 r = pMsiSourceListAddSourceExA(prodcode, usersid,
933 MSIINSTALLCONTEXT_USERUNMANAGED,
934 MSISOURCETYPE_URL, "", 1);
935 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
937 /* MSIINSTALLCONTEXT_USERMANAGED, non-NULL szUserSid */
939 r = pMsiSourceListAddSourceExA(prodcode, usersid,
940 MSIINSTALLCONTEXT_USERMANAGED,
941 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
942 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
944 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
945 lstrcatA(keypath, usersid);
946 lstrcatA(keypath, "\\Installer\\Products\\");
947 lstrcatA(keypath, prod_squashed);
949 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
950 if (res != ERROR_SUCCESS)
952 skip("Product key creation failed with error code %u\n", res);
953 goto machine_tests;
956 /* product key exists */
957 r = pMsiSourceListAddSourceExA(prodcode, usersid,
958 MSIINSTALLCONTEXT_USERMANAGED,
959 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
960 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
962 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL);
963 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
964 RegCloseKey(hkey);
966 /* SourceList exists */
967 r = pMsiSourceListAddSourceExA(prodcode, usersid,
968 MSIINSTALLCONTEXT_USERMANAGED,
969 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
972 res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
973 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
975 size = MAX_PATH;
976 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
977 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
978 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
979 ok(size == 11, "Expected 11, got %d\n", size);
981 RegCloseKey(url);
983 /* MSIINSTALLCONTEXT_USERMANAGED, NULL szUserSid */
985 r = pMsiSourceListAddSourceExA(prodcode, NULL,
986 MSIINSTALLCONTEXT_USERMANAGED,
987 MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
990 res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
991 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
993 size = MAX_PATH;
994 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
995 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
996 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
997 ok(size == 11, "Expected 11, got %d\n", size);
999 size = MAX_PATH;
1000 res = RegQueryValueExA(url, "2", NULL, NULL, (LPBYTE)value, &size);
1001 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1002 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
1003 ok(size == 9, "Expected 9, got %d\n", size);
1005 RegCloseKey(url);
1006 RegCloseKey(prodkey);
1008 /* MSIINSTALLCONTEXT_MACHINE */
1010 machine_tests:
1011 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
1012 r = pMsiSourceListAddSourceExA(prodcode, usersid,
1013 MSIINSTALLCONTEXT_MACHINE,
1014 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1015 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1017 r = pMsiSourceListAddSourceExA(prodcode, NULL,
1018 MSIINSTALLCONTEXT_MACHINE,
1019 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1020 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1022 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1023 lstrcatA(keypath, prod_squashed);
1025 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1026 if (res != ERROR_SUCCESS)
1028 skip("Product key creation failed with error code %u\n", res);
1029 LocalFree(usersid);
1030 return;
1033 /* product key exists */
1034 r = pMsiSourceListAddSourceExA(prodcode, NULL,
1035 MSIINSTALLCONTEXT_MACHINE,
1036 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1037 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1039 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL);
1040 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1041 RegCloseKey(hkey);
1043 /* SourceList exists */
1044 r = pMsiSourceListAddSourceExA(prodcode, NULL,
1045 MSIINSTALLCONTEXT_MACHINE,
1046 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1047 if (r == ERROR_ACCESS_DENIED)
1048 skip("MsiSourceListAddSourceEx (insufficient privileges)\n");
1049 else
1051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1053 res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
1054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1056 size = MAX_PATH;
1057 res = RegQueryValueExA(url, "1", NULL, NULL, (LPBYTE)value, &size);
1058 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1059 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
1060 ok(size == 11, "Expected 11, got %d\n", size);
1062 RegCloseKey(url);
1063 RegCloseKey(prodkey);
1065 LocalFree(usersid);
1068 static void test_MsiSourceListEnumSources(void)
1070 CHAR prodcode[MAX_PATH];
1071 CHAR prod_squashed[MAX_PATH];
1072 CHAR keypath[MAX_PATH*2];
1073 CHAR value[MAX_PATH];
1074 LPSTR usersid;
1075 LONG res;
1076 UINT r;
1077 HKEY prodkey, userkey;
1078 HKEY url, net, source;
1079 DWORD size;
1080 REGSAM access = KEY_ALL_ACCESS;
1082 if (!pMsiSourceListEnumSourcesA)
1084 win_skip("MsiSourceListEnumSourcesA is not available\n");
1085 return;
1088 create_test_guid(prodcode, prod_squashed);
1089 if (!(usersid = get_user_sid()))
1091 skip("User SID not available -> skipping MsiSourceListEnumSourcesA tests\n");
1092 return;
1095 if (is_wow64)
1096 access |= KEY_WOW64_64KEY;
1098 /* GetLastError is not set by the function */
1100 /* NULL szProductCodeOrPatchCode */
1101 size = 0xdeadbeef;
1102 r = pMsiSourceListEnumSourcesA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1103 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1104 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1105 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
1107 /* empty szProductCodeOrPatchCode */
1108 size = 0xdeadbeef;
1109 r = pMsiSourceListEnumSourcesA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1110 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1111 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1112 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
1114 /* garbage szProductCodeOrPatchCode */
1115 size = 0xdeadbeef;
1116 r = pMsiSourceListEnumSourcesA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1117 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1118 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1119 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
1121 /* guid without brackets */
1122 size = 0xdeadbeef;
1123 r = pMsiSourceListEnumSourcesA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
1124 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1125 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1126 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1127 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
1129 /* guid with brackets */
1130 size = 0xdeadbeef;
1131 r = pMsiSourceListEnumSourcesA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
1132 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1133 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1134 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1135 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
1137 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1139 size = MAX_PATH;
1140 lstrcpyA(value, "aaa");
1141 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1142 MSIINSTALLCONTEXT_USERUNMANAGED,
1143 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1144 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1145 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1146 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1148 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1149 lstrcatA(keypath, prod_squashed);
1151 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1152 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1154 /* user product key exists */
1155 size = MAX_PATH;
1156 lstrcpyA(value, "aaa");
1157 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1158 MSIINSTALLCONTEXT_USERUNMANAGED,
1159 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1160 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1161 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1162 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1164 res = RegCreateKeyA(userkey, "SourceList", &source);
1165 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1167 /* SourceList key exists */
1168 size = MAX_PATH;
1169 lstrcpyA(value, "aaa");
1170 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1171 MSIINSTALLCONTEXT_USERUNMANAGED,
1172 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1173 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1174 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1175 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1177 res = RegCreateKeyA(source, "URL", &url);
1178 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1180 /* URL key exists */
1181 size = MAX_PATH;
1182 lstrcpyA(value, "aaa");
1183 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1184 MSIINSTALLCONTEXT_USERUNMANAGED,
1185 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1186 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1187 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1188 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1190 res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1191 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1193 res = RegSetValueExA(url, "2", 0, REG_SZ, (LPBYTE)"second", 7);
1194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1196 res = RegSetValueExA(url, "4", 0, REG_SZ, (LPBYTE)"fourth", 7);
1197 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1199 /* sources exist */
1200 size = MAX_PATH;
1201 lstrcpyA(value, "aaa");
1202 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1203 MSIINSTALLCONTEXT_USERUNMANAGED,
1204 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1205 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1206 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1207 ok(size == 5, "Expected 5, got %d\n", size);
1209 /* try index 0 again */
1210 size = MAX_PATH;
1211 lstrcpyA(value, "aaa");
1212 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1213 MSIINSTALLCONTEXT_USERUNMANAGED,
1214 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1216 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1217 ok(size == 5, "Expected 5, got %d\n", size);
1219 /* both szSource and pcchSource are NULL, index 0 */
1220 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1221 MSIINSTALLCONTEXT_USERUNMANAGED,
1222 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, NULL, NULL);
1223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1225 /* both szSource and pcchSource are NULL, index 1 */
1226 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1227 MSIINSTALLCONTEXT_USERUNMANAGED,
1228 MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, NULL, NULL);
1229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1231 /* size is exactly 5 */
1232 size = 5;
1233 lstrcpyA(value, "aaa");
1234 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1235 MSIINSTALLCONTEXT_USERUNMANAGED,
1236 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1237 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
1238 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
1239 ok(size == 5, "Expected 5, got %d\n", size);
1241 /* szSource is non-NULL while pcchSource is NULL */
1242 lstrcpyA(value, "aaa");
1243 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1244 MSIINSTALLCONTEXT_USERUNMANAGED,
1245 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, NULL);
1246 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1247 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
1249 /* try index 1 after failure */
1250 size = MAX_PATH;
1251 lstrcpyA(value, "aaa");
1252 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1253 MSIINSTALLCONTEXT_USERUNMANAGED,
1254 MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, value, &size);
1255 ok(r == ERROR_INVALID_PARAMETER,
1256 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1257 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
1258 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1260 /* reset the enumeration */
1261 size = MAX_PATH;
1262 lstrcpyA(value, "aaa");
1263 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1264 MSIINSTALLCONTEXT_USERUNMANAGED,
1265 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1267 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1268 ok(size == 5, "Expected 5, got %d\n", size);
1270 /* try index 1 */
1271 size = MAX_PATH;
1272 lstrcpyA(value, "aaa");
1273 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1274 MSIINSTALLCONTEXT_USERUNMANAGED,
1275 MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, value, &size);
1276 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1277 ok(!lstrcmpA(value, "second"), "Expected \"second\", got %s\n", value);
1278 ok(size == 6, "Expected 6, got %d\n", size);
1280 /* try index 1 again */
1281 size = MAX_PATH;
1282 lstrcpyA(value, "aaa");
1283 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1284 MSIINSTALLCONTEXT_USERUNMANAGED,
1285 MSICODE_PRODUCT | MSISOURCETYPE_URL, 1, value, &size);
1286 ok(r == ERROR_INVALID_PARAMETER,
1287 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1288 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1289 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1291 /* try index 2 */
1292 size = MAX_PATH;
1293 lstrcpyA(value, "aaa");
1294 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1295 MSIINSTALLCONTEXT_USERUNMANAGED,
1296 MSICODE_PRODUCT | MSISOURCETYPE_URL, 2, value, &size);
1297 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1298 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1299 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1301 /* try index < 0 */
1302 size = MAX_PATH;
1303 lstrcpyA(value, "aaa");
1304 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1305 MSIINSTALLCONTEXT_USERUNMANAGED,
1306 MSICODE_PRODUCT | MSISOURCETYPE_URL, -1, value, &size);
1307 ok(r == ERROR_INVALID_PARAMETER,
1308 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1309 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1310 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1312 /* NULL szUserSid */
1313 size = MAX_PATH;
1314 lstrcpyA(value, "aaa");
1315 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1316 MSIINSTALLCONTEXT_USERUNMANAGED,
1317 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1319 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1320 ok(size == 5, "Expected 5, got %d\n", size);
1322 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1323 size = MAX_PATH;
1324 lstrcpyA(value, "aaa");
1325 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1326 MSIINSTALLCONTEXT_USERUNMANAGED,
1327 MSICODE_PRODUCT, 0, value, &size);
1328 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1329 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1330 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1332 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1333 size = MAX_PATH;
1334 lstrcpyA(value, "aaa");
1335 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1336 MSIINSTALLCONTEXT_USERUNMANAGED,
1337 MSICODE_PATCH, 0, value, &size);
1338 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1339 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1340 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1342 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1343 size = MAX_PATH;
1344 lstrcpyA(value, "aaa");
1345 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1346 MSIINSTALLCONTEXT_USERUNMANAGED,
1347 MSICODE_PRODUCT | MSICODE_PATCH | MSISOURCETYPE_URL,
1348 0, value, &size);
1349 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
1350 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1351 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1353 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1354 size = MAX_PATH;
1355 lstrcpyA(value, "aaa");
1356 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1357 MSIINSTALLCONTEXT_USERUNMANAGED,
1358 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL,
1359 0, value, &size);
1360 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1361 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1362 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1364 RegDeleteValueA(url, "1");
1365 RegDeleteValueA(url, "2");
1366 RegDeleteValueA(url, "4");
1367 RegDeleteKeyA(url, "");
1368 RegCloseKey(url);
1370 /* SourceList key exists */
1371 size = MAX_PATH;
1372 lstrcpyA(value, "aaa");
1373 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1374 MSIINSTALLCONTEXT_USERUNMANAGED,
1375 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1376 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1377 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1378 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1380 res = RegCreateKeyA(source, "Net", &net);
1381 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1383 /* Net key exists */
1384 size = MAX_PATH;
1385 lstrcpyA(value, "aaa");
1386 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1387 MSIINSTALLCONTEXT_USERUNMANAGED,
1388 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1389 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1390 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1391 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1393 res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1394 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1396 /* sources exist */
1397 size = MAX_PATH;
1398 lstrcpyA(value, "aaa");
1399 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1400 MSIINSTALLCONTEXT_USERUNMANAGED,
1401 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1403 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1404 ok(size == 5, "Expected 5, got %d\n", size);
1406 RegDeleteValueA(net, "1");
1407 RegDeleteKeyA(net, "");
1408 RegCloseKey(net);
1409 RegDeleteKeyA(source, "");
1410 RegCloseKey(source);
1411 RegDeleteKeyA(userkey, "");
1412 RegCloseKey(userkey);
1414 /* MSIINSTALLCONTEXT_USERMANAGED */
1416 size = MAX_PATH;
1417 lstrcpyA(value, "aaa");
1418 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1419 MSIINSTALLCONTEXT_USERMANAGED,
1420 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1421 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1422 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1423 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1425 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1426 lstrcatA(keypath, usersid);
1427 lstrcatA(keypath, "\\Installer\\Products\\");
1428 lstrcatA(keypath, prod_squashed);
1430 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1431 if (res != ERROR_SUCCESS)
1433 skip("Product key creation failed with error code %u\n", res);
1434 goto machine_tests;
1437 /* user product key exists */
1438 size = MAX_PATH;
1439 lstrcpyA(value, "aaa");
1440 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1441 MSIINSTALLCONTEXT_USERMANAGED,
1442 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1443 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1444 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1445 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1447 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
1448 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1450 /* SourceList key exists */
1451 size = MAX_PATH;
1452 lstrcpyA(value, "aaa");
1453 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1454 MSIINSTALLCONTEXT_USERMANAGED,
1455 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1456 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1457 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1458 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1460 res = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL);
1461 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1463 /* URL key exists */
1464 size = MAX_PATH;
1465 lstrcpyA(value, "aaa");
1466 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1467 MSIINSTALLCONTEXT_USERMANAGED,
1468 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1469 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1470 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1471 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1473 res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1474 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1476 /* sources exist */
1477 size = MAX_PATH;
1478 lstrcpyA(value, "aaa");
1479 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1480 MSIINSTALLCONTEXT_USERMANAGED,
1481 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1483 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1484 ok(size == 5, "Expected 5, got %d\n", size);
1486 /* NULL szUserSid */
1487 size = MAX_PATH;
1488 lstrcpyA(value, "aaa");
1489 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1490 MSIINSTALLCONTEXT_USERMANAGED,
1491 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1492 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1493 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1494 ok(size == 5, "Expected 5, got %d\n", size);
1496 RegDeleteValueA(url, "1");
1497 delete_key(url, "", access);
1498 RegCloseKey(url);
1500 /* SourceList key exists */
1501 size = MAX_PATH;
1502 lstrcpyA(value, "aaa");
1503 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1504 MSIINSTALLCONTEXT_USERMANAGED,
1505 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1506 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1507 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1508 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1510 res = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL);
1511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1513 /* Net key exists */
1514 size = MAX_PATH;
1515 lstrcpyA(value, "aaa");
1516 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1517 MSIINSTALLCONTEXT_USERMANAGED,
1518 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1519 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1520 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1521 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1523 res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1524 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1526 /* sources exist */
1527 size = MAX_PATH;
1528 lstrcpyA(value, "aaa");
1529 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1530 MSIINSTALLCONTEXT_USERMANAGED,
1531 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1533 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1534 ok(size == 5, "Expected 5, got %d\n", size);
1536 RegDeleteValueA(net, "1");
1537 delete_key(net, "", access);
1538 RegCloseKey(net);
1539 delete_key(source, "", access);
1540 RegCloseKey(source);
1541 delete_key(userkey, "", access);
1542 RegCloseKey(userkey);
1544 /* MSIINSTALLCONTEXT_MACHINE */
1546 machine_tests:
1547 /* szUserSid is non-NULL */
1548 size = MAX_PATH;
1549 lstrcpyA(value, "aaa");
1550 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1551 MSIINSTALLCONTEXT_MACHINE,
1552 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1553 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1554 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1555 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1557 /* szUserSid is NULL */
1558 size = MAX_PATH;
1559 lstrcpyA(value, "aaa");
1560 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1561 MSIINSTALLCONTEXT_MACHINE,
1562 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1563 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1564 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1565 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1567 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1568 lstrcatA(keypath, prod_squashed);
1570 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1571 if (res != ERROR_SUCCESS)
1573 skip("Product key creation failed with error code %u\n", res);
1574 LocalFree(usersid);
1575 return;
1578 /* user product key exists */
1579 size = MAX_PATH;
1580 lstrcpyA(value, "aaa");
1581 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1582 MSIINSTALLCONTEXT_MACHINE,
1583 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1584 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1585 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1586 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1588 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
1589 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1591 /* SourceList key exists */
1592 size = MAX_PATH;
1593 lstrcpyA(value, "aaa");
1594 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1595 MSIINSTALLCONTEXT_MACHINE,
1596 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1597 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1598 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1599 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1601 res = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL);
1602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1604 /* URL key exists */
1605 size = MAX_PATH;
1606 lstrcpyA(value, "aaa");
1607 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1608 MSIINSTALLCONTEXT_MACHINE,
1609 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1610 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1611 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1612 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1614 res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1615 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1617 /* sources exist */
1618 size = MAX_PATH;
1619 lstrcpyA(value, "aaa");
1620 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1621 MSIINSTALLCONTEXT_MACHINE,
1622 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1624 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1625 ok(size == 5, "Expected 5, got %d\n", size);
1627 /* NULL szUserSid */
1628 size = MAX_PATH;
1629 lstrcpyA(value, "aaa");
1630 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1631 MSIINSTALLCONTEXT_MACHINE,
1632 MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
1633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1634 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1635 ok(size == 5, "Expected 5, got %d\n", size);
1637 RegDeleteValueA(url, "1");
1638 delete_key(url, "", access);
1639 RegCloseKey(url);
1641 /* SourceList key exists */
1642 size = MAX_PATH;
1643 lstrcpyA(value, "aaa");
1644 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1645 MSIINSTALLCONTEXT_MACHINE,
1646 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1647 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1648 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1649 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1651 res = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL);
1652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1654 /* Net key exists */
1655 size = MAX_PATH;
1656 lstrcpyA(value, "aaa");
1657 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1658 MSIINSTALLCONTEXT_MACHINE,
1659 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1660 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1661 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1662 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
1664 res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1667 /* sources exist */
1668 size = MAX_PATH;
1669 lstrcpyA(value, "aaa");
1670 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1671 MSIINSTALLCONTEXT_MACHINE,
1672 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
1673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1674 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1675 ok(size == 5, "Expected 5, got %d\n", size);
1677 RegDeleteValueA(net, "1");
1678 delete_key(net, "", access);
1679 RegCloseKey(net);
1680 delete_key(source, "", access);
1681 RegCloseKey(source);
1682 delete_key(prodkey, "", access);
1683 RegCloseKey(prodkey);
1684 LocalFree(usersid);
1687 static void test_MsiSourceListSetInfo(void)
1689 CHAR prodcode[MAX_PATH];
1690 CHAR prod_squashed[MAX_PATH];
1691 CHAR keypath[MAX_PATH*2];
1692 HKEY prodkey, userkey;
1693 HKEY net, url, media, source;
1694 LPSTR usersid;
1695 LONG res;
1696 UINT r;
1697 REGSAM access = KEY_ALL_ACCESS;
1699 if (!pMsiSourceListSetInfoA)
1701 win_skip("MsiSourceListSetInfoA is not available\n");
1702 return;
1704 if (is_process_limited())
1706 skip("process is limited\n");
1707 return;
1710 create_test_guid(prodcode, prod_squashed);
1711 if (!(usersid = get_user_sid()))
1713 skip("User SID not available -> skipping MsiSourceListSetInfoA tests\n");
1714 return;
1717 if (is_wow64)
1718 access |= KEY_WOW64_64KEY;
1720 /* GetLastError is not set by the function */
1722 /* NULL szProductCodeOrPatchCode */
1723 r = pMsiSourceListSetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1724 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1725 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1726 ok(r == ERROR_INVALID_PARAMETER,
1727 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1729 /* empty szProductCodeOrPatchCode */
1730 r = pMsiSourceListSetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1731 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1732 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1733 ok(r == ERROR_INVALID_PARAMETER,
1734 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1736 /* garbage szProductCodeOrPatchCode */
1737 r = pMsiSourceListSetInfoA("garbage", usersid,
1738 MSIINSTALLCONTEXT_USERUNMANAGED,
1739 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1740 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1741 ok(r == ERROR_INVALID_PARAMETER,
1742 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1744 /* guid without brackets */
1745 r = pMsiSourceListSetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
1746 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1747 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1748 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1749 ok(r == ERROR_INVALID_PARAMETER,
1750 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1752 /* guid with brackets */
1753 r = pMsiSourceListSetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
1754 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1755 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1756 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1757 ok(r == ERROR_UNKNOWN_PRODUCT,
1758 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1760 /* dwOptions is MSICODE_PRODUCT */
1761 r = pMsiSourceListSetInfoA(prodcode, usersid,
1762 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1763 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1764 ok(r == ERROR_UNKNOWN_PRODUCT,
1765 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1767 /* dwOptions is MSICODE_PATCH */
1768 r = pMsiSourceListSetInfoA(prodcode, usersid,
1769 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PATCH,
1770 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1771 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
1773 /* dwOptions is both MSICODE_PRODUCT and MSICODE_PATCH */
1774 r = pMsiSourceListSetInfoA(prodcode, usersid,
1775 MSIINSTALLCONTEXT_USERUNMANAGED,
1776 MSICODE_PRODUCT | MSICODE_PATCH | MSISOURCETYPE_URL,
1777 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1778 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
1780 /* dwOptions has both MSISOURCETYPE_NETWORK and MSISOURCETYPE_URL */
1781 r = pMsiSourceListSetInfoA(prodcode, NULL,
1782 MSIINSTALLCONTEXT_USERUNMANAGED,
1783 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL,
1784 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1785 ok(r == ERROR_UNKNOWN_PRODUCT,
1786 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1788 /* LastUsedSource and dwOptions has both
1789 * MSISOURCETYPE_NETWORK and MSISOURCETYPE_URL
1791 r = pMsiSourceListSetInfoA(prodcode, NULL,
1792 MSIINSTALLCONTEXT_USERUNMANAGED,
1793 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK | MSISOURCETYPE_URL,
1794 INSTALLPROPERTY_LASTUSEDSOURCEA, "path");
1795 ok(r == ERROR_UNKNOWN_PRODUCT,
1796 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1798 /* LastUsedSource and dwOptions has no source type */
1799 r = pMsiSourceListSetInfoA(prodcode, NULL,
1800 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1801 INSTALLPROPERTY_LASTUSEDSOURCEA, "path");
1802 ok(r == ERROR_UNKNOWN_PRODUCT,
1803 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1805 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1807 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1808 lstrcatA(keypath, prod_squashed);
1810 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1813 /* user product key exists */
1814 r = pMsiSourceListSetInfoA(prodcode, NULL,
1815 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1816 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1817 ok(r == ERROR_BAD_CONFIGURATION,
1818 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1820 res = RegCreateKeyA(userkey, "SourceList", &source);
1821 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1823 /* SourceList key exists, no source type */
1824 r = pMsiSourceListSetInfoA(prodcode, NULL,
1825 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1826 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1829 /* Media key is created by MsiSourceListSetInfo */
1830 res = RegOpenKeyA(source, "Media", &media);
1831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1832 CHECK_REG_STR(media, "MediaPackage", "path");
1834 /* set the info again */
1835 r = pMsiSourceListSetInfoA(prodcode, NULL,
1836 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1837 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path2");
1838 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1839 CHECK_REG_STR(media, "MediaPackage", "path2");
1841 /* NULL szProperty */
1842 r = pMsiSourceListSetInfoA(prodcode, NULL,
1843 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1844 NULL, "path");
1845 ok(r == ERROR_INVALID_PARAMETER,
1846 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1848 /* empty szProperty */
1849 r = pMsiSourceListSetInfoA(prodcode, NULL,
1850 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1851 "", "path");
1852 ok(r == ERROR_UNKNOWN_PROPERTY,
1853 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
1855 /* NULL szValue */
1856 r = pMsiSourceListSetInfoA(prodcode, NULL,
1857 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1858 INSTALLPROPERTY_MEDIAPACKAGEPATHA, NULL);
1859 ok(r == ERROR_UNKNOWN_PROPERTY,
1860 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
1862 /* empty szValue */
1863 r = pMsiSourceListSetInfoA(prodcode, NULL,
1864 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1865 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "");
1866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1867 CHECK_REG_STR(media, "MediaPackage", "");
1869 /* INSTALLPROPERTY_MEDIAPACKAGEPATH, MSISOURCETYPE_NETWORK */
1870 r = pMsiSourceListSetInfoA(prodcode, NULL,
1871 MSIINSTALLCONTEXT_USERUNMANAGED,
1872 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1873 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1874 ok(r == ERROR_INVALID_PARAMETER,
1875 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1877 /* INSTALLPROPERTY_MEDIAPACKAGEPATH, MSISOURCETYPE_URL */
1878 r = pMsiSourceListSetInfoA(prodcode, NULL,
1879 MSIINSTALLCONTEXT_USERUNMANAGED,
1880 MSICODE_PRODUCT | MSISOURCETYPE_URL,
1881 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
1882 ok(r == ERROR_INVALID_PARAMETER,
1883 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1885 /* INSTALLPROPERTY_DISKPROMPT */
1886 r = pMsiSourceListSetInfoA(prodcode, NULL,
1887 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1888 INSTALLPROPERTY_DISKPROMPTA, "prompt");
1889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1890 CHECK_REG_STR(media, "DiskPrompt", "prompt");
1892 /* INSTALLPROPERTY_DISKPROMPT, MSISOURCETYPE_NETWORK */
1893 r = pMsiSourceListSetInfoA(prodcode, NULL,
1894 MSIINSTALLCONTEXT_USERUNMANAGED,
1895 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1896 INSTALLPROPERTY_DISKPROMPTA, "prompt");
1897 ok(r == ERROR_INVALID_PARAMETER,
1898 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1900 /* INSTALLPROPERTY_DISKPROMPT, MSISOURCETYPE_URL */
1901 r = pMsiSourceListSetInfoA(prodcode, NULL,
1902 MSIINSTALLCONTEXT_USERUNMANAGED,
1903 MSICODE_PRODUCT | MSISOURCETYPE_URL,
1904 INSTALLPROPERTY_DISKPROMPTA, "prompt");
1905 ok(r == ERROR_INVALID_PARAMETER,
1906 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1908 /* INSTALLPROPERTY_LASTUSEDSOURCE */
1909 r = pMsiSourceListSetInfoA(prodcode, NULL,
1910 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1911 INSTALLPROPERTY_LASTUSEDSOURCEA, "source");
1912 ok(r == ERROR_INVALID_PARAMETER,
1913 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1915 /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_NETWORK */
1916 r = pMsiSourceListSetInfoA(prodcode, NULL,
1917 MSIINSTALLCONTEXT_USERUNMANAGED,
1918 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1919 INSTALLPROPERTY_LASTUSEDSOURCEA, "source");
1920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1922 /* Net key is created by MsiSourceListSetInfo */
1923 res = RegOpenKeyA(source, "Net", &net);
1924 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1925 CHECK_REG_STR(net, "1", "source\\")
1926 CHECK_REG_STR(source, "LastUsedSource", "n;1;source");
1928 /* source has forward slash */
1929 r = pMsiSourceListSetInfoA(prodcode, NULL,
1930 MSIINSTALLCONTEXT_USERUNMANAGED,
1931 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1932 INSTALLPROPERTY_LASTUSEDSOURCEA, "source/");
1933 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1934 CHECK_REG_STR(net, "1", "source\\");
1935 CHECK_REG_STR(net, "2", "source/\\");
1936 CHECK_REG_STR(source, "LastUsedSource", "n;2;source/");
1938 /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_URL */
1939 r = pMsiSourceListSetInfoA(prodcode, NULL,
1940 MSIINSTALLCONTEXT_USERUNMANAGED,
1941 MSICODE_PRODUCT | MSISOURCETYPE_URL,
1942 INSTALLPROPERTY_LASTUSEDSOURCEA, "source");
1943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1945 /* URL key is created by MsiSourceListSetInfo */
1946 res = RegOpenKeyA(source, "URL", &url);
1947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1948 CHECK_REG_STR(url, "1", "source/");
1949 CHECK_REG_STR(source, "LastUsedSource", "u;1;source");
1951 /* source has backslash */
1952 r = pMsiSourceListSetInfoA(prodcode, NULL,
1953 MSIINSTALLCONTEXT_USERUNMANAGED,
1954 MSICODE_PRODUCT | MSISOURCETYPE_URL,
1955 INSTALLPROPERTY_LASTUSEDSOURCEA, "source\\");
1956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1957 CHECK_REG_STR(url, "1", "source/");
1958 CHECK_REG_STR(url, "2", "source\\/");
1959 CHECK_REG_STR(source, "LastUsedSource", "u;2;source\\");
1961 /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_MEDIA */
1962 r = pMsiSourceListSetInfoA(prodcode, NULL,
1963 MSIINSTALLCONTEXT_USERUNMANAGED,
1964 MSICODE_PRODUCT | MSISOURCETYPE_MEDIA,
1965 INSTALLPROPERTY_LASTUSEDSOURCEA, "source");
1966 ok(r == ERROR_INVALID_PARAMETER,
1967 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1969 /* INSTALLPROPERTY_PACKAGENAME */
1970 r = pMsiSourceListSetInfoA(prodcode, NULL,
1971 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1972 INSTALLPROPERTY_PACKAGENAMEA, "name");
1973 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1974 CHECK_REG_STR(source, "PackageName", "name");
1976 /* INSTALLPROPERTY_PACKAGENAME, MSISOURCETYPE_NETWORK */
1977 r = pMsiSourceListSetInfoA(prodcode, NULL,
1978 MSIINSTALLCONTEXT_USERUNMANAGED,
1979 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
1980 INSTALLPROPERTY_PACKAGENAMEA, "name");
1981 ok(r == ERROR_INVALID_PARAMETER,
1982 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1984 /* INSTALLPROPERTY_PACKAGENAME, MSISOURCETYPE_URL */
1985 r = pMsiSourceListSetInfoA(prodcode, NULL,
1986 MSIINSTALLCONTEXT_USERUNMANAGED,
1987 MSICODE_PRODUCT | MSISOURCETYPE_URL,
1988 INSTALLPROPERTY_PACKAGENAMEA, "name");
1989 ok(r == ERROR_INVALID_PARAMETER,
1990 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1992 /* INSTALLPROPERTY_LASTUSEDTYPE */
1993 r = pMsiSourceListSetInfoA(prodcode, NULL,
1994 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
1995 INSTALLPROPERTY_LASTUSEDTYPEA, "type");
1996 ok(r == ERROR_UNKNOWN_PROPERTY,
1997 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
1999 /* definitely unknown property */
2000 r = pMsiSourceListSetInfoA(prodcode, NULL,
2001 MSIINSTALLCONTEXT_USERUNMANAGED, MSICODE_PRODUCT,
2002 "unknown", "val");
2003 ok(r == ERROR_UNKNOWN_PROPERTY,
2004 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2006 RegDeleteValueA(net, "1");
2007 RegDeleteKeyA(net, "");
2008 RegCloseKey(net);
2009 RegDeleteValueA(url, "1");
2010 RegDeleteKeyA(url, "");
2011 RegCloseKey(url);
2012 RegDeleteValueA(media, "MediaPackage");
2013 RegDeleteValueA(media, "DiskPrompt");
2014 RegDeleteKeyA(media, "");
2015 RegCloseKey(media);
2016 RegDeleteValueA(source, "PackageName");
2017 RegDeleteKeyA(source, "");
2018 RegCloseKey(source);
2019 RegDeleteKeyA(userkey, "");
2020 RegCloseKey(userkey);
2022 /* MSIINSTALLCONTEXT_USERMANAGED */
2024 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2025 lstrcatA(keypath, usersid);
2026 lstrcatA(keypath, "\\Installer\\Products\\");
2027 lstrcatA(keypath, prod_squashed);
2029 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2030 if (res != ERROR_SUCCESS)
2032 skip("Product key creation failed with error code %u\n", res);
2033 goto machine_tests;
2036 /* user product key exists */
2037 r = pMsiSourceListSetInfoA(prodcode, NULL,
2038 MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT,
2039 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
2040 ok(r == ERROR_BAD_CONFIGURATION,
2041 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2043 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2044 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2046 /* SourceList key exists, no source type */
2047 r = pMsiSourceListSetInfoA(prodcode, NULL,
2048 MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT,
2049 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
2050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2052 /* Media key is created by MsiSourceListSetInfo */
2053 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2055 CHECK_REG_STR(media, "MediaPackage", "path");
2057 RegDeleteValueA(media, "MediaPackage");
2058 delete_key(media, "", access);
2059 RegCloseKey(media);
2060 delete_key(source, "", access);
2061 RegCloseKey(source);
2062 delete_key(userkey, "", access);
2063 RegCloseKey(userkey);
2065 /* MSIINSTALLCONTEXT_MACHINE */
2067 machine_tests:
2068 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2069 lstrcatA(keypath, prod_squashed);
2071 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2072 if (res != ERROR_SUCCESS)
2074 skip("Product key creation failed with error code %u\n", res);
2075 LocalFree(usersid);
2076 return;
2079 /* user product key exists */
2080 r = pMsiSourceListSetInfoA(prodcode, NULL,
2081 MSIINSTALLCONTEXT_MACHINE, MSICODE_PRODUCT,
2082 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
2083 ok(r == ERROR_BAD_CONFIGURATION,
2084 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2086 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2087 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2089 /* SourceList key exists, no source type */
2090 r = pMsiSourceListSetInfoA(prodcode, NULL,
2091 MSIINSTALLCONTEXT_MACHINE, MSICODE_PRODUCT,
2092 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
2093 if (r == ERROR_ACCESS_DENIED)
2095 skip("MsiSourceListSetInfo (insufficient privileges)\n");
2096 goto done;
2098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2100 /* Media key is created by MsiSourceListSetInfo */
2101 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2103 CHECK_REG_STR(media, "MediaPackage", "path");
2105 /* szUserSid is non-NULL */
2106 r = pMsiSourceListSetInfoA(prodcode, usersid,
2107 MSIINSTALLCONTEXT_MACHINE, MSICODE_PRODUCT,
2108 INSTALLPROPERTY_MEDIAPACKAGEPATHA, "path");
2109 ok(r == ERROR_INVALID_PARAMETER,
2110 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2111 RegDeleteValueA(media, "MediaPackage");
2112 delete_key(media, "", access);
2113 RegCloseKey(media);
2115 done:
2116 delete_key(source, "", access);
2117 RegCloseKey(source);
2118 delete_key(prodkey, "", access);
2119 RegCloseKey(prodkey);
2120 LocalFree(usersid);
2123 static void test_MsiSourceListAddMediaDisk(void)
2125 CHAR prodcode[MAX_PATH];
2126 CHAR prod_squashed[MAX_PATH];
2127 CHAR keypath[MAX_PATH*2];
2128 HKEY prodkey, userkey;
2129 HKEY media, source;
2130 LPSTR usersid;
2131 LONG res;
2132 UINT r;
2133 REGSAM access = KEY_ALL_ACCESS;
2135 if (!pMsiSourceListAddMediaDiskA)
2137 win_skip("MsiSourceListAddMediaDiskA is not available\n");
2138 return;
2140 if (is_process_limited())
2142 skip("process is limited\n");
2143 return;
2146 create_test_guid(prodcode, prod_squashed);
2147 if (!(usersid = get_user_sid()))
2149 skip("User SID not available -> skipping MsiSourceListAddMediaDiskA tests\n");
2150 return;
2153 if (is_wow64)
2154 access |= KEY_WOW64_64KEY;
2156 /* GetLastError is not set by the function */
2158 /* NULL szProductCodeOrPatchCode */
2159 r = pMsiSourceListAddMediaDiskA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2160 MSICODE_PRODUCT, 1, "label", "prompt");
2161 ok(r == ERROR_INVALID_PARAMETER,
2162 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2164 /* empty szProductCodeOrPatchCode */
2165 r = pMsiSourceListAddMediaDiskA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2166 MSICODE_PRODUCT, 1, "label", "prompt");
2167 ok(r == ERROR_INVALID_PARAMETER,
2168 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2170 /* garbage szProductCodeOrPatchCode */
2171 r = pMsiSourceListAddMediaDiskA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2172 MSICODE_PRODUCT, 1, "label", "prompt");
2173 ok(r == ERROR_INVALID_PARAMETER,
2174 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2176 /* guid without brackets */
2177 r = pMsiSourceListAddMediaDiskA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
2178 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2179 MSICODE_PRODUCT, 1, "label", "prompt");
2180 ok(r == ERROR_INVALID_PARAMETER,
2181 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2183 /* guid with brackets */
2184 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2185 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2186 MSICODE_PRODUCT, 1, "label", "prompt");
2187 ok(r == ERROR_UNKNOWN_PRODUCT,
2188 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2190 /* dwOptions has MSISOURCETYPE_NETWORK */
2191 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2192 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2193 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
2194 1, "label", "prompt");
2195 ok(r == ERROR_INVALID_PARAMETER,
2196 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2198 /* dwOptions has MSISOURCETYPE_URL */
2199 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2200 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2201 MSICODE_PRODUCT | MSISOURCETYPE_URL,
2202 1, "label", "prompt");
2203 ok(r == ERROR_INVALID_PARAMETER,
2204 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2206 /* dwOptions has MSISOURCETYPE_MEDIA */
2207 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2208 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2209 MSICODE_PRODUCT | MSISOURCETYPE_MEDIA,
2210 1, "label", "prompt");
2211 ok(r == ERROR_INVALID_PARAMETER,
2212 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2214 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2216 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2217 lstrcatA(keypath, prod_squashed);
2219 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2222 /* user product key exists */
2223 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2224 MSIINSTALLCONTEXT_USERUNMANAGED,
2225 MSICODE_PRODUCT, 1, "label", "prompt");
2226 ok(r == ERROR_BAD_CONFIGURATION,
2227 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2229 res = RegCreateKeyA(userkey, "SourceList", &source);
2230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2232 /* SourceList key exists */
2233 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2234 MSIINSTALLCONTEXT_USERUNMANAGED,
2235 MSICODE_PRODUCT, 1, "label", "prompt");
2236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2238 /* Media subkey is created by MsiSourceListAddMediaDisk */
2239 res = RegOpenKeyA(source, "Media", &media);
2240 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2242 CHECK_REG_STR(media, "1", "label;prompt");
2244 /* dwDiskId is random */
2245 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2246 MSIINSTALLCONTEXT_USERUNMANAGED,
2247 MSICODE_PRODUCT, 42, "label42", "prompt42");
2248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2250 CHECK_REG_STR(media, "1", "label;prompt");
2251 CHECK_REG_STR(media, "42", "label42;prompt42");
2253 /* dwDiskId is 0 */
2254 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2255 MSIINSTALLCONTEXT_USERUNMANAGED,
2256 MSICODE_PRODUCT, 0, "label0", "prompt0");
2257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2259 CHECK_REG_STR(media, "0", "label0;prompt0");
2260 CHECK_REG_STR(media, "1", "label;prompt");
2261 CHECK_REG_STR(media, "42", "label42;prompt42");
2263 /* dwDiskId is < 0 */
2264 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2265 MSIINSTALLCONTEXT_USERUNMANAGED,
2266 MSICODE_PRODUCT, -1, "label-1", "prompt-1");
2267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2269 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2270 CHECK_REG_STR(media, "0", "label0;prompt0");
2271 CHECK_REG_STR(media, "1", "label;prompt");
2272 CHECK_REG_STR(media, "42", "label42;prompt42");
2274 /* update dwDiskId 1 */
2275 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2276 MSIINSTALLCONTEXT_USERUNMANAGED,
2277 MSICODE_PRODUCT, 1, "newlabel", "newprompt");
2278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2280 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2281 CHECK_REG_STR(media, "0", "label0;prompt0");
2282 CHECK_REG_STR(media, "1", "newlabel;newprompt");
2283 CHECK_REG_STR(media, "42", "label42;prompt42");
2285 /* update dwDiskId 1, szPrompt is NULL */
2286 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2287 MSIINSTALLCONTEXT_USERUNMANAGED,
2288 MSICODE_PRODUCT, 1, "etiqueta", NULL);
2289 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2291 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2292 CHECK_REG_STR(media, "0", "label0;prompt0");
2293 CHECK_REG_STR(media, "1", "etiqueta;");
2294 CHECK_REG_STR(media, "42", "label42;prompt42");
2296 /* update dwDiskId 1, szPrompt is empty */
2297 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2298 MSIINSTALLCONTEXT_USERUNMANAGED,
2299 MSICODE_PRODUCT, 1, "etikett", "");
2300 ok(r == ERROR_INVALID_PARAMETER,
2301 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2303 /* update dwDiskId 1, szVolumeLabel is NULL */
2304 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2305 MSIINSTALLCONTEXT_USERUNMANAGED,
2306 MSICODE_PRODUCT, 1, NULL, "provocar");
2307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2309 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2310 CHECK_REG_STR(media, "0", "label0;prompt0");
2311 CHECK_REG_STR(media, "1", ";provocar");
2312 CHECK_REG_STR(media, "42", "label42;prompt42");
2314 /* update dwDiskId 1, szVolumeLabel is empty */
2315 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2316 MSIINSTALLCONTEXT_USERUNMANAGED,
2317 MSICODE_PRODUCT, 1, "", "provoquer");
2318 ok(r == ERROR_INVALID_PARAMETER,
2319 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2321 /* szUserSid is NULL */
2322 r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
2323 MSIINSTALLCONTEXT_USERUNMANAGED,
2324 MSICODE_PRODUCT, 1, NULL, "provoquer");
2325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2327 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2328 CHECK_REG_STR(media, "0", "label0;prompt0");
2329 CHECK_REG_STR(media, "1", ";provoquer");
2330 CHECK_REG_STR(media, "42", "label42;prompt42");
2332 RegDeleteValueA(media, "-1");
2333 RegDeleteValueA(media, "0");
2334 RegDeleteValueA(media, "1");
2335 RegDeleteValueA(media, "42");
2336 RegDeleteKeyA(media, "");
2337 RegCloseKey(media);
2338 RegDeleteKeyA(source, "");
2339 RegCloseKey(source);
2340 RegDeleteKeyA(userkey, "");
2341 RegCloseKey(userkey);
2343 /* MSIINSTALLCONTEXT_USERMANAGED */
2345 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2346 lstrcatA(keypath, usersid);
2347 lstrcatA(keypath, "\\Installer\\Products\\");
2348 lstrcatA(keypath, prod_squashed);
2350 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2351 if (res != ERROR_SUCCESS)
2353 skip("Product key creation failed with error code %u\n", res);
2354 goto machine_tests;
2357 /* user product key exists */
2358 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2359 MSIINSTALLCONTEXT_USERMANAGED,
2360 MSICODE_PRODUCT, 1, "label", "prompt");
2361 ok(r == ERROR_BAD_CONFIGURATION,
2362 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2364 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2365 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2367 /* SourceList key exists */
2368 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2369 MSIINSTALLCONTEXT_USERMANAGED,
2370 MSICODE_PRODUCT, 1, "label", "prompt");
2371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2373 /* Media subkey is created by MsiSourceListAddMediaDisk */
2374 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2375 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2377 CHECK_REG_STR(media, "1", "label;prompt");
2379 RegDeleteValueA(media, "1");
2380 delete_key(media, "", access);
2381 RegCloseKey(media);
2382 delete_key(source, "", access);
2383 RegCloseKey(source);
2384 delete_key(userkey, "", access);
2385 RegCloseKey(userkey);
2387 /* MSIINSTALLCONTEXT_MACHINE */
2389 machine_tests:
2390 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2391 lstrcatA(keypath, prod_squashed);
2393 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2394 if (res != ERROR_SUCCESS)
2396 skip("Product key creation failed with error code %u\n", res);
2397 LocalFree(usersid);
2398 return;
2401 /* machine product key exists */
2402 r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
2403 MSIINSTALLCONTEXT_MACHINE,
2404 MSICODE_PRODUCT, 1, "label", "prompt");
2405 ok(r == ERROR_BAD_CONFIGURATION,
2406 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2408 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2411 /* SourceList key exists */
2412 r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
2413 MSIINSTALLCONTEXT_MACHINE,
2414 MSICODE_PRODUCT, 1, "label", "prompt");
2415 if (r == ERROR_ACCESS_DENIED)
2417 skip("MsiSourceListAddMediaDisk (insufficient privileges)\n");
2418 goto done;
2420 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2422 /* Media subkey is created by MsiSourceListAddMediaDisk */
2423 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2424 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2426 CHECK_REG_STR(media, "1", "label;prompt");
2428 /* szUserSid is non-NULL */
2429 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2430 MSIINSTALLCONTEXT_MACHINE,
2431 MSICODE_PRODUCT, 1, "label", "prompt");
2432 ok(r == ERROR_INVALID_PARAMETER,
2433 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2434 RegDeleteValueA(media, "1");
2435 delete_key(media, "", access);
2436 RegCloseKey(media);
2438 done:
2439 delete_key(source, "", access);
2440 RegCloseKey(source);
2441 delete_key(prodkey, "", access);
2442 RegCloseKey(prodkey);
2443 LocalFree(usersid);
2446 static void test_MsiSourceListEnumMediaDisks(void)
2448 CHAR prodcode[MAX_PATH];
2449 CHAR prod_squashed[MAX_PATH];
2450 CHAR keypath[MAX_PATH*2];
2451 CHAR label[MAX_PATH];
2452 CHAR prompt[MAX_PATH];
2453 HKEY prodkey, userkey, media, source;
2454 DWORD labelsz, promptsz, val, id;
2455 LPSTR usersid;
2456 LONG res;
2457 UINT r;
2458 REGSAM access = KEY_ALL_ACCESS;
2460 if (!pMsiSourceListEnumMediaDisksA)
2462 win_skip("MsiSourceListEnumMediaDisksA is not available\n");
2463 return;
2466 create_test_guid(prodcode, prod_squashed);
2467 if (!(usersid = get_user_sid()))
2469 skip("User SID not available -> skipping MsiSourceListEnumMediaDisksA tests\n");
2470 return;
2473 if (is_wow64)
2474 access |= KEY_WOW64_64KEY;
2476 /* GetLastError is not set by the function */
2478 /* NULL szProductCodeOrPatchCode */
2479 labelsz = sizeof(label);
2480 promptsz = sizeof(prompt);
2481 r = pMsiSourceListEnumMediaDisksA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2482 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2483 prompt, &promptsz);
2484 ok(r == ERROR_INVALID_PARAMETER,
2485 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2487 /* empty szProductCodeOrPatchCode */
2488 labelsz = sizeof(label);
2489 promptsz = sizeof(prompt);
2490 r = pMsiSourceListEnumMediaDisksA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2491 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2492 prompt, &promptsz);
2493 ok(r == ERROR_INVALID_PARAMETER,
2494 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2496 /* garbage szProductCodeOrPatchCode */
2497 labelsz = sizeof(label);
2498 promptsz = sizeof(prompt);
2499 r = pMsiSourceListEnumMediaDisksA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2500 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2501 prompt, &promptsz);
2502 ok(r == ERROR_INVALID_PARAMETER,
2503 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2505 /* guid without brackets */
2506 labelsz = sizeof(label);
2507 promptsz = sizeof(prompt);
2508 r = pMsiSourceListEnumMediaDisksA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
2509 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2510 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2511 prompt, &promptsz);
2512 ok(r == ERROR_INVALID_PARAMETER,
2513 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2515 /* guid with brackets */
2516 labelsz = sizeof(label);
2517 promptsz = sizeof(prompt);
2518 r = pMsiSourceListEnumMediaDisksA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2519 usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2520 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2521 prompt, &promptsz);
2522 ok(r == ERROR_UNKNOWN_PRODUCT,
2523 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2525 /* dwOptions has MSISOURCETYPE_NETWORK */
2526 labelsz = sizeof(label);
2527 promptsz = sizeof(prompt);
2528 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2529 MSICODE_PRODUCT | MSISOURCETYPE_NETWORK,
2530 0, &id, label, &labelsz,
2531 prompt, &promptsz);
2532 ok(r == ERROR_INVALID_PARAMETER,
2533 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2535 /* dwOptions has MSISOURCETYPE_URL */
2536 labelsz = sizeof(label);
2537 promptsz = sizeof(prompt);
2538 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2539 MSICODE_PRODUCT | MSISOURCETYPE_URL,
2540 0, &id, label, &labelsz,
2541 prompt, &promptsz);
2542 ok(r == ERROR_INVALID_PARAMETER,
2543 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2545 /* dwIndex is non-zero */
2546 labelsz = sizeof(label);
2547 promptsz = sizeof(prompt);
2548 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2549 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2550 prompt, &promptsz);
2551 ok(r == ERROR_INVALID_PARAMETER,
2552 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2554 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2556 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2557 lstrcatA(keypath, prod_squashed);
2559 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2560 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2562 /* user product key exists */
2563 labelsz = sizeof(label);
2564 promptsz = sizeof(prompt);
2565 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2566 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2567 prompt, &promptsz);
2568 ok(r == ERROR_BAD_CONFIGURATION,
2569 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2571 res = RegCreateKeyA(userkey, "SourceList", &source);
2572 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2574 /* SourceList key exists */
2575 id = 0xbeef;
2576 lstrcpyA(label, "aaa");
2577 labelsz = 0xdeadbeef;
2578 lstrcpyA(prompt, "bbb");
2579 promptsz = 0xdeadbeef;
2580 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2581 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2582 prompt, &promptsz);
2583 ok(r == ERROR_NO_MORE_ITEMS,
2584 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2585 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
2586 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2587 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
2588 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2589 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
2591 res = RegCreateKeyA(source, "Media", &media);
2592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2594 /* Media key exists */
2595 id = 0xbeef;
2596 lstrcpyA(label, "aaa");
2597 labelsz = 0xdeadbeef;
2598 lstrcpyA(prompt, "bbb");
2599 promptsz = 0xdeadbeef;
2600 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2601 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2602 prompt, &promptsz);
2603 ok(r == ERROR_NO_MORE_ITEMS,
2604 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2605 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
2606 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2607 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
2608 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2609 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
2611 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label;prompt", 13);
2612 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2614 /* disk exists */
2615 id = 0;
2616 lstrcpyA(label, "aaa");
2617 labelsz = MAX_PATH;
2618 lstrcpyA(prompt, "bbb");
2619 promptsz = MAX_PATH;
2620 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2621 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2622 prompt, &promptsz);
2623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2624 ok(id == 1, "Expected 1, got %d\n", id);
2625 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2626 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2627 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2628 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2630 res = RegSetValueExA(media, "2", 0, REG_SZ, (LPBYTE)"one;two", 8);
2631 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2633 /* now disk 2 exists, get the sizes */
2634 id = 0;
2635 labelsz = MAX_PATH;
2636 promptsz = MAX_PATH;
2637 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2638 MSICODE_PRODUCT, 1, &id, NULL, &labelsz,
2639 NULL, &promptsz);
2640 ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER,
2641 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2642 if (r == ERROR_SUCCESS)
2644 ok(id == 2, "Expected 2, got %d\n", id);
2645 ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
2646 ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
2649 /* now fill in the values */
2650 id = 0xbeef;
2651 lstrcpyA(label, "aaa");
2652 labelsz = MAX_PATH;
2653 lstrcpyA(prompt, "bbb");
2654 promptsz = MAX_PATH;
2655 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2656 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2657 prompt, &promptsz);
2658 ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER,
2659 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2660 if (r == ERROR_SUCCESS)
2662 ok(id == 2, "Expected 2, got %d\n", id);
2663 ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
2664 ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
2665 ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
2666 ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
2668 else if (r == ERROR_INVALID_PARAMETER)
2670 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
2671 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2672 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
2673 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2674 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
2677 res = RegSetValueExA(media, "4", 0, REG_SZ, (LPBYTE)"three;four", 11);
2678 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2680 /* disks 1, 2, 4 exist, reset the enumeration */
2681 id = 0;
2682 lstrcpyA(label, "aaa");
2683 labelsz = MAX_PATH;
2684 lstrcpyA(prompt, "bbb");
2685 promptsz = MAX_PATH;
2686 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2687 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2688 prompt, &promptsz);
2689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2690 ok(id == 1, "Expected 1, got %d\n", id);
2691 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2692 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2693 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2694 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2696 /* disks 1, 2, 4 exist, index 1 */
2697 id = 0;
2698 lstrcpyA(label, "aaa");
2699 labelsz = MAX_PATH;
2700 lstrcpyA(prompt, "bbb");
2701 promptsz = MAX_PATH;
2702 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2703 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2704 prompt, &promptsz);
2705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2706 ok(id == 2, "Expected 2, got %d\n", id);
2707 ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
2708 ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
2709 ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
2710 ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
2712 /* disks 1, 2, 4 exist, index 2 */
2713 id = 0;
2714 lstrcpyA(label, "aaa");
2715 labelsz = MAX_PATH;
2716 lstrcpyA(prompt, "bbb");
2717 promptsz = MAX_PATH;
2718 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2719 MSICODE_PRODUCT, 2, &id, label, &labelsz,
2720 prompt, &promptsz);
2721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2722 ok(id == 4, "Expected 4, got %d\n", id);
2723 ok(!lstrcmpA(label, "three"), "Expected \"three\", got \"%s\"\n", label);
2724 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2725 ok(!lstrcmpA(prompt, "four"), "Expected \"four\", got \"%s\"\n", prompt);
2726 ok(promptsz == 4, "Expected 4, got %d\n", promptsz);
2728 /* disks 1, 2, 4 exist, index 3, invalid */
2729 id = 0xbeef;
2730 lstrcpyA(label, "aaa");
2731 labelsz = MAX_PATH;
2732 lstrcpyA(prompt, "bbb");
2733 promptsz = MAX_PATH;
2734 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2735 MSICODE_PRODUCT, 3, &id, label, &labelsz,
2736 prompt, &promptsz);
2737 ok(r == ERROR_NO_MORE_ITEMS,
2738 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2739 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
2740 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2741 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
2742 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2743 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
2745 /* disks 1, 2, 4 exist, reset the enumeration */
2746 id = 0;
2747 lstrcpyA(label, "aaa");
2748 labelsz = MAX_PATH;
2749 lstrcpyA(prompt, "bbb");
2750 promptsz = MAX_PATH;
2751 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2752 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2753 prompt, &promptsz);
2754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2755 ok(id == 1, "Expected 1, got %d\n", id);
2756 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2757 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2758 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2759 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2761 /* try index 0 again */
2762 id = 0;
2763 lstrcpyA(label, "aaa");
2764 labelsz = MAX_PATH;
2765 lstrcpyA(prompt, "bbb");
2766 promptsz = MAX_PATH;
2767 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2768 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2769 prompt, &promptsz);
2770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2771 ok(id == 1, "Expected 1, got %d\n", id);
2772 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2773 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2774 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2775 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2777 /* jump to index 2 */
2778 id = 0xbeef;
2779 lstrcpyA(label, "aaa");
2780 labelsz = MAX_PATH;
2781 lstrcpyA(prompt, "bbb");
2782 promptsz = MAX_PATH;
2783 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2784 MSICODE_PRODUCT, 2, &id, label, &labelsz,
2785 prompt, &promptsz);
2786 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2787 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
2788 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2789 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
2790 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2791 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
2793 /* after error, try index 1 */
2794 id = 0xbeef;
2795 lstrcpyA(label, "aaa");
2796 labelsz = MAX_PATH;
2797 lstrcpyA(prompt, "bbb");
2798 promptsz = MAX_PATH;
2799 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2800 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2801 prompt, &promptsz);
2802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2803 ok(id == 2, "Expected 2, got %d\n", id);
2804 ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
2805 ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
2806 ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
2807 ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
2809 /* try index 1 again */
2810 id = 0xbeef;
2811 lstrcpyA(label, "aaa");
2812 labelsz = MAX_PATH;
2813 lstrcpyA(prompt, "bbb");
2814 promptsz = MAX_PATH;
2815 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2816 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2817 prompt, &promptsz);
2818 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2819 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
2820 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2821 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
2822 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2823 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
2825 /* NULL pdwDiskId */
2826 lstrcpyA(label, "aaa");
2827 labelsz = MAX_PATH;
2828 lstrcpyA(prompt, "bbb");
2829 promptsz = MAX_PATH;
2830 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2831 MSICODE_PRODUCT, 0, NULL, label, &labelsz,
2832 prompt, &promptsz);
2833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2834 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2835 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2836 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2837 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2839 /* szVolumeLabel is NULL */
2840 id = 0;
2841 labelsz = MAX_PATH;
2842 lstrcpyA(prompt, "bbb");
2843 promptsz = MAX_PATH;
2844 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2845 MSICODE_PRODUCT, 0, &id, NULL, &labelsz,
2846 prompt, &promptsz);
2847 ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER,
2848 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2849 if (r == ERROR_SUCCESS)
2851 ok(id == 1, "Expected 1, got %d\n", id);
2852 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2853 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2854 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2857 /* szVolumeLabel and pcchVolumeLabel are NULL */
2858 id = 0;
2859 lstrcpyA(prompt, "bbb");
2860 promptsz = MAX_PATH;
2861 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2862 MSICODE_PRODUCT, 0, &id, NULL, NULL,
2863 prompt, &promptsz);
2864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2865 ok(id == 1, "Expected 1, got %d\n", id);
2866 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2867 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2869 /* szVolumeLabel is non-NULL while pcchVolumeLabel is NULL */
2870 id = 0xbeef;
2871 lstrcpyA(label, "aaa");
2872 lstrcpyA(prompt, "bbb");
2873 promptsz = MAX_PATH;
2874 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2875 MSICODE_PRODUCT, 0, &id, label, NULL,
2876 prompt, &promptsz);
2877 ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER,
2878 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2879 if (r == ERROR_SUCCESS)
2881 ok(id == 1, "Expected 1, got %d\n", id);
2882 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2883 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2884 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2887 /* szDiskPrompt is NULL */
2888 id = 0;
2889 lstrcpyA(label, "aaa");
2890 labelsz = MAX_PATH;
2891 promptsz = MAX_PATH;
2892 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2893 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2894 NULL, &promptsz);
2895 ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER, "Expected ERROR_SUCCESS, got %d\n", r);
2896 if (r == ERROR_SUCCESS)
2898 ok(id == 1, "Expected 1, got %d\n", id);
2899 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2900 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2901 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2904 /* szDiskPrompt and pcchDiskPrompt are NULL */
2905 id = 0;
2906 lstrcpyA(label, "aaa");
2907 labelsz = MAX_PATH;
2908 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2909 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2910 NULL, NULL);
2911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2912 ok(id == 1, "Expected 1, got %d\n", id);
2913 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2914 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2916 /* szDiskPrompt is non-NULL while pcchDiskPrompt is NULL */
2917 id = 0xbeef;
2918 lstrcpyA(label, "aaa");
2919 labelsz = MAX_PATH;
2920 lstrcpyA(prompt, "bbb");
2921 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2922 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2923 prompt, NULL);
2924 ok(r == ERROR_INVALID_PARAMETER,
2925 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2926 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
2927 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2928 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
2929 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2931 /* pcchVolumeLabel, szDiskPrompt and pcchDiskPrompt are NULL */
2932 id = 0;
2933 lstrcpyA(label, "aaa");
2934 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2935 MSICODE_PRODUCT, 0, &id, label, NULL,
2936 NULL, NULL);
2937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2938 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2939 ok(id == 1, "Expected 1, got %d\n", id);
2941 /* szVolumeLabel, pcchVolumeLabel, szDiskPrompt and pcchDiskPrompt are NULL */
2942 id = 0;
2943 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2944 MSICODE_PRODUCT, 0, &id, NULL, NULL,
2945 NULL, NULL);
2946 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2947 ok(id == 1, "Expected 1, got %d\n", id);
2949 /* pcchVolumeLabel is exactly 5 */
2950 lstrcpyA(label, "aaa");
2951 labelsz = 5;
2952 lstrcpyA(prompt, "bbb");
2953 promptsz = MAX_PATH;
2954 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2955 MSICODE_PRODUCT, 0, NULL, label, &labelsz,
2956 prompt, &promptsz);
2957 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2958 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2959 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2960 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2961 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2963 /* pcchDiskPrompt is exactly 6 */
2964 lstrcpyA(label, "aaa");
2965 labelsz = MAX_PATH;
2966 lstrcpyA(prompt, "bbb");
2967 promptsz = 6;
2968 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2969 MSICODE_PRODUCT, 0, NULL, label, &labelsz,
2970 prompt, &promptsz);
2971 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2972 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2973 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2974 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2975 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
2977 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label", 13);
2978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2980 /* no semicolon */
2981 id = 0;
2982 lstrcpyA(label, "aaa");
2983 labelsz = MAX_PATH;
2984 lstrcpyA(prompt, "bbb");
2985 promptsz = MAX_PATH;
2986 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2987 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2988 prompt, &promptsz);
2989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2990 ok(id == 1, "Expected 1, got %d\n", id);
2991 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2992 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
2993 ok(!lstrcmpA(prompt, "label"), "Expected \"label\", got \"%s\"\n", prompt);
2994 ok(promptsz == 5, "Expected 5, got %d\n", promptsz);
2996 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label;", 13);
2997 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2999 /* semicolon, no disk prompt */
3000 id = 0;
3001 lstrcpyA(label, "aaa");
3002 labelsz = MAX_PATH;
3003 lstrcpyA(prompt, "bbb");
3004 promptsz = MAX_PATH;
3005 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3006 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3007 prompt, &promptsz);
3008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3009 ok(id == 1, "Expected 1, got %d\n", id);
3010 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
3011 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
3012 ok(!lstrcmpA(prompt, ""), "Expected \"\", got \"%s\"\n", prompt);
3013 ok(promptsz == 0, "Expected 0, got %d\n", promptsz);
3015 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)";prompt", 13);
3016 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3018 /* semicolon, label doesn't exist */
3019 id = 0;
3020 lstrcpyA(label, "aaa");
3021 labelsz = MAX_PATH;
3022 lstrcpyA(prompt, "bbb");
3023 promptsz = MAX_PATH;
3024 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3025 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3026 prompt, &promptsz);
3027 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3028 ok(id == 1, "Expected 1, got %d\n", id);
3029 ok(!lstrcmpA(label, ""), "Expected \"\", got \"%s\"\n", label);
3030 ok(labelsz == 0, "Expected 0, got %d\n", labelsz);
3031 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
3032 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
3034 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)";", 13);
3035 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3037 /* semicolon, neither label nor disk prompt exist */
3038 id = 0;
3039 lstrcpyA(label, "aaa");
3040 labelsz = MAX_PATH;
3041 lstrcpyA(prompt, "bbb");
3042 promptsz = MAX_PATH;
3043 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3044 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3045 prompt, &promptsz);
3046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3047 ok(id == 1, "Expected 1, got %d\n", id);
3048 ok(!lstrcmpA(label, ""), "Expected \"\", got \"%s\"\n", label);
3049 ok(labelsz == 0, "Expected 0, got %d\n", labelsz);
3050 ok(!lstrcmpA(prompt, ""), "Expected \"\", got \"%s\"\n", prompt);
3051 ok(promptsz == 0, "Expected 0, got %d\n", promptsz);
3053 val = 42;
3054 res = RegSetValueExA(media, "1", 0, REG_DWORD, (LPBYTE)&val, sizeof(DWORD));
3055 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3057 /* type is REG_DWORD */
3058 id = 0;
3059 lstrcpyA(label, "aaa");
3060 labelsz = MAX_PATH;
3061 lstrcpyA(prompt, "bbb");
3062 promptsz = MAX_PATH;
3063 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3064 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3065 prompt, &promptsz);
3066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3067 ok(id == 1, "Expected 1, got %d\n", id);
3068 ok(!lstrcmpA(label, "#42"), "Expected \"#42\", got \"%s\"\n", label);
3069 ok(labelsz == 3, "Expected 3, got %d\n", labelsz);
3070 ok(!lstrcmpA(prompt, "#42"), "Expected \"#42\", got \"%s\"\n", prompt);
3071 ok(promptsz == 3, "Expected 3, got %d\n", promptsz);
3073 RegDeleteValueA(media, "1");
3074 RegDeleteValueA(media, "2");
3075 RegDeleteValueA(media, "4");
3076 RegDeleteKeyA(media, "");
3077 RegCloseKey(media);
3078 RegDeleteKeyA(source, "");
3079 RegCloseKey(source);
3080 RegDeleteKeyA(userkey, "");
3081 RegCloseKey(userkey);
3083 /* MSIINSTALLCONTEXT_USERMANAGED */
3085 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3086 lstrcatA(keypath, usersid);
3087 lstrcatA(keypath, "\\Installer\\Products\\");
3088 lstrcatA(keypath, prod_squashed);
3090 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
3091 if (res != ERROR_SUCCESS)
3093 skip("Product key creation failed with error code %u\n", res);
3094 goto machine_tests;
3097 /* user product key exists */
3098 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
3099 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3100 prompt, &promptsz);
3101 ok(r == ERROR_BAD_CONFIGURATION,
3102 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3104 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
3105 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3107 /* SourceList key exists */
3108 id = 0xbeef;
3109 lstrcpyA(label, "aaa");
3110 labelsz = 0xdeadbeef;
3111 lstrcpyA(prompt, "bbb");
3112 promptsz = 0xdeadbeef;
3113 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
3114 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3115 prompt, &promptsz);
3116 ok(r == ERROR_NO_MORE_ITEMS,
3117 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3118 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
3119 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
3120 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
3121 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
3122 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
3124 res = RegCreateKeyExA(source, "Media", 0, NULL, 0, access, NULL, &media, NULL);
3125 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3127 /* Media key exists */
3128 id = 0xbeef;
3129 lstrcpyA(label, "aaa");
3130 labelsz = 0xdeadbeef;
3131 lstrcpyA(prompt, "bbb");
3132 promptsz = 0xdeadbeef;
3133 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
3134 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3135 prompt, &promptsz);
3136 ok(r == ERROR_NO_MORE_ITEMS,
3137 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3138 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
3139 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
3140 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
3141 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
3142 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
3144 res = RegSetValueExA(media, "2", 0, REG_SZ, (LPBYTE)"label;prompt", 13);
3145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3147 /* disk exists, but no id 1 */
3148 id = 0;
3149 lstrcpyA(label, "aaa");
3150 labelsz = MAX_PATH;
3151 lstrcpyA(prompt, "bbb");
3152 promptsz = MAX_PATH;
3153 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
3154 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3155 prompt, &promptsz);
3156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3157 ok(id == 2, "Expected 2, got %d\n", id);
3158 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
3159 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
3160 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
3161 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
3163 RegDeleteValueA(media, "2");
3164 delete_key(media, "", access);
3165 RegCloseKey(media);
3166 delete_key(source, "", access);
3167 RegCloseKey(source);
3168 delete_key(userkey, "", access);
3169 RegCloseKey(userkey);
3171 /* MSIINSTALLCONTEXT_MACHINE */
3173 machine_tests:
3174 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3175 lstrcatA(keypath, prod_squashed);
3177 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3178 if (res != ERROR_SUCCESS)
3180 skip("Product key creation failed with error code %u\n", res);
3181 LocalFree(usersid);
3182 return;
3185 /* machine product key exists */
3186 r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
3187 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3188 prompt, &promptsz);
3189 ok(r == ERROR_BAD_CONFIGURATION,
3190 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3192 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
3193 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3195 /* SourceList key exists */
3196 id = 0xbeef;
3197 lstrcpyA(label, "aaa");
3198 labelsz = 0xdeadbeef;
3199 lstrcpyA(prompt, "bbb");
3200 promptsz = 0xdeadbeef;
3201 r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
3202 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3203 prompt, &promptsz);
3204 ok(r == ERROR_NO_MORE_ITEMS,
3205 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3206 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
3207 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
3208 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
3209 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
3210 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
3212 res = RegCreateKeyExA(source, "Media", 0, NULL, 0, access, NULL, &media, NULL);
3213 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3215 /* Media key exists */
3216 id = 0xbeef;
3217 lstrcpyA(label, "aaa");
3218 labelsz = 0xdeadbeef;
3219 lstrcpyA(prompt, "bbb");
3220 promptsz = 0xdeadbeef;
3221 r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
3222 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3223 prompt, &promptsz);
3224 ok(r == ERROR_NO_MORE_ITEMS,
3225 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3226 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
3227 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
3228 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", labelsz);
3229 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
3230 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", promptsz);
3232 res = RegSetValueExA(media, "2", 0, REG_SZ, (LPBYTE)"label;prompt", 13);
3233 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3235 /* disk exists, but no id 1 */
3236 id = 0;
3237 lstrcpyA(label, "aaa");
3238 labelsz = MAX_PATH;
3239 lstrcpyA(prompt, "bbb");
3240 promptsz = MAX_PATH;
3241 r = pMsiSourceListEnumMediaDisksA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
3242 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3243 prompt, &promptsz);
3244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3245 ok(id == 2, "Expected 2, got %d\n", id);
3246 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
3247 ok(labelsz == 5, "Expected 5, got %d\n", labelsz);
3248 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
3249 ok(promptsz == 6, "Expected 6, got %d\n", promptsz);
3251 /* szUserSid is non-NULL */
3252 id = 0xbeef;
3253 lstrcpyA(label, "aaa");
3254 labelsz = MAX_PATH;
3255 lstrcpyA(prompt, "bbb");
3256 promptsz = MAX_PATH;
3257 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
3258 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3259 prompt, &promptsz);
3260 ok(r == ERROR_INVALID_PARAMETER,
3261 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3262 ok(id == 0xbeef, "Expected 0xbeef, got %d\n", id);
3263 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
3264 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %d\n", labelsz);
3265 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
3266 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %d\n", promptsz);
3268 RegDeleteValueA(media, "2");
3269 delete_key(media, "", access);
3270 RegCloseKey(media);
3271 delete_key(source, "", access);
3272 RegCloseKey(source);
3273 delete_key(prodkey, "", access);
3274 RegCloseKey(prodkey);
3275 LocalFree(usersid);
3278 static void test_MsiSourceListAddSource(void)
3280 CHAR prodcode[MAX_PATH];
3281 CHAR prod_squashed[MAX_PATH];
3282 CHAR keypath[MAX_PATH*2];
3283 CHAR username[MAX_PATH];
3284 LPSTR usersid;
3285 LONG res;
3286 UINT r;
3287 HKEY prodkey, userkey, net, source;
3288 DWORD size;
3289 REGSAM access = KEY_ALL_ACCESS;
3291 if (!pMsiSourceListAddSourceA)
3293 win_skip("Skipping MsiSourceListAddSourceA tests\n");
3294 return;
3296 if (is_process_limited())
3298 skip("process is limited\n");
3299 return;
3302 create_test_guid(prodcode, prod_squashed);
3303 if (!(usersid = get_user_sid()))
3305 skip("User SID not available -> skipping MsiSourceListAddSourceA tests\n");
3306 return;
3309 /* MACHINENAME\username */
3310 size = MAX_PATH;
3311 GetUserNameExA(NameSamCompatible, username, &size);
3312 trace("username: %s\n", username);
3314 if (is_wow64)
3315 access |= KEY_WOW64_64KEY;
3317 /* GetLastError is not set by the function */
3319 /* NULL szProduct */
3320 r = pMsiSourceListAddSourceA(NULL, username, 0, "source");
3321 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3323 /* empty szProduct */
3324 r = pMsiSourceListAddSourceA("", username, 0, "source");
3325 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3327 /* garbage szProduct */
3328 r = pMsiSourceListAddSourceA("garbage", username, 0, "source");
3329 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3331 /* guid without brackets */
3332 r = pMsiSourceListAddSourceA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", username, 0, "source");
3333 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3335 /* guid with brackets */
3336 r = pMsiSourceListAddSourceA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", username, 0, "source");
3337 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3339 /* dwReserved is not 0 */
3340 r = pMsiSourceListAddSourceA(prodcode, username, 42, "source");
3341 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3343 /* szSource is NULL */
3344 r = pMsiSourceListAddSourceA(prodcode, username, 0, NULL);
3345 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3347 /* szSource is empty */
3348 r = pMsiSourceListAddSourceA(prodcode, username, 0, "");
3349 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3351 /* MSIINSTALLCONTEXT_USERMANAGED */
3353 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3354 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3356 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3357 lstrcatA(keypath, usersid);
3358 lstrcatA(keypath, "\\Installer\\Products\\");
3359 lstrcatA(keypath, prod_squashed);
3361 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
3362 if (res != ERROR_SUCCESS)
3364 skip("Product key creation failed with error code %u\n", res);
3365 goto userunmanaged_tests;
3368 /* user product key exists */
3369 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3370 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3372 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
3373 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3375 /* SourceList key exists */
3376 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3379 /* Net key is created */
3380 res = RegOpenKeyExA(source, "Net", 0, access, &net);
3381 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3383 /* LastUsedSource does not exist and it is not created */
3384 res = RegQueryValueExA(source, "LastUsedSource", 0, NULL, NULL, NULL);
3385 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3387 CHECK_REG_STR(net, "1", "source\\");
3389 RegDeleteValueA(net, "1");
3390 delete_key(net, "", access);
3391 RegCloseKey(net);
3393 res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"blah", 5);
3394 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3396 /* LastUsedSource value exists */
3397 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3400 /* Net key is created */
3401 res = RegOpenKeyExA(source, "Net", 0, access, &net);
3402 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3404 CHECK_REG_STR(source, "LastUsedSource", "blah");
3405 CHECK_REG_STR(net, "1", "source\\");
3407 RegDeleteValueA(net, "1");
3408 delete_key(net, "", access);
3409 RegCloseKey(net);
3411 res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"5", 2);
3412 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3414 /* LastUsedSource is an integer */
3415 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418 /* Net key is created */
3419 res = RegOpenKeyExA(source, "Net", 0, access, &net);
3420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3422 CHECK_REG_STR(source, "LastUsedSource", "5");
3423 CHECK_REG_STR(net, "1", "source\\");
3425 /* Add a second source, has trailing backslash */
3426 r = pMsiSourceListAddSourceA(prodcode, username, 0, "another\\");
3427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3429 CHECK_REG_STR(source, "LastUsedSource", "5");
3430 CHECK_REG_STR(net, "1", "source\\");
3431 CHECK_REG_STR(net, "2", "another\\");
3433 res = RegSetValueExA(source, "LastUsedSource", 0, REG_SZ, (LPBYTE)"2", 2);
3434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3436 /* LastUsedSource is in the source list */
3437 r = pMsiSourceListAddSourceA(prodcode, username, 0, "third/");
3438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3440 CHECK_REG_STR(source, "LastUsedSource", "2");
3441 CHECK_REG_STR(net, "1", "source\\");
3442 CHECK_REG_STR(net, "2", "another\\");
3443 CHECK_REG_STR(net, "3", "third/\\");
3445 RegDeleteValueA(net, "1");
3446 RegDeleteValueA(net, "2");
3447 RegDeleteValueA(net, "3");
3448 delete_key(net, "", access);
3449 RegCloseKey(net);
3450 delete_key(source, "", access);
3451 RegCloseKey(source);
3452 delete_key(userkey, "", access);
3453 RegCloseKey(userkey);
3455 /* MSIINSTALLCONTEXT_USERUNMANAGED */
3457 userunmanaged_tests:
3458 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3459 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3461 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3462 lstrcatA(keypath, prod_squashed);
3464 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
3465 if (res != ERROR_SUCCESS)
3467 skip("Product key creation failed with error code %u\n", res);
3468 goto machine_tests;
3471 /* user product key exists */
3472 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3473 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3475 res = RegCreateKeyA(userkey, "SourceList", &source);
3476 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3478 /* SourceList key exists */
3479 r = pMsiSourceListAddSourceA(prodcode, username, 0, "source");
3480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3482 /* Net key is created */
3483 res = RegOpenKeyA(source, "Net", &net);
3484 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3486 CHECK_REG_STR(net, "1", "source\\");
3488 RegDeleteValueA(net, "1");
3489 RegDeleteKeyA(net, "");
3490 RegCloseKey(net);
3491 RegDeleteKeyA(source, "");
3492 RegCloseKey(source);
3493 RegDeleteKeyA(userkey, "");
3494 RegCloseKey(userkey);
3496 /* MSIINSTALLCONTEXT_MACHINE */
3498 machine_tests:
3499 r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source");
3500 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3502 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3503 lstrcatA(keypath, prod_squashed);
3505 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3506 if (res != ERROR_SUCCESS)
3508 skip("Product key creation failed with error code %u\n", res);
3509 LocalFree(usersid);
3510 return;
3513 /* machine product key exists */
3514 r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source");
3515 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3517 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
3518 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3520 /* SourceList key exists */
3521 r = pMsiSourceListAddSourceA(prodcode, NULL, 0, "source");
3522 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3524 /* Net key is created */
3525 res = RegOpenKeyExA(source, "Net", 0, access, &net);
3526 if (res == ERROR_ACCESS_DENIED)
3528 skip("MsiSourceListAddSource (insufficient privileges)\n");
3529 goto done;
3531 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3533 CHECK_REG_STR(net, "1", "source\\");
3535 /* empty szUserName */
3536 r = pMsiSourceListAddSourceA(prodcode, "", 0, "another");
3537 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3539 CHECK_REG_STR(net, "1", "source\\");
3540 CHECK_REG_STR(net, "2", "another\\");
3542 RegDeleteValueA(net, "2");
3543 RegDeleteValueA(net, "1");
3544 delete_key(net, "", access);
3545 RegCloseKey(net);
3547 done:
3548 delete_key(source, "", access);
3549 RegCloseKey(source);
3550 delete_key(prodkey, "", access);
3551 RegCloseKey(prodkey);
3552 LocalFree(usersid);
3555 START_TEST(source)
3557 init_functionpointers();
3559 if (pIsWow64Process)
3560 pIsWow64Process(GetCurrentProcess(), &is_wow64);
3562 test_MsiSourceListGetInfo();
3563 test_MsiSourceListAddSourceEx();
3564 test_MsiSourceListEnumSources();
3565 test_MsiSourceListSetInfo();
3566 test_MsiSourceListAddMediaDisk();
3567 test_MsiSourceListEnumMediaDisks();
3568 test_MsiSourceListAddSource();