ReactOS 0.4.15-dev-7085-g12a5971
source.c
Go to the documentation of this file.
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#include "utils.h"
35
37
38static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
39static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
40
41static UINT (WINAPI *pMsiSourceListAddMediaDiskA)
43static UINT (WINAPI *pMsiSourceListAddSourceExA)
45static UINT (WINAPI *pMsiSourceListEnumMediaDisksA)
48static UINT (WINAPI *pMsiSourceListEnumSourcesA)
50static UINT (WINAPI *pMsiSourceListGetInfoA)
52static UINT (WINAPI *pMsiSourceListGetInfoW)
54static UINT (WINAPI *pMsiSourceListSetInfoA)
56static UINT (WINAPI *pMsiSourceListAddSourceA)
58
59static void init_functionpointers(void)
60{
61 HMODULE hmsi = GetModuleHandleA("msi.dll");
62 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
63 HMODULE hkernel32 = GetModuleHandleA("kernel32.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
78
79 GET_PROC(hadvapi32, RegDeleteKeyExA)
81
82#undef GET_PROC
83}
84
85/* copied from dlls/msi/registry.c */
87{
88 DWORD i,n=1;
89 GUID guid;
90
91 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
92 return FALSE;
93
94 for(i=0; i<8; i++)
95 out[7-i] = in[n++];
96 n++;
97 for(i=0; i<4; i++)
98 out[11-i] = in[n++];
99 n++;
100 for(i=0; i<4; i++)
101 out[15-i] = in[n++];
102 n++;
103 for(i=0; i<2; i++)
104 {
105 out[17+i*2] = in[n++];
106 out[16+i*2] = in[n++];
107 }
108 n++;
109 for( ; i<8; i++)
110 {
111 out[17+i*2] = in[n++];
112 out[16+i*2] = in[n++];
113 }
114 out[32]=0;
115 return TRUE;
116}
117
118static void create_test_guid(LPSTR prodcode, LPSTR squashed)
119{
120 WCHAR guidW[MAX_PATH];
121 WCHAR squashedW[MAX_PATH];
122 GUID guid;
123 HRESULT hr;
124 int size;
125
126 hr = CoCreateGuid(&guid);
127 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
128
129 size = StringFromGUID2(&guid, guidW, MAX_PATH);
130 ok(size == 39, "Expected 39, got %#lx\n", hr);
131
132 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
133 squash_guid(guidW, squashedW);
134 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
135}
136
137static char *get_user_sid(void)
138{
140 DWORD size = 0;
142 char *usersid = NULL;
143
146
147 user = malloc(size);
149 ConvertSidToStringSidA(user->User.Sid, &usersid);
150 free(user);
151
153 return usersid;
154}
155
156static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
157{
158 char val[MAX_PATH];
159 DWORD size, type;
160 LONG res;
161
162 size = MAX_PATH;
163 val[0] = '\0';
164 res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
165
166 if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
167 {
168 ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
169 return;
170 }
171
172 if (!expected)
173 ok_(__FILE__, line)(!val[0], "Expected empty string, got %s\n", val);
174 else
175 {
176 if (bcase)
177 ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
178 else
179 ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
180 }
181}
182
183#define CHECK_REG_STR(prodkey, name, expected) \
184 check_reg_str(prodkey, name, expected, TRUE, __LINE__);
185
186static inline WCHAR *strdupAW( const char *str )
187{
188 int len;
189 WCHAR *ret;
190 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
191 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
192 MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
193 return ret;
194}
195
197{
198 char prodcode[MAX_PATH], prod_squashed[MAX_PATH], keypath[MAX_PATH * 2], value[MAX_PATH], *usersid;
199 WCHAR valueW[MAX_PATH], *usersidW, *prodcodeW;
200 const char *data;
201 LONG res;
202 UINT r;
203 HKEY userkey, hkey, media;
204 DWORD size;
205
206 if (!pMsiSourceListGetInfoA)
207 {
208 win_skip("Skipping MsiSourceListGetInfoA tests\n");
209 return;
210 }
211
212 create_test_guid(prodcode, prod_squashed);
213 if (!(usersid = get_user_sid()))
214 {
215 skip("User SID not available -> skipping MsiSourceListGetInfoA tests\n");
216 return;
217 }
218
219 /* NULL szProductCodeOrPatchCode */
220 r = pMsiSourceListGetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
222 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
223
224 /* empty szProductCodeOrPatchCode */
225 r = pMsiSourceListGetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
227 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
228
229 /* garbage szProductCodeOrPatchCode */
230 r = pMsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
232 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
233
234 /* guid without brackets */
235 r = pMsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
237 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
238
239 /* guid with brackets */
240 r = pMsiSourceListGetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
242 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
243
244 /* same length as guid, but random */
245 r = pMsiSourceListGetInfoA("ADKD-2KSDFF2-DKK1KNFJASD9GLKWME-1I3KAD", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
247 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
248
249 /* invalid context */
250 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_NONE,
252 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
253
254 /* another invalid context */
255 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALLUSERMANAGED,
257 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
258
259 /* yet another invalid context */
260 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALL,
262 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
263
264 /* mix two valid contexts */
265 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED,
267 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
268
269 /* invalid option */
270 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
272 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
273
274 /* NULL property */
275 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
277 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
278
279 /* empty property */
280 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
282 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
283
284 /* value is non-NULL while size is NULL */
285 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
287 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
288
289 /* size is non-NULL while value is NULL */
290 size = MAX_PATH;
291 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
294 "Expected ERROR_UNKNOWN_PRODUCT or ERROR_INVALID_PARAMETER, got %d\n", r);
295
296 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
297 lstrcatA(keypath, prod_squashed);
298
299 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
301
302 /* user product key exists */
303 size = MAX_PATH;
304 lstrcpyA(value, "aaa");
305 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
307 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
308 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
309
310 res = RegCreateKeyA(userkey, "SourceList", &hkey);
311 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
312
313 /* SourceList key exists */
314 size = MAX_PATH;
315 lstrcpyA(value, "aaa");
316 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
319 ok(size == 0, "Expected 0, got %lu\n", size);
320 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
321
322 data = "msitest.msi";
323 res = RegSetValueExA(hkey, "PackageName", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
324 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
325
326 /* PackageName value exists */
327 size = 0xdeadbeef;
328 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
331 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
332 ok(size == 11 || r != ERROR_SUCCESS, "Expected 11, got %lu\n", size);
333
334 /* read the value, don't change size */
335 size = 11;
336 lstrcpyA(value, "aaa");
337 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
339 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
340 ok(!lstrcmpA(value, "aaa"), "Expected 'aaa', got %s\n", value);
341 ok(size == 11, "Expected 11, got %lu\n", size);
342
343 /* read the value, fix size */
344 size++;
345 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
348 ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
349 ok(size == 11, "Expected 11, got %lu\n", size);
350
351 /* empty property now that product key exists */
352 size = MAX_PATH;
353 lstrcpyA(value, "aaa");
354 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
355 MSICODE_PRODUCT, "", value, &size);
356 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
357 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
358 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
359
360 /* nonexistent property now that product key exists */
361 size = MAX_PATH;
362 lstrcpyA(value, "aaa");
363 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
364 MSICODE_PRODUCT, "nonexistent", value, &size);
365 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
366 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
367 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
368
369 data = "tester";
370 res = RegSetValueExA(hkey, "nonexistent", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
372
373 /* nonexistent property now that nonexistent value exists */
374 size = MAX_PATH;
375 lstrcpyA(value, "aaa");
376 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
377 MSICODE_PRODUCT, "nonexistent", value, &size);
378 ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
379 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
380 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
381
382 /* invalid option now that product key exists */
383 size = MAX_PATH;
384 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
387 ok(size == 11, "Expected 11, got %lu\n", size);
388
389 /* INSTALLPROPERTY_MEDIAPACKAGEPATH, media key does not exist */
390 size = MAX_PATH;
391 lstrcpyA(value, "aaa");
392 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
394 value, &size);
395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
396 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
397 ok(size == 0, "Expected 0, got %lu\n", size);
398
399 res = RegCreateKeyA(hkey, "Media", &media);
400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
401
402 data = "path";
403 res = RegSetValueExA(media, "MediaPackage", 0, REG_SZ,
404 (const BYTE *)data, lstrlenA(data) + 1);
405 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
406
407 /* INSTALLPROPERTY_MEDIAPACKAGEPATH */
408 size = MAX_PATH;
409 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
411 value, &size);
412 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
413 ok(!lstrcmpA(value, "path"), "Expected \"path\", got \"%s\"\n", value);
414 ok(size == 4, "Expected 4, got %lu\n", size);
415
416 /* INSTALLPROPERTY_DISKPROMPT */
417 data = "prompt";
418 res = RegSetValueExA(media, "DiskPrompt", 0, REG_SZ,
419 (const BYTE *)data, lstrlenA(data) + 1);
420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
421
422 size = MAX_PATH;
423 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
425 value, &size);
426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
427 ok(!lstrcmpA(value, "prompt"), "Expected \"prompt\", got \"%s\"\n", value);
428 ok(size == 6, "Expected 6, got %lu\n", size);
429
430 /* LastUsedSource value doesn't exist */
431 RegDeleteValueA(hkey, "LastUsedSource");
432 size = MAX_PATH;
433 memset(value, 0x55, sizeof(value));
434 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
436 value, &size);
437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
438 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
439 ok(size == 0, "Expected 0, got %lu\n", size);
440
441 size = MAX_PATH;
442 usersidW = strdupAW(usersid);
443 prodcodeW = strdupAW(prodcode);
444 memset(valueW, 0x55, sizeof(valueW));
445 r = pMsiSourceListGetInfoW(prodcodeW, usersidW, MSIINSTALLCONTEXT_USERUNMANAGED,
447 valueW, &size);
448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
449 ok(!valueW[0], "Expected \"\"");
450 ok(size == 0, "Expected 0, got %lu\n", size);
451 free(usersidW);
452 free(prodcodeW);
453
454 data = "";
455 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
456 (const BYTE *)data, lstrlenA(data) + 1);
457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
458
459 /* INSTALLPROPERTY_LASTUSEDSOURCE, source is empty */
460 size = MAX_PATH;
461 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
463 value, &size);
464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
465 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
466 ok(size == 0, "Expected 0, got %lu\n", size);
467
468 data = "source";
469 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
470 (const BYTE *)data, lstrlenA(data) + 1);
471 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
472
473 /* INSTALLPROPERTY_LASTUSEDSOURCE */
474 size = MAX_PATH;
475 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
477 value, &size);
478 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
479 ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value);
480 ok(size == 6, "Expected 6, got %lu\n", size);
481
482 /* INSTALLPROPERTY_LASTUSEDSOURCE, size is too short */
483 size = 4;
484 lstrcpyA(value, "aaa");
485 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
487 value, &size);
488 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
489 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value);
490 ok(size == 6, "Expected 6, got %lu\n", size);
491
492 /* INSTALLPROPERTY_LASTUSEDSOURCE, size is exactly 6 */
493 size = 6;
494 lstrcpyA(value, "aaa");
495 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
497 value, &size);
498 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
499 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got \"%s\"\n", value);
500 ok(size == 6, "Expected 6, got %lu\n", size);
501
502 data = "a;source";
503 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
504 (const BYTE *)data, lstrlenA(data) + 1);
505 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
506
507 /* INSTALLPROPERTY_LASTUSEDSOURCE, one semi-colon */
508 size = MAX_PATH;
509 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
511 value, &size);
512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
513 ok(!lstrcmpA(value, "source"), "Expected \"source\", got \"%s\"\n", value);
514 ok(size == 6, "Expected 6, got %lu\n", size);
515
516 data = "a:source";
517 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
518 (const BYTE *)data, lstrlenA(data) + 1);
519 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
520
521 /* INSTALLPROPERTY_LASTUSEDSOURCE, one colon */
522 size = MAX_PATH;
523 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
525 value, &size);
526 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
527 ok(!lstrcmpA(value, "a:source"), "Expected \"a:source\", got \"%s\"\n", value);
528 ok(size == 8, "Expected 8, got %lu\n", size);
529
530 /* INSTALLPROPERTY_LASTUSEDTYPE, invalid source format */
531 size = MAX_PATH;
532 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
534 value, &size);
535 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
536 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
537 ok(size == 0, "Expected 0, got %lu\n", size);
538
539 data = "x;y;z";
540 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
541 (const BYTE *)data, lstrlenA(data) + 1);
542 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
543
544 /* INSTALLPROPERTY_LASTUSEDTYPE, invalid source format */
545 size = MAX_PATH;
546 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
548 value, &size);
549 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
550 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
551 ok(size == 0, "Expected 0, got %lu\n", size);
552
553 data = "n;y;z";
554 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
555 (const BYTE *)data, lstrlenA(data) + 1);
556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
557
558 /* INSTALLPROPERTY_LASTUSEDTYPE */
559 size = MAX_PATH;
560 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
562 value, &size);
563 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
564 ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
565 ok(size == 1, "Expected 1, got %lu\n", size);
566
567 data = "negatory";
568 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
569 (const BYTE *)data, lstrlenA(data) + 1);
570 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
571
572 /* INSTALLPROPERTY_LASTUSEDTYPE */
573 size = MAX_PATH;
574 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
576 value, &size);
577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
578 ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
579 ok(size == 1, "Expected 1, got %lu\n", size);
580
581 data = "megatron";
582 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
583 (const BYTE *)data, lstrlenA(data) + 1);
584 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
585
586 /* INSTALLPROPERTY_LASTUSEDTYPE */
587 size = MAX_PATH;
588 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
590 value, &size);
591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
592 ok(!lstrcmpA(value, "m"), "Expected \"m\", got \"%s\"\n", value);
593 ok(size == 1, "Expected 1, got %lu\n", size);
594
595 data = "useless";
596 res = RegSetValueExA(hkey, "LastUsedSource", 0, REG_SZ,
597 (const BYTE *)data, lstrlenA(data) + 1);
598 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
599
600 /* INSTALLPROPERTY_LASTUSEDTYPE */
601 size = MAX_PATH;
602 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
604 value, &size);
605 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
606 ok(!lstrcmpA(value, "u"), "Expected \"u\", got \"%s\"\n", value);
607 ok(size == 1, "Expected 1, got %lu\n", size);
608
609 RegDeleteValueA(media, "MediaPackage");
610 RegDeleteValueA(media, "DiskPrompt");
611 RegDeleteKeyA(media, "");
612 RegDeleteValueA(hkey, "LastUsedSource");
613 RegDeleteValueA(hkey, "nonexistent");
614 RegDeleteValueA(hkey, "PackageName");
615 RegDeleteKeyA(hkey, "");
616 RegDeleteKeyA(userkey, "");
617 RegCloseKey(hkey);
618 RegCloseKey(userkey);
619
620 /* try a patch */
621 size = MAX_PATH;
622 lstrcpyA(value, "aaa");
623 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
625 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
626 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
627 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
628
629 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\");
630 lstrcatA(keypath, prod_squashed);
631
632 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
633 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
634
635 /* patch key exists
636 * NOTE: using prodcode guid, but it really doesn't matter
637 */
638 size = MAX_PATH;
639 lstrcpyA(value, "aaa");
640 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
642 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
643 ok(size == MAX_PATH, "Expected %d, got %lu\n", MAX_PATH, size);
644 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
645
646 res = RegCreateKeyA(userkey, "SourceList", &hkey);
647 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
648
649 /* SourceList key exists */
650 size = MAX_PATH;
651 lstrcpyA(value, "aaa");
652 r = pMsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
655 ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
656 ok(size == 0, "Expected 0, got %lu\n", size);
657
658 RegDeleteKeyA(hkey, "");
659 RegDeleteKeyA(userkey, "");
660 RegCloseKey(hkey);
661 RegCloseKey(userkey);
662 LocalFree(usersid);
663}
664
666{
667 if (pRegDeleteKeyExA)
668 return pRegDeleteKeyExA( key, subkey, access, 0 );
669 return RegDeleteKeyA( key, subkey );
670}
671
673{
674 CHAR prodcode[MAX_PATH];
675 CHAR prod_squashed[MAX_PATH];
676 CHAR keypath[MAX_PATH*2];
678 LPSTR usersid;
679 LONG res;
680 UINT r;
681 HKEY prodkey, userkey, hkey, url, net;
682 DWORD size;
684
685 if (!pMsiSourceListAddSourceExA)
686 {
687 win_skip("Skipping MsiSourceListAddSourceExA tests\n");
688 return;
689 }
690 if (is_process_limited())
691 {
692 skip("process is limited\n");
693 return;
694 }
695
696 create_test_guid(prodcode, prod_squashed);
697 if (!(usersid = get_user_sid()))
698 {
699 skip("User SID not available -> skipping MsiSourceListAddSourceExA tests\n");
700 return;
701 }
702
703 if (is_wow64)
705
706 /* GetLastError is not set by the function */
707
708 /* NULL szProductCodeOrPatchCode */
709 r = pMsiSourceListAddSourceExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
710 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
711 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
712
713 /* empty szProductCodeOrPatchCode */
714 r = pMsiSourceListAddSourceExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
715 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
716 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
717
718 /* garbage szProductCodeOrPatchCode */
719 r = pMsiSourceListAddSourceExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
720 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
721 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
722
723 /* guid without brackets */
724 r = pMsiSourceListAddSourceExA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid,
726 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
727 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
728
729 /* guid with brackets */
730 r = pMsiSourceListAddSourceExA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid,
732 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
733 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
734
735 /* MSIINSTALLCONTEXT_USERUNMANAGED */
736
737 r = pMsiSourceListAddSourceExA(prodcode, usersid,
739 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
740 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
741
742 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
743 lstrcatA(keypath, prod_squashed);
744
745 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
747
748 /* user product key exists */
749 r = pMsiSourceListAddSourceExA(prodcode, usersid,
751 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
752 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
753
754 res = RegCreateKeyA(userkey, "SourceList", &url);
755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
757
758 /* SourceList key exists */
759 r = pMsiSourceListAddSourceExA(prodcode, usersid,
761 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
763
764 res = RegOpenKeyA(userkey, "SourceList\\URL", &url);
765 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
766
767 size = MAX_PATH;
769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
770 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
771 ok(size == 11, "Expected 11, got %lu\n", size);
772
773 /* add another source, index 0 */
774 r = pMsiSourceListAddSourceExA(prodcode, usersid,
776 MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
777 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
778
779 size = MAX_PATH;
781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
782 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
783 ok(size == 11, "Expected 11, got %lu\n", size);
784
785 size = MAX_PATH;
787 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
788 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
789 ok(size == 9, "Expected 9, got %lu\n", size);
790
791 /* add another source, index 1 */
792 r = pMsiSourceListAddSourceExA(prodcode, usersid,
794 MSICODE_PRODUCT | MSISOURCETYPE_URL, "third/", 1);
795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
796
797 size = MAX_PATH;
799 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
800 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
801 ok(size == 7, "Expected 7, got %lu\n", size);
802
803 size = MAX_PATH;
805 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
806 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
807 ok(size == 11, "Expected 11, got %lu\n", size);
808
809 size = MAX_PATH;
811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
812 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
813 ok(size == 9, "Expected 9, got %lu\n", size);
814
815 /* add another source, index > N */
816 r = pMsiSourceListAddSourceExA(prodcode, usersid,
818 MSICODE_PRODUCT | MSISOURCETYPE_URL, "last/", 5);
819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
820
821 size = MAX_PATH;
823 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
824 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
825 ok(size == 7, "Expected 7, got %lu\n", size);
826
827 size = MAX_PATH;
829 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
830 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
831 ok(size == 11, "Expected 11, got %lu\n", size);
832
833 size = MAX_PATH;
835 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
836 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
837 ok(size == 9, "Expected 9, got %lu\n", size);
838
839 size = MAX_PATH;
841 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
842 ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
843 ok(size == 6, "Expected 6, got %lu\n", size);
844
845 /* just MSISOURCETYPE_NETWORK */
846 r = pMsiSourceListAddSourceExA(prodcode, usersid,
848 MSISOURCETYPE_NETWORK, "source", 0);
849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
850
851 res = RegOpenKeyA(userkey, "SourceList\\Net", &net);
852 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
853
854 size = MAX_PATH;
856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
857 ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
858 ok(size == 8, "Expected 8, got %lu\n", size);
859
860 /* just MSISOURCETYPE_URL */
861 r = pMsiSourceListAddSourceExA(prodcode, usersid,
863 MSISOURCETYPE_URL, "source", 0);
864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
865
866 size = MAX_PATH;
868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
869 ok(!lstrcmpA(value, "third/"), "Expected 'third/', got %s\n", value);
870 ok(size == 7, "Expected 7, got %lu\n", size);
871
872 size = MAX_PATH;
874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
875 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
876 ok(size == 11, "Expected 11, got %lu\n", size);
877
878 size = MAX_PATH;
880 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
881 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
882 ok(size == 9, "Expected 9, got %lu\n", size);
883
884 size = MAX_PATH;
886 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
887 ok(!lstrcmpA(value, "last/"), "Expected 'last/', got %s\n", value);
888 ok(size == 6, "Expected 6, got %lu\n", size);
889
890 size = MAX_PATH;
892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
893 ok(!lstrcmpA(value, "source/"), "Expected 'source/', got %s\n", value);
894 ok(size == 8, "Expected 8, got %lu\n", size);
895
896 /* NULL szUserSid */
897 r = pMsiSourceListAddSourceExA(prodcode, NULL,
899 MSISOURCETYPE_NETWORK, "nousersid", 0);
900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
901
902 size = MAX_PATH;
904 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
905 ok(!lstrcmpA(value, "source\\"), "Expected 'source\\', got %s\n", value);
906 ok(size == 8, "Expected 8, got %lu\n", size);
907
908 size = MAX_PATH;
910 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
911 ok(!lstrcmpA(value, "nousersid\\"), "Expected 'nousersid\\', got %s\n", value);
912 ok(size == 11, "Expected 11, got %lu\n", size);
913
914 /* invalid options, must have source type */
915 r = pMsiSourceListAddSourceExA(prodcode, usersid,
917 MSICODE_PRODUCT, "source", 0);
918 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
919
920 r = pMsiSourceListAddSourceExA(prodcode, usersid,
922 MSICODE_PATCH, "source", 0);
923 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
924
925 /* NULL szSource */
926 r = pMsiSourceListAddSourceExA(prodcode, usersid,
929 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
930
931 /* empty szSource */
932 r = pMsiSourceListAddSourceExA(prodcode, usersid,
934 MSISOURCETYPE_URL, "", 1);
935 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
936
937 /* MSIINSTALLCONTEXT_USERMANAGED, non-NULL szUserSid */
938
939 r = pMsiSourceListAddSourceExA(prodcode, usersid,
941 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
942 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
943
944 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
945 lstrcatA(keypath, usersid);
946 lstrcatA(keypath, "\\Installer\\Products\\");
947 lstrcatA(keypath, prod_squashed);
948
949 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
950 if (res != ERROR_SUCCESS)
951 {
952 skip("Product key creation failed with error code %ld\n", res);
953 goto machine_tests;
954 }
955
956 /* product key exists */
957 r = pMsiSourceListAddSourceExA(prodcode, usersid,
959 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
960 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
961
962 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL);
963 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
964 RegCloseKey(hkey);
965
966 /* SourceList exists */
967 r = pMsiSourceListAddSourceExA(prodcode, usersid,
969 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
971
972 res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
973 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
974
975 size = MAX_PATH;
977 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
978 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
979 ok(size == 11, "Expected 11, got %lu\n", size);
980
982
983 /* MSIINSTALLCONTEXT_USERMANAGED, NULL szUserSid */
984
985 r = pMsiSourceListAddSourceExA(prodcode, NULL,
987 MSICODE_PRODUCT | MSISOURCETYPE_URL, "another", 0);
988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
989
990 res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
991 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
992
993 size = MAX_PATH;
995 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
996 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
997 ok(size == 11, "Expected 11, got %lu\n", size);
998
999 size = MAX_PATH;
1001 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1002 ok(!lstrcmpA(value, "another/"), "Expected 'another/', got %s\n", value);
1003 ok(size == 9, "Expected 9, got %lu\n", size);
1004
1006 RegCloseKey(prodkey);
1007
1008 /* MSIINSTALLCONTEXT_MACHINE */
1009
1010machine_tests:
1011 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
1012 r = pMsiSourceListAddSourceExA(prodcode, usersid,
1014 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1015 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1016
1017 r = pMsiSourceListAddSourceExA(prodcode, NULL,
1019 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1020 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1021
1022 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1023 lstrcatA(keypath, prod_squashed);
1024
1025 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1026 if (res != ERROR_SUCCESS)
1027 {
1028 skip("Product key creation failed with error code %ld\n", res);
1029 LocalFree(usersid);
1030 return;
1031 }
1032
1033 /* product key exists */
1034 r = pMsiSourceListAddSourceExA(prodcode, NULL,
1036 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1037 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1038
1039 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &hkey, NULL);
1040 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1041 RegCloseKey(hkey);
1042
1043 /* SourceList exists */
1044 r = pMsiSourceListAddSourceExA(prodcode, NULL,
1046 MSICODE_PRODUCT | MSISOURCETYPE_URL, "C:\\source", 0);
1047 if (r == ERROR_ACCESS_DENIED)
1048 skip("MsiSourceListAddSourceEx (insufficient privileges)\n");
1049 else
1050 {
1051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1052
1053 res = RegOpenKeyExA(prodkey, "SourceList\\URL", 0, access, &url);
1054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1055
1056 size = MAX_PATH;
1058 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1059 ok(!lstrcmpA(value, "C:\\source/"), "Expected 'C:\\source/', got %s\n", value);
1060 ok(size == 11, "Expected 11, got %lu\n", size);
1061
1063 RegCloseKey(prodkey);
1064 }
1065 LocalFree(usersid);
1066}
1067
1069{
1070 CHAR prodcode[MAX_PATH];
1071 CHAR prod_squashed[MAX_PATH];
1072 CHAR keypath[MAX_PATH*2];
1074 LPSTR usersid;
1075 LONG res;
1076 UINT r;
1077 HKEY prodkey, userkey;
1078 HKEY url, net, source;
1079 DWORD size;
1081
1082 if (!pMsiSourceListEnumSourcesA)
1083 {
1084 win_skip("MsiSourceListEnumSourcesA is not available\n");
1085 return;
1086 }
1087
1088 create_test_guid(prodcode, prod_squashed);
1089 if (!(usersid = get_user_sid()))
1090 {
1091 skip("User SID not available -> skipping MsiSourceListEnumSourcesA tests\n");
1092 return;
1093 }
1094
1095 if (is_wow64)
1097
1098 /* GetLastError is not set by the function */
1099
1100 /* NULL szProductCodeOrPatchCode */
1101 size = 0xdeadbeef;
1102 r = pMsiSourceListEnumSourcesA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1104 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1105 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", size);
1106
1107 /* empty szProductCodeOrPatchCode */
1108 size = 0xdeadbeef;
1109 r = pMsiSourceListEnumSourcesA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1111 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1112 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", size);
1113
1114 /* garbage szProductCodeOrPatchCode */
1115 size = 0xdeadbeef;
1116 r = pMsiSourceListEnumSourcesA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1118 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1119 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", size);
1120
1121 /* guid without brackets */
1122 size = 0xdeadbeef;
1123 r = pMsiSourceListEnumSourcesA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
1126 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1127 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", size);
1128
1129 /* guid with brackets */
1130 size = 0xdeadbeef;
1131 r = pMsiSourceListEnumSourcesA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
1134 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1135 ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", size);
1136
1137 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1138
1139 size = MAX_PATH;
1140 lstrcpyA(value, "aaa");
1141 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1144 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1145 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1146 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1147
1148 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1149 lstrcatA(keypath, prod_squashed);
1150
1151 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1152 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1153
1154 /* user product key exists */
1155 size = MAX_PATH;
1156 lstrcpyA(value, "aaa");
1157 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1160 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1161 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1162 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1163
1164 res = RegCreateKeyA(userkey, "SourceList", &source);
1165 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1166
1167 /* SourceList key exists */
1168 size = MAX_PATH;
1169 lstrcpyA(value, "aaa");
1170 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1173 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1174 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1175 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1176
1177 res = RegCreateKeyA(source, "URL", &url);
1178 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1179
1180 /* URL key exists */
1181 size = MAX_PATH;
1182 lstrcpyA(value, "aaa");
1183 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1186 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1187 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1188 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1189
1190 res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1191 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1192
1193 res = RegSetValueExA(url, "2", 0, REG_SZ, (LPBYTE)"second", 7);
1194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1195
1196 res = RegSetValueExA(url, "4", 0, REG_SZ, (LPBYTE)"fourth", 7);
1197 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1198
1199 /* sources exist */
1200 size = MAX_PATH;
1201 lstrcpyA(value, "aaa");
1202 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1205 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1206 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1207 ok(size == 5, "Expected 5, got %lu\n", size);
1208
1209 /* try index 0 again */
1210 size = MAX_PATH;
1211 lstrcpyA(value, "aaa");
1212 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1216 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1217 ok(size == 5, "Expected 5, got %lu\n", size);
1218
1219 /* both szSource and pcchSource are NULL, index 0 */
1220 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1224
1225 /* both szSource and pcchSource are NULL, index 1 */
1226 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1230
1231 /* size is exactly 5 */
1232 size = 5;
1233 lstrcpyA(value, "aaa");
1234 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1237 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
1238 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
1239 ok(size == 5, "Expected 5, got %lu\n", size);
1240
1241 /* szSource is non-NULL while pcchSource is NULL */
1242 lstrcpyA(value, "aaa");
1243 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1246 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1247 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
1248
1249 /* try index 1 after failure */
1250 size = MAX_PATH;
1251 lstrcpyA(value, "aaa");
1252 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1256 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1257 ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got %s\n", value);
1258 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1259
1260 /* reset the enumeration */
1261 size = MAX_PATH;
1262 lstrcpyA(value, "aaa");
1263 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1267 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1268 ok(size == 5, "Expected 5, got %lu\n", size);
1269
1270 /* try index 1 */
1271 size = MAX_PATH;
1272 lstrcpyA(value, "aaa");
1273 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1276 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1277 ok(!lstrcmpA(value, "second"), "Expected \"second\", got %s\n", value);
1278 ok(size == 6, "Expected 6, got %lu\n", size);
1279
1280 /* try index 1 again */
1281 size = MAX_PATH;
1282 lstrcpyA(value, "aaa");
1283 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1287 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1288 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1289 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1290
1291 /* try index 2 */
1292 size = MAX_PATH;
1293 lstrcpyA(value, "aaa");
1294 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1297 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1298 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1299 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1300
1301 /* try index < 0 */
1302 size = MAX_PATH;
1303 lstrcpyA(value, "aaa");
1304 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1308 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1309 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1310 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1311
1312 /* NULL szUserSid */
1313 size = MAX_PATH;
1314 lstrcpyA(value, "aaa");
1315 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1319 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1320 ok(size == 5, "Expected 5, got %lu\n", size);
1321
1322 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1323 size = MAX_PATH;
1324 lstrcpyA(value, "aaa");
1325 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1327 MSICODE_PRODUCT, 0, value, &size);
1328 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1329 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1330 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1331
1332 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1333 size = MAX_PATH;
1334 lstrcpyA(value, "aaa");
1335 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1337 MSICODE_PATCH, 0, value, &size);
1338 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1339 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1340 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1341
1342 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1343 size = MAX_PATH;
1344 lstrcpyA(value, "aaa");
1345 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1348 0, value, &size);
1349 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
1350 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1351 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1352
1353 /* invalid dwOptions, must be one of MSICODE_ and MSISOURCETYPE_ */
1354 size = MAX_PATH;
1355 lstrcpyA(value, "aaa");
1356 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1359 0, value, &size);
1360 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1361 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1362 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1363
1364 RegDeleteValueA(url, "1");
1365 RegDeleteValueA(url, "2");
1366 RegDeleteValueA(url, "4");
1367 RegDeleteKeyA(url, "");
1369
1370 /* SourceList key exists */
1371 size = MAX_PATH;
1372 lstrcpyA(value, "aaa");
1373 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1376 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1377 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1378 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1379
1380 res = RegCreateKeyA(source, "Net", &net);
1381 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1382
1383 /* Net key exists */
1384 size = MAX_PATH;
1385 lstrcpyA(value, "aaa");
1386 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1389 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1390 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1391 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1392
1393 res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1394 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1395
1396 /* sources exist */
1397 size = MAX_PATH;
1398 lstrcpyA(value, "aaa");
1399 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1403 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1404 ok(size == 5, "Expected 5, got %lu\n", size);
1405
1406 RegDeleteValueA(net, "1");
1407 RegDeleteKeyA(net, "");
1409 RegDeleteKeyA(source, "");
1411 RegDeleteKeyA(userkey, "");
1412 RegCloseKey(userkey);
1413
1414 /* MSIINSTALLCONTEXT_USERMANAGED */
1415
1416 size = MAX_PATH;
1417 lstrcpyA(value, "aaa");
1418 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1421 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1422 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1423 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1424
1425 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1426 lstrcatA(keypath, usersid);
1427 lstrcatA(keypath, "\\Installer\\Products\\");
1428 lstrcatA(keypath, prod_squashed);
1429
1430 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1431 if (res != ERROR_SUCCESS)
1432 {
1433 skip("Product key creation failed with error code %ld\n", res);
1434 goto machine_tests;
1435 }
1436
1437 /* user product key exists */
1438 size = MAX_PATH;
1439 lstrcpyA(value, "aaa");
1440 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1443 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1444 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1445 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1446
1447 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
1448 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1449
1450 /* SourceList key exists */
1451 size = MAX_PATH;
1452 lstrcpyA(value, "aaa");
1453 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1456 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1457 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1458 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1459
1460 res = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL);
1461 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1462
1463 /* URL key exists */
1464 size = MAX_PATH;
1465 lstrcpyA(value, "aaa");
1466 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1469 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1470 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1471 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1472
1473 res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1474 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1475
1476 /* sources exist */
1477 size = MAX_PATH;
1478 lstrcpyA(value, "aaa");
1479 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1483 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1484 ok(size == 5, "Expected 5, got %lu\n", size);
1485
1486 /* NULL szUserSid */
1487 size = MAX_PATH;
1488 lstrcpyA(value, "aaa");
1489 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1492 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1493 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1494 ok(size == 5, "Expected 5, got %lu\n", size);
1495
1496 RegDeleteValueA(url, "1");
1497 delete_key(url, "", access);
1499
1500 /* SourceList key exists */
1501 size = MAX_PATH;
1502 lstrcpyA(value, "aaa");
1503 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1506 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1507 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1508 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1509
1510 res = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL);
1511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1512
1513 /* Net key exists */
1514 size = MAX_PATH;
1515 lstrcpyA(value, "aaa");
1516 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1519 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1520 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1521 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1522
1523 res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1524 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1525
1526 /* sources exist */
1527 size = MAX_PATH;
1528 lstrcpyA(value, "aaa");
1529 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1533 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1534 ok(size == 5, "Expected 5, got %lu\n", size);
1535
1536 RegDeleteValueA(net, "1");
1537 delete_key(net, "", access);
1539 delete_key(source, "", access);
1541 delete_key(userkey, "", access);
1542 RegCloseKey(userkey);
1543
1544 /* MSIINSTALLCONTEXT_MACHINE */
1545
1546machine_tests:
1547 /* szUserSid is non-NULL */
1548 size = MAX_PATH;
1549 lstrcpyA(value, "aaa");
1550 r = pMsiSourceListEnumSourcesA(prodcode, usersid,
1553 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1554 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1555 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1556
1557 /* szUserSid is NULL */
1558 size = MAX_PATH;
1559 lstrcpyA(value, "aaa");
1560 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1563 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1564 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1565 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1566
1567 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1568 lstrcatA(keypath, prod_squashed);
1569
1570 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1571 if (res != ERROR_SUCCESS)
1572 {
1573 skip("Product key creation failed with error code %ld\n", res);
1574 LocalFree(usersid);
1575 return;
1576 }
1577
1578 /* user product key exists */
1579 size = MAX_PATH;
1580 lstrcpyA(value, "aaa");
1581 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1584 ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1585 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1586 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1587
1588 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
1589 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1590
1591 /* SourceList key exists */
1592 size = MAX_PATH;
1593 lstrcpyA(value, "aaa");
1594 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1597 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1598 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1599 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1600
1601 res = RegCreateKeyExA(source, "URL", 0, NULL, 0, access, NULL, &url, NULL);
1602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1603
1604 /* URL key exists */
1605 size = MAX_PATH;
1606 lstrcpyA(value, "aaa");
1607 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1610 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1611 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1612 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1613
1614 res = RegSetValueExA(url, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1615 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1616
1617 /* sources exist */
1618 size = MAX_PATH;
1619 lstrcpyA(value, "aaa");
1620 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1624 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1625 ok(size == 5, "Expected 5, got %lu\n", size);
1626
1627 /* NULL szUserSid */
1628 size = MAX_PATH;
1629 lstrcpyA(value, "aaa");
1630 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1633 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1634 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1635 ok(size == 5, "Expected 5, got %lu\n", size);
1636
1637 RegDeleteValueA(url, "1");
1638 delete_key(url, "", access);
1640
1641 /* SourceList key exists */
1642 size = MAX_PATH;
1643 lstrcpyA(value, "aaa");
1644 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1647 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1648 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1649 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1650
1651 res = RegCreateKeyExA(source, "Net", 0, NULL, 0, access, NULL, &net, NULL);
1652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1653
1654 /* Net key exists */
1655 size = MAX_PATH;
1656 lstrcpyA(value, "aaa");
1657 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1660 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
1661 ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
1662 ok(size == MAX_PATH, "Expected MAX_PATH, got %lu\n", size);
1663
1664 res = RegSetValueExA(net, "1", 0, REG_SZ, (LPBYTE)"first", 6);
1665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1666
1667 /* sources exist */
1668 size = MAX_PATH;
1669 lstrcpyA(value, "aaa");
1670 r = pMsiSourceListEnumSourcesA(prodcode, NULL,
1673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1674 ok(!lstrcmpA(value, "first"), "Expected \"first\", got %s\n", value);
1675 ok(size == 5, "Expected 5, got %lu\n", size);
1676
1677 RegDeleteValueA(net, "1");
1678 delete_key(net, "", access);
1680 delete_key(source, "", access);
1682 delete_key(prodkey, "", access);
1683 RegCloseKey(prodkey);
1684 LocalFree(usersid);
1685}
1686
1688{
1689 CHAR prodcode[MAX_PATH];
1690 CHAR prod_squashed[MAX_PATH];
1691 CHAR keypath[MAX_PATH*2];
1692 HKEY prodkey, userkey;
1693 HKEY net, url, media, source;
1694 LPSTR usersid;
1695 LONG res;
1696 UINT r;
1698
1699 if (!pMsiSourceListSetInfoA)
1700 {
1701 win_skip("MsiSourceListSetInfoA is not available\n");
1702 return;
1703 }
1704 if (is_process_limited())
1705 {
1706 skip("process is limited\n");
1707 return;
1708 }
1709
1710 create_test_guid(prodcode, prod_squashed);
1711 if (!(usersid = get_user_sid()))
1712 {
1713 skip("User SID not available -> skipping MsiSourceListSetInfoA tests\n");
1714 return;
1715 }
1716
1717 if (is_wow64)
1719
1720 /* GetLastError is not set by the function */
1721
1722 /* NULL szProductCodeOrPatchCode */
1723 r = pMsiSourceListSetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1727 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1728
1729 /* empty szProductCodeOrPatchCode */
1730 r = pMsiSourceListSetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
1734 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1735
1736 /* garbage szProductCodeOrPatchCode */
1737 r = pMsiSourceListSetInfoA("garbage", usersid,
1742 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1743
1744 /* guid without brackets */
1745 r = pMsiSourceListSetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
1750 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1751
1752 /* guid with brackets */
1753 r = pMsiSourceListSetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
1758 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1759
1760 /* dwOptions is MSICODE_PRODUCT */
1761 r = pMsiSourceListSetInfoA(prodcode, usersid,
1765 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1766
1767 /* dwOptions is MSICODE_PATCH */
1768 r = pMsiSourceListSetInfoA(prodcode, usersid,
1771 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
1772
1773 /* dwOptions is both MSICODE_PRODUCT and MSICODE_PATCH */
1774 r = pMsiSourceListSetInfoA(prodcode, usersid,
1778 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
1779
1780 /* dwOptions has both MSISOURCETYPE_NETWORK and MSISOURCETYPE_URL */
1781 r = pMsiSourceListSetInfoA(prodcode, NULL,
1786 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1787
1788 /* LastUsedSource and dwOptions has both
1789 * MSISOURCETYPE_NETWORK and MSISOURCETYPE_URL
1790 */
1791 r = pMsiSourceListSetInfoA(prodcode, NULL,
1796 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1797
1798 /* LastUsedSource and dwOptions has no source type */
1799 r = pMsiSourceListSetInfoA(prodcode, NULL,
1803 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1804
1805 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1806
1807 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1808 lstrcatA(keypath, prod_squashed);
1809
1810 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1812
1813 /* user product key exists */
1814 r = pMsiSourceListSetInfoA(prodcode, NULL,
1818 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
1819
1820 res = RegCreateKeyA(userkey, "SourceList", &source);
1821 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1822
1823 /* SourceList key exists, no source type */
1824 r = pMsiSourceListSetInfoA(prodcode, NULL,
1827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1828
1829 /* Media key is created by MsiSourceListSetInfo */
1830 res = RegOpenKeyA(source, "Media", &media);
1831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1832 CHECK_REG_STR(media, "MediaPackage", "path");
1833
1834 /* set the info again */
1835 r = pMsiSourceListSetInfoA(prodcode, NULL,
1838 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1839 CHECK_REG_STR(media, "MediaPackage", "path2");
1840
1841 /* NULL szProperty */
1842 r = pMsiSourceListSetInfoA(prodcode, NULL,
1844 NULL, "path");
1846 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1847
1848 /* empty szProperty */
1849 r = pMsiSourceListSetInfoA(prodcode, NULL,
1851 "", "path");
1853 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
1854
1855 /* NULL szValue */
1856 r = pMsiSourceListSetInfoA(prodcode, NULL,
1860 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
1861
1862 /* empty szValue */
1863 r = pMsiSourceListSetInfoA(prodcode, NULL,
1866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1867 CHECK_REG_STR(media, "MediaPackage", "");
1868
1869 /* INSTALLPROPERTY_MEDIAPACKAGEPATH, MSISOURCETYPE_NETWORK */
1870 r = pMsiSourceListSetInfoA(prodcode, NULL,
1875 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1876
1877 /* INSTALLPROPERTY_MEDIAPACKAGEPATH, MSISOURCETYPE_URL */
1878 r = pMsiSourceListSetInfoA(prodcode, NULL,
1883 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1884
1885 /* INSTALLPROPERTY_DISKPROMPT */
1886 r = pMsiSourceListSetInfoA(prodcode, NULL,
1888 INSTALLPROPERTY_DISKPROMPTA, "prompt");
1889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1890 CHECK_REG_STR(media, "DiskPrompt", "prompt");
1891
1892 /* INSTALLPROPERTY_DISKPROMPT, MSISOURCETYPE_NETWORK */
1893 r = pMsiSourceListSetInfoA(prodcode, NULL,
1896 INSTALLPROPERTY_DISKPROMPTA, "prompt");
1898 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1899
1900 /* INSTALLPROPERTY_DISKPROMPT, MSISOURCETYPE_URL */
1901 r = pMsiSourceListSetInfoA(prodcode, NULL,
1904 INSTALLPROPERTY_DISKPROMPTA, "prompt");
1906 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1907
1908 /* INSTALLPROPERTY_LASTUSEDSOURCE */
1909 r = pMsiSourceListSetInfoA(prodcode, NULL,
1913 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1914
1915 /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_NETWORK */
1916 r = pMsiSourceListSetInfoA(prodcode, NULL,
1920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1921
1922 /* Net key is created by MsiSourceListSetInfo */
1923 res = RegOpenKeyA(source, "Net", &net);
1924 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1925 CHECK_REG_STR(net, "1", "source\\")
1926 CHECK_REG_STR(source, "LastUsedSource", "n;1;source");
1927
1928 /* source has forward slash */
1929 r = pMsiSourceListSetInfoA(prodcode, NULL,
1933 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1934 CHECK_REG_STR(net, "1", "source\\");
1935 CHECK_REG_STR(net, "2", "source/\\");
1936 CHECK_REG_STR(source, "LastUsedSource", "n;2;source/");
1937
1938 /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_URL */
1939 r = pMsiSourceListSetInfoA(prodcode, NULL,
1943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1944
1945 /* URL key is created by MsiSourceListSetInfo */
1946 res = RegOpenKeyA(source, "URL", &url);
1947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
1948 CHECK_REG_STR(url, "1", "source/");
1949 CHECK_REG_STR(source, "LastUsedSource", "u;1;source");
1950
1951 /* source has backslash */
1952 r = pMsiSourceListSetInfoA(prodcode, NULL,
1956 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1957 CHECK_REG_STR(url, "1", "source/");
1958 CHECK_REG_STR(url, "2", "source\\/");
1959 CHECK_REG_STR(source, "LastUsedSource", "u;2;source\\");
1960
1961 /* INSTALLPROPERTY_LASTUSEDSOURCE, MSISOURCETYPE_MEDIA */
1962 r = pMsiSourceListSetInfoA(prodcode, NULL,
1967 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1968
1969 /* INSTALLPROPERTY_PACKAGENAME */
1970 r = pMsiSourceListSetInfoA(prodcode, NULL,
1973 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1974 CHECK_REG_STR(source, "PackageName", "name");
1975
1976 /* INSTALLPROPERTY_PACKAGENAME, MSISOURCETYPE_NETWORK */
1977 r = pMsiSourceListSetInfoA(prodcode, NULL,
1982 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1983
1984 /* INSTALLPROPERTY_PACKAGENAME, MSISOURCETYPE_URL */
1985 r = pMsiSourceListSetInfoA(prodcode, NULL,
1990 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1991
1992 /* INSTALLPROPERTY_LASTUSEDTYPE */
1993 r = pMsiSourceListSetInfoA(prodcode, NULL,
1997 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
1998
1999 /* definitely unknown property */
2000 r = pMsiSourceListSetInfoA(prodcode, NULL,
2002 "unknown", "val");
2004 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2005
2006 RegDeleteValueA(net, "1");
2007 RegDeleteKeyA(net, "");
2009 RegDeleteValueA(url, "1");
2010 RegDeleteKeyA(url, "");
2012 RegDeleteValueA(media, "MediaPackage");
2013 RegDeleteValueA(media, "DiskPrompt");
2014 RegDeleteKeyA(media, "");
2016 RegDeleteValueA(source, "PackageName");
2017 RegDeleteKeyA(source, "");
2019 RegDeleteKeyA(userkey, "");
2020 RegCloseKey(userkey);
2021
2022 /* MSIINSTALLCONTEXT_USERMANAGED */
2023
2024 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2025 lstrcatA(keypath, usersid);
2026 lstrcatA(keypath, "\\Installer\\Products\\");
2027 lstrcatA(keypath, prod_squashed);
2028
2029 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2030 if (res != ERROR_SUCCESS)
2031 {
2032 skip("Product key creation failed with error code %ld\n", res);
2033 goto machine_tests;
2034 }
2035
2036 /* user product key exists */
2037 r = pMsiSourceListSetInfoA(prodcode, NULL,
2041 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2042
2043 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2044 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2045
2046 /* SourceList key exists, no source type */
2047 r = pMsiSourceListSetInfoA(prodcode, NULL,
2050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2051
2052 /* Media key is created by MsiSourceListSetInfo */
2053 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2055 CHECK_REG_STR(media, "MediaPackage", "path");
2056
2057 RegDeleteValueA(media, "MediaPackage");
2058 delete_key(media, "", access);
2060 delete_key(source, "", access);
2062 delete_key(userkey, "", access);
2063 RegCloseKey(userkey);
2064
2065 /* MSIINSTALLCONTEXT_MACHINE */
2066
2067machine_tests:
2068 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2069 lstrcatA(keypath, prod_squashed);
2070
2071 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2072 if (res != ERROR_SUCCESS)
2073 {
2074 skip("Product key creation failed with error code %ld\n", res);
2075 LocalFree(usersid);
2076 return;
2077 }
2078
2079 /* user product key exists */
2080 r = pMsiSourceListSetInfoA(prodcode, NULL,
2084 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2085
2086 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2087 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2088
2089 /* SourceList key exists, no source type */
2090 r = pMsiSourceListSetInfoA(prodcode, NULL,
2093 if (r == ERROR_ACCESS_DENIED)
2094 {
2095 skip("MsiSourceListSetInfo (insufficient privileges)\n");
2096 goto done;
2097 }
2098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2099
2100 /* Media key is created by MsiSourceListSetInfo */
2101 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2103 CHECK_REG_STR(media, "MediaPackage", "path");
2104
2105 /* szUserSid is non-NULL */
2106 r = pMsiSourceListSetInfoA(prodcode, usersid,
2110 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2111 RegDeleteValueA(media, "MediaPackage");
2112 delete_key(media, "", access);
2114
2115done:
2116 delete_key(source, "", access);
2118 delete_key(prodkey, "", access);
2119 RegCloseKey(prodkey);
2120 LocalFree(usersid);
2121}
2122
2124{
2125 CHAR prodcode[MAX_PATH];
2126 CHAR prod_squashed[MAX_PATH];
2127 CHAR keypath[MAX_PATH*2];
2128 HKEY prodkey, userkey;
2129 HKEY media, source;
2130 LPSTR usersid;
2131 LONG res;
2132 UINT r;
2134
2135 if (!pMsiSourceListAddMediaDiskA)
2136 {
2137 win_skip("MsiSourceListAddMediaDiskA is not available\n");
2138 return;
2139 }
2140 if (is_process_limited())
2141 {
2142 skip("process is limited\n");
2143 return;
2144 }
2145
2146 create_test_guid(prodcode, prod_squashed);
2147 if (!(usersid = get_user_sid()))
2148 {
2149 skip("User SID not available -> skipping MsiSourceListAddMediaDiskA tests\n");
2150 return;
2151 }
2152
2153 if (is_wow64)
2155
2156 /* GetLastError is not set by the function */
2157
2158 /* NULL szProductCodeOrPatchCode */
2159 r = pMsiSourceListAddMediaDiskA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2160 MSICODE_PRODUCT, 1, "label", "prompt");
2162 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2163
2164 /* empty szProductCodeOrPatchCode */
2165 r = pMsiSourceListAddMediaDiskA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2166 MSICODE_PRODUCT, 1, "label", "prompt");
2168 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2169
2170 /* garbage szProductCodeOrPatchCode */
2171 r = pMsiSourceListAddMediaDiskA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2172 MSICODE_PRODUCT, 1, "label", "prompt");
2174 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2175
2176 /* guid without brackets */
2177 r = pMsiSourceListAddMediaDiskA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
2179 MSICODE_PRODUCT, 1, "label", "prompt");
2181 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2182
2183 /* guid with brackets */
2184 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2186 MSICODE_PRODUCT, 1, "label", "prompt");
2188 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2189
2190 /* dwOptions has MSISOURCETYPE_NETWORK */
2191 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2194 1, "label", "prompt");
2196 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2197
2198 /* dwOptions has MSISOURCETYPE_URL */
2199 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2202 1, "label", "prompt");
2204 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2205
2206 /* dwOptions has MSISOURCETYPE_MEDIA */
2207 r = pMsiSourceListAddMediaDiskA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2210 1, "label", "prompt");
2212 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2213
2214 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2215
2216 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2217 lstrcatA(keypath, prod_squashed);
2218
2219 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2221
2222 /* user product key exists */
2223 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2225 MSICODE_PRODUCT, 1, "label", "prompt");
2227 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2228
2229 res = RegCreateKeyA(userkey, "SourceList", &source);
2230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2231
2232 /* SourceList key exists */
2233 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2235 MSICODE_PRODUCT, 1, "label", "prompt");
2236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2237
2238 /* Media subkey is created by MsiSourceListAddMediaDisk */
2239 res = RegOpenKeyA(source, "Media", &media);
2240 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2241
2242 CHECK_REG_STR(media, "1", "label;prompt");
2243
2244 /* dwDiskId is random */
2245 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2247 MSICODE_PRODUCT, 42, "label42", "prompt42");
2248 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2249
2250 CHECK_REG_STR(media, "1", "label;prompt");
2251 CHECK_REG_STR(media, "42", "label42;prompt42");
2252
2253 /* dwDiskId is 0 */
2254 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2256 MSICODE_PRODUCT, 0, "label0", "prompt0");
2257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2258
2259 CHECK_REG_STR(media, "0", "label0;prompt0");
2260 CHECK_REG_STR(media, "1", "label;prompt");
2261 CHECK_REG_STR(media, "42", "label42;prompt42");
2262
2263 /* dwDiskId is < 0 */
2264 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2266 MSICODE_PRODUCT, -1, "label-1", "prompt-1");
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", "label;prompt");
2272 CHECK_REG_STR(media, "42", "label42;prompt42");
2273
2274 /* update dwDiskId 1 */
2275 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2277 MSICODE_PRODUCT, 1, "newlabel", "newprompt");
2278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2279
2280 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2281 CHECK_REG_STR(media, "0", "label0;prompt0");
2282 CHECK_REG_STR(media, "1", "newlabel;newprompt");
2283 CHECK_REG_STR(media, "42", "label42;prompt42");
2284
2285 /* update dwDiskId 1, szPrompt is NULL */
2286 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2288 MSICODE_PRODUCT, 1, "etiqueta", NULL);
2289 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2290
2291 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2292 CHECK_REG_STR(media, "0", "label0;prompt0");
2293 CHECK_REG_STR(media, "1", "etiqueta;");
2294 CHECK_REG_STR(media, "42", "label42;prompt42");
2295
2296 /* update dwDiskId 1, szPrompt is empty */
2297 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2299 MSICODE_PRODUCT, 1, "etikett", "");
2301 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2302
2303 /* update dwDiskId 1, szVolumeLabel is NULL */
2304 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2306 MSICODE_PRODUCT, 1, NULL, "provocar");
2307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2308
2309 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2310 CHECK_REG_STR(media, "0", "label0;prompt0");
2311 CHECK_REG_STR(media, "1", ";provocar");
2312 CHECK_REG_STR(media, "42", "label42;prompt42");
2313
2314 /* update dwDiskId 1, szVolumeLabel is empty */
2315 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2317 MSICODE_PRODUCT, 1, "", "provoquer");
2319 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2320
2321 /* szUserSid is NULL */
2322 r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
2324 MSICODE_PRODUCT, 1, NULL, "provoquer");
2325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2326
2327 CHECK_REG_STR(media, "-1", "label-1;prompt-1");
2328 CHECK_REG_STR(media, "0", "label0;prompt0");
2329 CHECK_REG_STR(media, "1", ";provoquer");
2330 CHECK_REG_STR(media, "42", "label42;prompt42");
2331
2332 RegDeleteValueA(media, "-1");
2333 RegDeleteValueA(media, "0");
2334 RegDeleteValueA(media, "1");
2335 RegDeleteValueA(media, "42");
2336 RegDeleteKeyA(media, "");
2338 RegDeleteKeyA(source, "");
2340 RegDeleteKeyA(userkey, "");
2341 RegCloseKey(userkey);
2342
2343 /* MSIINSTALLCONTEXT_USERMANAGED */
2344
2345 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2346 lstrcatA(keypath, usersid);
2347 lstrcatA(keypath, "\\Installer\\Products\\");
2348 lstrcatA(keypath, prod_squashed);
2349
2350 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2351 if (res != ERROR_SUCCESS)
2352 {
2353 skip("Product key creation failed with error code %ld\n", res);
2354 goto machine_tests;
2355 }
2356
2357 /* user product key exists */
2358 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2360 MSICODE_PRODUCT, 1, "label", "prompt");
2362 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2363
2364 res = RegCreateKeyExA(userkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2365 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2366
2367 /* SourceList key exists */
2368 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2370 MSICODE_PRODUCT, 1, "label", "prompt");
2371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2372
2373 /* Media subkey is created by MsiSourceListAddMediaDisk */
2374 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2375 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2376
2377 CHECK_REG_STR(media, "1", "label;prompt");
2378
2379 RegDeleteValueA(media, "1");
2380 delete_key(media, "", access);
2382 delete_key(source, "", access);
2384 delete_key(userkey, "", access);
2385 RegCloseKey(userkey);
2386
2387 /* MSIINSTALLCONTEXT_MACHINE */
2388
2389machine_tests:
2390 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2391 lstrcatA(keypath, prod_squashed);
2392
2393 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2394 if (res != ERROR_SUCCESS)
2395 {
2396 skip("Product key creation failed with error code %ld\n", res);
2397 LocalFree(usersid);
2398 return;
2399 }
2400
2401 /* machine product key exists */
2402 r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
2404 MSICODE_PRODUCT, 1, "label", "prompt");
2406 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2407
2408 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
2409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2410
2411 /* SourceList key exists */
2412 r = pMsiSourceListAddMediaDiskA(prodcode, NULL,
2414 MSICODE_PRODUCT, 1, "label", "prompt");
2415 if (r == ERROR_ACCESS_DENIED)
2416 {
2417 skip("MsiSourceListAddMediaDisk (insufficient privileges)\n");
2418 goto done;
2419 }
2420 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2421
2422 /* Media subkey is created by MsiSourceListAddMediaDisk */
2423 res = RegOpenKeyExA(source, "Media", 0, access, &media);
2424 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2425
2426 CHECK_REG_STR(media, "1", "label;prompt");
2427
2428 /* szUserSid is non-NULL */
2429 r = pMsiSourceListAddMediaDiskA(prodcode, usersid,
2431 MSICODE_PRODUCT, 1, "label", "prompt");
2433 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2434 RegDeleteValueA(media, "1");
2435 delete_key(media, "", access);
2437
2438done:
2439 delete_key(source, "", access);
2441 delete_key(prodkey, "", access);
2442 RegCloseKey(prodkey);
2443 LocalFree(usersid);
2444}
2445
2447{
2448 CHAR prodcode[MAX_PATH];
2449 CHAR prod_squashed[MAX_PATH];
2450 CHAR keypath[MAX_PATH*2];
2452 CHAR prompt[MAX_PATH];
2453 HKEY prodkey, userkey, media, source;
2454 DWORD labelsz, promptsz, val, id;
2455 LPSTR usersid;
2456 LONG res;
2457 UINT r;
2459
2460 if (!pMsiSourceListEnumMediaDisksA)
2461 {
2462 win_skip("MsiSourceListEnumMediaDisksA is not available\n");
2463 return;
2464 }
2465
2466 create_test_guid(prodcode, prod_squashed);
2467 if (!(usersid = get_user_sid()))
2468 {
2469 skip("User SID not available -> skipping MsiSourceListEnumMediaDisksA tests\n");
2470 return;
2471 }
2472
2473 if (is_wow64)
2475
2476 /* GetLastError is not set by the function */
2477
2478 /* NULL szProductCodeOrPatchCode */
2479 labelsz = sizeof(label);
2480 promptsz = sizeof(prompt);
2481 r = pMsiSourceListEnumMediaDisksA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2482 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2483 prompt, &promptsz);
2485 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2486
2487 /* empty szProductCodeOrPatchCode */
2488 labelsz = sizeof(label);
2489 promptsz = sizeof(prompt);
2490 r = pMsiSourceListEnumMediaDisksA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2491 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2492 prompt, &promptsz);
2494 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2495
2496 /* garbage szProductCodeOrPatchCode */
2497 labelsz = sizeof(label);
2498 promptsz = sizeof(prompt);
2499 r = pMsiSourceListEnumMediaDisksA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2500 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2501 prompt, &promptsz);
2503 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2504
2505 /* guid without brackets */
2506 labelsz = sizeof(label);
2507 promptsz = sizeof(prompt);
2508 r = pMsiSourceListEnumMediaDisksA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA",
2510 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2511 prompt, &promptsz);
2513 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2514
2515 /* guid with brackets */
2516 labelsz = sizeof(label);
2517 promptsz = sizeof(prompt);
2518 r = pMsiSourceListEnumMediaDisksA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}",
2520 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2521 prompt, &promptsz);
2523 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2524
2525 /* dwOptions has MSISOURCETYPE_NETWORK */
2526 labelsz = sizeof(label);
2527 promptsz = sizeof(prompt);
2528 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2530 0, &id, label, &labelsz,
2531 prompt, &promptsz);
2533 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2534
2535 /* dwOptions has MSISOURCETYPE_URL */
2536 labelsz = sizeof(label);
2537 promptsz = sizeof(prompt);
2538 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2540 0, &id, label, &labelsz,
2541 prompt, &promptsz);
2543 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2544
2545 /* dwIndex is non-zero */
2546 labelsz = sizeof(label);
2547 promptsz = sizeof(prompt);
2548 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2549 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2550 prompt, &promptsz);
2552 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2553
2554 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2555
2556 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2557 lstrcatA(keypath, prod_squashed);
2558
2559 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2560 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2561
2562 /* user product key exists */
2563 labelsz = sizeof(label);
2564 promptsz = sizeof(prompt);
2565 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2566 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2567 prompt, &promptsz);
2569 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
2570
2571 res = RegCreateKeyA(userkey, "SourceList", &source);
2572 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2573
2574 /* SourceList key exists */
2575 id = 0xbeef;
2576 lstrcpyA(label, "aaa");
2577 labelsz = 0xdeadbeef;
2578 lstrcpyA(prompt, "bbb");
2579 promptsz = 0xdeadbeef;
2580 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2581 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2582 prompt, &promptsz);
2584 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2585 ok(id == 0xbeef, "Expected 0xbeef, got %lu\n", id);
2586 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2587 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", labelsz);
2588 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2589 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", promptsz);
2590
2591 res = RegCreateKeyA(source, "Media", &media);
2592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2593
2594 /* Media key exists */
2595 id = 0xbeef;
2596 lstrcpyA(label, "aaa");
2597 labelsz = 0xdeadbeef;
2598 lstrcpyA(prompt, "bbb");
2599 promptsz = 0xdeadbeef;
2600 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2601 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2602 prompt, &promptsz);
2604 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2605 ok(id == 0xbeef, "Expected 0xbeef, got %lu\n", id);
2606 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2607 ok(labelsz == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", labelsz);
2608 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2609 ok(promptsz == 0xdeadbeef, "Expected 0xdeadbeef, got %lu\n", promptsz);
2610
2611 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label;prompt", 13);
2612 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2613
2614 /* disk exists */
2615 id = 0;
2616 lstrcpyA(label, "aaa");
2617 labelsz = MAX_PATH;
2618 lstrcpyA(prompt, "bbb");
2619 promptsz = MAX_PATH;
2620 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2621 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2622 prompt, &promptsz);
2623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2624 ok(id == 1, "Expected 1, got %lu\n", id);
2625 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2626 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2627 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2628 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2629
2630 res = RegSetValueExA(media, "2", 0, REG_SZ, (LPBYTE)"one;two", 8);
2631 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2632
2633 /* now disk 2 exists, get the sizes */
2634 id = 0;
2635 labelsz = MAX_PATH;
2636 promptsz = MAX_PATH;
2637 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2638 MSICODE_PRODUCT, 1, &id, NULL, &labelsz,
2639 NULL, &promptsz);
2641 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2642 if (r == ERROR_SUCCESS)
2643 {
2644 ok(id == 2, "Expected 2, got %lu\n", id);
2645 ok(labelsz == 3, "Expected 3, got %lu\n", labelsz);
2646 ok(promptsz == 3, "Expected 3, got %lu\n", promptsz);
2647 }
2648
2649 /* now fill in the values */
2650 id = 0xbeef;
2651 lstrcpyA(label, "aaa");
2652 labelsz = MAX_PATH;
2653 lstrcpyA(prompt, "bbb");
2654 promptsz = MAX_PATH;
2655 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2656 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2657 prompt, &promptsz);
2659 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2660 if (r == ERROR_SUCCESS)
2661 {
2662 ok(id == 2, "Expected 2, got %lu\n", id);
2663 ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
2664 ok(labelsz == 3, "Expected 3, got %lu\n", labelsz);
2665 ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
2666 ok(promptsz == 3, "Expected 3, got %lu\n", promptsz);
2667 }
2668 else if (r == ERROR_INVALID_PARAMETER)
2669 {
2670 ok(id == 0xbeef, "Expected 0xbeef, got %lu\n", id);
2671 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2672 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", labelsz);
2673 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2674 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", promptsz);
2675 }
2676
2677 res = RegSetValueExA(media, "4", 0, REG_SZ, (LPBYTE)"three;four", 11);
2678 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2679
2680 /* disks 1, 2, 4 exist, reset the enumeration */
2681 id = 0;
2682 lstrcpyA(label, "aaa");
2683 labelsz = MAX_PATH;
2684 lstrcpyA(prompt, "bbb");
2685 promptsz = MAX_PATH;
2686 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2687 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2688 prompt, &promptsz);
2689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2690 ok(id == 1, "Expected 1, got %lu\n", id);
2691 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2692 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2693 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2694 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2695
2696 /* disks 1, 2, 4 exist, index 1 */
2697 id = 0;
2698 lstrcpyA(label, "aaa");
2699 labelsz = MAX_PATH;
2700 lstrcpyA(prompt, "bbb");
2701 promptsz = MAX_PATH;
2702 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2703 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2704 prompt, &promptsz);
2705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2706 ok(id == 2, "Expected 2, got %lu\n", id);
2707 ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
2708 ok(labelsz == 3, "Expected 3, got %lu\n", labelsz);
2709 ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
2710 ok(promptsz == 3, "Expected 3, got %lu\n", promptsz);
2711
2712 /* disks 1, 2, 4 exist, index 2 */
2713 id = 0;
2714 lstrcpyA(label, "aaa");
2715 labelsz = MAX_PATH;
2716 lstrcpyA(prompt, "bbb");
2717 promptsz = MAX_PATH;
2718 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2719 MSICODE_PRODUCT, 2, &id, label, &labelsz,
2720 prompt, &promptsz);
2721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2722 ok(id == 4, "Expected 4, got %lu\n", id);
2723 ok(!lstrcmpA(label, "three"), "Expected \"three\", got \"%s\"\n", label);
2724 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2725 ok(!lstrcmpA(prompt, "four"), "Expected \"four\", got \"%s\"\n", prompt);
2726 ok(promptsz == 4, "Expected 4, got %lu\n", promptsz);
2727
2728 /* disks 1, 2, 4 exist, index 3, invalid */
2729 id = 0xbeef;
2730 lstrcpyA(label, "aaa");
2731 labelsz = MAX_PATH;
2732 lstrcpyA(prompt, "bbb");
2733 promptsz = MAX_PATH;
2734 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2735 MSICODE_PRODUCT, 3, &id, label, &labelsz,
2736 prompt, &promptsz);
2738 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2739 ok(id == 0xbeef, "Expected 0xbeef, got %lu\n", id);
2740 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2741 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", labelsz);
2742 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2743 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", promptsz);
2744
2745 /* disks 1, 2, 4 exist, reset the enumeration */
2746 id = 0;
2747 lstrcpyA(label, "aaa");
2748 labelsz = MAX_PATH;
2749 lstrcpyA(prompt, "bbb");
2750 promptsz = MAX_PATH;
2751 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2752 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2753 prompt, &promptsz);
2754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2755 ok(id == 1, "Expected 1, got %lu\n", id);
2756 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2757 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2758 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2759 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2760
2761 /* try index 0 again */
2762 id = 0;
2763 lstrcpyA(label, "aaa");
2764 labelsz = MAX_PATH;
2765 lstrcpyA(prompt, "bbb");
2766 promptsz = MAX_PATH;
2767 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2768 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2769 prompt, &promptsz);
2770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2771 ok(id == 1, "Expected 1, got %lu\n", id);
2772 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2773 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2774 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2775 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2776
2777 /* jump to index 2 */
2778 id = 0xbeef;
2779 lstrcpyA(label, "aaa");
2780 labelsz = MAX_PATH;
2781 lstrcpyA(prompt, "bbb");
2782 promptsz = MAX_PATH;
2783 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2784 MSICODE_PRODUCT, 2, &id, label, &labelsz,
2785 prompt, &promptsz);
2786 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2787 ok(id == 0xbeef, "Expected 0xbeef, got %lu\n", id);
2788 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2789 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", labelsz);
2790 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2791 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", promptsz);
2792
2793 /* after error, try index 1 */
2794 id = 0xbeef;
2795 lstrcpyA(label, "aaa");
2796 labelsz = MAX_PATH;
2797 lstrcpyA(prompt, "bbb");
2798 promptsz = MAX_PATH;
2799 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2800 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2801 prompt, &promptsz);
2802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2803 ok(id == 2, "Expected 2, got %lu\n", id);
2804 ok(!lstrcmpA(label, "one"), "Expected \"one\", got \"%s\"\n", label);
2805 ok(labelsz == 3, "Expected 3, got %lu\n", labelsz);
2806 ok(!lstrcmpA(prompt, "two"), "Expected \"two\", got \"%s\"\n", prompt);
2807 ok(promptsz == 3, "Expected 3, got %lu\n", promptsz);
2808
2809 /* try index 1 again */
2810 id = 0xbeef;
2811 lstrcpyA(label, "aaa");
2812 labelsz = MAX_PATH;
2813 lstrcpyA(prompt, "bbb");
2814 promptsz = MAX_PATH;
2815 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2816 MSICODE_PRODUCT, 1, &id, label, &labelsz,
2817 prompt, &promptsz);
2818 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2819 ok(id == 0xbeef, "Expected 0xbeef, got %lu\n", id);
2820 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2821 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", labelsz);
2822 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2823 ok(promptsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", promptsz);
2824
2825 /* NULL pdwDiskId */
2826 lstrcpyA(label, "aaa");
2827 labelsz = MAX_PATH;
2828 lstrcpyA(prompt, "bbb");
2829 promptsz = MAX_PATH;
2830 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2831 MSICODE_PRODUCT, 0, NULL, label, &labelsz,
2832 prompt, &promptsz);
2833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2834 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2835 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2836 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2837 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2838
2839 /* szVolumeLabel is NULL */
2840 id = 0;
2841 labelsz = MAX_PATH;
2842 lstrcpyA(prompt, "bbb");
2843 promptsz = MAX_PATH;
2844 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2845 MSICODE_PRODUCT, 0, &id, NULL, &labelsz,
2846 prompt, &promptsz);
2848 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2849 if (r == ERROR_SUCCESS)
2850 {
2851 ok(id == 1, "Expected 1, got %lu\n", id);
2852 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2853 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2854 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2855 }
2856
2857 /* szVolumeLabel and pcchVolumeLabel are NULL */
2858 id = 0;
2859 lstrcpyA(prompt, "bbb");
2860 promptsz = MAX_PATH;
2861 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2862 MSICODE_PRODUCT, 0, &id, NULL, NULL,
2863 prompt, &promptsz);
2864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2865 ok(id == 1, "Expected 1, got %lu\n", id);
2866 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2867 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2868
2869 /* szVolumeLabel is non-NULL while pcchVolumeLabel is NULL */
2870 id = 0xbeef;
2871 lstrcpyA(label, "aaa");
2872 lstrcpyA(prompt, "bbb");
2873 promptsz = MAX_PATH;
2874 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2875 MSICODE_PRODUCT, 0, &id, label, NULL,
2876 prompt, &promptsz);
2878 "Expected ERROR_SUCCESS or ERROR_INVALID_PARAMETER, got %d\n", r);
2879 if (r == ERROR_SUCCESS)
2880 {
2881 ok(id == 1, "Expected 1, got %lu\n", id);
2882 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2883 ok(!lstrcmpA(prompt, "prompt"), "Expected \"prompt\", got \"%s\"\n", prompt);
2884 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2885 }
2886
2887 /* szDiskPrompt is NULL */
2888 id = 0;
2889 lstrcpyA(label, "aaa");
2890 labelsz = MAX_PATH;
2891 promptsz = MAX_PATH;
2892 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2893 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2894 NULL, &promptsz);
2895 ok(r == ERROR_SUCCESS || r == ERROR_INVALID_PARAMETER, "Expected ERROR_SUCCESS, got %d\n", r);
2896 if (r == ERROR_SUCCESS)
2897 {
2898 ok(id == 1, "Expected 1, got %lu\n", id);
2899 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2900 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2901 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2902 }
2903
2904 /* szDiskPrompt and pcchDiskPrompt are NULL */
2905 id = 0;
2906 lstrcpyA(label, "aaa");
2907 labelsz = MAX_PATH;
2908 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2909 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2910 NULL, NULL);
2911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2912 ok(id == 1, "Expected 1, got %lu\n", id);
2913 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2914 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2915
2916 /* szDiskPrompt is non-NULL while pcchDiskPrompt is NULL */
2917 id = 0xbeef;
2918 lstrcpyA(label, "aaa");
2919 labelsz = MAX_PATH;
2920 lstrcpyA(prompt, "bbb");
2921 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2922 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2923 prompt, NULL);
2925 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2926 ok(id == 0xbeef, "Expected 0xbeef, got %lu\n", id);
2927 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2928 ok(labelsz == MAX_PATH, "Expected MAX_PATH, got %lu\n", labelsz);
2929 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2930
2931 /* pcchVolumeLabel, szDiskPrompt and pcchDiskPrompt are NULL */
2932 id = 0;
2933 lstrcpyA(label, "aaa");
2934 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2935 MSICODE_PRODUCT, 0, &id, label, NULL,
2936 NULL, NULL);
2937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2938 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2939 ok(id == 1, "Expected 1, got %lu\n", id);
2940
2941 /* szVolumeLabel, pcchVolumeLabel, szDiskPrompt and pcchDiskPrompt are NULL */
2942 id = 0;
2943 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2944 MSICODE_PRODUCT, 0, &id, NULL, NULL,
2945 NULL, NULL);
2946 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2947 ok(id == 1, "Expected 1, got %lu\n", id);
2948
2949 /* pcchVolumeLabel is exactly 5 */
2950 lstrcpyA(label, "aaa");
2951 labelsz = 5;
2952 lstrcpyA(prompt, "bbb");
2953 promptsz = MAX_PATH;
2954 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2955 MSICODE_PRODUCT, 0, NULL, label, &labelsz,
2956 prompt, &promptsz);
2957 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2958 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2959 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2960 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2961 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2962
2963 /* pcchDiskPrompt is exactly 6 */
2964 lstrcpyA(label, "aaa");
2965 labelsz = MAX_PATH;
2966 lstrcpyA(prompt, "bbb");
2967 promptsz = 6;
2968 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2969 MSICODE_PRODUCT, 0, NULL, label, &labelsz,
2970 prompt, &promptsz);
2971 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2972 ok(!lstrcmpA(label, "aaa"), "Expected \"aaa\", got \"%s\"\n", label);
2973 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2974 ok(!lstrcmpA(prompt, "bbb"), "Expected \"bbb\", got \"%s\"\n", prompt);
2975 ok(promptsz == 6, "Expected 6, got %lu\n", promptsz);
2976
2977 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label", 13);
2978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2979
2980 /* no semicolon */
2981 id = 0;
2982 lstrcpyA(label, "aaa");
2983 labelsz = MAX_PATH;
2984 lstrcpyA(prompt, "bbb");
2985 promptsz = MAX_PATH;
2986 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
2987 MSICODE_PRODUCT, 0, &id, label, &labelsz,
2988 prompt, &promptsz);
2989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2990 ok(id == 1, "Expected 1, got %lu\n", id);
2991 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
2992 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
2993 ok(!lstrcmpA(prompt, "label"), "Expected \"label\", got \"%s\"\n", prompt);
2994 ok(promptsz == 5, "Expected 5, got %lu\n", promptsz);
2995
2996 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)"label;", 13);
2997 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2998
2999 /* semicolon, no disk prompt */
3000 id = 0;
3001 lstrcpyA(label, "aaa");
3002 labelsz = MAX_PATH;
3003 lstrcpyA(prompt, "bbb");
3004 promptsz = MAX_PATH;
3005 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3006 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3007 prompt, &promptsz);
3008 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3009 ok(id == 1, "Expected 1, got %lu\n", id);
3010 ok(!lstrcmpA(label, "label"), "Expected \"label\", got \"%s\"\n", label);
3011 ok(labelsz == 5, "Expected 5, got %lu\n", labelsz);
3012 ok(!lstrcmpA(prompt, ""), "Expected \"\", got \"%s\"\n", prompt);
3013 ok(promptsz == 0, "Expected 0, got %lu\n", promptsz);
3014
3015 res = RegSetValueExA(media, "1", 0, REG_SZ, (LPBYTE)";prompt", 13);
3016 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3017
3018 /* semicolon, label doesn't exist */
3019 id = 0;
3020 lstrcpyA(label, "aaa");
3021 labelsz = MAX_PATH;
3022 lstrcpyA(prompt, "bbb");
3023 promptsz = MAX_PATH;
3024 r = pMsiSourceListEnumMediaDisksA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3025 MSICODE_PRODUCT, 0, &id, label, &labelsz,
3026