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