Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninstall.c
Go to the documentation of this file.
00001 /* 00002 * Implementation of the Microsoft Installer (msi.dll) 00003 * 00004 * Copyright 2005 Aric Stewart for CodeWeavers 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 /* Msi top level apis directly related to installs */ 00022 00023 #define COBJMACROS 00024 00025 #include <stdarg.h> 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "winerror.h" 00030 #include "wine/debug.h" 00031 #include "msi.h" 00032 #include "msidefs.h" 00033 #include "objbase.h" 00034 #include "oleauto.h" 00035 00036 #include "msipriv.h" 00037 #include "msiserver.h" 00038 #include "wine/unicode.h" 00039 00040 WINE_DEFAULT_DEBUG_CHANNEL(msi); 00041 00042 /*********************************************************************** 00043 * MsiDoActionA (MSI.@) 00044 */ 00045 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction ) 00046 { 00047 LPWSTR szwAction; 00048 UINT ret; 00049 00050 TRACE("%s\n", debugstr_a(szAction)); 00051 00052 szwAction = strdupAtoW(szAction); 00053 if (szAction && !szwAction) 00054 return ERROR_FUNCTION_FAILED; 00055 00056 ret = MsiDoActionW( hInstall, szwAction ); 00057 msi_free( szwAction ); 00058 return ret; 00059 } 00060 00061 /*********************************************************************** 00062 * MsiDoActionW (MSI.@) 00063 */ 00064 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction ) 00065 { 00066 MSIPACKAGE *package; 00067 UINT ret; 00068 00069 TRACE("%s\n",debugstr_w(szAction)); 00070 00071 if (!szAction) 00072 return ERROR_INVALID_PARAMETER; 00073 00074 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 00075 if (!package) 00076 { 00077 HRESULT hr; 00078 BSTR action; 00079 IWineMsiRemotePackage *remote_package; 00080 00081 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 00082 if (!remote_package) 00083 return ERROR_INVALID_HANDLE; 00084 00085 action = SysAllocString( szAction ); 00086 if (!action) 00087 { 00088 IWineMsiRemotePackage_Release( remote_package ); 00089 return ERROR_OUTOFMEMORY; 00090 } 00091 00092 hr = IWineMsiRemotePackage_DoAction( remote_package, action ); 00093 00094 SysFreeString( action ); 00095 IWineMsiRemotePackage_Release( remote_package ); 00096 00097 if (FAILED(hr)) 00098 { 00099 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 00100 return HRESULT_CODE(hr); 00101 00102 return ERROR_FUNCTION_FAILED; 00103 } 00104 00105 return ERROR_SUCCESS; 00106 } 00107 00108 ret = ACTION_PerformUIAction( package, szAction, SCRIPT_NONE ); 00109 msiobj_release( &package->hdr ); 00110 00111 return ret; 00112 } 00113 00114 /*********************************************************************** 00115 * MsiSequenceA (MSI.@) 00116 */ 00117 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode ) 00118 { 00119 LPWSTR szwTable; 00120 UINT ret; 00121 00122 TRACE("%s, %d\n", debugstr_a(szTable), iSequenceMode); 00123 00124 szwTable = strdupAtoW(szTable); 00125 if (szTable && !szwTable) 00126 return ERROR_FUNCTION_FAILED; 00127 00128 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode ); 00129 msi_free( szwTable ); 00130 return ret; 00131 } 00132 00133 /*********************************************************************** 00134 * MsiSequenceW (MSI.@) 00135 */ 00136 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode ) 00137 { 00138 MSIPACKAGE *package; 00139 UINT ret; 00140 00141 TRACE("%s, %d\n", debugstr_w(szTable), iSequenceMode); 00142 00143 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 00144 if (!package) 00145 { 00146 HRESULT hr; 00147 BSTR table; 00148 IWineMsiRemotePackage *remote_package; 00149 00150 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 00151 if (!remote_package) 00152 return ERROR_INVALID_HANDLE; 00153 00154 table = SysAllocString( szTable ); 00155 if (!table) 00156 { 00157 IWineMsiRemotePackage_Release( remote_package ); 00158 return ERROR_OUTOFMEMORY; 00159 } 00160 00161 hr = IWineMsiRemotePackage_Sequence( remote_package, table, iSequenceMode ); 00162 00163 SysFreeString( table ); 00164 IWineMsiRemotePackage_Release( remote_package ); 00165 00166 if (FAILED(hr)) 00167 { 00168 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 00169 return HRESULT_CODE(hr); 00170 00171 return ERROR_FUNCTION_FAILED; 00172 } 00173 00174 return ERROR_SUCCESS; 00175 } 00176 ret = MSI_Sequence( package, szTable ); 00177 msiobj_release( &package->hdr ); 00178 return ret; 00179 } 00180 00181 UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz ) 00182 { 00183 UINT len, r = ERROR_SUCCESS; 00184 00185 if (awbuf->str.w && !sz ) 00186 return ERROR_INVALID_PARAMETER; 00187 00188 if (!sz) 00189 return r; 00190 00191 if (awbuf->unicode) 00192 { 00193 len = lstrlenW( str ); 00194 if (awbuf->str.w) 00195 lstrcpynW( awbuf->str.w, str, *sz ); 00196 } 00197 else 00198 { 00199 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL ); 00200 if (len) 00201 len--; 00202 WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL ); 00203 if ( awbuf->str.a && *sz && (len >= *sz) ) 00204 awbuf->str.a[*sz - 1] = 0; 00205 } 00206 00207 if (awbuf->str.w && len >= *sz) 00208 r = ERROR_MORE_DATA; 00209 *sz = len; 00210 return r; 00211 } 00212 00213 const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name ) 00214 { 00215 MSIFOLDER *folder = msi_get_loaded_folder( package, name ); 00216 00217 if (!folder) return NULL; 00218 if (!folder->ResolvedTarget) 00219 { 00220 MSIFOLDER *parent = folder; 00221 while (parent->Parent && strcmpW( parent->Parent, parent->Directory )) 00222 { 00223 parent = msi_get_loaded_folder( package, parent->Parent ); 00224 } 00225 msi_resolve_target_folder( package, parent->Directory, TRUE ); 00226 } 00227 return folder->ResolvedTarget; 00228 } 00229 00230 /*********************************************************************** 00231 * MsiGetTargetPath (internal) 00232 */ 00233 static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder, 00234 awstring *szPathBuf, LPDWORD pcchPathBuf ) 00235 { 00236 MSIPACKAGE *package; 00237 const WCHAR *path; 00238 UINT r = ERROR_FUNCTION_FAILED; 00239 00240 if (!szFolder) 00241 return ERROR_INVALID_PARAMETER; 00242 00243 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 00244 if (!package) 00245 { 00246 HRESULT hr; 00247 IWineMsiRemotePackage *remote_package; 00248 LPWSTR value = NULL; 00249 BSTR folder; 00250 DWORD len; 00251 00252 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 00253 if (!remote_package) 00254 return ERROR_INVALID_HANDLE; 00255 00256 folder = SysAllocString( szFolder ); 00257 if (!folder) 00258 { 00259 IWineMsiRemotePackage_Release( remote_package ); 00260 return ERROR_OUTOFMEMORY; 00261 } 00262 00263 len = 0; 00264 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, NULL, &len ); 00265 if (FAILED(hr)) 00266 goto done; 00267 00268 len++; 00269 value = msi_alloc(len * sizeof(WCHAR)); 00270 if (!value) 00271 { 00272 r = ERROR_OUTOFMEMORY; 00273 goto done; 00274 } 00275 00276 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, value, &len ); 00277 if (FAILED(hr)) 00278 goto done; 00279 00280 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf ); 00281 00282 done: 00283 IWineMsiRemotePackage_Release( remote_package ); 00284 SysFreeString( folder ); 00285 msi_free( value ); 00286 00287 if (FAILED(hr)) 00288 { 00289 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 00290 return HRESULT_CODE(hr); 00291 00292 return ERROR_FUNCTION_FAILED; 00293 } 00294 00295 return r; 00296 } 00297 00298 path = msi_get_target_folder( package, szFolder ); 00299 msiobj_release( &package->hdr ); 00300 00301 if (!path) 00302 return ERROR_DIRECTORY; 00303 00304 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf ); 00305 return r; 00306 } 00307 00308 /*********************************************************************** 00309 * MsiGetTargetPathA (MSI.@) 00310 */ 00311 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, 00312 LPSTR szPathBuf, LPDWORD pcchPathBuf ) 00313 { 00314 LPWSTR szwFolder; 00315 awstring path; 00316 UINT r; 00317 00318 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf); 00319 00320 szwFolder = strdupAtoW(szFolder); 00321 if (szFolder && !szwFolder) 00322 return ERROR_FUNCTION_FAILED; 00323 00324 path.unicode = FALSE; 00325 path.str.a = szPathBuf; 00326 00327 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf ); 00328 00329 msi_free( szwFolder ); 00330 00331 return r; 00332 } 00333 00334 /*********************************************************************** 00335 * MsiGetTargetPathW (MSI.@) 00336 */ 00337 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, 00338 LPWSTR szPathBuf, LPDWORD pcchPathBuf ) 00339 { 00340 awstring path; 00341 00342 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf); 00343 00344 path.unicode = TRUE; 00345 path.str.w = szPathBuf; 00346 00347 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf ); 00348 } 00349 00350 static WCHAR *get_source_root( MSIPACKAGE *package ) 00351 { 00352 msi_set_sourcedir_props( package, FALSE ); 00353 return msi_dup_property( package->db, szSourceDir ); 00354 } 00355 00356 WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder ) 00357 { 00358 MSIFOLDER *f; 00359 LPWSTR p, path = NULL, parent; 00360 00361 TRACE("working to resolve %s\n", debugstr_w(name)); 00362 00363 if (!strcmpW( name, szSourceDir )) name = szTargetDir; 00364 if (!(f = msi_get_loaded_folder( package, name ))) return NULL; 00365 00366 /* special resolving for root dir */ 00367 if (!strcmpW( name, szTargetDir ) && !f->ResolvedSource) 00368 { 00369 f->ResolvedSource = get_source_root( package ); 00370 } 00371 if (folder) *folder = f; 00372 if (f->ResolvedSource) 00373 { 00374 path = strdupW( f->ResolvedSource ); 00375 TRACE(" already resolved to %s\n", debugstr_w(path)); 00376 return path; 00377 } 00378 if (!f->Parent) return path; 00379 parent = f->Parent; 00380 TRACE(" ! parent is %s\n", debugstr_w(parent)); 00381 00382 p = msi_resolve_source_folder( package, parent, NULL ); 00383 00384 if (package->WordCount & msidbSumInfoSourceTypeCompressed) 00385 path = get_source_root( package ); 00386 else if (package->WordCount & msidbSumInfoSourceTypeSFN) 00387 path = msi_build_directory_name( 3, p, f->SourceShortPath, NULL ); 00388 else 00389 path = msi_build_directory_name( 3, p, f->SourceLongPath, NULL ); 00390 00391 TRACE("-> %s\n", debugstr_w(path)); 00392 f->ResolvedSource = strdupW( path ); 00393 msi_free( p ); 00394 00395 return path; 00396 } 00397 00398 /*********************************************************************** 00399 * MSI_GetSourcePath (internal) 00400 */ 00401 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder, 00402 awstring *szPathBuf, LPDWORD pcchPathBuf ) 00403 { 00404 MSIPACKAGE *package; 00405 LPWSTR path; 00406 UINT r = ERROR_FUNCTION_FAILED; 00407 00408 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf ); 00409 00410 if (!szFolder) 00411 return ERROR_INVALID_PARAMETER; 00412 00413 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 00414 if (!package) 00415 { 00416 HRESULT hr; 00417 IWineMsiRemotePackage *remote_package; 00418 LPWSTR value = NULL; 00419 BSTR folder; 00420 DWORD len; 00421 00422 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 00423 if (!remote_package) 00424 return ERROR_INVALID_HANDLE; 00425 00426 folder = SysAllocString( szFolder ); 00427 if (!folder) 00428 { 00429 IWineMsiRemotePackage_Release( remote_package ); 00430 return ERROR_OUTOFMEMORY; 00431 } 00432 00433 len = 0; 00434 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, NULL, &len ); 00435 if (FAILED(hr)) 00436 goto done; 00437 00438 len++; 00439 value = msi_alloc(len * sizeof(WCHAR)); 00440 if (!value) 00441 { 00442 r = ERROR_OUTOFMEMORY; 00443 goto done; 00444 } 00445 00446 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, value, &len ); 00447 if (FAILED(hr)) 00448 goto done; 00449 00450 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf ); 00451 00452 done: 00453 IWineMsiRemotePackage_Release( remote_package ); 00454 SysFreeString( folder ); 00455 msi_free( value ); 00456 00457 if (FAILED(hr)) 00458 { 00459 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 00460 return HRESULT_CODE(hr); 00461 00462 return ERROR_FUNCTION_FAILED; 00463 } 00464 00465 return r; 00466 } 00467 00468 if (szPathBuf->str.w && !pcchPathBuf ) 00469 { 00470 msiobj_release( &package->hdr ); 00471 return ERROR_INVALID_PARAMETER; 00472 } 00473 00474 path = msi_resolve_source_folder( package, szFolder, NULL ); 00475 msiobj_release( &package->hdr ); 00476 00477 TRACE("path = %s\n", debugstr_w(path)); 00478 if (!path) 00479 return ERROR_DIRECTORY; 00480 00481 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf ); 00482 msi_free( path ); 00483 return r; 00484 } 00485 00486 /*********************************************************************** 00487 * MsiGetSourcePathA (MSI.@) 00488 */ 00489 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder, 00490 LPSTR szPathBuf, LPDWORD pcchPathBuf ) 00491 { 00492 LPWSTR folder; 00493 awstring str; 00494 UINT r; 00495 00496 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf); 00497 00498 str.unicode = FALSE; 00499 str.str.a = szPathBuf; 00500 00501 folder = strdupAtoW( szFolder ); 00502 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf ); 00503 msi_free( folder ); 00504 00505 return r; 00506 } 00507 00508 /*********************************************************************** 00509 * MsiGetSourcePathW (MSI.@) 00510 */ 00511 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, 00512 LPWSTR szPathBuf, LPDWORD pcchPathBuf ) 00513 { 00514 awstring str; 00515 00516 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf ); 00517 00518 str.unicode = TRUE; 00519 str.str.w = szPathBuf; 00520 00521 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf ); 00522 } 00523 00524 /*********************************************************************** 00525 * MsiSetTargetPathA (MSI.@) 00526 */ 00527 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, 00528 LPCSTR szFolderPath ) 00529 { 00530 LPWSTR szwFolder = NULL, szwFolderPath = NULL; 00531 UINT rc = ERROR_OUTOFMEMORY; 00532 00533 if ( !szFolder || !szFolderPath ) 00534 return ERROR_INVALID_PARAMETER; 00535 00536 szwFolder = strdupAtoW(szFolder); 00537 szwFolderPath = strdupAtoW(szFolderPath); 00538 if (!szwFolder || !szwFolderPath) 00539 goto end; 00540 00541 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath ); 00542 00543 end: 00544 msi_free(szwFolder); 00545 msi_free(szwFolderPath); 00546 00547 return rc; 00548 } 00549 00550 static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR *path ) 00551 { 00552 FolderList *fl; 00553 MSIFOLDER *child; 00554 WCHAR *target_path; 00555 00556 if (!(target_path = msi_normalize_path( path ))) return; 00557 if (strcmpW( target_path, folder->ResolvedTarget )) 00558 { 00559 msi_free( folder->ResolvedTarget ); 00560 folder->ResolvedTarget = target_path; 00561 msi_set_property( package->db, folder->Directory, folder->ResolvedTarget ); 00562 00563 LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry ) 00564 { 00565 child = fl->folder; 00566 msi_resolve_target_folder( package, child->Directory, FALSE ); 00567 } 00568 } 00569 else msi_free( target_path ); 00570 } 00571 00572 UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath ) 00573 { 00574 DWORD attrib; 00575 MSIFOLDER *folder; 00576 MSIFILE *file; 00577 00578 TRACE("%p %s %s\n", package, debugstr_w(szFolder), debugstr_w(szFolderPath)); 00579 00580 attrib = GetFileAttributesW(szFolderPath); 00581 /* native MSI tests writeability by making temporary files at each drive */ 00582 if (attrib != INVALID_FILE_ATTRIBUTES && 00583 (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY)) 00584 { 00585 return ERROR_FUNCTION_FAILED; 00586 } 00587 if (!(folder = msi_get_loaded_folder( package, szFolder ))) return ERROR_DIRECTORY; 00588 00589 set_target_path( package, folder, szFolderPath ); 00590 00591 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) 00592 { 00593 const WCHAR *dir; 00594 MSICOMPONENT *comp = file->Component; 00595 00596 if (!comp->Enabled || (comp->assembly && !comp->assembly->application)) continue; 00597 00598 dir = msi_get_target_folder( package, comp->Directory ); 00599 msi_free( file->TargetPath ); 00600 file->TargetPath = msi_build_directory_name( 2, dir, file->FileName ); 00601 } 00602 return ERROR_SUCCESS; 00603 } 00604 00605 /*********************************************************************** 00606 * MsiSetTargetPathW (MSI.@) 00607 */ 00608 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, 00609 LPCWSTR szFolderPath) 00610 { 00611 MSIPACKAGE *package; 00612 UINT ret; 00613 00614 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath)); 00615 00616 if ( !szFolder || !szFolderPath ) 00617 return ERROR_INVALID_PARAMETER; 00618 00619 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 00620 if (!package) 00621 { 00622 HRESULT hr; 00623 BSTR folder, path; 00624 IWineMsiRemotePackage *remote_package; 00625 00626 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 00627 if (!remote_package) 00628 return ERROR_INVALID_HANDLE; 00629 00630 folder = SysAllocString( szFolder ); 00631 path = SysAllocString( szFolderPath ); 00632 if (!folder || !path) 00633 { 00634 SysFreeString(folder); 00635 SysFreeString(path); 00636 IWineMsiRemotePackage_Release( remote_package ); 00637 return ERROR_OUTOFMEMORY; 00638 } 00639 00640 hr = IWineMsiRemotePackage_SetTargetPath( remote_package, folder, path ); 00641 00642 SysFreeString(folder); 00643 SysFreeString(path); 00644 IWineMsiRemotePackage_Release( remote_package ); 00645 00646 if (FAILED(hr)) 00647 { 00648 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 00649 return HRESULT_CODE(hr); 00650 00651 return ERROR_FUNCTION_FAILED; 00652 } 00653 00654 return ERROR_SUCCESS; 00655 } 00656 00657 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath ); 00658 msiobj_release( &package->hdr ); 00659 return ret; 00660 } 00661 00662 /*********************************************************************** 00663 * MsiGetMode (MSI.@) 00664 * 00665 * Returns an internal installer state (if it is running in a mode iRunMode) 00666 * 00667 * PARAMS 00668 * hInstall [I] Handle to the installation 00669 * hRunMode [I] Checking run mode 00670 * MSIRUNMODE_ADMIN Administrative mode 00671 * MSIRUNMODE_ADVERTISE Advertisement mode 00672 * MSIRUNMODE_MAINTENANCE Maintenance mode 00673 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled 00674 * MSIRUNMODE_LOGENABLED Log file is writing 00675 * MSIRUNMODE_OPERATIONS Operations in progress?? 00676 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed 00677 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation 00678 * MSIRUNMODE_CABINET Files from cabinet are installed 00679 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed 00680 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed 00681 * MSIRUNMODE_RESERVED11 Reserved 00682 * MSIRUNMODE_WINDOWS9X Running under Windows95/98 00683 * MSIRUNMODE_ZAWENABLED Demand installation is supported 00684 * MSIRUNMODE_RESERVED14 Reserved 00685 * MSIRUNMODE_RESERVED15 Reserved 00686 * MSIRUNMODE_SCHEDULED called from install script 00687 * MSIRUNMODE_ROLLBACK called from rollback script 00688 * MSIRUNMODE_COMMIT called from commit script 00689 * 00690 * RETURNS 00691 * In the state: TRUE 00692 * Not in the state: FALSE 00693 * 00694 */ 00695 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) 00696 { 00697 MSIPACKAGE *package; 00698 BOOL r = FALSE; 00699 00700 TRACE("%d %d\n", hInstall, iRunMode); 00701 00702 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 00703 if (!package) 00704 { 00705 BOOL ret; 00706 HRESULT hr; 00707 IWineMsiRemotePackage *remote_package; 00708 00709 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 00710 if (!remote_package) 00711 return FALSE; 00712 00713 hr = IWineMsiRemotePackage_GetMode(remote_package, iRunMode, &ret); 00714 IWineMsiRemotePackage_Release(remote_package); 00715 00716 if (hr == S_OK) 00717 return ret; 00718 00719 return FALSE; 00720 } 00721 00722 switch (iRunMode) 00723 { 00724 case MSIRUNMODE_ADMIN: 00725 FIXME("no support for administrative installs\n"); 00726 break; 00727 00728 case MSIRUNMODE_ADVERTISE: 00729 FIXME("no support for advertised installs\n"); 00730 break; 00731 00732 case MSIRUNMODE_WINDOWS9X: 00733 if (GetVersion() & 0x80000000) 00734 r = TRUE; 00735 break; 00736 00737 case MSIRUNMODE_OPERATIONS: 00738 case MSIRUNMODE_RESERVED11: 00739 case MSIRUNMODE_RESERVED14: 00740 case MSIRUNMODE_RESERVED15: 00741 break; 00742 00743 case MSIRUNMODE_SCHEDULED: 00744 r = package->scheduled_action_running; 00745 break; 00746 00747 case MSIRUNMODE_ROLLBACK: 00748 r = package->rollback_action_running; 00749 break; 00750 00751 case MSIRUNMODE_COMMIT: 00752 r = package->commit_action_running; 00753 break; 00754 00755 case MSIRUNMODE_MAINTENANCE: 00756 r = msi_get_property_int( package->db, szInstalled, 0 ) != 0; 00757 break; 00758 00759 case MSIRUNMODE_ROLLBACKENABLED: 00760 r = msi_get_property_int( package->db, szRollbackDisabled, 0 ) == 0; 00761 break; 00762 00763 case MSIRUNMODE_REBOOTATEND: 00764 r = package->need_reboot_at_end; 00765 break; 00766 00767 case MSIRUNMODE_REBOOTNOW: 00768 r = package->need_reboot_now; 00769 break; 00770 00771 case MSIRUNMODE_LOGENABLED: 00772 r = (package->log_file != INVALID_HANDLE_VALUE); 00773 break; 00774 00775 default: 00776 FIXME("unimplemented run mode: %d\n", iRunMode); 00777 r = TRUE; 00778 } 00779 00780 msiobj_release( &package->hdr ); 00781 return r; 00782 } 00783 00784 /*********************************************************************** 00785 * MsiSetMode (MSI.@) 00786 */ 00787 UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState) 00788 { 00789 MSIPACKAGE *package; 00790 UINT r; 00791 00792 TRACE("%d %d %d\n", hInstall, iRunMode, fState); 00793 00794 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE ); 00795 if (!package) 00796 { 00797 HRESULT hr; 00798 IWineMsiRemotePackage *remote_package; 00799 00800 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); 00801 if (!remote_package) 00802 return FALSE; 00803 00804 hr = IWineMsiRemotePackage_SetMode( remote_package, iRunMode, fState ); 00805 IWineMsiRemotePackage_Release( remote_package ); 00806 00807 if (FAILED(hr)) 00808 { 00809 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 00810 return HRESULT_CODE(hr); 00811 00812 return ERROR_FUNCTION_FAILED; 00813 } 00814 00815 return ERROR_SUCCESS; 00816 } 00817 00818 switch (iRunMode) 00819 { 00820 case MSIRUNMODE_REBOOTATEND: 00821 package->need_reboot_at_end = (fState != 0); 00822 r = ERROR_SUCCESS; 00823 break; 00824 00825 case MSIRUNMODE_REBOOTNOW: 00826 package->need_reboot_now = (fState != 0); 00827 r = ERROR_SUCCESS; 00828 break; 00829 00830 default: 00831 r = ERROR_ACCESS_DENIED; 00832 } 00833 00834 msiobj_release( &package->hdr ); 00835 return r; 00836 } 00837 00838 /*********************************************************************** 00839 * MsiSetFeatureStateA (MSI.@) 00840 * 00841 * According to the docs, when this is called it immediately recalculates 00842 * all the component states as well 00843 */ 00844 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, 00845 INSTALLSTATE iState) 00846 { 00847 LPWSTR szwFeature = NULL; 00848 UINT rc; 00849 00850 szwFeature = strdupAtoW(szFeature); 00851 00852 if (!szwFeature) 00853 return ERROR_FUNCTION_FAILED; 00854 00855 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); 00856 00857 msi_free(szwFeature); 00858 00859 return rc; 00860 } 00861 00862 /* update component state based on a feature change */ 00863 void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature ) 00864 { 00865 INSTALLSTATE newstate; 00866 ComponentList *cl; 00867 00868 newstate = feature->ActionRequest; 00869 if (newstate == INSTALLSTATE_ABSENT) newstate = INSTALLSTATE_UNKNOWN; 00870 00871 LIST_FOR_EACH_ENTRY(cl, &feature->Components, ComponentList, entry) 00872 { 00873 MSICOMPONENT *component = cl->component; 00874 00875 if (!component->Enabled) continue; 00876 00877 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n", 00878 newstate, debugstr_w(component->Component), component->Installed, 00879 component->Action, component->ActionRequest); 00880 00881 if (newstate == INSTALLSTATE_LOCAL) 00882 { 00883 component->Action = INSTALLSTATE_LOCAL; 00884 component->ActionRequest = INSTALLSTATE_LOCAL; 00885 } 00886 else 00887 { 00888 ComponentList *clist; 00889 MSIFEATURE *f; 00890 00891 component->hasLocalFeature = FALSE; 00892 00893 component->Action = newstate; 00894 component->ActionRequest = newstate; 00895 /* if any other feature wants it local we need to set it local */ 00896 LIST_FOR_EACH_ENTRY(f, &package->features, MSIFEATURE, entry) 00897 { 00898 if ( f->ActionRequest != INSTALLSTATE_LOCAL && 00899 f->ActionRequest != INSTALLSTATE_SOURCE ) 00900 { 00901 continue; 00902 } 00903 LIST_FOR_EACH_ENTRY(clist, &f->Components, ComponentList, entry) 00904 { 00905 if (clist->component == component && 00906 (f->ActionRequest == INSTALLSTATE_LOCAL || 00907 f->ActionRequest == INSTALLSTATE_SOURCE)) 00908 { 00909 TRACE("Saved by %s\n", debugstr_w(f->Feature)); 00910 component->hasLocalFeature = TRUE; 00911 00912 if (component->Attributes & msidbComponentAttributesOptional) 00913 { 00914 if (f->Attributes & msidbFeatureAttributesFavorSource) 00915 { 00916 component->Action = INSTALLSTATE_SOURCE; 00917 component->ActionRequest = INSTALLSTATE_SOURCE; 00918 } 00919 else 00920 { 00921 component->Action = INSTALLSTATE_LOCAL; 00922 component->ActionRequest = INSTALLSTATE_LOCAL; 00923 } 00924 } 00925 else if (component->Attributes & msidbComponentAttributesSourceOnly) 00926 { 00927 component->Action = INSTALLSTATE_SOURCE; 00928 component->ActionRequest = INSTALLSTATE_SOURCE; 00929 } 00930 else 00931 { 00932 component->Action = INSTALLSTATE_LOCAL; 00933 component->ActionRequest = INSTALLSTATE_LOCAL; 00934 } 00935 } 00936 } 00937 } 00938 } 00939 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n", 00940 newstate, debugstr_w(component->Component), component->Installed, 00941 component->Action, component->ActionRequest); 00942 } 00943 } 00944 00945 UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE iState ) 00946 { 00947 UINT rc = ERROR_SUCCESS; 00948 MSIFEATURE *feature, *child; 00949 00950 TRACE("%s %i\n", debugstr_w(szFeature), iState); 00951 00952 feature = msi_get_loaded_feature( package, szFeature ); 00953 if (!feature) 00954 return ERROR_UNKNOWN_FEATURE; 00955 00956 if (iState == INSTALLSTATE_ADVERTISED && 00957 feature->Attributes & msidbFeatureAttributesDisallowAdvertise) 00958 return ERROR_FUNCTION_FAILED; 00959 00960 feature->ActionRequest = iState; 00961 00962 ACTION_UpdateComponentStates( package, feature ); 00963 00964 /* update all the features that are children of this feature */ 00965 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry ) 00966 { 00967 if (child->Feature_Parent && !strcmpW( szFeature, child->Feature_Parent )) 00968 MSI_SetFeatureStateW(package, child->Feature, iState); 00969 } 00970 00971 return rc; 00972 } 00973 00974 /*********************************************************************** 00975 * MsiSetFeatureStateW (MSI.@) 00976 */ 00977 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, 00978 INSTALLSTATE iState) 00979 { 00980 MSIPACKAGE* package; 00981 UINT rc = ERROR_SUCCESS; 00982 00983 TRACE("%s %i\n",debugstr_w(szFeature), iState); 00984 00985 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 00986 if (!package) 00987 { 00988 HRESULT hr; 00989 BSTR feature; 00990 IWineMsiRemotePackage *remote_package; 00991 00992 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 00993 if (!remote_package) 00994 return ERROR_INVALID_HANDLE; 00995 00996 feature = SysAllocString(szFeature); 00997 if (!feature) 00998 { 00999 IWineMsiRemotePackage_Release(remote_package); 01000 return ERROR_OUTOFMEMORY; 01001 } 01002 01003 hr = IWineMsiRemotePackage_SetFeatureState(remote_package, feature, iState); 01004 01005 SysFreeString(feature); 01006 IWineMsiRemotePackage_Release(remote_package); 01007 01008 if (FAILED(hr)) 01009 { 01010 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 01011 return HRESULT_CODE(hr); 01012 01013 return ERROR_FUNCTION_FAILED; 01014 } 01015 01016 return ERROR_SUCCESS; 01017 } 01018 01019 rc = MSI_SetFeatureStateW(package,szFeature,iState); 01020 01021 msiobj_release( &package->hdr ); 01022 return rc; 01023 } 01024 01025 /*********************************************************************** 01026 * MsiSetFeatureAttributesA (MSI.@) 01027 */ 01028 UINT WINAPI MsiSetFeatureAttributesA( MSIHANDLE handle, LPCSTR feature, DWORD attrs ) 01029 { 01030 UINT r; 01031 WCHAR *featureW = NULL; 01032 01033 TRACE("%u, %s, 0x%08x\n", handle, debugstr_a(feature), attrs); 01034 01035 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY; 01036 01037 r = MsiSetFeatureAttributesW( handle, featureW, attrs ); 01038 msi_free( featureW ); 01039 return r; 01040 } 01041 01042 static DWORD unmap_feature_attributes( DWORD attrs ) 01043 { 01044 DWORD ret = 0; 01045 01046 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORLOCAL) ret = msidbFeatureAttributesFavorLocal; 01047 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORSOURCE) ret |= msidbFeatureAttributesFavorSource; 01048 if (attrs & INSTALLFEATUREATTRIBUTE_FOLLOWPARENT) ret |= msidbFeatureAttributesFollowParent; 01049 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORADVERTISE) ret |= msidbFeatureAttributesFavorAdvertise; 01050 if (attrs & INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE) ret |= msidbFeatureAttributesDisallowAdvertise; 01051 if (attrs & INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE) ret |= msidbFeatureAttributesNoUnsupportedAdvertise; 01052 return ret; 01053 } 01054 01055 /*********************************************************************** 01056 * MsiSetFeatureAttributesW (MSI.@) 01057 */ 01058 UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attrs ) 01059 { 01060 MSIPACKAGE *package; 01061 MSIFEATURE *feature; 01062 WCHAR *costing; 01063 01064 TRACE("%u, %s, 0x%08x\n", handle, debugstr_w(name), attrs); 01065 01066 if (!name || !name[0]) return ERROR_UNKNOWN_FEATURE; 01067 01068 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ))) 01069 return ERROR_INVALID_HANDLE; 01070 01071 costing = msi_dup_property( package->db, szCostingComplete ); 01072 if (!costing || !strcmpW( costing, szOne )) 01073 { 01074 msi_free( costing ); 01075 msiobj_release( &package->hdr ); 01076 return ERROR_FUNCTION_FAILED; 01077 } 01078 msi_free( costing ); 01079 if (!(feature = msi_get_loaded_feature( package, name ))) 01080 { 01081 msiobj_release( &package->hdr ); 01082 return ERROR_UNKNOWN_FEATURE; 01083 } 01084 feature->Attributes = unmap_feature_attributes( attrs ); 01085 msiobj_release( &package->hdr ); 01086 return ERROR_SUCCESS; 01087 } 01088 01089 /*********************************************************************** 01090 * MsiGetFeatureStateA (MSI.@) 01091 */ 01092 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature, 01093 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 01094 { 01095 LPWSTR szwFeature = NULL; 01096 UINT rc; 01097 01098 if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY; 01099 01100 rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction); 01101 msi_free( szwFeature); 01102 return rc; 01103 } 01104 01105 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature, 01106 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 01107 { 01108 MSIFEATURE *feature; 01109 01110 feature = msi_get_loaded_feature(package,szFeature); 01111 if (!feature) 01112 return ERROR_UNKNOWN_FEATURE; 01113 01114 if (piInstalled) 01115 *piInstalled = feature->Installed; 01116 01117 if (piAction) 01118 *piAction = feature->ActionRequest; 01119 01120 TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest); 01121 01122 return ERROR_SUCCESS; 01123 } 01124 01125 /*********************************************************************** 01126 * MsiGetFeatureStateW (MSI.@) 01127 */ 01128 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, 01129 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 01130 { 01131 MSIPACKAGE* package; 01132 UINT ret; 01133 01134 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction); 01135 01136 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 01137 if (!package) 01138 { 01139 HRESULT hr; 01140 BSTR feature; 01141 IWineMsiRemotePackage *remote_package; 01142 01143 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 01144 if (!remote_package) 01145 return ERROR_INVALID_HANDLE; 01146 01147 feature = SysAllocString(szFeature); 01148 if (!feature) 01149 { 01150 IWineMsiRemotePackage_Release(remote_package); 01151 return ERROR_OUTOFMEMORY; 01152 } 01153 01154 hr = IWineMsiRemotePackage_GetFeatureState(remote_package, feature, 01155 piInstalled, piAction); 01156 01157 SysFreeString(feature); 01158 IWineMsiRemotePackage_Release(remote_package); 01159 01160 if (FAILED(hr)) 01161 { 01162 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 01163 return HRESULT_CODE(hr); 01164 01165 return ERROR_FUNCTION_FAILED; 01166 } 01167 01168 return ERROR_SUCCESS; 01169 } 01170 01171 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction); 01172 msiobj_release( &package->hdr ); 01173 return ret; 01174 } 01175 01176 /*********************************************************************** 01177 * MsiGetFeatureCostA (MSI.@) 01178 */ 01179 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature, 01180 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost) 01181 { 01182 LPWSTR szwFeature = NULL; 01183 UINT rc; 01184 01185 szwFeature = strdupAtoW(szFeature); 01186 01187 rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost); 01188 01189 msi_free(szwFeature); 01190 01191 return rc; 01192 } 01193 01194 static INT feature_cost( MSIFEATURE *feature ) 01195 { 01196 INT cost = 0; 01197 MSICOMPONENT *comp; 01198 01199 LIST_FOR_EACH_ENTRY( comp, &feature->Components, MSICOMPONENT, entry ) 01200 { 01201 cost += comp->Cost; 01202 } 01203 return cost; 01204 } 01205 01206 UINT MSI_GetFeatureCost( MSIPACKAGE *package, MSIFEATURE *feature, MSICOSTTREE tree, 01207 INSTALLSTATE state, LPINT cost ) 01208 { 01209 TRACE("%s, %u, %d, %p\n", debugstr_w(feature->Feature), tree, state, cost); 01210 01211 *cost = 0; 01212 switch (tree) 01213 { 01214 case MSICOSTTREE_CHILDREN: 01215 { 01216 MSIFEATURE *child; 01217 01218 LIST_FOR_EACH_ENTRY( child, &feature->Children, MSIFEATURE, entry ) 01219 { 01220 if (child->ActionRequest == state) 01221 *cost += feature_cost( child ); 01222 } 01223 break; 01224 } 01225 case MSICOSTTREE_PARENTS: 01226 { 01227 const WCHAR *feature_parent = feature->Feature_Parent; 01228 for (;;) 01229 { 01230 MSIFEATURE *parent = msi_get_loaded_feature( package, feature_parent ); 01231 if (!parent) 01232 break; 01233 01234 if (parent->ActionRequest == state) 01235 *cost += feature_cost( parent ); 01236 01237 feature_parent = parent->Feature_Parent; 01238 } 01239 break; 01240 } 01241 case MSICOSTTREE_SELFONLY: 01242 if (feature->ActionRequest == state) 01243 *cost = feature_cost( feature ); 01244 break; 01245 01246 default: 01247 WARN("unhandled cost tree %u\n", tree); 01248 break; 01249 } 01250 01251 *cost /= 512; 01252 return ERROR_SUCCESS; 01253 } 01254 01255 /*********************************************************************** 01256 * MsiGetFeatureCostW (MSI.@) 01257 */ 01258 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature, 01259 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost) 01260 { 01261 MSIPACKAGE *package; 01262 MSIFEATURE *feature; 01263 UINT ret; 01264 01265 TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature), 01266 iCostTree, iState, piCost); 01267 01268 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 01269 if (!package) 01270 { 01271 HRESULT hr; 01272 BSTR feature; 01273 IWineMsiRemotePackage *remote_package; 01274 01275 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 01276 if (!remote_package) 01277 return ERROR_INVALID_HANDLE; 01278 01279 feature = SysAllocString(szFeature); 01280 if (!feature) 01281 { 01282 IWineMsiRemotePackage_Release(remote_package); 01283 return ERROR_OUTOFMEMORY; 01284 } 01285 01286 hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature, 01287 iCostTree, iState, piCost); 01288 01289 SysFreeString(feature); 01290 IWineMsiRemotePackage_Release(remote_package); 01291 01292 if (FAILED(hr)) 01293 { 01294 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 01295 return HRESULT_CODE(hr); 01296 01297 return ERROR_FUNCTION_FAILED; 01298 } 01299 01300 return ERROR_SUCCESS; 01301 } 01302 01303 feature = msi_get_loaded_feature(package, szFeature); 01304 01305 if (feature) 01306 ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost); 01307 else 01308 ret = ERROR_UNKNOWN_FEATURE; 01309 01310 msiobj_release( &package->hdr ); 01311 return ret; 01312 } 01313 01314 /*********************************************************************** 01315 * MsiGetFeatureInfoA (MSI.@) 01316 */ 01317 UINT WINAPI MsiGetFeatureInfoA( MSIHANDLE handle, LPCSTR feature, LPDWORD attrs, 01318 LPSTR title, LPDWORD title_len, LPSTR help, LPDWORD help_len ) 01319 { 01320 UINT r; 01321 WCHAR *titleW = NULL, *helpW = NULL, *featureW = NULL; 01322 01323 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_a(feature), attrs, title, 01324 title_len, help, help_len); 01325 01326 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY; 01327 01328 if (title && title_len && !(titleW = msi_alloc( *title_len * sizeof(WCHAR) ))) 01329 { 01330 msi_free( featureW ); 01331 return ERROR_OUTOFMEMORY; 01332 } 01333 if (help && help_len && !(helpW = msi_alloc( *help_len * sizeof(WCHAR) ))) 01334 { 01335 msi_free( featureW ); 01336 msi_free( titleW ); 01337 return ERROR_OUTOFMEMORY; 01338 } 01339 r = MsiGetFeatureInfoW( handle, featureW, attrs, titleW, title_len, helpW, help_len ); 01340 if (r == ERROR_SUCCESS) 01341 { 01342 if (titleW) WideCharToMultiByte( CP_ACP, 0, titleW, -1, title, *title_len + 1, NULL, NULL ); 01343 if (helpW) WideCharToMultiByte( CP_ACP, 0, helpW, -1, help, *help_len + 1, NULL, NULL ); 01344 } 01345 msi_free( titleW ); 01346 msi_free( helpW ); 01347 msi_free( featureW ); 01348 return r; 01349 } 01350 01351 static DWORD map_feature_attributes( DWORD attrs ) 01352 { 01353 DWORD ret = 0; 01354 01355 if (attrs == msidbFeatureAttributesFavorLocal) ret |= INSTALLFEATUREATTRIBUTE_FAVORLOCAL; 01356 if (attrs & msidbFeatureAttributesFavorSource) ret |= INSTALLFEATUREATTRIBUTE_FAVORSOURCE; 01357 if (attrs & msidbFeatureAttributesFollowParent) ret |= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT; 01358 if (attrs & msidbFeatureAttributesFavorAdvertise) ret |= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE; 01359 if (attrs & msidbFeatureAttributesDisallowAdvertise) ret |= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE; 01360 if (attrs & msidbFeatureAttributesNoUnsupportedAdvertise) ret |= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE; 01361 return ret; 01362 } 01363 01364 static UINT MSI_GetFeatureInfo( MSIPACKAGE *package, LPCWSTR name, LPDWORD attrs, 01365 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len ) 01366 { 01367 UINT r = ERROR_SUCCESS; 01368 MSIFEATURE *feature = msi_get_loaded_feature( package, name ); 01369 int len; 01370 01371 if (!feature) return ERROR_UNKNOWN_FEATURE; 01372 if (attrs) *attrs = map_feature_attributes( feature->Attributes ); 01373 if (title_len) 01374 { 01375 if (feature->Title) len = strlenW( feature->Title ); 01376 else len = 0; 01377 if (*title_len <= len) 01378 { 01379 *title_len = len; 01380 if (title) r = ERROR_MORE_DATA; 01381 } 01382 else if (title) 01383 { 01384 if (feature->Title) strcpyW( title, feature->Title ); 01385 else *title = 0; 01386 *title_len = len; 01387 } 01388 } 01389 if (help_len) 01390 { 01391 if (feature->Description) len = strlenW( feature->Description ); 01392 else len = 0; 01393 if (*help_len <= len) 01394 { 01395 *help_len = len; 01396 if (help) r = ERROR_MORE_DATA; 01397 } 01398 else if (help) 01399 { 01400 if (feature->Description) strcpyW( help, feature->Description ); 01401 else *help = 0; 01402 *help_len = len; 01403 } 01404 } 01405 return r; 01406 } 01407 01408 /*********************************************************************** 01409 * MsiGetFeatureInfoW (MSI.@) 01410 */ 01411 UINT WINAPI MsiGetFeatureInfoW( MSIHANDLE handle, LPCWSTR feature, LPDWORD attrs, 01412 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len ) 01413 { 01414 UINT r; 01415 MSIPACKAGE *package; 01416 01417 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_w(feature), attrs, title, 01418 title_len, help, help_len); 01419 01420 if (!feature) return ERROR_INVALID_PARAMETER; 01421 01422 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ))) 01423 return ERROR_INVALID_HANDLE; 01424 01425 /* features may not have been loaded yet */ 01426 msi_load_all_components( package ); 01427 msi_load_all_features( package ); 01428 01429 r = MSI_GetFeatureInfo( package, feature, attrs, title, title_len, help, help_len ); 01430 msiobj_release( &package->hdr ); 01431 return r; 01432 } 01433 01434 /*********************************************************************** 01435 * MsiSetComponentStateA (MSI.@) 01436 */ 01437 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, 01438 INSTALLSTATE iState) 01439 { 01440 UINT rc; 01441 LPWSTR szwComponent = strdupAtoW(szComponent); 01442 01443 rc = MsiSetComponentStateW(hInstall, szwComponent, iState); 01444 01445 msi_free(szwComponent); 01446 01447 return rc; 01448 } 01449 01450 /*********************************************************************** 01451 * MsiGetComponentStateA (MSI.@) 01452 */ 01453 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent, 01454 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 01455 { 01456 LPWSTR szwComponent= NULL; 01457 UINT rc; 01458 01459 szwComponent= strdupAtoW(szComponent); 01460 01461 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction); 01462 01463 msi_free( szwComponent); 01464 01465 return rc; 01466 } 01467 01468 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent, 01469 INSTALLSTATE iState) 01470 { 01471 MSICOMPONENT *comp; 01472 01473 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState); 01474 01475 comp = msi_get_loaded_component(package, szComponent); 01476 if (!comp) 01477 return ERROR_UNKNOWN_COMPONENT; 01478 01479 if (comp->Enabled) 01480 comp->Action = iState; 01481 01482 return ERROR_SUCCESS; 01483 } 01484 01485 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent, 01486 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 01487 { 01488 MSICOMPONENT *comp; 01489 01490 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent), 01491 piInstalled, piAction); 01492 01493 comp = msi_get_loaded_component(package,szComponent); 01494 if (!comp) 01495 return ERROR_UNKNOWN_COMPONENT; 01496 01497 if (piInstalled) 01498 { 01499 if (comp->Enabled) 01500 *piInstalled = comp->Installed; 01501 else 01502 *piInstalled = INSTALLSTATE_UNKNOWN; 01503 } 01504 01505 if (piAction) 01506 { 01507 if (comp->Enabled) 01508 *piAction = comp->Action; 01509 else 01510 *piAction = INSTALLSTATE_UNKNOWN; 01511 } 01512 01513 TRACE("states (%i, %i)\n", comp->Installed, comp->Action ); 01514 return ERROR_SUCCESS; 01515 } 01516 01517 /*********************************************************************** 01518 * MsiSetComponentStateW (MSI.@) 01519 */ 01520 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent, 01521 INSTALLSTATE iState) 01522 { 01523 MSIPACKAGE* package; 01524 UINT ret; 01525 01526 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 01527 if (!package) 01528 { 01529 HRESULT hr; 01530 BSTR component; 01531 IWineMsiRemotePackage *remote_package; 01532 01533 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 01534 if (!remote_package) 01535 return ERROR_INVALID_HANDLE; 01536 01537 component = SysAllocString(szComponent); 01538 if (!component) 01539 { 01540 IWineMsiRemotePackage_Release(remote_package); 01541 return ERROR_OUTOFMEMORY; 01542 } 01543 01544 hr = IWineMsiRemotePackage_SetComponentState(remote_package, component, iState); 01545 01546 SysFreeString(component); 01547 IWineMsiRemotePackage_Release(remote_package); 01548 01549 if (FAILED(hr)) 01550 { 01551 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 01552 return HRESULT_CODE(hr); 01553 01554 return ERROR_FUNCTION_FAILED; 01555 } 01556 01557 return ERROR_SUCCESS; 01558 } 01559 01560 ret = MSI_SetComponentStateW(package, szComponent, iState); 01561 msiobj_release(&package->hdr); 01562 return ret; 01563 } 01564 01565 /*********************************************************************** 01566 * MsiGetComponentStateW (MSI.@) 01567 */ 01568 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent, 01569 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction) 01570 { 01571 MSIPACKAGE* package; 01572 UINT ret; 01573 01574 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szComponent), 01575 piInstalled, piAction); 01576 01577 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 01578 if (!package) 01579 { 01580 HRESULT hr; 01581 BSTR component; 01582 IWineMsiRemotePackage *remote_package; 01583 01584 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 01585 if (!remote_package) 01586 return ERROR_INVALID_HANDLE; 01587 01588 component = SysAllocString(szComponent); 01589 if (!component) 01590 { 01591 IWineMsiRemotePackage_Release(remote_package); 01592 return ERROR_OUTOFMEMORY; 01593 } 01594 01595 hr = IWineMsiRemotePackage_GetComponentState(remote_package, component, 01596 piInstalled, piAction); 01597 01598 SysFreeString(component); 01599 IWineMsiRemotePackage_Release(remote_package); 01600 01601 if (FAILED(hr)) 01602 { 01603 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 01604 return HRESULT_CODE(hr); 01605 01606 return ERROR_FUNCTION_FAILED; 01607 } 01608 01609 return ERROR_SUCCESS; 01610 } 01611 01612 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction); 01613 msiobj_release( &package->hdr ); 01614 return ret; 01615 } 01616 01617 /*********************************************************************** 01618 * MsiGetLanguage (MSI.@) 01619 */ 01620 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall) 01621 { 01622 MSIPACKAGE* package; 01623 LANGID langid; 01624 01625 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 01626 if (!package) 01627 { 01628 HRESULT hr; 01629 LANGID lang; 01630 IWineMsiRemotePackage *remote_package; 01631 01632 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 01633 if (!remote_package) 01634 return ERROR_INVALID_HANDLE; 01635 01636 hr = IWineMsiRemotePackage_GetLanguage(remote_package, &lang); 01637 01638 if (SUCCEEDED(hr)) 01639 return lang; 01640 01641 return 0; 01642 } 01643 01644 langid = msi_get_property_int( package->db, szProductLanguage, 0 ); 01645 msiobj_release( &package->hdr ); 01646 return langid; 01647 } 01648 01649 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) 01650 { 01651 static const WCHAR fmt[] = { '%','d',0 }; 01652 WCHAR level[6]; 01653 UINT r; 01654 01655 TRACE("%p %i\n", package, iInstallLevel); 01656 01657 if (iInstallLevel > 32767) 01658 return ERROR_INVALID_PARAMETER; 01659 01660 if (iInstallLevel < 1) 01661 return MSI_SetFeatureStates( package ); 01662 01663 sprintfW( level, fmt, iInstallLevel ); 01664 r = msi_set_property( package->db, szInstallLevel, level ); 01665 if ( r == ERROR_SUCCESS ) 01666 r = MSI_SetFeatureStates( package ); 01667 01668 return r; 01669 } 01670 01671 /*********************************************************************** 01672 * MsiSetInstallLevel (MSI.@) 01673 */ 01674 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel) 01675 { 01676 MSIPACKAGE* package; 01677 UINT r; 01678 01679 TRACE("%d %i\n", hInstall, iInstallLevel); 01680 01681 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); 01682 if (!package) 01683 { 01684 HRESULT hr; 01685 IWineMsiRemotePackage *remote_package; 01686 01687 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); 01688 if (!remote_package) 01689 return ERROR_INVALID_HANDLE; 01690 01691 hr = IWineMsiRemotePackage_SetInstallLevel(remote_package, iInstallLevel); 01692 01693 IWineMsiRemotePackage_Release(remote_package); 01694 01695 if (FAILED(hr)) 01696 { 01697 if (HRESULT_FACILITY(hr) == FACILITY_WIN32) 01698 return HRESULT_CODE(hr); 01699 01700 return ERROR_FUNCTION_FAILED; 01701 } 01702 01703 return ERROR_SUCCESS; 01704 } 01705 01706 r = MSI_SetInstallLevel( package, iInstallLevel ); 01707 01708 msiobj_release( &package->hdr ); 01709 01710 return r; 01711 } 01712 01713 /*********************************************************************** 01714 * MsiGetFeatureValidStatesW (MSI.@) 01715 */ 01716 UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature, 01717 LPDWORD pInstallState) 01718 { 01719 if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL; 01720 FIXME("%d %s %p stub returning %d\n", 01721 hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0); 01722 01723 return ERROR_SUCCESS; 01724 } 01725 01726 /*********************************************************************** 01727 * MsiGetFeatureValidStatesA (MSI.@) 01728 */ 01729 UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature, 01730 LPDWORD pInstallState) 01731 { 01732 UINT ret; 01733 LPWSTR szwFeature = strdupAtoW(szFeature); 01734 01735 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState); 01736 01737 msi_free(szwFeature); 01738 01739 return ret; 01740 } Generated on Sat May 26 2012 04:18:06 for ReactOS by
1.7.6.1
|