ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

install.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.