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