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