1 /* 2 * DLL for testing type 1 custom actions 3 * 4 * Copyright 2017 Zebediah Figura 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 #include <stdio.h> 23 24 #include <windef.h> 25 #include <winbase.h> 26 #include <winsvc.h> 27 #include <odbcinst.h> 28 #define COBJMACROS 29 #include <shlobj.h> 30 #include <msxml.h> 31 #include <msi.h> 32 #include <msiquery.h> 33 #include <msidefs.h> 34 35 static int todo_level, todo_do_loop; 36 37 static void WINAPIV ok_(MSIHANDLE hinst, int todo, const char *file, int line, int condition, const char *msg, ...) 38 { 39 static char buffer[2000]; 40 MSIHANDLE record; 41 va_list valist; 42 43 va_start(valist, msg); 44 vsprintf(buffer, msg, valist); 45 va_end(valist); 46 47 record = MsiCreateRecord(5); 48 MsiRecordSetInteger(record, 1, todo); 49 MsiRecordSetStringA(record, 2, file); 50 MsiRecordSetInteger(record, 3, line); 51 MsiRecordSetInteger(record, 4, condition); 52 MsiRecordSetStringA(record, 5, buffer); 53 MsiProcessMessage(hinst, INSTALLMESSAGE_USER, record); 54 MsiCloseHandle(record); 55 } 56 57 static void winetest_start_todo( int is_todo ) 58 { 59 todo_level = (todo_level << 1) | (is_todo != 0); 60 todo_do_loop=1; 61 } 62 63 static int winetest_loop_todo(void) 64 { 65 int do_loop=todo_do_loop; 66 todo_do_loop=0; 67 return do_loop; 68 } 69 70 static void winetest_end_todo(void) 71 { 72 todo_level >>= 1; 73 } 74 75 #define ok(hinst, condition, ...) ok_(hinst, todo_level, __FILE__, __LINE__, condition, __VA_ARGS__) 76 #define todo_wine_if(is_todo) for (winetest_start_todo(is_todo); \ 77 winetest_loop_todo(); \ 78 winetest_end_todo()) 79 #define todo_wine todo_wine_if(1) 80 81 static const char *dbgstr_w(WCHAR *str) 82 { 83 static char buffer[300], *p; 84 85 if (!str) return "(null)"; 86 87 p = buffer; 88 *p++ = 'L'; 89 *p++ = '"'; 90 while ((*p++ = *str++)); 91 *p++ = '"'; 92 *p++ = 0; 93 94 return buffer; 95 } 96 97 static void check_prop(MSIHANDLE hinst, const char *prop, const char *expect) 98 { 99 char buffer[10] = "x"; 100 DWORD sz = sizeof(buffer); 101 UINT r = MsiGetPropertyA(hinst, prop, buffer, &sz); 102 ok(hinst, !r, "'%s': got %u\n", prop, r); 103 ok(hinst, sz == strlen(buffer), "'%s': expected %u, got %u\n", prop, strlen(buffer), sz); 104 ok(hinst, !strcmp(buffer, expect), "expected '%s', got '%s'\n", expect, buffer); 105 } 106 107 static void test_props(MSIHANDLE hinst) 108 { 109 char buffer[10]; 110 WCHAR bufferW[10]; 111 DWORD sz; 112 UINT r; 113 114 /* test invalid values */ 115 r = MsiGetPropertyA(hinst, NULL, NULL, NULL); 116 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 117 118 r = MsiGetPropertyA(hinst, "boo", NULL, NULL); 119 ok(hinst, !r, "got %u\n", r); 120 121 r = MsiGetPropertyA(hinst, "boo", buffer, NULL ); 122 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 123 124 sz = 0; 125 r = MsiGetPropertyA(hinst, "boo", NULL, &sz); 126 ok(hinst, !r, "got %u\n", r); 127 ok(hinst, sz == 0, "got size %u\n", sz); 128 129 sz = 0; 130 strcpy(buffer,"x"); 131 r = MsiGetPropertyA(hinst, "boo", buffer, &sz); 132 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 133 ok(hinst, !strcmp(buffer, "x"), "got \"%s\"\n", buffer); 134 ok(hinst, sz == 0, "got size %u\n", sz); 135 136 sz = 1; 137 strcpy(buffer,"x"); 138 r = MsiGetPropertyA(hinst, "boo", buffer, &sz); 139 ok(hinst, !r, "got %u\n", r); 140 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 141 ok(hinst, sz == 0, "got size %u\n", sz); 142 143 /* set the property to something */ 144 r = MsiSetPropertyA(hinst, NULL, NULL); 145 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 146 147 r = MsiSetPropertyA(hinst, "", NULL); 148 ok(hinst, !r, "got %u\n", r); 149 150 r = MsiSetPropertyA(hinst, "", "asdf"); 151 ok(hinst, r == ERROR_FUNCTION_FAILED, "got %u\n", r); 152 153 r = MsiSetPropertyA(hinst, "=", "asdf"); 154 ok(hinst, !r, "got %u\n", r); 155 check_prop(hinst, "=", "asdf"); 156 157 r = MsiSetPropertyA(hinst, " ", "asdf"); 158 ok(hinst, !r, "got %u\n", r); 159 check_prop(hinst, " ", "asdf"); 160 161 r = MsiSetPropertyA(hinst, "'", "asdf"); 162 ok(hinst, !r, "got %u\n", r); 163 check_prop(hinst, "'", "asdf"); 164 165 r = MsiSetPropertyA(hinst, "boo", NULL); 166 ok(hinst, !r, "got %u\n", r); 167 check_prop(hinst, "boo", ""); 168 169 r = MsiSetPropertyA(hinst, "boo", ""); 170 ok(hinst, !r, "got %u\n", r); 171 check_prop(hinst, "boo", ""); 172 173 r = MsiSetPropertyA(hinst, "boo", "xyz"); 174 ok(hinst, !r, "got %u\n", r); 175 check_prop(hinst, "boo", "xyz"); 176 177 r = MsiGetPropertyA(hinst, "boo", NULL, NULL); 178 ok(hinst, !r, "got %u\n", r); 179 180 r = MsiGetPropertyA(hinst, "boo", buffer, NULL ); 181 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 182 183 /* Returned size is in bytes, not chars, but only for custom actions. 184 * Seems to be a casualty of RPC... */ 185 186 sz = 0; 187 r = MsiGetPropertyA(hinst, "boo", NULL, &sz); 188 ok(hinst, !r, "got %u\n", r); 189 ok(hinst, sz == 6, "got size %u\n", sz); 190 191 sz = 0; 192 strcpy(buffer,"q"); 193 r = MsiGetPropertyA(hinst, "boo", buffer, &sz); 194 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 195 ok(hinst, !strcmp(buffer, "q"), "got \"%s\"\n", buffer); 196 ok(hinst, sz == 6, "got size %u\n", sz); 197 198 sz = 1; 199 strcpy(buffer,"x"); 200 r = MsiGetPropertyA(hinst, "boo", buffer, &sz); 201 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 202 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 203 ok(hinst, sz == 6, "got size %u\n", sz); 204 205 sz = 3; 206 strcpy(buffer,"x"); 207 r = MsiGetPropertyA(hinst, "boo", buffer, &sz); 208 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 209 ok(hinst, !strcmp(buffer, "xy"), "got \"%s\"\n", buffer); 210 ok(hinst, sz == 6, "got size %u\n", sz); 211 212 sz = 4; 213 strcpy(buffer,"x"); 214 r = MsiGetPropertyA(hinst, "boo", buffer, &sz); 215 ok(hinst, !r, "got %u\n", r); 216 ok(hinst, !strcmp(buffer, "xyz"), "got \"%s\"\n", buffer); 217 ok(hinst, sz == 3, "got size %u\n", sz); 218 219 r = MsiGetPropertyW(hinst, L"boo", NULL, NULL); 220 ok(hinst, !r, "got %u\n", r); 221 222 r = MsiGetPropertyW(hinst, L"boo", bufferW, NULL ); 223 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 224 225 sz = 0; 226 r = MsiGetPropertyW(hinst, L"boo", NULL, &sz); 227 ok(hinst, !r, "got %u\n", r); 228 ok(hinst, sz == 3, "got size %u\n", sz); 229 230 sz = 0; 231 lstrcpyW(bufferW, L"boo"); 232 r = MsiGetPropertyW(hinst, L"boo", bufferW, &sz); 233 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 234 ok(hinst, !lstrcmpW(bufferW, L"boo"), "got %s\n", dbgstr_w(bufferW)); 235 ok(hinst, sz == 3, "got size %u\n", sz); 236 237 sz = 1; 238 lstrcpyW(bufferW, L"boo"); 239 r = MsiGetPropertyW(hinst, L"boo", bufferW, &sz); 240 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 241 ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW)); 242 ok(hinst, sz == 3, "got size %u\n", sz); 243 244 sz = 3; 245 lstrcpyW(bufferW, L"boo"); 246 r = MsiGetPropertyW(hinst, L"boo", bufferW, &sz); 247 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 248 ok(hinst, !lstrcmpW(bufferW, L"xy"), "got %s\n", dbgstr_w(bufferW)); 249 ok(hinst, sz == 3, "got size %u\n", sz); 250 251 sz = 4; 252 lstrcpyW(bufferW, L"boo"); 253 r = MsiGetPropertyW(hinst, L"boo", bufferW, &sz); 254 ok(hinst, !r, "got %u\n", r); 255 ok(hinst, !lstrcmpW(bufferW, L"xyz"), "got %s\n", dbgstr_w(bufferW)); 256 ok(hinst, sz == 3, "got size %u\n", sz); 257 258 r = MsiSetPropertyA(hinst, "boo", NULL); 259 ok(hinst, !r, "got %u\n", r); 260 check_prop(hinst, "boo", ""); 261 262 sz = 0; 263 r = MsiGetPropertyA(hinst, "embednullprop", NULL, &sz); 264 ok(hinst, !r, "got %u\n", r); 265 ok(hinst, sz == 6, "got size %u\n", sz); 266 267 sz = 4; 268 memset(buffer, 0xcc, sizeof(buffer)); 269 r = MsiGetPropertyA(hinst, "embednullprop", buffer, &sz); 270 ok(hinst, !r, "got %u\n", r); 271 ok(hinst, sz == 3, "got size %u\n", sz); 272 ok(hinst, !memcmp(buffer, "a\0\0\0\xcc", 5), "wrong data\n"); 273 } 274 275 static void test_db(MSIHANDLE hinst) 276 { 277 static const UINT prop_type[20] = { VT_EMPTY, VT_EMPTY, VT_LPSTR, VT_EMPTY, VT_EMPTY, 278 VT_EMPTY, VT_EMPTY, VT_LPSTR, VT_EMPTY, VT_LPSTR, 279 VT_EMPTY, VT_EMPTY, VT_EMPTY, VT_EMPTY, VT_I4, 280 VT_I4, VT_EMPTY, VT_EMPTY, VT_EMPTY, VT_EMPTY }; 281 MSIHANDLE hdb, hdb2, view, rec, rec2, suminfo; 282 char buffer[10]; 283 DWORD sz; 284 UINT r, count, type, i; 285 INT int_value; 286 FILETIME ft; 287 288 hdb = MsiGetActiveDatabase(hinst); 289 ok(hinst, hdb, "MsiGetActiveDatabase failed\n"); 290 291 r = MsiDatabaseIsTablePersistentA(hdb, "Test"); 292 ok(hinst, r == MSICONDITION_TRUE, "got %u\n", r); 293 294 r = MsiDatabaseOpenViewA(hdb, NULL, &view); 295 ok(hinst, r == ERROR_BAD_QUERY_SYNTAX, "got %u\n", r); 296 297 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `Test`", NULL); 298 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 299 300 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `Test`", &view); 301 ok(hinst, !r, "got %u\n", r); 302 303 r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec2); 304 ok(hinst, !r, "got %u\n", r); 305 306 sz = sizeof(buffer); 307 r = MsiRecordGetStringA(rec2, 1, buffer, &sz); 308 ok(hinst, !r, "got %u\n", r); 309 ok(hinst, sz == strlen(buffer), "got size %u\n", sz); 310 ok(hinst, !strcmp(buffer, "Name"), "got '%s'\n", buffer); 311 312 /* Test MsiGetActiveDatabase + MsiDatabaseIsTablePersistent once again */ 313 hdb2 = MsiGetActiveDatabase(hinst); 314 ok(hinst, hdb2, "MsiGetActiveDatabase failed\n"); 315 ok(hinst, hdb2 != hdb, "db handles should be different\n"); 316 317 r = MsiDatabaseIsTablePersistentA(hdb2, "Test"); 318 ok(hinst, r == MSICONDITION_TRUE, "got %u\n", r); 319 320 r = MsiCloseHandle(hdb2); 321 ok(hinst, !r, "got %u\n", r); 322 323 r = MsiCloseHandle(rec2); 324 ok(hinst, !r, "got %u\n", r); 325 326 r = MsiViewExecute(view, 0); 327 ok(hinst, !r, "got %u\n", r); 328 329 r = MsiViewFetch(view, &rec2); 330 ok(hinst, !r, "got %u\n", r); 331 332 r = MsiRecordGetFieldCount(rec2); 333 ok(hinst, r == 3, "got %u\n", r); 334 335 sz = sizeof(buffer); 336 r = MsiRecordGetStringA(rec2, 1, buffer, &sz); 337 ok(hinst, !r, "got %u\n", r); 338 ok(hinst, sz == strlen(buffer), "got size %u\n", sz); 339 ok(hinst, !strcmp(buffer, "one"), "got '%s'\n", buffer); 340 341 r = MsiRecordGetInteger(rec2, 2); 342 ok(hinst, r == 1, "got %d\n", r); 343 344 sz = sizeof(buffer); 345 r = MsiRecordReadStream(rec2, 3, buffer, &sz); 346 ok(hinst, !r, "got %u\n", r); 347 ok(hinst, !memcmp(buffer, "unus", 4), "wrong data\n"); 348 349 r = MsiCloseHandle(rec2); 350 ok(hinst, !r, "got %u\n", r); 351 352 r = MsiViewFetch(view, &rec2); 353 ok(hinst, !r, "got %u\n", r); 354 355 r = MsiRecordGetFieldCount(rec2); 356 ok(hinst, r == 3, "got %u\n", r); 357 358 sz = sizeof(buffer); 359 r = MsiRecordGetStringA(rec2, 1, buffer, &sz); 360 ok(hinst, !r, "got %u\n", r); 361 ok(hinst, sz == strlen(buffer), "got size %u\n", sz); 362 ok(hinst, !strcmp(buffer, "two"), "got '%s'\n", buffer); 363 364 r = MsiRecordGetInteger(rec2, 2); 365 ok(hinst, r == 2, "got %d\n", r); 366 367 sz = sizeof(buffer); 368 r = MsiRecordReadStream(rec2, 3, buffer, &sz); 369 ok(hinst, !r, "got %u\n", r); 370 ok(hinst, !memcmp(buffer, "duo", 3), "wrong data\n"); 371 372 r = MsiViewModify(view, MSIMODIFY_REFRESH, 0); 373 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 374 375 r = MsiRecordSetStringA(rec2, 1, "three"); 376 ok(hinst, !r, "got %u\n", r); 377 378 r = MsiRecordSetInteger(rec2, 2, 3); 379 ok(hinst, !r, "got %u\n", r); 380 381 r = MsiRecordSetInteger(rec2, 3, 3); 382 ok(hinst, !r, "got %u\n", r); 383 384 r = MsiViewModify(view, MSIMODIFY_REFRESH, rec2); 385 ok(hinst, !r, "got %d\n", r); 386 387 sz = sizeof(buffer); 388 r = MsiRecordGetStringA(rec2, 1, buffer, &sz); 389 ok(hinst, !r, "got %u\n", r); 390 ok(hinst, sz == strlen(buffer), "got size %u\n", sz); 391 ok(hinst, !strcmp(buffer, "two"), "got '%s'\n", buffer); 392 393 r = MsiRecordGetInteger(rec2, 2); 394 ok(hinst, r == 2, "got %d\n", r); 395 396 sz = sizeof(buffer); 397 r = MsiRecordReadStream(rec2, 3, buffer, &sz); 398 ok(hinst, !r, "got %u\n", r); 399 ok(hinst, !memcmp(buffer, "duo", 3), "wrong data\n"); 400 401 r = MsiCloseHandle(rec2); 402 ok(hinst, !r, "got %u\n", r); 403 404 r = MsiViewFetch(view, &rec2); 405 ok(hinst, r == ERROR_NO_MORE_ITEMS, "got %u\n", r); 406 ok(hinst, !rec2, "got %u\n", rec2); 407 408 r = MsiViewClose(view); 409 ok(hinst, !r, "got %u\n", r); 410 411 r = MsiCloseHandle(view); 412 ok(hinst, !r, "got %u\n", r); 413 414 r = MsiDatabaseOpenViewA(hdb, "SELECT * FROM `Test` WHERE `Name` = ?", &view); 415 ok(hinst, !r, "got %u\n", r); 416 417 rec = MsiCreateRecord(1); 418 MsiRecordSetStringA(rec, 1, "one"); 419 420 r = MsiViewExecute(view, rec); 421 ok(hinst, !r, "got %u\n", r); 422 423 r = MsiViewFetch(view, &rec2); 424 ok(hinst, !r, "got %u\n", r); 425 426 r = MsiRecordGetInteger(rec2, 2); 427 ok(hinst, r == 1, "got %d\n", r); 428 429 r = MsiCloseHandle(rec2); 430 ok(hinst, !r, "got %u\n", r); 431 432 r = MsiViewFetch(view, &rec2); 433 ok(hinst, r == ERROR_NO_MORE_ITEMS, "got %u\n", r); 434 ok(hinst, !rec2, "got %u\n", rec2); 435 436 r = MsiCloseHandle(rec); 437 ok(hinst, !r, "got %u\n", r); 438 439 r = MsiCloseHandle(view); 440 ok(hinst, !r, "got %u\n", r); 441 442 /* test MsiDatabaseGetPrimaryKeys() */ 443 r = MsiDatabaseGetPrimaryKeysA(hdb, "Test", &rec); 444 ok(hinst, !r, "got %u\n", r); 445 446 r = MsiRecordGetFieldCount(rec); 447 ok(hinst, r == 1, "got %d\n", r); 448 449 sz = sizeof(buffer); 450 r = MsiRecordGetStringA(rec, 0, buffer, &sz); 451 ok(hinst, !r, "got %u\n", r); 452 ok(hinst, sz == strlen(buffer), "got size %u\n", sz); 453 ok(hinst, !strcmp(buffer, "Test"), "got '%s'\n", buffer); 454 455 sz = sizeof(buffer); 456 r = MsiRecordGetStringA(rec, 1, buffer, &sz); 457 ok(hinst, !r, "got %u\n", r); 458 ok(hinst, sz == strlen(buffer), "got size %u\n", sz); 459 ok(hinst, !strcmp(buffer, "Name"), "got '%s'\n", buffer); 460 461 r = MsiCloseHandle(rec); 462 ok(hinst, !r, "got %u\n", r); 463 464 r = MsiGetSummaryInformationA(hdb, NULL, 1, NULL); 465 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 466 467 r = MsiGetSummaryInformationA(hdb, NULL, 1, &suminfo); 468 ok(hinst, !r, "got %u\n", r); 469 470 r = MsiSummaryInfoGetPropertyCount(suminfo, NULL); 471 ok(hinst, r == RPC_X_NULL_REF_POINTER, "got %u\n", r); 472 473 count = 0xdeadbeef; 474 r = MsiSummaryInfoGetPropertyCount(suminfo, &count); 475 ok(hinst, !r, "got %u\n", r); 476 ok(hinst, count == 5, "got %u\n", count); 477 478 r = MsiSummaryInfoGetPropertyA(suminfo, 0, NULL, NULL, NULL, NULL, NULL); 479 ok(hinst, r == RPC_X_NULL_REF_POINTER, "got %u\n", r); 480 481 for (i = 0; i < 20; i++) 482 { 483 /* for some reason query for PID_TITLE leads to install failure under Windows */ 484 if (i == PID_TITLE) continue; 485 486 type = 0xdeadbeef; 487 int_value = 0xdeadbeef; 488 *buffer = 0; 489 sz = sizeof(buffer); 490 r = MsiSummaryInfoGetPropertyA(suminfo, i, &type, &int_value, &ft, buffer, &sz); 491 if (sz == sizeof(buffer) || i == PID_TEMPLATE) 492 ok(hinst, !r, "%u: got %u\n", i, r); 493 else 494 ok(hinst, r == ERROR_MORE_DATA, "%u: got %u\n", i, r); 495 ok(hinst, type == prop_type[i], "%u: expected %u, got %u\n", i, prop_type[i], type); 496 if (i == PID_PAGECOUNT) 497 ok(hinst, int_value == 100, "%u: got %u\n", i, int_value); 498 else 499 ok(hinst, int_value == 0, "%u: got %u\n", i, int_value); 500 if (i == PID_TEMPLATE) 501 { 502 ok(hinst, sz == 5, "%u: got %u\n", i, sz); 503 ok(hinst, !lstrcmpA(buffer, ";1033"), "%u: got %s\n", i, buffer); 504 } 505 else if (i == PID_REVNUMBER) 506 { 507 ok(hinst, sz == 76, "%u: got %u\n", i, sz); 508 ok(hinst, !lstrcmpA(buffer, "{004757CA"), "%u: got %s\n", i, buffer); 509 } 510 else 511 { 512 ok(hinst, sz == sizeof(buffer), "%u: got %u\n", i, sz); 513 ok(hinst, !*buffer, "%u: got %s\n", i, buffer); 514 } 515 } 516 517 GetSystemTimeAsFileTime(&ft); 518 519 for (i = 0; i < 20; i++) 520 { 521 r = MsiSummaryInfoSetPropertyA(suminfo, i, prop_type[i], 1252, &ft, ""); 522 ok(hinst, r == ERROR_FUNCTION_FAILED, "%u: got %u\n", i, r); 523 524 r = MsiSummaryInfoSetPropertyW(suminfo, i, prop_type[i], 1252, &ft, L""); 525 ok(hinst, r == ERROR_FUNCTION_FAILED, "%u: got %u\n", i, r); 526 } 527 528 r = MsiCloseHandle(suminfo); 529 ok(hinst, !r, "got %u\n", r); 530 531 r = MsiCloseHandle(hdb); 532 ok(hinst, !r, "got %u\n", r); 533 } 534 535 static void test_doaction(MSIHANDLE hinst) 536 { 537 UINT r; 538 539 r = MsiDoActionA(hinst, "nested51"); 540 ok(hinst, !r, "got %u\n", r); 541 check_prop(hinst, "nested", "1"); 542 543 r = MsiDoActionA(hinst, "nested1"); 544 ok(hinst, !r, "got %u\n", r); 545 check_prop(hinst, "nested", "2"); 546 547 r = MsiSequenceA(hinst, NULL, 0); 548 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 549 550 r = MsiSequenceA(hinst, "TestSequence", 0); 551 ok(hinst, !r, "got %u\n", r); 552 check_prop(hinst, "nested", "1"); 553 } 554 555 UINT WINAPI nested(MSIHANDLE hinst) 556 { 557 MsiSetPropertyA(hinst, "nested", "2"); 558 559 return ERROR_SUCCESS; 560 } 561 562 static void test_targetpath(MSIHANDLE hinst) 563 { 564 WCHAR bufferW[100]; 565 char buffer[100]; 566 DWORD sz, srcsz; 567 UINT r; 568 569 /* test invalid values */ 570 r = MsiGetTargetPathA(hinst, NULL, NULL, NULL); 571 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 572 573 r = MsiGetTargetPathA(hinst, "TARGETDIR", NULL, NULL ); 574 ok(hinst, !r, "got %u\n", r); 575 576 r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, NULL ); 577 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 578 579 /* Returned size is in bytes, not chars, but only for custom actions. 580 * Seems to be a casualty of RPC... */ 581 582 sz = 0; 583 r = MsiGetTargetPathA(hinst, "TARGETDIR", NULL, &sz); 584 ok(hinst, !r, "got %u\n", r); 585 ok(hinst, sz == 6, "got size %u\n", sz); 586 587 sz = 0; 588 strcpy(buffer,"q"); 589 r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz); 590 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 591 ok(hinst, !strcmp(buffer, "q"), "got \"%s\"\n", buffer); 592 ok(hinst, sz == 6, "got size %u\n", sz); 593 594 sz = 1; 595 strcpy(buffer,"x"); 596 r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz); 597 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 598 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 599 ok(hinst, sz == 6, "got size %u\n", sz); 600 601 sz = 3; 602 strcpy(buffer,"x"); 603 r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz); 604 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 605 ok(hinst, !strcmp(buffer, "C:"), "got \"%s\"\n", buffer); 606 ok(hinst, sz == 6, "got size %u\n", sz); 607 608 sz = 4; 609 strcpy(buffer,"x"); 610 r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz); 611 ok(hinst, !r, "got %u\n", r); 612 ok(hinst, !strcmp(buffer, "C:\\"), "got \"%s\"\n", buffer); 613 ok(hinst, sz == 3, "got size %u\n", sz); 614 615 sz = 0; 616 r = MsiGetTargetPathW(hinst, L"TARGETDIR", NULL, &sz); 617 ok(hinst, !r, "got %u\n", r); 618 ok(hinst, sz == 3, "got size %u\n", sz); 619 620 sz = 0; 621 bufferW[0] = 'q'; 622 r = MsiGetTargetPathW(hinst, L"TARGETDIR", bufferW, &sz); 623 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 624 ok(hinst, bufferW[0] == 'q', "got %s\n", dbgstr_w(bufferW)); 625 ok(hinst, sz == 3, "got size %u\n", sz); 626 627 sz = 1; 628 bufferW[0] = 'q'; 629 r = MsiGetTargetPathW(hinst, L"TARGETDIR", bufferW, &sz); 630 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 631 ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW)); 632 ok(hinst, sz == 3, "got size %u\n", sz); 633 634 sz = 3; 635 bufferW[0] = 'q'; 636 r = MsiGetTargetPathW(hinst, L"TARGETDIR", bufferW, &sz); 637 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 638 ok(hinst, !lstrcmpW(bufferW, L"C:"), "got %s\n", dbgstr_w(bufferW)); 639 ok(hinst, sz == 3, "got size %u\n", sz); 640 641 sz = 4; 642 bufferW[0] = 'q'; 643 r = MsiGetTargetPathW(hinst, L"TARGETDIR", bufferW, &sz); 644 ok(hinst, !r, "got %u\n", r); 645 ok(hinst, !lstrcmpW(bufferW, L"C:\\"), "got %s\n", dbgstr_w(bufferW)); 646 ok(hinst, sz == 3, "got size %u\n", sz); 647 648 r = MsiSetTargetPathA(hinst, NULL, "C:\\subdir"); 649 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 650 651 r = MsiSetTargetPathA(hinst, "MSITESTDIR", NULL); 652 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 653 654 r = MsiSetTargetPathA(hinst, "MSITESTDIR", "C:\\subdir"); 655 ok(hinst, !r, "got %u\n", r); 656 657 sz = sizeof(buffer); 658 r = MsiGetTargetPathA(hinst, "MSITESTDIR", buffer, &sz); 659 ok(hinst, !r, "got %u\n", r); 660 ok(hinst, !strcmp(buffer, "C:\\subdir\\"), "got \"%s\"\n", buffer); 661 662 r = MsiSetTargetPathA(hinst, "MSITESTDIR", "C:\\"); 663 664 /* test GetSourcePath() */ 665 666 r = MsiGetSourcePathA(hinst, NULL, NULL, NULL); 667 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 668 669 r = MsiGetSourcePathA(hinst, "TARGETDIR", NULL, NULL ); 670 ok(hinst, !r, "got %u\n", r); 671 672 r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, NULL ); 673 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 674 675 /* Returned size is in bytes, not chars, but only for custom actions. 676 * Seems to be a casualty of RPC... */ 677 678 srcsz = 0; 679 MsiGetSourcePathW(hinst, L"TARGETDIR", NULL, &srcsz); 680 681 sz = 0; 682 r = MsiGetSourcePathA(hinst, "TARGETDIR", NULL, &sz); 683 ok(hinst, !r, "got %u\n", r); 684 ok(hinst, sz == srcsz * 2, "got size %u\n", sz); 685 686 sz = 0; 687 strcpy(buffer,"q"); 688 r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); 689 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 690 ok(hinst, !strcmp(buffer, "q"), "got \"%s\"\n", buffer); 691 ok(hinst, sz == srcsz * 2, "got size %u\n", sz); 692 693 sz = 1; 694 strcpy(buffer,"x"); 695 r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); 696 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 697 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 698 ok(hinst, sz == srcsz * 2, "got size %u\n", sz); 699 700 sz = srcsz; 701 strcpy(buffer,"x"); 702 r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); 703 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 704 ok(hinst, strlen(buffer) == srcsz - 1, "wrong buffer length %d\n", strlen(buffer)); 705 ok(hinst, sz == srcsz * 2, "got size %u\n", sz); 706 707 sz = srcsz + 1; 708 strcpy(buffer,"x"); 709 r = MsiGetSourcePathA(hinst, "TARGETDIR", buffer, &sz); 710 ok(hinst, !r, "got %u\n", r); 711 ok(hinst, strlen(buffer) == srcsz, "wrong buffer length %d\n", strlen(buffer)); 712 ok(hinst, sz == srcsz, "got size %u\n", sz); 713 714 sz = 0; 715 r = MsiGetSourcePathW(hinst, L"TARGETDIR", NULL, &sz); 716 ok(hinst, !r, "got %u\n", r); 717 ok(hinst, sz == srcsz, "got size %u\n", sz); 718 719 sz = 0; 720 bufferW[0] = 'q'; 721 r = MsiGetSourcePathW(hinst, L"TARGETDIR", bufferW, &sz); 722 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 723 ok(hinst, bufferW[0] == 'q', "got %s\n", dbgstr_w(bufferW)); 724 ok(hinst, sz == srcsz, "got size %u\n", sz); 725 726 sz = 1; 727 bufferW[0] = 'q'; 728 r = MsiGetSourcePathW(hinst, L"TARGETDIR", bufferW, &sz); 729 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 730 ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW)); 731 ok(hinst, sz == srcsz, "got size %u\n", sz); 732 733 sz = srcsz; 734 bufferW[0] = 'q'; 735 r = MsiGetSourcePathW(hinst, L"TARGETDIR", bufferW, &sz); 736 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 737 ok(hinst, lstrlenW(bufferW) == srcsz - 1, "wrong buffer length %d\n", lstrlenW(bufferW)); 738 ok(hinst, sz == srcsz, "got size %u\n", sz); 739 740 sz = srcsz + 1; 741 bufferW[0] = 'q'; 742 r = MsiGetSourcePathW(hinst, L"TARGETDIR", bufferW, &sz); 743 ok(hinst, !r, "got %u\n", r); 744 ok(hinst, lstrlenW(bufferW) == srcsz, "wrong buffer length %d\n", lstrlenW(bufferW)); 745 ok(hinst, sz == srcsz, "got size %u\n", sz); 746 } 747 748 static void test_misc(MSIHANDLE hinst) 749 { 750 MSICONDITION cond; 751 LANGID lang; 752 UINT r; 753 754 r = MsiSetMode(hinst, MSIRUNMODE_REBOOTATEND, FALSE); 755 ok(hinst, !r, "got %u\n", r); 756 757 lang = MsiGetLanguage(hinst); 758 ok(hinst, lang == 1033, "got %u\n", lang); 759 760 check_prop(hinst, "INSTALLLEVEL", "3"); 761 r = MsiSetInstallLevel(hinst, 123); 762 ok(hinst, !r, "got %u\n", r); 763 check_prop(hinst, "INSTALLLEVEL", "123"); 764 MsiSetInstallLevel(hinst, 3); 765 766 cond = MsiEvaluateConditionA(hinst, NULL); 767 ok(hinst, cond == MSICONDITION_NONE, "got %u\n", cond); 768 MsiSetPropertyA(hinst, "condprop", "1"); 769 cond = MsiEvaluateConditionA(hinst, "condprop = 1"); 770 ok(hinst, cond == MSICONDITION_TRUE, "got %u\n", cond); 771 } 772 773 static void test_feature_states(MSIHANDLE hinst) 774 { 775 INSTALLSTATE state, action; 776 UINT r; 777 778 /* test feature states */ 779 780 r = MsiGetFeatureStateA(hinst, NULL, &state, &action); 781 ok(hinst, r == ERROR_UNKNOWN_FEATURE, "got %u\n", r); 782 783 r = MsiGetFeatureStateA(hinst, "fake", &state, &action); 784 ok(hinst, r == ERROR_UNKNOWN_FEATURE, "got %u\n", r); 785 786 r = MsiGetFeatureStateA(hinst, "One", NULL, &action); 787 ok(hinst, r == RPC_X_NULL_REF_POINTER, "got %u\n", r); 788 789 r = MsiGetFeatureStateA(hinst, "One", &state, NULL); 790 ok(hinst, r == RPC_X_NULL_REF_POINTER, "got %u\n", r); 791 792 r = MsiGetFeatureStateA(hinst, "One", &state, &action); 793 ok(hinst, !r, "got %u\n", r); 794 ok(hinst, state == INSTALLSTATE_ABSENT, "got state %d\n", state); 795 ok(hinst, action == INSTALLSTATE_LOCAL, "got action %d\n", action); 796 797 r = MsiSetFeatureStateA(hinst, NULL, INSTALLSTATE_ABSENT); 798 ok(hinst, r == ERROR_UNKNOWN_FEATURE, "got %u\n", r); 799 800 r = MsiSetFeatureStateA(hinst, "One", INSTALLSTATE_ADVERTISED); 801 ok(hinst, !r, "got %u\n", r); 802 803 r = MsiGetFeatureStateA(hinst, "One", &state, &action); 804 ok(hinst, !r, "got %u\n", r); 805 ok(hinst, action == INSTALLSTATE_ADVERTISED, "got action %d\n", action); 806 807 r = MsiSetFeatureStateA(hinst, "One", INSTALLSTATE_LOCAL); 808 ok(hinst, !r, "got %u\n", r); 809 810 r = MsiGetFeatureStateA(hinst, "One", &state, &action); 811 ok(hinst, !r, "got %u\n", r); 812 ok(hinst, action == INSTALLSTATE_LOCAL, "got action %d\n", action); 813 814 /* test component states */ 815 816 r = MsiGetComponentStateA(hinst, NULL, &state, &action); 817 ok(hinst, r == ERROR_UNKNOWN_COMPONENT, "got %u\n", r); 818 819 r = MsiGetComponentStateA(hinst, "fake", &state, &action); 820 ok(hinst, r == ERROR_UNKNOWN_COMPONENT, "got %u\n", r); 821 822 r = MsiGetComponentStateA(hinst, "One", NULL, &action); 823 ok(hinst, r == RPC_X_NULL_REF_POINTER, "got %u\n", r); 824 825 r = MsiGetComponentStateA(hinst, "One", &state, NULL); 826 ok(hinst, r == RPC_X_NULL_REF_POINTER, "got %u\n", r); 827 828 r = MsiGetComponentStateA(hinst, "One", &state, &action); 829 ok(hinst, !r, "got %u\n", r); 830 ok(hinst, state == INSTALLSTATE_ABSENT, "got state %d\n", state); 831 ok(hinst, action == INSTALLSTATE_LOCAL, "got action %d\n", action); 832 833 r = MsiGetComponentStateA(hinst, "dangler", &state, &action); 834 ok(hinst, !r, "got %u\n", r); 835 ok(hinst, state == INSTALLSTATE_ABSENT, "got state %d\n", state); 836 ok(hinst, action == INSTALLSTATE_UNKNOWN, "got action %d\n", action); 837 838 r = MsiGetComponentStateA(hinst, "component", &state, &action); 839 ok(hinst, !r, "got %u\n", r); 840 ok(hinst, state == INSTALLSTATE_UNKNOWN, "got state %d\n", state); 841 ok(hinst, action == INSTALLSTATE_LOCAL, "got action %d\n", action); 842 843 r = MsiSetComponentStateA(hinst, NULL, INSTALLSTATE_ABSENT); 844 ok(hinst, r == ERROR_UNKNOWN_COMPONENT, "got %u\n", r); 845 846 r = MsiSetComponentStateA(hinst, "One", INSTALLSTATE_SOURCE); 847 ok(hinst, !r, "got %u\n", r); 848 849 r = MsiGetComponentStateA(hinst, "One", &state, &action); 850 ok(hinst, !r, "got %u\n", r); 851 ok(hinst, state == INSTALLSTATE_ABSENT, "got state %d\n", state); 852 ok(hinst, action == INSTALLSTATE_SOURCE, "got action %d\n", action); 853 854 r = MsiSetComponentStateA(hinst, "One", INSTALLSTATE_LOCAL); 855 ok(hinst, !r, "got %u\n", r); 856 857 r = MsiGetComponentStateA(hinst, "One", &state, &action); 858 ok(hinst, !r, "got %u\n", r); 859 ok(hinst, state == INSTALLSTATE_ABSENT, "got state %d\n", state); 860 ok(hinst, action == INSTALLSTATE_LOCAL, "got action %d\n", action); 861 } 862 863 static void test_format_record(MSIHANDLE hinst) 864 { 865 WCHAR bufferW[10]; 866 char buffer[10]; 867 MSIHANDLE rec; 868 DWORD sz; 869 UINT r; 870 871 r = MsiFormatRecordA(hinst, 0, NULL, NULL); 872 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 873 874 rec = MsiCreateRecord(1); 875 MsiRecordSetStringA(rec, 0, "foo [1]"); 876 MsiRecordSetInteger(rec, 1, 123); 877 878 r = MsiFormatRecordA(hinst, rec, NULL, NULL); 879 ok(hinst, !r, "got %u\n", r); 880 881 r = MsiFormatRecordA(hinst, rec, buffer, NULL); 882 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 883 884 /* Returned size is in bytes, not chars, but only for custom actions. */ 885 886 sz = 0; 887 r = MsiFormatRecordA(hinst, rec, NULL, &sz); 888 ok(hinst, !r, "got %u\n", r); 889 ok(hinst, sz == 14, "got size %u\n", sz); 890 891 sz = 0; 892 strcpy(buffer,"q"); 893 r = MsiFormatRecordA(hinst, rec, buffer, &sz); 894 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 895 ok(hinst, !strcmp(buffer, "q"), "got \"%s\"\n", buffer); 896 ok(hinst, sz == 14, "got size %u\n", sz); 897 898 sz = 1; 899 strcpy(buffer,"x"); 900 r = MsiFormatRecordA(hinst, rec, buffer, &sz); 901 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 902 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 903 ok(hinst, sz == 14, "got size %u\n", sz); 904 905 sz = 7; 906 strcpy(buffer,"x"); 907 r = MsiFormatRecordA(hinst, rec, buffer, &sz); 908 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 909 ok(hinst, !strcmp(buffer, "foo 12"), "got \"%s\"\n", buffer); 910 ok(hinst, sz == 14, "got size %u\n", sz); 911 912 sz = 8; 913 strcpy(buffer,"x"); 914 r = MsiFormatRecordA(hinst, rec, buffer, &sz); 915 ok(hinst, !r, "got %u\n", r); 916 ok(hinst, !strcmp(buffer, "foo 123"), "got \"%s\"\n", buffer); 917 ok(hinst, sz == 7, "got size %u\n", sz); 918 919 r = MsiFormatRecordW(hinst, rec, NULL, NULL); 920 ok(hinst, !r, "got %u\n", r); 921 922 r = MsiFormatRecordW(hinst, rec, bufferW, NULL); 923 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 924 925 sz = 0; 926 r = MsiFormatRecordW(hinst, rec, NULL, &sz); 927 ok(hinst, !r, "got %u\n", r); 928 ok(hinst, sz == 7, "got size %u\n", sz); 929 930 sz = 0; 931 bufferW[0] = 'q'; 932 r = MsiFormatRecordW(hinst, rec, bufferW, &sz); 933 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 934 ok(hinst, bufferW[0] == 'q', "got %s\n", dbgstr_w(bufferW)); 935 ok(hinst, sz == 7, "got size %u\n", sz); 936 937 sz = 1; 938 bufferW[0] = 'q'; 939 r = MsiFormatRecordW(hinst, rec, bufferW, &sz); 940 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 941 ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW)); 942 ok(hinst, sz == 7, "got size %u\n", sz); 943 944 sz = 7; 945 bufferW[0] = 'q'; 946 r = MsiFormatRecordW(hinst, rec, bufferW, &sz); 947 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 948 ok(hinst, !lstrcmpW(bufferW, L"foo 12"), "got %s\n", dbgstr_w(bufferW)); 949 ok(hinst, sz == 7, "got size %u\n", sz); 950 951 sz = 8; 952 bufferW[0] = 'q'; 953 r = MsiFormatRecordW(hinst, rec, bufferW, &sz); 954 ok(hinst, !r, "got %u\n", r); 955 ok(hinst, !lstrcmpW(bufferW, L"foo 123"), "got %s\n", dbgstr_w(bufferW)); 956 ok(hinst, sz == 7, "got size %u\n", sz); 957 958 /* check that properties work */ 959 MsiSetPropertyA(hinst, "fmtprop", "foobar"); 960 MsiRecordSetStringA(rec, 0, "[fmtprop]"); 961 sz = sizeof(buffer); 962 r = MsiFormatRecordA(hinst, rec, buffer, &sz); 963 ok(hinst, !r, "got %u\n", r); 964 ok(hinst, !strcmp(buffer, "foobar"), "got \"%s\"\n", buffer); 965 ok(hinst, sz == 6, "got size %u\n", sz); 966 967 MsiCloseHandle(rec); 968 } 969 970 static void test_costs(MSIHANDLE hinst) 971 { 972 WCHAR bufferW[10]; 973 char buffer[10]; 974 int cost, temp; 975 DWORD sz; 976 UINT r; 977 978 cost = 0xdead; 979 r = MsiGetFeatureCostA(hinst, NULL, MSICOSTTREE_CHILDREN, INSTALLSTATE_LOCAL, &cost); 980 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 981 todo_wine 982 ok(hinst, !cost, "got %d\n", cost); 983 984 r = MsiGetFeatureCostA(hinst, "One", MSICOSTTREE_CHILDREN, INSTALLSTATE_LOCAL, NULL); 985 ok(hinst, r == RPC_X_NULL_REF_POINTER, "got %u\n", r); 986 987 cost = 0xdead; 988 r = MsiGetFeatureCostA(hinst, "One", MSICOSTTREE_CHILDREN, INSTALLSTATE_LOCAL, &cost); 989 ok(hinst, !r, "got %u\n", r); 990 todo_wine 991 ok(hinst, cost == 8, "got %d\n", cost); 992 993 sz = cost = temp = 0xdead; 994 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, NULL, &sz, &cost, &temp); 995 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 996 ok(hinst, sz == 0xdead, "got size %d\n", sz); 997 ok(hinst, cost == 0xdead, "got cost %d\n", cost); 998 ok(hinst, temp == 0xdead, "got temp %d\n", temp); 999 1000 cost = temp = 0xdead; 1001 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, NULL, &cost, &temp); 1002 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 1003 ok(hinst, cost == 0xdead, "got cost %d\n", cost); 1004 ok(hinst, temp == 0xdead, "got temp %d\n", temp); 1005 1006 sz = temp = 0xdead; 1007 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, &sz, NULL, &temp); 1008 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 1009 ok(hinst, sz == 0xdead, "got size %d\n", sz); 1010 ok(hinst, temp == 0xdead, "got temp %d\n", temp); 1011 1012 sz = cost = 0xdead; 1013 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, &sz, &cost, NULL); 1014 ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r); 1015 ok(hinst, sz == 0xdead, "got size %d\n", sz); 1016 ok(hinst, cost == 0xdead, "got cost %d\n", cost); 1017 1018 cost = temp = 0xdead; 1019 sz = sizeof(buffer); 1020 r = MsiEnumComponentCostsA(hinst, NULL, 0, INSTALLSTATE_LOCAL, buffer, &sz, &cost, &temp); 1021 ok(hinst, !r, "got %u\n", r); 1022 ok(hinst, sz == 2, "got size %u\n", sz); 1023 ok(hinst, !strcmp(buffer, "C:"), "got '%s'\n", buffer); 1024 ok(hinst, !cost, "got cost %d\n", cost); 1025 ok(hinst, temp && temp != 0xdead, "got temp %d\n", temp); 1026 1027 cost = temp = 0xdead; 1028 sz = sizeof(buffer); 1029 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, &sz, &cost, &temp); 1030 ok(hinst, !r, "got %u\n", r); 1031 ok(hinst, sz == 2, "got size %u\n", sz); 1032 ok(hinst, !strcmp(buffer, "C:"), "got '%s'\n", buffer); 1033 ok(hinst, cost == 8, "got cost %d\n", cost); 1034 ok(hinst, !temp, "got temp %d\n", temp); 1035 1036 /* same string behaviour */ 1037 cost = temp = 0xdead; 1038 sz = 0; 1039 strcpy(buffer,"q"); 1040 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, &sz, &cost, &temp); 1041 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 1042 ok(hinst, !strcmp(buffer, "q"), "got \"%s\"\n", buffer); 1043 todo_wine 1044 ok(hinst, sz == 4, "got size %u\n", sz); 1045 ok(hinst, cost == 8, "got cost %d\n", cost); 1046 ok(hinst, !temp, "got temp %d\n", temp); 1047 1048 sz = 1; 1049 strcpy(buffer,"x"); 1050 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, &sz, &cost, &temp); 1051 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 1052 todo_wine { 1053 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 1054 ok(hinst, sz == 4, "got size %u\n", sz); 1055 } 1056 1057 sz = 2; 1058 strcpy(buffer,"x"); 1059 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, &sz, &cost, &temp); 1060 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 1061 todo_wine { 1062 ok(hinst, !strcmp(buffer, "C"), "got \"%s\"\n", buffer); 1063 ok(hinst, sz == 4, "got size %u\n", sz); 1064 } 1065 1066 sz = 3; 1067 strcpy(buffer,"x"); 1068 r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, &sz, &cost, &temp); 1069 ok(hinst, !r, "got %u\n", r); 1070 ok(hinst, !strcmp(buffer, "C:"), "got \"%s\"\n", buffer); 1071 ok(hinst, sz == 2, "got size %u\n", sz); 1072 1073 sz = 0; 1074 bufferW[0] = 'q'; 1075 r = MsiEnumComponentCostsW(hinst, L"One", 0, INSTALLSTATE_LOCAL, bufferW, &sz, &cost, &temp); 1076 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 1077 ok(hinst, bufferW[0] == 'q', "got %s\n", dbgstr_w(bufferW)); 1078 ok(hinst, sz == 2, "got size %u\n", sz); 1079 1080 sz = 1; 1081 bufferW[0] = 'q'; 1082 r = MsiEnumComponentCostsW(hinst, L"One", 0, INSTALLSTATE_LOCAL, bufferW, &sz, &cost, &temp); 1083 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 1084 ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW)); 1085 ok(hinst, sz == 2, "got size %u\n", sz); 1086 1087 sz = 2; 1088 bufferW[0] = 'q'; 1089 r = MsiEnumComponentCostsW(hinst, L"One", 0, INSTALLSTATE_LOCAL, bufferW, &sz, &cost, &temp); 1090 ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r); 1091 ok(hinst, !lstrcmpW(bufferW, L"C"), "got %s\n", dbgstr_w(bufferW)); 1092 ok(hinst, sz == 2, "got size %u\n", sz); 1093 1094 sz = 3; 1095 bufferW[0] = 'q'; 1096 r = MsiEnumComponentCostsW(hinst, L"One", 0, INSTALLSTATE_LOCAL, bufferW, &sz, &cost, &temp); 1097 ok(hinst, !r, "got %u\n", r); 1098 ok(hinst, !lstrcmpW(bufferW, L"C:"), "got %s\n", dbgstr_w(bufferW)); 1099 ok(hinst, sz == 2, "got size %u\n", sz); 1100 } 1101 1102 static void test_invalid_functions(MSIHANDLE hinst) 1103 { 1104 char path[MAX_PATH], package_name[20]; 1105 MSIHANDLE db, preview, package; 1106 UINT r; 1107 1108 r = MsiGetDatabaseState(hinst); 1109 ok(hinst, r == MSIDBSTATE_ERROR, "got %u\n", r); 1110 1111 db = MsiGetActiveDatabase(hinst); 1112 ok(hinst, db, "MsiGetActiveDatabase failed\n"); 1113 1114 r = MsiDatabaseGenerateTransformA(db, db, "bogus.mst", 0, 0); 1115 todo_wine ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 1116 1117 r = MsiDatabaseApplyTransformA(db, "bogus.mst", 0); 1118 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 1119 1120 r = MsiCreateTransformSummaryInfoA(db, db, "bogus.mst", 0, 0); 1121 todo_wine ok(hinst, r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || 1122 r == ERROR_INSTALL_PACKAGE_INVALID /* winxp */, 1123 "got %u\n", r); 1124 1125 GetCurrentDirectoryA(sizeof(path), path); 1126 r = MsiDatabaseExportA(db, "Test", path, "bogus.idt"); 1127 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 1128 1129 r = MsiDatabaseImportA(db, path, "bogus.idt"); 1130 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 1131 1132 r = MsiDatabaseCommit(db); 1133 ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); 1134 1135 r = MsiDatabaseMergeA(db, db, "MergeErrors"); 1136 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 1137 1138 r = MsiGetDatabaseState(db); 1139 ok(hinst, r == MSIDBSTATE_ERROR, "got %u\n", r); 1140 1141 r = MsiEnableUIPreview(db, &preview); 1142 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 1143 1144 sprintf(package_name, "#%lu", db); 1145 r = MsiOpenPackageA(package_name, &package); 1146 ok(hinst, r == ERROR_INVALID_HANDLE, "got %u\n", r); 1147 1148 MsiCloseHandle(db); 1149 } 1150 1151 static void test_view_get_error(MSIHANDLE hinst) 1152 { 1153 MSIHANDLE db, view, rec; 1154 char buffer[5]; 1155 MSIDBERROR err; 1156 DWORD sz; 1157 UINT r; 1158 1159 db = MsiGetActiveDatabase(hinst); 1160 ok(hinst, db, "MsiGetActiveDatabase failed\n"); 1161 1162 r = MsiDatabaseOpenViewA(db, "SELECT * FROM `test2`", &view); 1163 ok(hinst, !r, "got %u\n", r); 1164 1165 r = MsiViewExecute(view, 0); 1166 ok(hinst, !r, "got %u\n", r); 1167 1168 sz = 0; 1169 err = MsiViewGetErrorA(0, NULL, &sz); 1170 todo_wine ok(hinst, err == MSIDBERROR_FUNCTIONERROR, "got %d\n", err); 1171 ok(hinst, sz == 0, "got size %u\n", sz); 1172 1173 err = MsiViewGetErrorA(view, NULL, NULL); 1174 ok(hinst, err == MSIDBERROR_INVALIDARG, "got %d\n", err); 1175 1176 sz = 0; 1177 err = MsiViewGetErrorA(view, NULL, &sz); 1178 ok(hinst, err == MSIDBERROR_FUNCTIONERROR, "got %d\n", err); 1179 ok(hinst, sz == 0, "got size %u\n", sz); 1180 1181 sz = 0; 1182 strcpy(buffer, "x"); 1183 err = MsiViewGetErrorA(view, buffer, &sz); 1184 ok(hinst, err == MSIDBERROR_FUNCTIONERROR, "got %d\n", err); 1185 ok(hinst, !strcmp(buffer, "x"), "got \"%s\"\n", buffer); 1186 ok(hinst, sz == 0, "got size %u\n", sz); 1187 1188 sz = 1; 1189 strcpy(buffer, "x"); 1190 err = MsiViewGetErrorA(view, buffer, &sz); 1191 ok(hinst, err == MSIDBERROR_NOERROR, "got %d\n", err); 1192 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 1193 ok(hinst, sz == 0, "got size %u\n", sz); 1194 1195 rec = MsiCreateRecord(2); 1196 MsiRecordSetInteger(rec, 1, 1); 1197 MsiRecordSetInteger(rec, 2, 2); 1198 r = MsiViewModify(view, MSIMODIFY_VALIDATE_NEW, rec); 1199 ok(hinst, r == ERROR_INVALID_DATA, "got %u\n", r); 1200 1201 sz = 2; 1202 strcpy(buffer, "x"); 1203 err = MsiViewGetErrorA(view, buffer, &sz); 1204 ok(hinst, err == MSIDBERROR_DUPLICATEKEY, "got %d\n", err); 1205 ok(hinst, !strcmp(buffer, "A"), "got \"%s\"\n", buffer); 1206 ok(hinst, sz == 1, "got size %u\n", sz); 1207 1208 sz = 2; 1209 strcpy(buffer, "x"); 1210 err = MsiViewGetErrorA(view, buffer, &sz); 1211 todo_wine ok(hinst, err == MSIDBERROR_NOERROR, "got %d\n", err); 1212 todo_wine ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 1213 todo_wine ok(hinst, sz == 0, "got size %u\n", sz); 1214 1215 r = MsiViewModify(view, MSIMODIFY_VALIDATE_NEW, rec); 1216 ok(hinst, r == ERROR_INVALID_DATA, "got %u\n", r); 1217 1218 sz = 1; 1219 strcpy(buffer, "x"); 1220 err = MsiViewGetErrorA(view, buffer, &sz); 1221 ok(hinst, err == MSIDBERROR_MOREDATA, "got %d\n", err); 1222 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 1223 ok(hinst, sz == 1, "got size %u\n", sz); 1224 1225 sz = 1; 1226 strcpy(buffer, "x"); 1227 err = MsiViewGetErrorA(view, buffer, &sz); 1228 todo_wine ok(hinst, err == MSIDBERROR_NOERROR, "got %d\n", err); 1229 ok(hinst, !buffer[0], "got \"%s\"\n", buffer); 1230 todo_wine ok(hinst, sz == 0, "got size %u\n", sz); 1231 1232 r = MsiViewModify(view, MSIMODIFY_VALIDATE_NEW, rec); 1233 ok(hinst, r == ERROR_INVALID_DATA, "got %u\n", r); 1234 1235 sz = 0; 1236 strcpy(buffer, "x"); 1237 err = MsiViewGetErrorA(view, buffer, &sz); 1238 ok(hinst, err == MSIDBERROR_FUNCTIONERROR, "got %d\n", err); 1239 ok(hinst, !strcmp(buffer, "x"), "got \"%s\"\n", buffer); 1240 ok(hinst, sz == 0, "got size %u\n", sz); 1241 1242 sz = 0; 1243 strcpy(buffer, "x"); 1244 err = MsiViewGetErrorA(view, buffer, &sz); 1245 ok(hinst, err == MSIDBERROR_FUNCTIONERROR, "got %d\n", err); 1246 ok(hinst, !strcmp(buffer, "x"), "got \"%s\"\n", buffer); 1247 ok(hinst, sz == 0, "got size %u\n", sz); 1248 1249 MsiCloseHandle(rec); 1250 MsiCloseHandle(view); 1251 MsiCloseHandle(db); 1252 } 1253 1254 /* Main test. Anything that doesn't depend on a specific install configuration 1255 * or have undesired side effects should go here. */ 1256 UINT WINAPI main_test(MSIHANDLE hinst) 1257 { 1258 IUnknown *unk = NULL; 1259 HRESULT hr; 1260 1261 /* Test for an MTA apartment */ 1262 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk); 1263 ok(hinst, hr == S_OK, "CoCreateInstance failed with %08x\n", hr); 1264 1265 if (unk) IUnknown_Release(unk); 1266 1267 /* but ours is uninitialized */ 1268 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 1269 ok(hinst, hr == S_OK, "got %#x\n", hr); 1270 CoUninitialize(); 1271 1272 test_props(hinst); 1273 test_db(hinst); 1274 test_doaction(hinst); 1275 test_targetpath(hinst); 1276 test_misc(hinst); 1277 test_feature_states(hinst); 1278 test_format_record(hinst); 1279 test_costs(hinst); 1280 test_invalid_functions(hinst); 1281 test_view_get_error(hinst); 1282 1283 return ERROR_SUCCESS; 1284 } 1285 1286 UINT WINAPI test_retval(MSIHANDLE hinst) 1287 { 1288 char prop[10]; 1289 DWORD len = sizeof(prop); 1290 UINT retval; 1291 1292 MsiGetPropertyA(hinst, "TEST_RETVAL", prop, &len); 1293 sscanf(prop, "%u", &retval); 1294 return retval; 1295 } 1296 1297 static void append_file(MSIHANDLE hinst, const char *filename, const char *text) 1298 { 1299 DWORD size; 1300 HANDLE file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 1301 ok(hinst, file != INVALID_HANDLE_VALUE, "CreateFile failed, error %u\n", GetLastError()); 1302 1303 SetFilePointer(file, 0, NULL, FILE_END); 1304 WriteFile(file, text, strlen(text), &size, NULL); 1305 CloseHandle(file); 1306 } 1307 1308 UINT WINAPI da_immediate(MSIHANDLE hinst) 1309 { 1310 char prop[300]; 1311 DWORD len = sizeof(prop); 1312 1313 MsiGetPropertyA(hinst, "TESTPATH", prop, &len); 1314 1315 append_file(hinst, prop, "one"); 1316 1317 ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_SCHEDULED), "shouldn't be scheduled\n"); 1318 ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_ROLLBACK), "shouldn't be rollback\n"); 1319 ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_COMMIT), "shouldn't be commit\n"); 1320 1321 return ERROR_SUCCESS; 1322 } 1323 1324 UINT WINAPI da_deferred(MSIHANDLE hinst) 1325 { 1326 char prop[300]; 1327 DWORD len = sizeof(prop); 1328 LANGID lang; 1329 UINT r; 1330 1331 /* Test that we were in fact deferred */ 1332 r = MsiGetPropertyA(hinst, "CustomActionData", prop, &len); 1333 ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); 1334 ok(hinst, prop[0], "CustomActionData was empty\n"); 1335 1336 append_file(hinst, prop, "two"); 1337 1338 /* Test available properties */ 1339 len = sizeof(prop); 1340 r = MsiGetPropertyA(hinst, "ProductCode", prop, &len); 1341 ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); 1342 ok(hinst, prop[0], "got %s\n", prop); 1343 1344 len = sizeof(prop); 1345 r = MsiGetPropertyA(hinst, "UserSID", prop, &len); 1346 ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); 1347 ok(hinst, prop[0], "got %s\n", prop); 1348 1349 len = sizeof(prop); 1350 r = MsiGetPropertyA(hinst, "TESTPATH", prop, &len); 1351 ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); 1352 todo_wine 1353 ok(hinst, !prop[0], "got %s\n", prop); 1354 1355 /* Test modes */ 1356 ok(hinst, MsiGetMode(hinst, MSIRUNMODE_SCHEDULED), "should be scheduled\n"); 1357 ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_ROLLBACK), "shouldn't be rollback\n"); 1358 ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_COMMIT), "shouldn't be commit\n"); 1359 1360 lang = MsiGetLanguage(hinst); 1361 ok(hinst, lang != ERROR_INVALID_HANDLE, "MsiGetLanguage failed\n"); 1362 1363 return ERROR_SUCCESS; 1364 } 1365 1366 static int global_state; 1367 1368 UINT WINAPI process1(MSIHANDLE hinst) 1369 { 1370 SetEnvironmentVariableA("MSI_PROCESS_TEST","1"); 1371 global_state++; 1372 return ERROR_SUCCESS; 1373 } 1374 1375 UINT WINAPI process2(MSIHANDLE hinst) 1376 { 1377 char env[2] = {0}; 1378 DWORD r = GetEnvironmentVariableA("MSI_PROCESS_TEST", env, sizeof(env)); 1379 ok(hinst, r == 1, "got %d, error %u\n", r, GetLastError()); 1380 ok(hinst, !strcmp(env, "1"), "got %s\n", env); 1381 ok(hinst, !global_state, "got global_state %d\n", global_state); 1382 return ERROR_SUCCESS; 1383 } 1384 1385 UINT WINAPI async1(MSIHANDLE hinst) 1386 { 1387 HANDLE event = CreateEventA(NULL, TRUE, FALSE, "wine_msi_async_test"); 1388 HANDLE event2 = CreateEventA(NULL, TRUE, FALSE, "wine_msi_async_test2"); 1389 DWORD r = WaitForSingleObject(event, 10000); 1390 ok(hinst, !r, "wait timed out\n"); 1391 SetEvent(event2); 1392 return ERROR_SUCCESS; 1393 } 1394 1395 UINT WINAPI async2(MSIHANDLE hinst) 1396 { 1397 HANDLE event = CreateEventA(NULL, TRUE, FALSE, "wine_msi_async_test"); 1398 HANDLE event2 = CreateEventA(NULL, TRUE, FALSE, "wine_msi_async_test2"); 1399 DWORD r; 1400 SetEvent(event); 1401 r = WaitForSingleObject(event2, 10000); 1402 ok(hinst, !r, "wait timed out\n"); 1403 return ERROR_SUCCESS; 1404 } 1405 1406 static BOOL pf_exists(const char *file) 1407 { 1408 char path[MAX_PATH]; 1409 1410 if (FAILED(SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path))) 1411 SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); 1412 strcat(path, "\\"); 1413 strcat(path, file); 1414 return GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES; 1415 } 1416 1417 UINT WINAPI cf_present(MSIHANDLE hinst) 1418 { 1419 ok(hinst, pf_exists("msitest\\first"), "folder absent\n"); 1420 ok(hinst, pf_exists("msitest\\second"), "folder absent\n"); 1421 ok(hinst, pf_exists("msitest\\third"), "folder absent\n"); 1422 return ERROR_SUCCESS; 1423 } 1424 1425 UINT WINAPI cf_absent(MSIHANDLE hinst) 1426 { 1427 ok(hinst, !pf_exists("msitest\\first"), "folder present\n"); 1428 ok(hinst, !pf_exists("msitest\\second"), "folder present\n"); 1429 ok(hinst, !pf_exists("msitest\\third"), "folder present\n"); 1430 return ERROR_SUCCESS; 1431 } 1432 1433 UINT WINAPI file_present(MSIHANDLE hinst) 1434 { 1435 ok(hinst, pf_exists("msitest\\first\\one.txt"), "file absent\n"); 1436 ok(hinst, pf_exists("msitest\\second\\two.txt"), "file absent\n"); 1437 return ERROR_SUCCESS; 1438 } 1439 1440 UINT WINAPI file_absent(MSIHANDLE hinst) 1441 { 1442 ok(hinst, !pf_exists("msitest\\first\\one.txt"), "file present\n"); 1443 ok(hinst, !pf_exists("msitest\\second\\two.txt"), "file present\n"); 1444 return ERROR_SUCCESS; 1445 } 1446 1447 UINT WINAPI crs_present(MSIHANDLE hinst) 1448 { 1449 ok(hinst, pf_exists("msitest\\shortcut.lnk"), "shortcut absent\n"); 1450 return ERROR_SUCCESS; 1451 } 1452 1453 UINT WINAPI crs_absent(MSIHANDLE hinst) 1454 { 1455 ok(hinst, !pf_exists("msitest\\shortcut.lnk"), "shortcut present\n"); 1456 return ERROR_SUCCESS; 1457 } 1458 1459 UINT WINAPI sds_present(MSIHANDLE hinst) 1460 { 1461 SC_HANDLE manager, service; 1462 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); 1463 service = OpenServiceA(manager, "TestService3", GENERIC_ALL); 1464 ok(hinst, !!service, "service absent: %u\n", GetLastError()); 1465 CloseServiceHandle(service); 1466 CloseServiceHandle(manager); 1467 return ERROR_SUCCESS; 1468 } 1469 1470 UINT WINAPI sds_absent(MSIHANDLE hinst) 1471 { 1472 SC_HANDLE manager, service; 1473 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); 1474 service = OpenServiceA(manager, "TestService3", GENERIC_ALL); 1475 ok(hinst, !service, "service present\n"); 1476 if (service) CloseServiceHandle(service); 1477 CloseServiceHandle(manager); 1478 return ERROR_SUCCESS; 1479 } 1480 1481 UINT WINAPI sis_present(MSIHANDLE hinst) 1482 { 1483 SC_HANDLE manager, service; 1484 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); 1485 service = OpenServiceA(manager, "TestService", GENERIC_ALL); 1486 ok(hinst, !!service, "service absent: %u\n", GetLastError()); 1487 CloseServiceHandle(service); 1488 CloseServiceHandle(manager); 1489 return ERROR_SUCCESS; 1490 } 1491 1492 UINT WINAPI sis_absent(MSIHANDLE hinst) 1493 { 1494 SC_HANDLE manager, service; 1495 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); 1496 service = OpenServiceA(manager, "TestService", GENERIC_ALL); 1497 ok(hinst, !service, "service present\n"); 1498 if (service) CloseServiceHandle(service); 1499 CloseServiceHandle(manager); 1500 return ERROR_SUCCESS; 1501 } 1502 1503 UINT WINAPI sss_started(MSIHANDLE hinst) 1504 { 1505 SC_HANDLE manager, service; 1506 SERVICE_STATUS status; 1507 BOOL ret; 1508 1509 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); 1510 service = OpenServiceA(manager, "Spooler", SC_MANAGER_ALL_ACCESS); 1511 ret = QueryServiceStatus(service, &status); 1512 ok(hinst, ret, "QueryServiceStatus failed: %u\n", GetLastError()); 1513 ok(hinst, status.dwCurrentState == SERVICE_RUNNING, "got %u\n", status.dwCurrentState); 1514 1515 CloseServiceHandle(service); 1516 CloseServiceHandle(manager); 1517 return ERROR_SUCCESS; 1518 } 1519 1520 UINT WINAPI sss_stopped(MSIHANDLE hinst) 1521 { 1522 SC_HANDLE manager, service; 1523 SERVICE_STATUS status; 1524 BOOL ret; 1525 1526 manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); 1527 service = OpenServiceA(manager, "Spooler", SC_MANAGER_ALL_ACCESS); 1528 ret = QueryServiceStatus(service, &status); 1529 ok(hinst, ret, "QueryServiceStatus failed: %u\n", GetLastError()); 1530 ok(hinst, status.dwCurrentState == SERVICE_STOPPED, "got %u\n", status.dwCurrentState); 1531 1532 CloseServiceHandle(service); 1533 CloseServiceHandle(manager); 1534 return ERROR_SUCCESS; 1535 } 1536 1537 UINT WINAPI rd_present(MSIHANDLE hinst) 1538 { 1539 ok(hinst, pf_exists("msitest\\original2.txt"), "file absent\n"); 1540 ok(hinst, pf_exists("msitest\\duplicate.txt"), "file absent\n"); 1541 ok(hinst, !pf_exists("msitest\\original3.txt"), "file present\n"); 1542 ok(hinst, !pf_exists("msitest\\duplicate2.txt"), "file present\n"); 1543 return ERROR_SUCCESS; 1544 } 1545 1546 UINT WINAPI rd_absent(MSIHANDLE hinst) 1547 { 1548 ok(hinst, !pf_exists("msitest\\original2.txt"), "file present\n"); 1549 ok(hinst, !pf_exists("msitest\\duplicate.txt"), "file present\n"); 1550 ok(hinst, !pf_exists("msitest\\original3.txt"), "file present\n"); 1551 ok(hinst, !pf_exists("msitest\\duplicate2.txt"), "file present\n"); 1552 return ERROR_SUCCESS; 1553 } 1554 1555 UINT WINAPI odbc_present(MSIHANDLE hinst) 1556 { 1557 int gotdriver = 0, gotdriver2 = 0; 1558 char buffer[1000], *p; 1559 WORD len; 1560 BOOL r; 1561 1562 buffer[0] = 0; 1563 len = sizeof(buffer); 1564 r = SQLGetInstalledDrivers(buffer, sizeof(buffer), &len); 1565 if (r) ok(hinst, len < sizeof(buffer), "buffer too small\n"); 1566 for (p = buffer; *p; p += strlen(p) + 1) 1567 { 1568 if (!strcmp(p, "ODBC test driver")) 1569 gotdriver = 1; 1570 if (!strcmp(p, "ODBC test driver2")) 1571 gotdriver2 = 1; 1572 } 1573 ok(hinst, gotdriver, "driver absent\n"); 1574 ok(hinst, gotdriver2, "driver 2 absent\n"); 1575 return ERROR_SUCCESS; 1576 } 1577 1578 UINT WINAPI odbc_absent(MSIHANDLE hinst) 1579 { 1580 int gotdriver = 0, gotdriver2 = 0; 1581 char buffer[1000], *p; 1582 WORD len; 1583 BOOL r; 1584 1585 buffer[0] = 0; 1586 len = sizeof(buffer); 1587 r = SQLGetInstalledDrivers(buffer, sizeof(buffer), &len); 1588 if (r) ok(hinst, len < sizeof(buffer), "buffer too small\n"); 1589 for (p = buffer; *p; p += strlen(p) + 1) 1590 { 1591 if (!strcmp(p, "ODBC test driver")) 1592 gotdriver = 1; 1593 if (!strcmp(p, "ODBC test driver2")) 1594 gotdriver2 = 1; 1595 } 1596 ok(hinst, !gotdriver, "driver present\n"); 1597 ok(hinst, !gotdriver2, "driver 2 present\n"); 1598 return ERROR_SUCCESS; 1599 } 1600 1601 UINT WINAPI mov_present(MSIHANDLE hinst) 1602 { 1603 ok(hinst, pf_exists("msitest\\canada"), "file absent\n"); 1604 ok(hinst, pf_exists("msitest\\dominica"), "file absent\n"); 1605 return ERROR_SUCCESS; 1606 } 1607 1608 UINT WINAPI mov_absent(MSIHANDLE hinst) 1609 { 1610 ok(hinst, !pf_exists("msitest\\canada"), "file present\n"); 1611 ok(hinst, !pf_exists("msitest\\dominica"), "file present\n"); 1612 return ERROR_SUCCESS; 1613 } 1614 1615 static void check_reg_str(MSIHANDLE hinst, HKEY key, const char *name, const char *expect) 1616 { 1617 char value[300]; 1618 DWORD sz; 1619 LONG res; 1620 1621 sz = sizeof(value); 1622 res = RegQueryValueExA(key, name, NULL, NULL, (BYTE *)value, &sz); 1623 if (expect) 1624 { 1625 ok(hinst, !res, "failed to get value \"%s\": %d\n", name, res); 1626 ok(hinst, !strcmp(value, expect), "\"%s\": expected \"%s\", got \"%s\"\n", 1627 name, expect, value); 1628 } 1629 else 1630 ok(hinst, res == ERROR_FILE_NOT_FOUND, "\"%s\": expected missing, got %u\n", 1631 name, res); 1632 } 1633 1634 static const char path_dotnet[] = "Software\\Microsoft\\Installer\\Assemblies\\Global"; 1635 static const char name_dotnet[] = "Wine.Dotnet.Assembly,processorArchitecture=\"MSIL\"," 1636 "publicKeyToken=\"abcdef0123456789\",version=\"1.0.0.0\",culture=\"neutral\""; 1637 1638 UINT WINAPI pa_present(MSIHANDLE hinst) 1639 { 1640 HKEY key; 1641 LONG res; 1642 1643 res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &key); 1644 ok(hinst, !res, "got %d\n", res); 1645 check_reg_str(hinst, key, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]"); 1646 RegCloseKey(key); 1647 1648 return ERROR_SUCCESS; 1649 } 1650 1651 UINT WINAPI pa_absent(MSIHANDLE hinst) 1652 { 1653 HKEY key; 1654 LONG res; 1655 1656 res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &key); 1657 ok(hinst, !res || res == ERROR_FILE_NOT_FOUND, "got %d\n", res); 1658 if (!res) 1659 { 1660 check_reg_str(hinst, key, name_dotnet, NULL); 1661 RegCloseKey(key); 1662 } 1663 return ERROR_SUCCESS; 1664 } 1665 1666 static const char ppc_key[] = "Software\\Microsoft\\Windows\\CurrentVersion\\" 1667 "Installer\\UserData\\S-1-5-18\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5"; 1668 1669 UINT WINAPI ppc_present(MSIHANDLE hinst) 1670 { 1671 char expect[MAX_PATH]; 1672 HKEY key; 1673 UINT r; 1674 1675 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ppc_key, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key); 1676 ok(hinst, !r, "got %u\n", r); 1677 1678 if (FAILED(SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, expect))) 1679 SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, expect); 1680 strcat(expect, "\\msitest\\maximus"); 1681 check_reg_str(hinst, key, "84A88FD7F6998CE40A22FB59F6B9C2BB", expect); 1682 1683 RegCloseKey(key); 1684 return ERROR_SUCCESS; 1685 } 1686 1687 UINT WINAPI ppc_absent(MSIHANDLE hinst) 1688 { 1689 HKEY key; 1690 UINT r; 1691 1692 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ppc_key, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key); 1693 ok(hinst, r == ERROR_FILE_NOT_FOUND, "got %u\n", r); 1694 return ERROR_SUCCESS; 1695 } 1696 1697 static const char pub_key[] = "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA"; 1698 1699 UINT WINAPI pub_present(MSIHANDLE hinst) 1700 { 1701 HKEY key; 1702 LONG res; 1703 1704 res = RegOpenKeyA(HKEY_CURRENT_USER, pub_key, &key); 1705 ok(hinst, !res, "got %u\n", res); 1706 res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL); 1707 ok(hinst, !res, "got %u\n", res); 1708 RegCloseKey(key); 1709 return ERROR_SUCCESS; 1710 } 1711 1712 UINT WINAPI pub_absent(MSIHANDLE hinst) 1713 { 1714 HKEY key; 1715 LONG res; 1716 1717 res = RegOpenKeyA(HKEY_CURRENT_USER, pub_key, &key); 1718 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1719 return ERROR_SUCCESS; 1720 } 1721 1722 static const char pf_classkey[] = "Installer\\Features\\84A88FD7F6998CE40A22FB59F6B9C2BB"; 1723 static const char pf_userkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\" 1724 "Installer\\UserData\\S-1-5-18\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features"; 1725 1726 UINT WINAPI pf_present(MSIHANDLE hinst) 1727 { 1728 HKEY key; 1729 LONG res; 1730 1731 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, pf_classkey, 0, KEY_READ | KEY_WOW64_64KEY, &key); 1732 ok(hinst, !res, "got %u\n", res); 1733 check_reg_str(hinst, key, "feature", ""); 1734 check_reg_str(hinst, key, "montecristo", ""); 1735 RegCloseKey(key); 1736 1737 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, pf_userkey, 0, KEY_READ | KEY_WOW64_64KEY, &key); 1738 ok(hinst, !res, "got %u\n", res); 1739 check_reg_str(hinst, key, "feature", "VGtfp^p+,?82@JU1j_KE"); 1740 check_reg_str(hinst, key, "montecristo", "VGtfp^p+,?82@JU1j_KE"); 1741 RegCloseKey(key); 1742 1743 return ERROR_SUCCESS; 1744 } 1745 1746 UINT WINAPI pf_absent(MSIHANDLE hinst) 1747 { 1748 HKEY key; 1749 LONG res; 1750 1751 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, pf_classkey, 0, KEY_READ | KEY_WOW64_64KEY, &key); 1752 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1753 1754 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, pf_userkey, 0, KEY_READ | KEY_WOW64_64KEY, &key); 1755 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1756 1757 return ERROR_SUCCESS; 1758 } 1759 1760 static const char pp_prodkey[] = "Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB"; 1761 1762 UINT WINAPI pp_present(MSIHANDLE hinst) 1763 { 1764 HKEY key; 1765 LONG res; 1766 1767 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, pp_prodkey, 0, KEY_READ | KEY_WOW64_64KEY, &key); 1768 ok(hinst, !res, "got %u\n", res); 1769 check_reg_str(hinst, key, "ProductName", "MSITEST"); 1770 check_reg_str(hinst, key, "PackageCode", "AC75740029052C94DA02821EECD05F2F"); 1771 check_reg_str(hinst, key, "Clients", ":"); 1772 1773 RegCloseKey(key); 1774 return ERROR_SUCCESS; 1775 } 1776 1777 UINT WINAPI pp_absent(MSIHANDLE hinst) 1778 { 1779 HKEY key; 1780 LONG res; 1781 1782 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, pp_prodkey, 0, KEY_READ | KEY_WOW64_64KEY, &key); 1783 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1784 1785 return ERROR_SUCCESS; 1786 } 1787 1788 UINT WINAPI rci_present(MSIHANDLE hinst) 1789 { 1790 HKEY key; 1791 LONG res; 1792 1793 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", 1794 0, KEY_READ | KEY_WOW64_32KEY, &key); 1795 ok(hinst, !res, "got %u\n", res); 1796 RegCloseKey(key); 1797 1798 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &key); 1799 ok(hinst, !res, "got %u\n", res); 1800 RegCloseKey(key); 1801 1802 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &key); 1803 ok(hinst, !res, "got %u\n", res); 1804 RegCloseKey(key); 1805 1806 return ERROR_SUCCESS; 1807 } 1808 1809 UINT WINAPI rci_absent(MSIHANDLE hinst) 1810 { 1811 HKEY key; 1812 LONG res; 1813 1814 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", 1815 0, KEY_READ | KEY_WOW64_32KEY, &key); 1816 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1817 1818 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &key); 1819 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1820 1821 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &key); 1822 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1823 1824 return ERROR_SUCCESS; 1825 } 1826 1827 UINT WINAPI rei_present(MSIHANDLE hinst) 1828 { 1829 HKEY key; 1830 LONG res; 1831 1832 res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &key); 1833 ok(hinst, !res, "got %u\n", res); 1834 RegCloseKey(key); 1835 1836 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &key); 1837 ok(hinst, !res, "got %u\n", res); 1838 RegCloseKey(key); 1839 1840 return ERROR_SUCCESS; 1841 } 1842 1843 UINT WINAPI rei_absent(MSIHANDLE hinst) 1844 { 1845 HKEY key; 1846 LONG res; 1847 1848 res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &key); 1849 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1850 1851 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &key); 1852 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1853 1854 return ERROR_SUCCESS; 1855 } 1856 1857 static const char font_key[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; 1858 1859 UINT WINAPI font_present(MSIHANDLE hinst) 1860 { 1861 HKEY key; 1862 LONG res; 1863 1864 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, font_key, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key); 1865 ok(hinst, !res, "got %u\n", res); 1866 res = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL); 1867 ok(hinst, !res, "got %u\n", res); 1868 RegCloseKey(key); 1869 1870 return ERROR_SUCCESS; 1871 } 1872 1873 UINT WINAPI font_absent(MSIHANDLE hinst) 1874 { 1875 HKEY key; 1876 LONG res; 1877 1878 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, font_key, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key); 1879 ok(hinst, !res, "got %u\n", res); 1880 check_reg_str(hinst, key, "msi test font", NULL); 1881 RegCloseKey(key); 1882 1883 return ERROR_SUCCESS; 1884 } 1885 1886 UINT WINAPI rmi_present(MSIHANDLE hinst) 1887 { 1888 HKEY key; 1889 LONG res; 1890 1891 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &key); 1892 ok(hinst, !res, "got %u\n", res); 1893 1894 return ERROR_SUCCESS; 1895 } 1896 1897 UINT WINAPI rmi_absent(MSIHANDLE hinst) 1898 { 1899 HKEY key; 1900 LONG res; 1901 1902 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &key); 1903 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1904 1905 return ERROR_SUCCESS; 1906 } 1907 1908 static const char rp_key[] = "Software\\Microsoft\\Windows\\CurrentVersion\\" 1909 "Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; 1910 1911 UINT WINAPI rp_present(MSIHANDLE hinst) 1912 { 1913 HKEY key; 1914 LONG res; 1915 1916 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, rp_key, 0, KEY_READ | KEY_WOW64_32KEY, &key); 1917 ok(hinst, !res, "got %u\n", res); 1918 check_reg_str(hinst, key, "DisplayName", "MSITEST"); 1919 RegCloseKey(key); 1920 1921 return ERROR_SUCCESS; 1922 } 1923 1924 UINT WINAPI rp_absent(MSIHANDLE hinst) 1925 { 1926 HKEY key; 1927 LONG res; 1928 1929 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, rp_key, 0, KEY_READ | KEY_WOW64_32KEY, &key); 1930 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1931 1932 return ERROR_SUCCESS; 1933 } 1934 1935 UINT WINAPI rpi_present(MSIHANDLE hinst) 1936 { 1937 HKEY key; 1938 LONG res; 1939 1940 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", 1941 0, KEY_READ | KEY_WOW64_32KEY, &key); 1942 ok(hinst, !res, "got %u\n", res); 1943 RegCloseKey(key); 1944 1945 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.1", &key); 1946 ok(hinst, !res, "got %u\n", res); 1947 RegCloseKey(key); 1948 1949 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class", &key); 1950 ok(hinst, !res, "got %u\n", res); 1951 RegCloseKey(key); 1952 1953 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.2", &key); 1954 ok(hinst, !res, "got %u\n", res); 1955 RegCloseKey(key); 1956 1957 return ERROR_SUCCESS; 1958 } 1959 1960 UINT WINAPI rpi_absent(MSIHANDLE hinst) 1961 { 1962 HKEY key; 1963 LONG res; 1964 1965 res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", 1966 0, KEY_READ | KEY_WOW64_32KEY, &key); 1967 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1968 1969 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.1", &key); 1970 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1971 1972 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class", &key); 1973 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1974 1975 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.2", &key); 1976 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 1977 1978 return ERROR_SUCCESS; 1979 } 1980 1981 static const CHAR ru_key[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" 1982 "\\UserData\\S-1-5-18\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties"; 1983 1984 UINT WINAPI ru_present(MSIHANDLE hinst) 1985 { 1986 HKEY key; 1987 LONG res; 1988 1989 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ru_key, 0, KEY_READ | KEY_WOW64_64KEY, &key); 1990 ok(hinst, !res, "got %u\n", res); 1991 check_reg_str(hinst, key, "ProductID", "none"); 1992 RegCloseKey(key); 1993 1994 return ERROR_SUCCESS; 1995 } 1996 1997 UINT WINAPI ru_absent(MSIHANDLE hinst) 1998 { 1999 HKEY key; 2000 LONG res; 2001 2002 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ru_key, 0, KEY_READ | KEY_WOW64_64KEY, &key); 2003 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 2004 2005 return ERROR_SUCCESS; 2006 } 2007 2008 static const GUID LIBID_register_test = 2009 {0xeac5166a, 0x9734, 0x4d91, {0x87,0x8f, 0x1d,0xd0,0x23,0x04,0xc6,0x6c}}; 2010 2011 UINT WINAPI tl_present(MSIHANDLE hinst) 2012 { 2013 ITypeLib *tlb; 2014 HRESULT hr; 2015 2016 hr = LoadRegTypeLib(&LIBID_register_test, 7, 1, 0, &tlb); 2017 ok(hinst, hr == S_OK, "got %#x\n", hr); 2018 ITypeLib_Release(tlb); 2019 2020 return ERROR_SUCCESS; 2021 } 2022 2023 UINT WINAPI tl_absent(MSIHANDLE hinst) 2024 { 2025 ITypeLib *tlb; 2026 HRESULT hr; 2027 2028 hr = LoadRegTypeLib(&LIBID_register_test, 7, 1, 0, &tlb); 2029 ok(hinst, hr == TYPE_E_LIBNOTREGISTERED, "got %#x\n", hr); 2030 2031 return ERROR_SUCCESS; 2032 } 2033 2034 UINT WINAPI sr_present(MSIHANDLE hinst) 2035 { 2036 HKEY key; 2037 LONG res; 2038 2039 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "selfreg_test", &key); 2040 ok(hinst, !res, "got %u\n", res); 2041 RegCloseKey(key); 2042 2043 return ERROR_SUCCESS; 2044 } 2045 2046 UINT WINAPI sr_absent(MSIHANDLE hinst) 2047 { 2048 HKEY key; 2049 LONG res; 2050 2051 res = RegOpenKeyA(HKEY_CLASSES_ROOT, "selfreg_test", &key); 2052 ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res); 2053 2054 return ERROR_SUCCESS; 2055 } 2056 2057 UINT WINAPI env_present(MSIHANDLE hinst) 2058 { 2059 HKEY key; 2060 LONG res; 2061 2062 res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); 2063 ok(hinst, !res, "got %u\n", res); 2064 check_reg_str(hinst, key, "MSITESTVAR3", "1"); 2065 check_reg_str(hinst, key, "MSITESTVAR4", "1"); 2066 RegCloseKey(key); 2067 2068 return ERROR_SUCCESS; 2069 } 2070 2071 UINT WINAPI env_absent(MSIHANDLE hinst) 2072 { 2073 HKEY key; 2074 LONG res; 2075 2076 res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key); 2077 ok(hinst, !res, "got %u\n", res); 2078 check_reg_str(hinst, key, "MSITESTVAR3", NULL); 2079 check_reg_str(hinst, key, "MSITESTVAR4", NULL); 2080 RegCloseKey(key); 2081 2082 return ERROR_SUCCESS; 2083 } 2084 2085 UINT WINAPI ini_present(MSIHANDLE hinst) 2086 { 2087 char path[MAX_PATH], buf[10]; 2088 DWORD len; 2089 2090 if (FAILED(SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path))) 2091 SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); 2092 strcat(path, "\\msitest\\test.ini"); 2093 2094 len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), path); 2095 ok(hinst, len == 6, "got %u\n", len); 2096 2097 return ERROR_SUCCESS; 2098 } 2099 2100 UINT WINAPI ini_absent(MSIHANDLE hinst) 2101 { 2102 char path[MAX_PATH], buf[10]; 2103 DWORD len; 2104 2105 if (FAILED(SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path))) 2106 SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); 2107 strcat(path, "\\msitest\\test.ini"); 2108 2109 len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), path); 2110 ok(hinst, !len, "got %u\n", len); 2111 2112 return ERROR_SUCCESS; 2113 } 2114 2115 UINT WINAPI wrv_present(MSIHANDLE hinst) 2116 { 2117 HKEY key; 2118 LONG res; 2119 2120 res = RegOpenKeyA(HKEY_CURRENT_USER, "msitest", &key); 2121 ok(hinst, !res, "got %u\n", res); 2122 check_reg_str(hinst, key, "sz", "string"); 2123 RegCloseKey(key); 2124 2125 return ERROR_SUCCESS; 2126 } 2127 2128 UINT WINAPI wrv_absent(MSIHANDLE hinst) 2129 { 2130 HKEY key; 2131 LONG res; 2132 2133 res = RegOpenKeyA(HKEY_CURRENT_USER, "msitest", &key); 2134 ok(hinst, !res, "got %u\n", res); 2135 check_reg_str(hinst, key, "sz", NULL); 2136 RegCloseKey(key); 2137 2138 return ERROR_SUCCESS; 2139 } 2140