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