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