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