1 /* 2 * Implementation of the Microsoft Installer (msi.dll) 3 * 4 * Copyright 2005 Aric Stewart for CodeWeavers 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 /* Msi top level apis directly related to installs */ 22 23 #include "msipriv.h" 24 25 WINE_DEFAULT_DEBUG_CHANNEL(msi); 26 27 /*********************************************************************** 28 * MsiDoActionA (MSI.@) 29 */ 30 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction ) 31 { 32 LPWSTR szwAction; 33 UINT ret; 34 35 TRACE("%s\n", debugstr_a(szAction)); 36 37 szwAction = strdupAtoW(szAction); 38 if (szAction && !szwAction) 39 return ERROR_FUNCTION_FAILED; 40 41 ret = MsiDoActionW( hInstall, szwAction ); 42 msi_free( szwAction ); 43 return ret; 44 } 45 46 /*********************************************************************** 47 * MsiDoActionW (MSI.@) 48 */ 49 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction ) 50 { 51 MSIPACKAGE *package; 52 UINT ret; 53 54 TRACE("%s\n",debugstr_w(szAction)); 55 56 if (!szAction) 57 return ERROR_INVALID_PARAMETER; 58 59 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 60 if (!package) 61 { 62 HRESULT hr; 63 BSTR action; 64 IWineMsiRemotePackage *remote_package; 65 66 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 67 if (!remote_package) 68 return ERROR_INVALID_HANDLE; 69 70 action = SysAllocString( szAction ); 71 if (!action) 72 { 73 IWineMsiRemotePackage_Release( remote_package ); 74 return ERROR_OUTOFMEMORY; 75 } 76 77 hr = IWineMsiRemotePackage_DoAction( remote_package, action ); 78 79 SysFreeString( action ); 80 IWineMsiRemotePackage_Release( remote_package ); 81 82 if (FAILED(hr)) 83 { 84 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 85 return HRESULT_CODE(hr); 86 87 return ERROR_FUNCTION_FAILED; 88 } 89 90 return ERROR_SUCCESS; 91 } 92 93 ret = ACTION_PerformUIAction( package, szAction, SCRIPT_NONE ); 94 msiobj_release( &package->hdr ); 95 96 return ret; 97 } 98 99 /*********************************************************************** 100 * MsiSequenceA (MSI.@) 101 */ 102 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode ) 103 { 104 LPWSTR szwTable; 105 UINT ret; 106 107 TRACE("%s, %d\n", debugstr_a(szTable), iSequenceMode); 108 109 szwTable = strdupAtoW(szTable); 110 if (szTable && !szwTable) 111 return ERROR_FUNCTION_FAILED; 112 113 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode ); 114 msi_free( szwTable ); 115 return ret; 116 } 117 118 /*********************************************************************** 119 * MsiSequenceW (MSI.@) 120 */ 121 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode ) 122 { 123 MSIPACKAGE *package; 124 UINT ret; 125 126 TRACE("%s, %d\n", debugstr_w(szTable), iSequenceMode); 127 128 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 129 if (!package) 130 { 131 HRESULT hr; 132 BSTR table; 133 IWineMsiRemotePackage *remote_package; 134 135 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 136 if (!remote_package) 137 return ERROR_INVALID_HANDLE; 138 139 table = SysAllocString( szTable ); 140 if (!table) 141 { 142 IWineMsiRemotePackage_Release( remote_package ); 143 return ERROR_OUTOFMEMORY; 144 } 145 146 hr = IWineMsiRemotePackage_Sequence( remote_package, table, iSequenceMode ); 147 148 SysFreeString( table ); 149 IWineMsiRemotePackage_Release( remote_package ); 150 151 if (FAILED(hr)) 152 { 153 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 154 return HRESULT_CODE(hr); 155 156 return ERROR_FUNCTION_FAILED; 157 } 158 159 return ERROR_SUCCESS; 160 } 161 ret = MSI_Sequence( package, szTable ); 162 msiobj_release( &package->hdr ); 163 return ret; 164 } 165 166 UINT msi_strcpy_to_awstring( const WCHAR *str, int len, awstring *awbuf, DWORD *sz ) 167 { 168 UINT r = ERROR_SUCCESS; 169 170 if (awbuf->str.w && !sz) 171 return ERROR_INVALID_PARAMETER; 172 if (!sz) 173 return ERROR_SUCCESS; 174 175 if (len < 0) len = strlenW( str ); 176 177 if (awbuf->unicode && awbuf->str.w) 178 memcpy( awbuf->str.w, str, min(len + 1, *sz) * sizeof(WCHAR) ); 179 else 180 { 181 int lenA = WideCharToMultiByte( CP_ACP, 0, str, len + 1, NULL, 0, NULL, NULL ); 182 if (lenA) lenA--; 183 WideCharToMultiByte( CP_ACP, 0, str, len + 1, awbuf->str.a, *sz, NULL, NULL ); 184 if (awbuf->str.a && *sz && lenA >= *sz) 185 awbuf->str.a[*sz - 1] = 0; 186 len = lenA; 187 } 188 if (awbuf->str.w && len >= *sz) 189 r = ERROR_MORE_DATA; 190 *sz = len; 191 return r; 192 } 193 194 const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name ) 195 { 196 MSIFOLDER *folder = msi_get_loaded_folder( package, name ); 197 198 if (!folder) return NULL; 199 if (!folder->ResolvedTarget) 200 { 201 MSIFOLDER *parent = folder; 202 while (parent->Parent && strcmpW( parent->Parent, parent->Directory )) 203 { 204 parent = msi_get_loaded_folder( package, parent->Parent ); 205 } 206 msi_resolve_target_folder( package, parent->Directory, TRUE ); 207 } 208 return folder->ResolvedTarget; 209 } 210 211 /*********************************************************************** 212 * MsiGetTargetPath (internal) 213 */ 214 static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder, 215 awstring *szPathBuf, LPDWORD pcchPathBuf ) 216 { 217 MSIPACKAGE *package; 218 const WCHAR *path; 219 UINT r = ERROR_FUNCTION_FAILED; 220 221 if (!szFolder) 222 return ERROR_INVALID_PARAMETER; 223 224 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 225 if (!package) 226 { 227 HRESULT hr; 228 IWineMsiRemotePackage *remote_package; 229 LPWSTR value = NULL; 230 BSTR folder; 231 DWORD len; 232 233 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 234 if (!remote_package) 235 return ERROR_INVALID_HANDLE; 236 237 folder = SysAllocString( szFolder ); 238 if (!folder) 239 { 240 IWineMsiRemotePackage_Release( remote_package ); 241 return ERROR_OUTOFMEMORY; 242 } 243 244 len = 0; 245 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, NULL, &len ); 246 if (FAILED(hr)) 247 goto done; 248 249 len++; 250 value = msi_alloc(len * sizeof(WCHAR)); 251 if (!value) 252 { 253 r = ERROR_OUTOFMEMORY; 254 goto done; 255 } 256 257 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, value, &len ); 258 if (FAILED(hr)) 259 goto done; 260 261 r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf ); 262 263 done: 264 IWineMsiRemotePackage_Release( remote_package ); 265 SysFreeString( folder ); 266 msi_free( value ); 267 268 if (FAILED(hr)) 269 { 270 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 271 return HRESULT_CODE(hr); 272 273 return ERROR_FUNCTION_FAILED; 274 } 275 276 return r; 277 } 278 279 path = msi_get_target_folder( package, szFolder ); 280 msiobj_release( &package->hdr ); 281 282 if (!path) 283 return ERROR_DIRECTORY; 284 285 return msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf ); 286 } 287 288 /*********************************************************************** 289 * MsiGetTargetPathA (MSI.@) 290 */ 291 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, 292 LPSTR szPathBuf, LPDWORD pcchPathBuf ) 293 { 294 LPWSTR szwFolder; 295 awstring path; 296 UINT r; 297 298 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf); 299 300 szwFolder = strdupAtoW(szFolder); 301 if (szFolder && !szwFolder) 302 return ERROR_FUNCTION_FAILED; 303 304 path.unicode = FALSE; 305 path.str.a = szPathBuf; 306 307 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf ); 308 309 msi_free( szwFolder ); 310 311 return r; 312 } 313 314 /*********************************************************************** 315 * MsiGetTargetPathW (MSI.@) 316 */ 317 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, 318 LPWSTR szPathBuf, LPDWORD pcchPathBuf ) 319 { 320 awstring path; 321 322 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf); 323 324 path.unicode = TRUE; 325 path.str.w = szPathBuf; 326 327 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf ); 328 } 329 330 static WCHAR *get_source_root( MSIPACKAGE *package ) 331 { 332 msi_set_sourcedir_props( package, FALSE ); 333 return msi_dup_property( package->db, szSourceDir ); 334 } 335 336 WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder ) 337 { 338 MSIFOLDER *f; 339 LPWSTR p, path = NULL, parent; 340 341 TRACE("working to resolve %s\n", debugstr_w(name)); 342 343 if (!strcmpW( name, szSourceDir )) name = szTargetDir; 344 if (!(f = msi_get_loaded_folder( package, name ))) return NULL; 345 346 /* special resolving for root dir */ 347 if (!strcmpW( name, szTargetDir ) && !f->ResolvedSource) 348 { 349 f->ResolvedSource = get_source_root( package ); 350 } 351 if (folder) *folder = f; 352 if (f->ResolvedSource) 353 { 354 path = strdupW( f->ResolvedSource ); 355 TRACE(" already resolved to %s\n", debugstr_w(path)); 356 return path; 357 } 358 if (!f->Parent) return path; 359 parent = f->Parent; 360 TRACE(" ! parent is %s\n", debugstr_w(parent)); 361 362 p = msi_resolve_source_folder( package, parent, NULL ); 363 364 if (package->WordCount & msidbSumInfoSourceTypeCompressed) 365 path = get_source_root( package ); 366 else if (package->WordCount & msidbSumInfoSourceTypeSFN) 367 path = msi_build_directory_name( 3, p, f->SourceShortPath, NULL ); 368 else 369 path = msi_build_directory_name( 3, p, f->SourceLongPath, NULL ); 370 371 TRACE("-> %s\n", debugstr_w(path)); 372 f->ResolvedSource = strdupW( path ); 373 msi_free( p ); 374 375 return path; 376 } 377 378 /*********************************************************************** 379 * MSI_GetSourcePath (internal) 380 */ 381 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder, 382 awstring *szPathBuf, LPDWORD pcchPathBuf ) 383 { 384 MSIPACKAGE *package; 385 LPWSTR path; 386 UINT r = ERROR_FUNCTION_FAILED; 387 388 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf ); 389 390 if (!szFolder) 391 return ERROR_INVALID_PARAMETER; 392 393 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 394 if (!package) 395 { 396 HRESULT hr; 397 IWineMsiRemotePackage *remote_package; 398 LPWSTR value = NULL; 399 BSTR folder; 400 DWORD len; 401 402 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 403 if (!remote_package) 404 return ERROR_INVALID_HANDLE; 405 406 folder = SysAllocString( szFolder ); 407 if (!folder) 408 { 409 IWineMsiRemotePackage_Release( remote_package ); 410 return ERROR_OUTOFMEMORY; 411 } 412 413 len = 0; 414 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, NULL, &len ); 415 if (FAILED(hr)) 416 goto done; 417 418 len++; 419 value = msi_alloc(len * sizeof(WCHAR)); 420 if (!value) 421 { 422 r = ERROR_OUTOFMEMORY; 423 goto done; 424 } 425 426 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, value, &len ); 427 if (FAILED(hr)) 428 goto done; 429 430 r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf ); 431 432 done: 433 IWineMsiRemotePackage_Release( remote_package ); 434 SysFreeString( folder ); 435 msi_free( value ); 436 437 if (FAILED(hr)) 438 { 439 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 440 return HRESULT_CODE(hr); 441 442 return ERROR_FUNCTION_FAILED; 443 } 444 445 return r; 446 } 447 448 if (szPathBuf->str.w && !pcchPathBuf ) 449 { 450 msiobj_release( &package->hdr ); 451 return ERROR_INVALID_PARAMETER; 452 } 453 454 path = msi_resolve_source_folder( package, szFolder, NULL ); 455 msiobj_release( &package->hdr ); 456 457 TRACE("path = %s\n", debugstr_w(path)); 458 if (!path) 459 return ERROR_DIRECTORY; 460 461 r = msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf ); 462 msi_free( path ); 463 return r; 464 } 465 466 /*********************************************************************** 467 * MsiGetSourcePathA (MSI.@) 468 */ 469 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder, 470 LPSTR szPathBuf, LPDWORD pcchPathBuf ) 471 { 472 LPWSTR folder; 473 awstring str; 474 UINT r; 475 476 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf); 477 478 str.unicode = FALSE; 479 str.str.a = szPathBuf; 480 481 folder = strdupAtoW( szFolder ); 482 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf ); 483 msi_free( folder ); 484 485 return r; 486 } 487 488 /*********************************************************************** 489 * MsiGetSourcePathW (MSI.@) 490 */ 491 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, 492 LPWSTR szPathBuf, LPDWORD pcchPathBuf ) 493 { 494 awstring str; 495 496 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf ); 497 498 str.unicode = TRUE; 499 str.str.w = szPathBuf; 500 501 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf ); 502 } 503 504 /*********************************************************************** 505 * MsiSetTargetPathA (MSI.@) 506 */ 507 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, 508 LPCSTR szFolderPath ) 509 { 510 LPWSTR szwFolder = NULL, szwFolderPath = NULL; 511 UINT rc = ERROR_OUTOFMEMORY; 512 513 if ( !szFolder || !szFolderPath ) 514 return ERROR_INVALID_PARAMETER; 515 516 szwFolder = strdupAtoW(szFolder); 517 szwFolderPath = strdupAtoW(szFolderPath); 518 if (!szwFolder || !szwFolderPath) 519 goto end; 520 521 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath ); 522 523 end: 524 msi_free(szwFolder); 525 msi_free(szwFolderPath); 526 527 return rc; 528 } 529 530 static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR *path ) 531 { 532 FolderList *fl; 533 MSIFOLDER *child; 534 WCHAR *target_path; 535 536 if (!(target_path = msi_normalize_path( path ))) return; 537 if (strcmpW( target_path, folder->ResolvedTarget )) 538 { 539 msi_free( folder->ResolvedTarget ); 540 folder->ResolvedTarget = target_path; 541 msi_set_property( package->db, folder->Directory, folder->ResolvedTarget, -1 ); 542 543 LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry ) 544 { 545 child = fl->folder; 546 msi_resolve_target_folder( package, child->Directory, FALSE ); 547 } 548 } 549 else msi_free( target_path ); 550 } 551 552 UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath ) 553 { 554 DWORD attrib; 555 MSIFOLDER *folder; 556 MSIFILE *file; 557 558 TRACE("%p %s %s\n", package, debugstr_w(szFolder), debugstr_w(szFolderPath)); 559 560 attrib = GetFileAttributesW(szFolderPath); 561 /* native MSI tests writeability by making temporary files at each drive */ 562 if (attrib != INVALID_FILE_ATTRIBUTES && 563 (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY)) 564 { 565 return ERROR_FUNCTION_FAILED; 566 } 567 if (!(folder = msi_get_loaded_folder( package, szFolder ))) return ERROR_DIRECTORY; 568 569 set_target_path( package, folder, szFolderPath ); 570 571 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) 572 { 573 const WCHAR *dir; 574 MSICOMPONENT *comp = file->Component; 575 576 if (!comp->Enabled || msi_is_global_assembly( comp )) continue; 577 578 dir = msi_get_target_folder( package, comp->Directory ); 579 msi_free( file->TargetPath ); 580 file->TargetPath = msi_build_directory_name( 2, dir, file->FileName ); 581 } 582 return ERROR_SUCCESS; 583 } 584 585 /*********************************************************************** 586 * MsiSetTargetPathW (MSI.@) 587 */ 588 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, 589 LPCWSTR szFolderPath) 590 { 591 MSIPACKAGE *package; 592 UINT ret; 593 594 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath)); 595 596 if ( !szFolder || !szFolderPath ) 597 return ERROR_INVALID_PARAMETER; 598 599 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 600 if (!package) 601 { 602 HRESULT hr; 603 BSTR folder, path; 604 IWineMsiRemotePackage *remote_package; 605 606 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 607 if (!remote_package) 608 return ERROR_INVALID_HANDLE; 609 610 folder = SysAllocString( szFolder ); 611 path = SysAllocString( szFolderPath ); 612 if (!folder || !path) 613 { 614 SysFreeString(folder); 615 SysFreeString(path); 616 IWineMsiRemotePackage_Release( remote_package ); 617 return ERROR_OUTOFMEMORY; 618 } 619 620 hr = IWineMsiRemotePackage_SetTargetPath( remote_package, folder, path ); 621 622 SysFreeString(folder); 623 SysFreeString(path); 624 IWineMsiRemotePackage_Release( remote_package ); 625 626 if (FAILED(hr)) 627 { 628 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 629 return HRESULT_CODE(hr); 630 631 return ERROR_FUNCTION_FAILED; 632 } 633 634 return ERROR_SUCCESS; 635 } 636 637 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath ); 638 msiobj_release( &package->hdr ); 639 return ret; 640 } 641 642 /*********************************************************************** 643 * MsiGetMode (MSI.@) 644 * 645 * Returns an internal installer state (if it is running in a mode iRunMode) 646 * 647 * PARAMS 648 * hInstall [I] Handle to the installation 649 * hRunMode [I] Checking run mode 650 * MSIRUNMODE_ADMIN Administrative mode 651 * MSIRUNMODE_ADVERTISE Advertisement mode 652 * MSIRUNMODE_MAINTENANCE Maintenance mode 653 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled 654 * MSIRUNMODE_LOGENABLED Log file is writing 655 * MSIRUNMODE_OPERATIONS Operations in progress?? 656 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed 657 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation 658 * MSIRUNMODE_CABINET Files from cabinet are installed 659 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed 660 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed 661 * MSIRUNMODE_RESERVED11 Reserved 662 * MSIRUNMODE_WINDOWS9X Running under Windows95/98 663 * MSIRUNMODE_ZAWENABLED Demand installation is supported 664 * MSIRUNMODE_RESERVED14 Reserved 665 * MSIRUNMODE_RESERVED15 Reserved 666 * MSIRUNMODE_SCHEDULED called from install script 667 * MSIRUNMODE_ROLLBACK called from rollback script 668 * MSIRUNMODE_COMMIT called from commit script 669 * 670 * RETURNS 671 * In the state: TRUE 672 * Not in the state: FALSE 673 * 674 */ 675 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) 676 { 677 MSIPACKAGE *package; 678 BOOL r = FALSE; 679 680 TRACE("%d %d\n", hInstall, iRunMode); 681 682 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 683 if (!package) 684 { 685 BOOL ret; 686 HRESULT hr; 687 IWineMsiRemotePackage *remote_package; 688 689 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 690 if (!remote_package) 691 return FALSE; 692 693 hr = IWineMsiRemotePackage_GetMode(remote_package, iRunMode, &ret); 694 IWineMsiRemotePackage_Release(remote_package); 695 696 if (hr == S_OK) 697 return ret; 698 699 return FALSE; 700 } 701 702 switch (iRunMode) 703 { 704 case MSIRUNMODE_ADMIN: 705 FIXME("no support for administrative installs\n"); 706 break; 707 708 case MSIRUNMODE_ADVERTISE: 709 FIXME("no support for advertised installs\n"); 710 break; 711 712 case MSIRUNMODE_WINDOWS9X: 713 if (GetVersion() & 0x80000000) 714 r = TRUE; 715 break; 716 717 case MSIRUNMODE_OPERATIONS: 718 case MSIRUNMODE_RESERVED11: 719 case MSIRUNMODE_RESERVED14: 720 case MSIRUNMODE_RESERVED15: 721 break; 722 723 case MSIRUNMODE_SCHEDULED: 724 r = package->scheduled_action_running; 725 break; 726 727 case MSIRUNMODE_ROLLBACK: 728 r = package->rollback_action_running; 729 break; 730 731 case MSIRUNMODE_COMMIT: 732 r = package->commit_action_running; 733 break; 734 735 case MSIRUNMODE_MAINTENANCE: 736 r = msi_get_property_int( package->db, szInstalled, 0 ) != 0; 737 break; 738 739 case MSIRUNMODE_ROLLBACKENABLED: 740 r = msi_get_property_int( package->db, szRollbackDisabled, 0 ) == 0; 741 break; 742 743 case MSIRUNMODE_REBOOTATEND: 744 r = package->need_reboot_at_end; 745 break; 746 747 case MSIRUNMODE_REBOOTNOW: 748 r = package->need_reboot_now; 749 break; 750 751 case MSIRUNMODE_LOGENABLED: 752 r = (package->log_file != INVALID_HANDLE_VALUE); 753 break; 754 755 default: 756 FIXME("unimplemented run mode: %d\n", iRunMode); 757 r = TRUE; 758 } 759 760 msiobj_release( &package->hdr ); 761 return r; 762 } 763 764 /*********************************************************************** 765 * MsiSetMode (MSI.@) 766 */ 767 UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState) 768 { 769 MSIPACKAGE *package; 770 UINT r; 771 772 TRACE("%d %d %d\n", hInstall, iRunMode, fState); 773 774 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 775 if (!package) 776 { 777 HRESULT hr; 778 IWineMsiRemotePackage *remote_package; 779 780 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 781 if (!remote_package) 782 return FALSE; 783 784 hr = IWineMsiRemotePackage_SetMode( remote_package, iRunMode, fState ); 785 IWineMsiRemotePackage_Release( remote_package ); 786 787 if (FAILED(hr)) 788 { 789 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 790 return HRESULT_CODE(hr); 791 792 return ERROR_FUNCTION_FAILED; 793 } 794 795 return ERROR_SUCCESS; 796 } 797 798 switch (iRunMode) 799 { 800 case MSIRUNMODE_REBOOTATEND: 801 package->need_reboot_at_end = (fState != 0); 802 r = ERROR_SUCCESS; 803 break; 804 805 case MSIRUNMODE_REBOOTNOW: 806 package->need_reboot_now = (fState != 0); 807 r = ERROR_SUCCESS; 808 break; 809 810 default: 811 r = ERROR_ACCESS_DENIED; 812 } 813 814 msiobj_release( &package->hdr ); 815 return r; 816 } 817 818 /*********************************************************************** 819 * MsiSetFeatureStateA (MSI.@) 820 * 821 * According to the docs, when this is called it immediately recalculates 822 * all the component states as well 823 */ 824 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, 825 INSTALLSTATE iState) 826 { 827 LPWSTR szwFeature = NULL; 828 UINT rc; 829 830 szwFeature = strdupAtoW(szFeature); 831 832 if (!szwFeature) 833 return ERROR_FUNCTION_FAILED; 834 835 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); 836 837 msi_free(szwFeature); 838 839 return rc; 840 } 841 842 /* update component state based on a feature change */ 843 void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature ) 844 { 845 INSTALLSTATE newstate; 846 ComponentList *cl; 847 848 newstate = feature->ActionRequest; 849 if (newstate == INSTALLSTATE_ABSENT) newstate = INSTALLSTATE_UNKNOWN; 850 851 LIST_FOR_EACH_ENTRY(cl, &feature->Components, ComponentList, entry) 852 { 853 MSICOMPONENT *component = cl->component; 854 855 if (!component->Enabled) continue; 856 857 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n", 858 newstate, debugstr_w(component->Component), component->Installed, 859 component->Action, component->ActionRequest); 860 861 if (newstate == INSTALLSTATE_LOCAL) 862 { 863 component->Action = INSTALLSTATE_LOCAL; 864 component->ActionRequest = INSTALLSTATE_LOCAL; 865 } 866 else 867 { 868 ComponentList *clist; 869 MSIFEATURE *f; 870 871 component->hasLocalFeature = FALSE; 872 873 component->Action = newstate; 874 component->ActionRequest = newstate; 875 /* if any other feature wants it local we need to set it local */ 876 LIST_FOR_EACH_ENTRY(f, &package->features, MSIFEATURE, entry) 877 { 878 if ( f->ActionRequest != INSTALLSTATE_LOCAL && 879 f->ActionRequest != INSTALLSTATE_SOURCE ) 880 { 881 continue; 882 } 883 LIST_FOR_EACH_ENTRY(clist, &f->Components, ComponentList, entry) 884 { 885 if (clist->component == component && 886 (f->ActionRequest == INSTALLSTATE_LOCAL || 887 f->ActionRequest == INSTALLSTATE_SOURCE)) 888 { 889 TRACE("Saved by %s\n", debugstr_w(f->Feature)); 890 component->hasLocalFeature = TRUE; 891 892 if (component->Attributes & msidbComponentAttributesOptional) 893 { 894 if (f->Attributes & msidbFeatureAttributesFavorSource) 895 { 896 component->Action = INSTALLSTATE_SOURCE; 897 component->ActionRequest = INSTALLSTATE_SOURCE; 898 } 899 else 900 { 901 component->Action = INSTALLSTATE_LOCAL; 902 component->ActionRequest = INSTALLSTATE_LOCAL; 903 } 904 } 905 else if (component->Attributes & msidbComponentAttributesSourceOnly) 906 { 907 component->Action = INSTALLSTATE_SOURCE; 908 component->ActionRequest = INSTALLSTATE_SOURCE; 909 } 910 else 911 { 912 component->Action = INSTALLSTATE_LOCAL; 913 component->ActionRequest = INSTALLSTATE_LOCAL; 914 } 915 } 916 } 917 } 918 } 919 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n", 920 newstate, debugstr_w(component->Component), component->Installed, 921 component->Action, component->ActionRequest); 922 } 923 } 924 925 UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE iState ) 926 { 927 UINT rc = ERROR_SUCCESS; 928 MSIFEATURE *feature, *child; 929 930 TRACE("%s %i\n", debugstr_w(szFeature), iState); 931 932 feature = msi_get_loaded_feature( package, szFeature ); 933 if (!feature) 934 return ERROR_UNKNOWN_FEATURE; 935 936 if (iState == INSTALLSTATE_ADVERTISED && 937 feature->Attributes & msidbFeatureAttributesDisallowAdvertise) 938 return ERROR_FUNCTION_FAILED; 939 940 feature->ActionRequest = iState; 941 942 ACTION_UpdateComponentStates( package, feature ); 943 944 /* update all the features that are children of this feature */ 945 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry ) 946 { 947 if (child->Feature_Parent && !strcmpW( szFeature, child->Feature_Parent )) 948 MSI_SetFeatureStateW(package, child->Feature, iState); 949 } 950 951 return rc; 952 } 953 954 /*********************************************************************** 955 * MsiSetFeatureStateW (MSI.@) 956 */ 957 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, 958 INSTALLSTATE iState) 959 { 960 MSIPACKAGE* package; 961 UINT rc = ERROR_SUCCESS; 962 963 TRACE("%s %i\n",debugstr_w(szFeature), iState); 964 965 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 966 if (!package) 967 { 968 HRESULT hr; 969 BSTR feature; 970 IWineMsiRemotePackage *remote_package; 971 972 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 973 if (!remote_package) 974 return ERROR_INVALID_HANDLE; 975 976 feature = SysAllocString(szFeature); 977 if (!feature) 978 { 979 IWineMsiRemotePackage_Release(remote_package); 980 return ERROR_OUTOFMEMORY; 981 } 982 983 hr = IWineMsiRemotePackage_SetFeatureState(remote_package, feature, iState); 984 985 SysFreeString(feature); 986 IWineMsiRemotePackage_Release(remote_package); 987 988 if (FAILED(hr)) 989 { 990 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 991 return HRESULT_CODE(hr); 992 993 return ERROR_FUNCTION_FAILED; 994 } 995 996 return ERROR_SUCCESS; 997 } 998 999 rc = MSI_SetFeatureStateW(package,szFeature,iState); 1000 1001 msiobj_release( &package->hdr ); 1002 return rc; 1003 } 1004 1005 /*********************************************************************** 1006 * MsiSetFeatureAttributesA (MSI.@) 1007 */ 1008 UINT WINAPI MsiSetFeatureAttributesA( MSIHANDLE handle, LPCSTR feature, DWORD attrs ) 1009 { 1010 UINT r; 1011 WCHAR *featureW = NULL; 1012 1013 TRACE("%u, %s, 0x%08x\n", handle, debugstr_a(feature), attrs); 1014 1015 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY; 1016 1017 r = MsiSetFeatureAttributesW( handle, featureW, attrs ); 1018 msi_free( featureW ); 1019 return r; 1020 } 1021 1022 static DWORD unmap_feature_attributes( DWORD attrs ) 1023 { 1024 DWORD ret = 0; 1025 1026 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORLOCAL) ret = msidbFeatureAttributesFavorLocal; 1027 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORSOURCE) ret |= msidbFeatureAttributesFavorSource; 1028 if (attrs & INSTALLFEATUREATTRIBUTE_FOLLOWPARENT) ret |= msidbFeatureAttributesFollowParent; 1029 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORADVERTISE) ret |= msidbFeatureAttributesFavorAdvertise; 1030 if (attrs & INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE) ret |= msidbFeatureAttributesDisallowAdvertise; 1031 if (attrs & INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE) ret |= msidbFeatureAttributesNoUnsupportedAdvertise; 1032 return ret; 1033 } 1034 1035 /*********************************************************************** 1036 * MsiSetFeatureAttributesW (MSI.@) 1037 */ 1038 UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attrs ) 1039 { 1040 MSIPACKAGE *package; 1041 MSIFEATURE *feature; 1042 WCHAR *costing; 1043 1044 TRACE("%u, %s, 0x%08x\n", handle, debugstr_w(name), attrs); 1045 1046 if (!name || !name[0]) return ERROR_UNKNOWN_FEATURE; 1047 1048 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ))) 1049 return ERROR_INVALID_HANDLE; 1050 1051 costing = msi_dup_property( package->db, szCostingComplete ); 1052 if (!costing || !strcmpW( costing, szOne )) 1053 { 1054 msi_free( costing ); 1055 msiobj_release( &package->hdr ); 1056 return ERROR_FUNCTION_FAILED; 1057 } 1058 msi_free( costing ); 1059 if (!(feature = msi_get_loaded_feature( package, name ))) 1060 { 1061 msiobj_release( &package->hdr ); 1062 return ERROR_UNKNOWN_FEATURE; 1063 } 1064 feature->Attributes = unmap_feature_attributes( attrs ); 1065 msiobj_release( &package->hdr ); 1066 return ERROR_SUCCESS; 1067 } 1068 1069 /*********************************************************************** 1070 * MsiGetFeatureStateA (MSI.@) 1071 */ 1072 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, 1073 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 1074 { 1075 LPWSTR szwFeature = NULL; 1076 UINT rc; 1077 1078 if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY; 1079 1080 rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction); 1081 msi_free( szwFeature); 1082 return rc; 1083 } 1084 1085 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature, 1086 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 1087 { 1088 MSIFEATURE *feature; 1089 1090 feature = msi_get_loaded_feature(package,szFeature); 1091 if (!feature) 1092 return ERROR_UNKNOWN_FEATURE; 1093 1094 if (piInstalled) 1095 *piInstalled = feature->Installed; 1096 1097 if (piAction) 1098 *piAction = feature->ActionRequest; 1099 1100 TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest); 1101 1102 return ERROR_SUCCESS; 1103 } 1104 1105 /*********************************************************************** 1106 * MsiGetFeatureStateW (MSI.@) 1107 */ 1108 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, 1109 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 1110 { 1111 MSIPACKAGE* package; 1112 UINT ret; 1113 1114 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction); 1115 1116 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 1117 if (!package) 1118 { 1119 HRESULT hr; 1120 BSTR feature; 1121 IWineMsiRemotePackage *remote_package; 1122 1123 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 1124 if (!remote_package) 1125 return ERROR_INVALID_HANDLE; 1126 1127 feature = SysAllocString(szFeature); 1128 if (!feature) 1129 { 1130 IWineMsiRemotePackage_Release(remote_package); 1131 return ERROR_OUTOFMEMORY; 1132 } 1133 1134 hr = IWineMsiRemotePackage_GetFeatureState(remote_package, feature, 1135 piInstalled, piAction); 1136 1137 SysFreeString(feature); 1138 IWineMsiRemotePackage_Release(remote_package); 1139 1140 if (FAILED(hr)) 1141 { 1142 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 1143 return HRESULT_CODE(hr); 1144 1145 return ERROR_FUNCTION_FAILED; 1146 } 1147 1148 return ERROR_SUCCESS; 1149 } 1150 1151 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction); 1152 msiobj_release( &package->hdr ); 1153 return ret; 1154 } 1155 1156 /*********************************************************************** 1157 * MsiGetFeatureCostA (MSI.@) 1158 */ 1159 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature, 1160 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost) 1161 { 1162 LPWSTR szwFeature = NULL; 1163 UINT rc; 1164 1165 szwFeature = strdupAtoW(szFeature); 1166 1167 rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost); 1168 1169 msi_free(szwFeature); 1170 1171 return rc; 1172 } 1173 1174 static INT feature_cost( MSIFEATURE *feature ) 1175 { 1176 INT cost = 0; 1177 ComponentList *cl; 1178 1179 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) 1180 { 1181 cost += cl->component->Cost; 1182 } 1183 return cost; 1184 } 1185 1186 UINT MSI_GetFeatureCost( MSIPACKAGE *package, MSIFEATURE *feature, MSICOSTTREE tree, 1187 INSTALLSTATE state, LPINT cost ) 1188 { 1189 TRACE("%s, %u, %d, %p\n", debugstr_w(feature->Feature), tree, state, cost); 1190 1191 *cost = 0; 1192 switch (tree) 1193 { 1194 case MSICOSTTREE_CHILDREN: 1195 { 1196 MSIFEATURE *child; 1197 1198 LIST_FOR_EACH_ENTRY( child, &feature->Children, MSIFEATURE, entry ) 1199 { 1200 if (child->ActionRequest == state) 1201 *cost += feature_cost( child ); 1202 } 1203 break; 1204 } 1205 case MSICOSTTREE_PARENTS: 1206 { 1207 const WCHAR *feature_parent = feature->Feature_Parent; 1208 for (;;) 1209 { 1210 MSIFEATURE *parent = msi_get_loaded_feature( package, feature_parent ); 1211 if (!parent) 1212 break; 1213 1214 if (parent->ActionRequest == state) 1215 *cost += feature_cost( parent ); 1216 1217 feature_parent = parent->Feature_Parent; 1218 } 1219 break; 1220 } 1221 case MSICOSTTREE_SELFONLY: 1222 if (feature->ActionRequest == state) 1223 *cost = feature_cost( feature ); 1224 break; 1225 1226 default: 1227 WARN("unhandled cost tree %u\n", tree); 1228 break; 1229 } 1230 1231 *cost /= 512; 1232 return ERROR_SUCCESS; 1233 } 1234 1235 /*********************************************************************** 1236 * MsiGetFeatureCostW (MSI.@) 1237 */ 1238 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature, 1239 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost) 1240 { 1241 MSIPACKAGE *package; 1242 MSIFEATURE *feature; 1243 UINT ret; 1244 1245 TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature), 1246 iCostTree, iState, piCost); 1247 1248 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 1249 if (!package) 1250 { 1251 HRESULT hr; 1252 BSTR feature; 1253 IWineMsiRemotePackage *remote_package; 1254 1255 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 1256 if (!remote_package) 1257 return ERROR_INVALID_HANDLE; 1258 1259 feature = SysAllocString(szFeature); 1260 if (!feature) 1261 { 1262 IWineMsiRemotePackage_Release(remote_package); 1263 return ERROR_OUTOFMEMORY; 1264 } 1265 1266 hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature, 1267 iCostTree, iState, piCost); 1268 1269 SysFreeString(feature); 1270 IWineMsiRemotePackage_Release(remote_package); 1271 1272 if (FAILED(hr)) 1273 { 1274 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 1275 return HRESULT_CODE(hr); 1276 1277 return ERROR_FUNCTION_FAILED; 1278 } 1279 1280 return ERROR_SUCCESS; 1281 } 1282 1283 feature = msi_get_loaded_feature(package, szFeature); 1284 1285 if (feature) 1286 ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost); 1287 else 1288 ret = ERROR_UNKNOWN_FEATURE; 1289 1290 msiobj_release( &package->hdr ); 1291 return ret; 1292 } 1293 1294 /*********************************************************************** 1295 * MsiGetFeatureInfoA (MSI.@) 1296 */ 1297 UINT WINAPI MsiGetFeatureInfoA( MSIHANDLE handle, LPCSTR feature, LPDWORD attrs, 1298 LPSTR title, LPDWORD title_len, LPSTR help, LPDWORD help_len ) 1299 { 1300 UINT r; 1301 WCHAR *titleW = NULL, *helpW = NULL, *featureW = NULL; 1302 1303 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_a(feature), attrs, title, 1304 title_len, help, help_len); 1305 1306 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY; 1307 1308 if (title && title_len && !(titleW = msi_alloc( *title_len * sizeof(WCHAR) ))) 1309 { 1310 msi_free( featureW ); 1311 return ERROR_OUTOFMEMORY; 1312 } 1313 if (help && help_len && !(helpW = msi_alloc( *help_len * sizeof(WCHAR) ))) 1314 { 1315 msi_free( featureW ); 1316 msi_free( titleW ); 1317 return ERROR_OUTOFMEMORY; 1318 } 1319 r = MsiGetFeatureInfoW( handle, featureW, attrs, titleW, title_len, helpW, help_len ); 1320 if (r == ERROR_SUCCESS) 1321 { 1322 if (titleW) WideCharToMultiByte( CP_ACP, 0, titleW, -1, title, *title_len + 1, NULL, NULL ); 1323 if (helpW) WideCharToMultiByte( CP_ACP, 0, helpW, -1, help, *help_len + 1, NULL, NULL ); 1324 } 1325 msi_free( titleW ); 1326 msi_free( helpW ); 1327 msi_free( featureW ); 1328 return r; 1329 } 1330 1331 static DWORD map_feature_attributes( DWORD attrs ) 1332 { 1333 DWORD ret = 0; 1334 1335 if (attrs == msidbFeatureAttributesFavorLocal) ret |= INSTALLFEATUREATTRIBUTE_FAVORLOCAL; 1336 if (attrs & msidbFeatureAttributesFavorSource) ret |= INSTALLFEATUREATTRIBUTE_FAVORSOURCE; 1337 if (attrs & msidbFeatureAttributesFollowParent) ret |= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT; 1338 if (attrs & msidbFeatureAttributesFavorAdvertise) ret |= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE; 1339 if (attrs & msidbFeatureAttributesDisallowAdvertise) ret |= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE; 1340 if (attrs & msidbFeatureAttributesNoUnsupportedAdvertise) ret |= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE; 1341 return ret; 1342 } 1343 1344 static UINT MSI_GetFeatureInfo( MSIPACKAGE *package, LPCWSTR name, LPDWORD attrs, 1345 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len ) 1346 { 1347 UINT r = ERROR_SUCCESS; 1348 MSIFEATURE *feature = msi_get_loaded_feature( package, name ); 1349 int len; 1350 1351 if (!feature) return ERROR_UNKNOWN_FEATURE; 1352 if (attrs) *attrs = map_feature_attributes( feature->Attributes ); 1353 if (title_len) 1354 { 1355 if (feature->Title) len = strlenW( feature->Title ); 1356 else len = 0; 1357 if (*title_len <= len) 1358 { 1359 *title_len = len; 1360 if (title) r = ERROR_MORE_DATA; 1361 } 1362 else if (title) 1363 { 1364 if (feature->Title) strcpyW( title, feature->Title ); 1365 else *title = 0; 1366 *title_len = len; 1367 } 1368 } 1369 if (help_len) 1370 { 1371 if (feature->Description) len = strlenW( feature->Description ); 1372 else len = 0; 1373 if (*help_len <= len) 1374 { 1375 *help_len = len; 1376 if (help) r = ERROR_MORE_DATA; 1377 } 1378 else if (help) 1379 { 1380 if (feature->Description) strcpyW( help, feature->Description ); 1381 else *help = 0; 1382 *help_len = len; 1383 } 1384 } 1385 return r; 1386 } 1387 1388 /*********************************************************************** 1389 * MsiGetFeatureInfoW (MSI.@) 1390 */ 1391 UINT WINAPI MsiGetFeatureInfoW( MSIHANDLE handle, LPCWSTR feature, LPDWORD attrs, 1392 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len ) 1393 { 1394 UINT r; 1395 MSIPACKAGE *package; 1396 1397 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_w(feature), attrs, title, 1398 title_len, help, help_len); 1399 1400 if (!feature) return ERROR_INVALID_PARAMETER; 1401 1402 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ))) 1403 return ERROR_INVALID_HANDLE; 1404 1405 /* features may not have been loaded yet */ 1406 msi_load_all_components( package ); 1407 msi_load_all_features( package ); 1408 1409 r = MSI_GetFeatureInfo( package, feature, attrs, title, title_len, help, help_len ); 1410 msiobj_release( &package->hdr ); 1411 return r; 1412 } 1413 1414 /*********************************************************************** 1415 * MsiSetComponentStateA (MSI.@) 1416 */ 1417 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, 1418 INSTALLSTATE iState) 1419 { 1420 UINT rc; 1421 LPWSTR szwComponent = strdupAtoW(szComponent); 1422 1423 rc = MsiSetComponentStateW(hInstall, szwComponent, iState); 1424 1425 msi_free(szwComponent); 1426 1427 return rc; 1428 } 1429 1430 /*********************************************************************** 1431 * MsiGetComponentStateA (MSI.@) 1432 */ 1433 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, 1434 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 1435 { 1436 LPWSTR szwComponent= NULL; 1437 UINT rc; 1438 1439 szwComponent= strdupAtoW(szComponent); 1440 1441 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction); 1442 1443 msi_free( szwComponent); 1444 1445 return rc; 1446 } 1447 1448 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent, 1449 INSTALLSTATE iState) 1450 { 1451 MSICOMPONENT *comp; 1452 1453 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState); 1454 1455 comp = msi_get_loaded_component(package, szComponent); 1456 if (!comp) 1457 return ERROR_UNKNOWN_COMPONENT; 1458 1459 if (comp->Enabled) 1460 comp->Action = iState; 1461 1462 return ERROR_SUCCESS; 1463 } 1464 1465 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent, 1466 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 1467 { 1468 MSICOMPONENT *comp; 1469 1470 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent), 1471 piInstalled, piAction); 1472 1473 comp = msi_get_loaded_component(package,szComponent); 1474 if (!comp) 1475 return ERROR_UNKNOWN_COMPONENT; 1476 1477 if (piInstalled) 1478 { 1479 if (comp->Enabled) 1480 *piInstalled = comp->Installed; 1481 else 1482 *piInstalled = INSTALLSTATE_UNKNOWN; 1483 } 1484 1485 if (piAction) 1486 { 1487 if (comp->Enabled) 1488 *piAction = comp->Action; 1489 else 1490 *piAction = INSTALLSTATE_UNKNOWN; 1491 } 1492 1493 TRACE("states (%i, %i)\n", comp->Installed, comp->Action ); 1494 return ERROR_SUCCESS; 1495 } 1496 1497 /*********************************************************************** 1498 * MsiSetComponentStateW (MSI.@) 1499 */ 1500 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent, 1501 INSTALLSTATE iState) 1502 { 1503 MSIPACKAGE* package; 1504 UINT ret; 1505 1506 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 1507 if (!package) 1508 { 1509 HRESULT hr; 1510 BSTR component; 1511 IWineMsiRemotePackage *remote_package; 1512 1513 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 1514 if (!remote_package) 1515 return ERROR_INVALID_HANDLE; 1516 1517 component = SysAllocString(szComponent); 1518 if (!component) 1519 { 1520 IWineMsiRemotePackage_Release(remote_package); 1521 return ERROR_OUTOFMEMORY; 1522 } 1523 1524 hr = IWineMsiRemotePackage_SetComponentState(remote_package, component, iState); 1525 1526 SysFreeString(component); 1527 IWineMsiRemotePackage_Release(remote_package); 1528 1529 if (FAILED(hr)) 1530 { 1531 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 1532 return HRESULT_CODE(hr); 1533 1534 return ERROR_FUNCTION_FAILED; 1535 } 1536 1537 return ERROR_SUCCESS; 1538 } 1539 1540 ret = MSI_SetComponentStateW(package, szComponent, iState); 1541 msiobj_release(&package->hdr); 1542 return ret; 1543 } 1544 1545 /*********************************************************************** 1546 * MsiGetComponentStateW (MSI.@) 1547 */ 1548 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent, 1549 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 1550 { 1551 MSIPACKAGE* package; 1552 UINT ret; 1553 1554 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szComponent), 1555 piInstalled, piAction); 1556 1557 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 1558 if (!package) 1559 { 1560 HRESULT hr; 1561 BSTR component; 1562 IWineMsiRemotePackage *remote_package; 1563 1564 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 1565 if (!remote_package) 1566 return ERROR_INVALID_HANDLE; 1567 1568 component = SysAllocString(szComponent); 1569 if (!component) 1570 { 1571 IWineMsiRemotePackage_Release(remote_package); 1572 return ERROR_OUTOFMEMORY; 1573 } 1574 1575 hr = IWineMsiRemotePackage_GetComponentState(remote_package, component, 1576 piInstalled, piAction); 1577 1578 SysFreeString(component); 1579 IWineMsiRemotePackage_Release(remote_package); 1580 1581 if (FAILED(hr)) 1582 { 1583 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 1584 return HRESULT_CODE(hr); 1585 1586 return ERROR_FUNCTION_FAILED; 1587 } 1588 1589 return ERROR_SUCCESS; 1590 } 1591 1592 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction); 1593 msiobj_release( &package->hdr ); 1594 return ret; 1595 } 1596 1597 /*********************************************************************** 1598 * MsiGetLanguage (MSI.@) 1599 */ 1600 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall) 1601 { 1602 MSIPACKAGE* package; 1603 LANGID langid; 1604 1605 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 1606 if (!package) 1607 { 1608 HRESULT hr; 1609 LANGID lang; 1610 IWineMsiRemotePackage *remote_package; 1611 1612 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 1613 if (!remote_package) 1614 return ERROR_INVALID_HANDLE; 1615 1616 hr = IWineMsiRemotePackage_GetLanguage(remote_package, &lang); 1617 1618 if (SUCCEEDED(hr)) 1619 return lang; 1620 1621 return 0; 1622 } 1623 1624 langid = msi_get_property_int( package->db, szProductLanguage, 0 ); 1625 msiobj_release( &package->hdr ); 1626 return langid; 1627 } 1628 1629 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) 1630 { 1631 static const WCHAR fmt[] = { '%','d',0 }; 1632 WCHAR level[6]; 1633 int len; 1634 UINT r; 1635 1636 TRACE("%p %i\n", package, iInstallLevel); 1637 1638 if (iInstallLevel > 32767) 1639 return ERROR_INVALID_PARAMETER; 1640 1641 if (iInstallLevel < 1) 1642 return MSI_SetFeatureStates( package ); 1643 1644 len = sprintfW( level, fmt, iInstallLevel ); 1645 r = msi_set_property( package->db, szInstallLevel, level, len ); 1646 if ( r == ERROR_SUCCESS ) 1647 r = MSI_SetFeatureStates( package ); 1648 1649 return r; 1650 } 1651 1652 /*********************************************************************** 1653 * MsiSetInstallLevel (MSI.@) 1654 */ 1655 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel) 1656 { 1657 MSIPACKAGE* package; 1658 UINT r; 1659 1660 TRACE("%d %i\n", hInstall, iInstallLevel); 1661 1662 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 1663 if (!package) 1664 { 1665 HRESULT hr; 1666 IWineMsiRemotePackage *remote_package; 1667 1668 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 1669 if (!remote_package) 1670 return ERROR_INVALID_HANDLE; 1671 1672 hr = IWineMsiRemotePackage_SetInstallLevel(remote_package, iInstallLevel); 1673 1674 IWineMsiRemotePackage_Release(remote_package); 1675 1676 if (FAILED(hr)) 1677 { 1678 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 1679 return HRESULT_CODE(hr); 1680 1681 return ERROR_FUNCTION_FAILED; 1682 } 1683 1684 return ERROR_SUCCESS; 1685 } 1686 1687 r = MSI_SetInstallLevel( package, iInstallLevel ); 1688 1689 msiobj_release( &package->hdr ); 1690 1691 return r; 1692 } 1693 1694 /*********************************************************************** 1695 * MsiGetFeatureValidStatesW (MSI.@) 1696 */ 1697 UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature, 1698 LPDWORD pInstallState) 1699 { 1700 if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL; 1701 FIXME("%d %s %p stub returning %d\n", 1702 hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0); 1703 1704 return ERROR_SUCCESS; 1705 } 1706 1707 /*********************************************************************** 1708 * MsiGetFeatureValidStatesA (MSI.@) 1709 */ 1710 UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature, 1711 LPDWORD pInstallState) 1712 { 1713 UINT ret; 1714 LPWSTR szwFeature = strdupAtoW(szFeature); 1715 1716 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState); 1717 1718 msi_free(szwFeature); 1719 1720 return ret; 1721 } 1722