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