2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2005 Aric Stewart for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* Msi top level apis directly related to installs */
30 #include "wine/debug.h"
37 #include "msiserver.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
42 /***********************************************************************
43 * MsiDoActionA (MSI.@)
45 UINT WINAPI
MsiDoActionA( MSIHANDLE hInstall
, LPCSTR szAction
)
50 TRACE("%s\n", debugstr_a(szAction
));
52 szwAction
= strdupAtoW(szAction
);
53 if (szAction
&& !szwAction
)
54 return ERROR_FUNCTION_FAILED
;
56 ret
= MsiDoActionW( hInstall
, szwAction
);
57 msi_free( szwAction
);
61 /***********************************************************************
62 * MsiDoActionW (MSI.@)
64 UINT WINAPI
MsiDoActionW( MSIHANDLE hInstall
, LPCWSTR szAction
)
69 TRACE("%s\n",debugstr_w(szAction
));
72 return ERROR_INVALID_PARAMETER
;
74 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
79 IWineMsiRemotePackage
*remote_package
;
81 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
83 return ERROR_INVALID_HANDLE
;
85 action
= SysAllocString( szAction
);
88 IWineMsiRemotePackage_Release( remote_package
);
89 return ERROR_OUTOFMEMORY
;
92 hr
= IWineMsiRemotePackage_DoAction( remote_package
, action
);
94 SysFreeString( action
);
95 IWineMsiRemotePackage_Release( remote_package
);
99 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
100 return HRESULT_CODE(hr
);
102 return ERROR_FUNCTION_FAILED
;
105 return ERROR_SUCCESS
;
108 ret
= ACTION_PerformUIAction( package
, szAction
, -1 );
109 msiobj_release( &package
->hdr
);
114 /***********************************************************************
115 * MsiSequenceA (MSI.@)
117 UINT WINAPI
MsiSequenceA( MSIHANDLE hInstall
, LPCSTR szTable
, INT iSequenceMode
)
122 TRACE("%s, %d\n", debugstr_a(szTable
), iSequenceMode
);
124 szwTable
= strdupAtoW(szTable
);
125 if (szTable
&& !szwTable
)
126 return ERROR_FUNCTION_FAILED
;
128 ret
= MsiSequenceW( hInstall
, szwTable
, iSequenceMode
);
129 msi_free( szwTable
);
133 /***********************************************************************
134 * MsiSequenceW (MSI.@)
136 UINT WINAPI
MsiSequenceW( MSIHANDLE hInstall
, LPCWSTR szTable
, INT iSequenceMode
)
141 TRACE("%s, %d\n", debugstr_w(szTable
), iSequenceMode
);
143 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
148 IWineMsiRemotePackage
*remote_package
;
150 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
152 return ERROR_INVALID_HANDLE
;
154 table
= SysAllocString( szTable
);
157 IWineMsiRemotePackage_Release( remote_package
);
158 return ERROR_OUTOFMEMORY
;
161 hr
= IWineMsiRemotePackage_Sequence( remote_package
, table
, iSequenceMode
);
163 SysFreeString( table
);
164 IWineMsiRemotePackage_Release( remote_package
);
168 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
169 return HRESULT_CODE(hr
);
171 return ERROR_FUNCTION_FAILED
;
174 return ERROR_SUCCESS
;
176 ret
= MSI_Sequence( package
, szTable
);
177 msiobj_release( &package
->hdr
);
181 UINT
msi_strcpy_to_awstring( LPCWSTR str
, awstring
*awbuf
, DWORD
*sz
)
183 UINT len
, r
= ERROR_SUCCESS
;
185 if (awbuf
->str
.w
&& !sz
)
186 return ERROR_INVALID_PARAMETER
;
193 len
= lstrlenW( str
);
195 lstrcpynW( awbuf
->str
.w
, str
, *sz
);
199 len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1, NULL
, 0, NULL
, NULL
);
202 WideCharToMultiByte( CP_ACP
, 0, str
, -1, awbuf
->str
.a
, *sz
, NULL
, NULL
);
203 if ( awbuf
->str
.a
&& *sz
&& (len
>= *sz
) )
204 awbuf
->str
.a
[*sz
- 1] = 0;
207 if (awbuf
->str
.w
&& len
>= *sz
)
213 const WCHAR
*msi_get_target_folder( MSIPACKAGE
*package
, const WCHAR
*name
)
215 MSIFOLDER
*folder
= msi_get_loaded_folder( package
, name
);
216 if (folder
) return folder
->ResolvedTarget
;
220 /***********************************************************************
221 * MsiGetTargetPath (internal)
223 static UINT
MSI_GetTargetPath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
224 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
228 UINT r
= ERROR_FUNCTION_FAILED
;
231 return ERROR_INVALID_PARAMETER
;
233 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
237 IWineMsiRemotePackage
*remote_package
;
242 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
244 return ERROR_INVALID_HANDLE
;
246 folder
= SysAllocString( szFolder
);
249 IWineMsiRemotePackage_Release( remote_package
);
250 return ERROR_OUTOFMEMORY
;
254 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
, NULL
, &len
);
259 value
= msi_alloc(len
* sizeof(WCHAR
));
262 r
= ERROR_OUTOFMEMORY
;
266 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
, value
, &len
);
270 r
= msi_strcpy_to_awstring( value
, szPathBuf
, pcchPathBuf
);
273 IWineMsiRemotePackage_Release( remote_package
);
274 SysFreeString( folder
);
279 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
280 return HRESULT_CODE(hr
);
282 return ERROR_FUNCTION_FAILED
;
288 path
= msi_get_target_folder( package
, szFolder
);
289 msiobj_release( &package
->hdr
);
292 return ERROR_DIRECTORY
;
294 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
298 /***********************************************************************
299 * MsiGetTargetPathA (MSI.@)
301 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
302 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
308 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
310 szwFolder
= strdupAtoW(szFolder
);
311 if (szFolder
&& !szwFolder
)
312 return ERROR_FUNCTION_FAILED
;
314 path
.unicode
= FALSE
;
315 path
.str
.a
= szPathBuf
;
317 r
= MSI_GetTargetPath( hInstall
, szwFolder
, &path
, pcchPathBuf
);
319 msi_free( szwFolder
);
324 /***********************************************************************
325 * MsiGetTargetPathW (MSI.@)
327 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
328 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
332 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
335 path
.str
.w
= szPathBuf
;
337 return MSI_GetTargetPath( hInstall
, szFolder
, &path
, pcchPathBuf
);
340 static WCHAR
*get_source_root( MSIDATABASE
*db
)
344 if ((path
= msi_dup_property( db
, szSourceDir
))) return path
;
345 if ((path
= msi_dup_property( db
, szDatabase
)))
347 if ((p
= strrchrW( path
, '\\' ))) p
[1] = 0;
352 WCHAR
*msi_resolve_source_folder( MSIPACKAGE
*package
, const WCHAR
*name
, MSIFOLDER
**folder
)
355 LPWSTR p
, path
= NULL
, parent
;
357 TRACE("working to resolve %s\n", debugstr_w(name
));
359 if (!strcmpW( name
, szSourceDir
)) name
= szTargetDir
;
360 if (!(f
= msi_get_loaded_folder( package
, name
))) return NULL
;
362 /* special resolving for root dir */
363 if (!strcmpW( name
, szTargetDir
) && !f
->ResolvedSource
)
365 f
->ResolvedSource
= get_source_root( package
->db
);
367 if (folder
) *folder
= f
;
368 if (f
->ResolvedSource
)
370 path
= strdupW( f
->ResolvedSource
);
371 TRACE(" already resolved to %s\n", debugstr_w(path
));
374 if (!f
->Parent
) return path
;
376 TRACE(" ! parent is %s\n", debugstr_w(parent
));
378 p
= msi_resolve_source_folder( package
, parent
, NULL
);
380 if (package
->WordCount
& msidbSumInfoSourceTypeCompressed
)
381 path
= get_source_root( package
->db
);
382 else if (package
->WordCount
& msidbSumInfoSourceTypeSFN
)
383 path
= msi_build_directory_name( 3, p
, f
->SourceShortPath
, NULL
);
385 path
= msi_build_directory_name( 3, p
, f
->SourceLongPath
, NULL
);
387 TRACE("-> %s\n", debugstr_w(path
));
388 f
->ResolvedSource
= strdupW( path
);
394 /***********************************************************************
395 * MSI_GetSourcePath (internal)
397 static UINT
MSI_GetSourcePath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
398 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
402 UINT r
= ERROR_FUNCTION_FAILED
;
404 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
407 return ERROR_INVALID_PARAMETER
;
409 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
413 IWineMsiRemotePackage
*remote_package
;
418 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
420 return ERROR_INVALID_HANDLE
;
422 folder
= SysAllocString( szFolder
);
425 IWineMsiRemotePackage_Release( remote_package
);
426 return ERROR_OUTOFMEMORY
;
430 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, NULL
, &len
);
435 value
= msi_alloc(len
* sizeof(WCHAR
));
438 r
= ERROR_OUTOFMEMORY
;
442 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, value
, &len
);
446 r
= msi_strcpy_to_awstring( value
, szPathBuf
, pcchPathBuf
);
449 IWineMsiRemotePackage_Release( remote_package
);
450 SysFreeString( folder
);
455 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
456 return HRESULT_CODE(hr
);
458 return ERROR_FUNCTION_FAILED
;
464 if (szPathBuf
->str
.w
&& !pcchPathBuf
)
466 msiobj_release( &package
->hdr
);
467 return ERROR_INVALID_PARAMETER
;
470 path
= msi_resolve_source_folder( package
, szFolder
, NULL
);
471 msiobj_release( &package
->hdr
);
473 TRACE("path = %s\n", debugstr_w(path
));
475 return ERROR_DIRECTORY
;
477 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
482 /***********************************************************************
483 * MsiGetSourcePathA (MSI.@)
485 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
486 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
492 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
495 str
.str
.a
= szPathBuf
;
497 folder
= strdupAtoW( szFolder
);
498 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
504 /***********************************************************************
505 * MsiGetSourcePathW (MSI.@)
507 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
508 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
512 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
515 str
.str
.w
= szPathBuf
;
517 return MSI_GetSourcePath( hInstall
, szFolder
, &str
, pcchPathBuf
);
520 /***********************************************************************
521 * MsiSetTargetPathA (MSI.@)
523 UINT WINAPI
MsiSetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
524 LPCSTR szFolderPath
)
526 LPWSTR szwFolder
= NULL
, szwFolderPath
= NULL
;
527 UINT rc
= ERROR_OUTOFMEMORY
;
529 if ( !szFolder
|| !szFolderPath
)
530 return ERROR_INVALID_PARAMETER
;
532 szwFolder
= strdupAtoW(szFolder
);
533 szwFolderPath
= strdupAtoW(szFolderPath
);
534 if (!szwFolder
|| !szwFolderPath
)
537 rc
= MsiSetTargetPathW( hInstall
, szwFolder
, szwFolderPath
);
541 msi_free(szwFolderPath
);
546 static void set_target_path( MSIPACKAGE
*package
, MSIFOLDER
*folder
, const WCHAR
*path
)
552 if (!(target_path
= strdupW( path
))) return;
553 msi_clean_path( target_path
);
554 if (strcmpW( target_path
, folder
->ResolvedTarget
))
556 msi_free( folder
->ResolvedTarget
);
557 folder
->ResolvedTarget
= target_path
;
558 msi_set_property( package
->db
, folder
->Directory
, folder
->ResolvedTarget
);
560 LIST_FOR_EACH_ENTRY( fl
, &folder
->children
, FolderList
, entry
)
563 msi_resolve_target_folder( package
, child
->Directory
, FALSE
);
566 else msi_free( target_path
);
569 UINT
MSI_SetTargetPathW( MSIPACKAGE
*package
, LPCWSTR szFolder
, LPCWSTR szFolderPath
)
575 TRACE("%p %s %s\n", package
, debugstr_w(szFolder
), debugstr_w(szFolderPath
));
577 attrib
= GetFileAttributesW(szFolderPath
);
578 /* native MSI tests writeability by making temporary files at each drive */
579 if (attrib
!= INVALID_FILE_ATTRIBUTES
&&
580 (attrib
& FILE_ATTRIBUTE_OFFLINE
|| attrib
& FILE_ATTRIBUTE_READONLY
))
582 return ERROR_FUNCTION_FAILED
;
584 if (!(folder
= msi_get_loaded_folder( package
, szFolder
))) return ERROR_DIRECTORY
;
586 len
= strlenW( szFolderPath
);
587 if (len
&& szFolderPath
[len
- 1] != '\\')
589 WCHAR
*path
= msi_alloc( (len
+ 2) * sizeof(WCHAR
) );
590 memcpy( path
, szFolderPath
, len
* sizeof(WCHAR
) );
593 set_target_path( package
, folder
, path
);
596 else set_target_path( package
, folder
, szFolderPath
);
598 LIST_FOR_EACH_ENTRY( file
, &package
->files
, MSIFILE
, entry
)
601 MSICOMPONENT
*comp
= file
->Component
;
603 if (!comp
->Enabled
|| (comp
->assembly
&& !comp
->assembly
->application
)) continue;
605 dir
= msi_get_target_folder( package
, comp
->Directory
);
606 msi_free( file
->TargetPath
);
607 file
->TargetPath
= msi_build_directory_name( 2, dir
, file
->FileName
);
609 return ERROR_SUCCESS
;
612 /***********************************************************************
613 * MsiSetTargetPathW (MSI.@)
615 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
616 LPCWSTR szFolderPath
)
621 TRACE("%s %s\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
623 if ( !szFolder
|| !szFolderPath
)
624 return ERROR_INVALID_PARAMETER
;
626 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
631 IWineMsiRemotePackage
*remote_package
;
633 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
635 return ERROR_INVALID_HANDLE
;
637 folder
= SysAllocString( szFolder
);
638 path
= SysAllocString( szFolderPath
);
639 if (!folder
|| !path
)
641 SysFreeString(folder
);
643 IWineMsiRemotePackage_Release( remote_package
);
644 return ERROR_OUTOFMEMORY
;
647 hr
= IWineMsiRemotePackage_SetTargetPath( remote_package
, folder
, path
);
649 SysFreeString(folder
);
651 IWineMsiRemotePackage_Release( remote_package
);
655 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
656 return HRESULT_CODE(hr
);
658 return ERROR_FUNCTION_FAILED
;
661 return ERROR_SUCCESS
;
664 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
665 msiobj_release( &package
->hdr
);
669 /***********************************************************************
672 * Returns an internal installer state (if it is running in a mode iRunMode)
675 * hInstall [I] Handle to the installation
676 * hRunMode [I] Checking run mode
677 * MSIRUNMODE_ADMIN Administrative mode
678 * MSIRUNMODE_ADVERTISE Advertisement mode
679 * MSIRUNMODE_MAINTENANCE Maintenance mode
680 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
681 * MSIRUNMODE_LOGENABLED Log file is writing
682 * MSIRUNMODE_OPERATIONS Operations in progress??
683 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
684 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
685 * MSIRUNMODE_CABINET Files from cabinet are installed
686 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
687 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
688 * MSIRUNMODE_RESERVED11 Reserved
689 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
690 * MSIRUNMODE_ZAWENABLED Demand installation is supported
691 * MSIRUNMODE_RESERVED14 Reserved
692 * MSIRUNMODE_RESERVED15 Reserved
693 * MSIRUNMODE_SCHEDULED called from install script
694 * MSIRUNMODE_ROLLBACK called from rollback script
695 * MSIRUNMODE_COMMIT called from commit script
699 * Not in the state: FALSE
702 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
707 TRACE("%d %d\n", hInstall
, iRunMode
);
709 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
714 IWineMsiRemotePackage
*remote_package
;
716 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
720 hr
= IWineMsiRemotePackage_GetMode(remote_package
, iRunMode
, &ret
);
721 IWineMsiRemotePackage_Release(remote_package
);
731 case MSIRUNMODE_ADMIN
:
732 FIXME("no support for administrative installs\n");
735 case MSIRUNMODE_ADVERTISE
:
736 FIXME("no support for advertised installs\n");
739 case MSIRUNMODE_WINDOWS9X
:
740 if (GetVersion() & 0x80000000)
744 case MSIRUNMODE_OPERATIONS
:
745 case MSIRUNMODE_RESERVED11
:
746 case MSIRUNMODE_RESERVED14
:
747 case MSIRUNMODE_RESERVED15
:
750 case MSIRUNMODE_SCHEDULED
:
751 r
= package
->scheduled_action_running
;
754 case MSIRUNMODE_ROLLBACK
:
755 r
= package
->rollback_action_running
;
758 case MSIRUNMODE_COMMIT
:
759 r
= package
->commit_action_running
;
762 case MSIRUNMODE_MAINTENANCE
:
763 r
= msi_get_property_int( package
->db
, szInstalled
, 0 ) != 0;
766 case MSIRUNMODE_ROLLBACKENABLED
:
767 r
= msi_get_property_int( package
->db
, szRollbackDisabled
, 0 ) == 0;
770 case MSIRUNMODE_REBOOTATEND
:
771 r
= package
->need_reboot
;
774 case MSIRUNMODE_LOGENABLED
:
775 r
= (package
->log_file
!= INVALID_HANDLE_VALUE
);
779 FIXME("unimplemented run mode: %d\n", iRunMode
);
783 msiobj_release( &package
->hdr
);
787 /***********************************************************************
790 UINT WINAPI
MsiSetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
, BOOL fState
)
795 TRACE("%d %d %d\n", hInstall
, iRunMode
, fState
);
797 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
801 IWineMsiRemotePackage
*remote_package
;
803 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
807 hr
= IWineMsiRemotePackage_SetMode( remote_package
, iRunMode
, fState
);
808 IWineMsiRemotePackage_Release( remote_package
);
812 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
813 return HRESULT_CODE(hr
);
815 return ERROR_FUNCTION_FAILED
;
818 return ERROR_SUCCESS
;
823 case MSIRUNMODE_REBOOTATEND
:
824 package
->need_reboot
= 1;
828 case MSIRUNMODE_REBOOTNOW
:
829 FIXME("unimplemented run mode: %d\n", iRunMode
);
830 r
= ERROR_FUNCTION_FAILED
;
834 r
= ERROR_ACCESS_DENIED
;
837 msiobj_release( &package
->hdr
);
841 /***********************************************************************
842 * MsiSetFeatureStateA (MSI.@)
844 * According to the docs, when this is called it immediately recalculates
845 * all the component states as well
847 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
850 LPWSTR szwFeature
= NULL
;
853 szwFeature
= strdupAtoW(szFeature
);
856 return ERROR_FUNCTION_FAILED
;
858 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
860 msi_free(szwFeature
);
865 /* update component state based on a feature change */
866 void ACTION_UpdateComponentStates( MSIPACKAGE
*package
, MSIFEATURE
*feature
)
868 INSTALLSTATE newstate
;
871 newstate
= feature
->ActionRequest
;
872 if (newstate
== INSTALLSTATE_ABSENT
) newstate
= INSTALLSTATE_UNKNOWN
;
874 LIST_FOR_EACH_ENTRY(cl
, &feature
->Components
, ComponentList
, entry
)
876 MSICOMPONENT
*component
= cl
->component
;
878 if (!component
->Enabled
) continue;
880 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
881 newstate
, debugstr_w(component
->Component
), component
->Installed
,
882 component
->Action
, component
->ActionRequest
);
884 if (newstate
== INSTALLSTATE_LOCAL
)
886 component
->Action
= INSTALLSTATE_LOCAL
;
887 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
891 ComponentList
*clist
;
894 component
->hasLocalFeature
= FALSE
;
896 component
->Action
= newstate
;
897 component
->ActionRequest
= newstate
;
898 /* if any other feature wants it local we need to set it local */
899 LIST_FOR_EACH_ENTRY(f
, &package
->features
, MSIFEATURE
, entry
)
901 if ( f
->ActionRequest
!= INSTALLSTATE_LOCAL
&&
902 f
->ActionRequest
!= INSTALLSTATE_SOURCE
)
906 LIST_FOR_EACH_ENTRY(clist
, &f
->Components
, ComponentList
, entry
)
908 if (clist
->component
== component
&&
909 (f
->ActionRequest
== INSTALLSTATE_LOCAL
||
910 f
->ActionRequest
== INSTALLSTATE_SOURCE
))
912 TRACE("Saved by %s\n", debugstr_w(f
->Feature
));
913 component
->hasLocalFeature
= TRUE
;
915 if (component
->Attributes
& msidbComponentAttributesOptional
)
917 if (f
->Attributes
& msidbFeatureAttributesFavorSource
)
919 component
->Action
= INSTALLSTATE_SOURCE
;
920 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
924 component
->Action
= INSTALLSTATE_LOCAL
;
925 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
928 else if (component
->Attributes
& msidbComponentAttributesSourceOnly
)
930 component
->Action
= INSTALLSTATE_SOURCE
;
931 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
935 component
->Action
= INSTALLSTATE_LOCAL
;
936 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
942 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
943 newstate
, debugstr_w(component
->Component
), component
->Installed
,
944 component
->Action
, component
->ActionRequest
);
948 UINT
MSI_SetFeatureStateW( MSIPACKAGE
*package
, LPCWSTR szFeature
, INSTALLSTATE iState
)
950 UINT rc
= ERROR_SUCCESS
;
951 MSIFEATURE
*feature
, *child
;
953 TRACE("%s %i\n", debugstr_w(szFeature
), iState
);
955 feature
= msi_get_loaded_feature( package
, szFeature
);
957 return ERROR_UNKNOWN_FEATURE
;
959 if (iState
== INSTALLSTATE_ADVERTISED
&&
960 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
961 return ERROR_FUNCTION_FAILED
;
963 feature
->ActionRequest
= iState
;
965 ACTION_UpdateComponentStates( package
, feature
);
967 /* update all the features that are children of this feature */
968 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
970 if (child
->Feature_Parent
&& !strcmpW( szFeature
, child
->Feature_Parent
))
971 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
977 /***********************************************************************
978 * MsiSetFeatureStateW (MSI.@)
980 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
984 UINT rc
= ERROR_SUCCESS
;
986 TRACE("%s %i\n",debugstr_w(szFeature
), iState
);
988 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
993 IWineMsiRemotePackage
*remote_package
;
995 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
997 return ERROR_INVALID_HANDLE
;
999 feature
= SysAllocString(szFeature
);
1002 IWineMsiRemotePackage_Release(remote_package
);
1003 return ERROR_OUTOFMEMORY
;
1006 hr
= IWineMsiRemotePackage_SetFeatureState(remote_package
, feature
, iState
);
1008 SysFreeString(feature
);
1009 IWineMsiRemotePackage_Release(remote_package
);
1013 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1014 return HRESULT_CODE(hr
);
1016 return ERROR_FUNCTION_FAILED
;
1019 return ERROR_SUCCESS
;
1022 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
1024 msiobj_release( &package
->hdr
);
1028 /***********************************************************************
1029 * MsiSetFeatureAttributesA (MSI.@)
1031 UINT WINAPI
MsiSetFeatureAttributesA( MSIHANDLE handle
, LPCSTR feature
, DWORD attrs
)
1034 WCHAR
*featureW
= NULL
;
1036 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_a(feature
), attrs
);
1038 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1040 r
= MsiSetFeatureAttributesW( handle
, featureW
, attrs
);
1041 msi_free( featureW
);
1045 static DWORD
unmap_feature_attributes( DWORD attrs
)
1049 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORLOCAL
) ret
= msidbFeatureAttributesFavorLocal
;
1050 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORSOURCE
) ret
|= msidbFeatureAttributesFavorSource
;
1051 if (attrs
& INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
) ret
|= msidbFeatureAttributesFollowParent
;
1052 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
) ret
|= msidbFeatureAttributesFavorAdvertise
;
1053 if (attrs
& INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
) ret
|= msidbFeatureAttributesDisallowAdvertise
;
1054 if (attrs
& INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
) ret
|= msidbFeatureAttributesNoUnsupportedAdvertise
;
1058 /***********************************************************************
1059 * MsiSetFeatureAttributesW (MSI.@)
1061 UINT WINAPI
MsiSetFeatureAttributesW( MSIHANDLE handle
, LPCWSTR name
, DWORD attrs
)
1063 MSIPACKAGE
*package
;
1064 MSIFEATURE
*feature
;
1067 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_w(name
), attrs
);
1069 if (!name
|| !name
[0]) return ERROR_UNKNOWN_FEATURE
;
1071 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1072 return ERROR_INVALID_HANDLE
;
1074 costing
= msi_dup_property( package
->db
, szCostingComplete
);
1075 if (!costing
|| !strcmpW( costing
, szOne
))
1077 msi_free( costing
);
1078 msiobj_release( &package
->hdr
);
1079 return ERROR_FUNCTION_FAILED
;
1081 msi_free( costing
);
1082 if (!(feature
= msi_get_loaded_feature( package
, name
)))
1084 msiobj_release( &package
->hdr
);
1085 return ERROR_UNKNOWN_FEATURE
;
1087 feature
->Attributes
= unmap_feature_attributes( attrs
);
1088 msiobj_release( &package
->hdr
);
1089 return ERROR_SUCCESS
;
1092 /***********************************************************************
1093 * MsiGetFeatureStateA (MSI.@)
1095 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1096 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1098 LPWSTR szwFeature
= NULL
;
1101 if (szFeature
&& !(szwFeature
= strdupAtoW(szFeature
))) return ERROR_OUTOFMEMORY
;
1103 rc
= MsiGetFeatureStateW(hInstall
, szwFeature
, piInstalled
, piAction
);
1104 msi_free( szwFeature
);
1108 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPCWSTR szFeature
,
1109 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1111 MSIFEATURE
*feature
;
1113 feature
= msi_get_loaded_feature(package
,szFeature
);
1115 return ERROR_UNKNOWN_FEATURE
;
1118 *piInstalled
= feature
->Installed
;
1121 *piAction
= feature
->ActionRequest
;
1123 TRACE("returning %i %i\n", feature
->Installed
, feature
->ActionRequest
);
1125 return ERROR_SUCCESS
;
1128 /***********************************************************************
1129 * MsiGetFeatureStateW (MSI.@)
1131 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1132 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1134 MSIPACKAGE
* package
;
1137 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
, piAction
);
1139 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1144 IWineMsiRemotePackage
*remote_package
;
1146 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1147 if (!remote_package
)
1148 return ERROR_INVALID_HANDLE
;
1150 feature
= SysAllocString(szFeature
);
1153 IWineMsiRemotePackage_Release(remote_package
);
1154 return ERROR_OUTOFMEMORY
;
1157 hr
= IWineMsiRemotePackage_GetFeatureState(remote_package
, feature
,
1158 piInstalled
, piAction
);
1160 SysFreeString(feature
);
1161 IWineMsiRemotePackage_Release(remote_package
);
1165 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1166 return HRESULT_CODE(hr
);
1168 return ERROR_FUNCTION_FAILED
;
1171 return ERROR_SUCCESS
;
1174 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
1175 msiobj_release( &package
->hdr
);
1179 /***********************************************************************
1180 * MsiGetFeatureCostA (MSI.@)
1182 UINT WINAPI
MsiGetFeatureCostA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1183 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1185 LPWSTR szwFeature
= NULL
;
1188 szwFeature
= strdupAtoW(szFeature
);
1190 rc
= MsiGetFeatureCostW(hInstall
, szwFeature
, iCostTree
, iState
, piCost
);
1192 msi_free(szwFeature
);
1197 static INT
feature_cost( MSIFEATURE
*feature
)
1202 LIST_FOR_EACH_ENTRY( comp
, &feature
->Components
, MSICOMPONENT
, entry
)
1209 UINT
MSI_GetFeatureCost( MSIPACKAGE
*package
, MSIFEATURE
*feature
, MSICOSTTREE tree
,
1210 INSTALLSTATE state
, LPINT cost
)
1212 TRACE("%s, %u, %d, %p\n", debugstr_w(feature
->Feature
), tree
, state
, cost
);
1217 case MSICOSTTREE_CHILDREN
:
1221 LIST_FOR_EACH_ENTRY( child
, &feature
->Children
, MSIFEATURE
, entry
)
1223 if (child
->ActionRequest
== state
)
1224 *cost
+= feature_cost( child
);
1228 case MSICOSTTREE_PARENTS
:
1230 const WCHAR
*feature_parent
= feature
->Feature_Parent
;
1233 MSIFEATURE
*parent
= msi_get_loaded_feature( package
, feature_parent
);
1237 if (parent
->ActionRequest
== state
)
1238 *cost
+= feature_cost( parent
);
1240 feature_parent
= parent
->Feature_Parent
;
1244 case MSICOSTTREE_SELFONLY
:
1245 if (feature
->ActionRequest
== state
)
1246 *cost
= feature_cost( feature
);
1250 WARN("unhandled cost tree %u\n", tree
);
1255 return ERROR_SUCCESS
;
1258 /***********************************************************************
1259 * MsiGetFeatureCostW (MSI.@)
1261 UINT WINAPI
MsiGetFeatureCostW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1262 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1264 MSIPACKAGE
*package
;
1265 MSIFEATURE
*feature
;
1268 TRACE("(%d %s %i %i %p)\n", hInstall
, debugstr_w(szFeature
),
1269 iCostTree
, iState
, piCost
);
1271 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1276 IWineMsiRemotePackage
*remote_package
;
1278 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1279 if (!remote_package
)
1280 return ERROR_INVALID_HANDLE
;
1282 feature
= SysAllocString(szFeature
);
1285 IWineMsiRemotePackage_Release(remote_package
);
1286 return ERROR_OUTOFMEMORY
;
1289 hr
= IWineMsiRemotePackage_GetFeatureCost(remote_package
, feature
,
1290 iCostTree
, iState
, piCost
);
1292 SysFreeString(feature
);
1293 IWineMsiRemotePackage_Release(remote_package
);
1297 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1298 return HRESULT_CODE(hr
);
1300 return ERROR_FUNCTION_FAILED
;
1303 return ERROR_SUCCESS
;
1306 feature
= msi_get_loaded_feature(package
, szFeature
);
1309 ret
= MSI_GetFeatureCost(package
, feature
, iCostTree
, iState
, piCost
);
1311 ret
= ERROR_UNKNOWN_FEATURE
;
1313 msiobj_release( &package
->hdr
);
1317 /***********************************************************************
1318 * MsiGetFeatureInfoA (MSI.@)
1320 UINT WINAPI
MsiGetFeatureInfoA( MSIHANDLE handle
, LPCSTR feature
, LPDWORD attrs
,
1321 LPSTR title
, LPDWORD title_len
, LPSTR help
, LPDWORD help_len
)
1324 WCHAR
*titleW
= NULL
, *helpW
= NULL
, *featureW
= NULL
;
1326 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_a(feature
), attrs
, title
,
1327 title_len
, help
, help_len
);
1329 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1331 if (title
&& title_len
&& !(titleW
= msi_alloc( *title_len
* sizeof(WCHAR
) )))
1333 msi_free( featureW
);
1334 return ERROR_OUTOFMEMORY
;
1336 if (help
&& help_len
&& !(helpW
= msi_alloc( *help_len
* sizeof(WCHAR
) )))
1338 msi_free( featureW
);
1340 return ERROR_OUTOFMEMORY
;
1342 r
= MsiGetFeatureInfoW( handle
, featureW
, attrs
, titleW
, title_len
, helpW
, help_len
);
1343 if (r
== ERROR_SUCCESS
)
1345 if (titleW
) WideCharToMultiByte( CP_ACP
, 0, titleW
, -1, title
, *title_len
+ 1, NULL
, NULL
);
1346 if (helpW
) WideCharToMultiByte( CP_ACP
, 0, helpW
, -1, help
, *help_len
+ 1, NULL
, NULL
);
1350 msi_free( featureW
);
1354 static DWORD
map_feature_attributes( DWORD attrs
)
1358 if (attrs
== msidbFeatureAttributesFavorLocal
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORLOCAL
;
1359 if (attrs
& msidbFeatureAttributesFavorSource
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORSOURCE
;
1360 if (attrs
& msidbFeatureAttributesFollowParent
) ret
|= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
;
1361 if (attrs
& msidbFeatureAttributesFavorAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
;
1362 if (attrs
& msidbFeatureAttributesDisallowAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
;
1363 if (attrs
& msidbFeatureAttributesNoUnsupportedAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
;
1367 static UINT
MSI_GetFeatureInfo( MSIPACKAGE
*package
, LPCWSTR name
, LPDWORD attrs
,
1368 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1370 UINT r
= ERROR_SUCCESS
;
1371 MSIFEATURE
*feature
= msi_get_loaded_feature( package
, name
);
1374 if (!feature
) return ERROR_UNKNOWN_FEATURE
;
1375 if (attrs
) *attrs
= map_feature_attributes( feature
->Attributes
);
1378 if (feature
->Title
) len
= strlenW( feature
->Title
);
1380 if (*title_len
<= len
)
1383 if (title
) r
= ERROR_MORE_DATA
;
1387 if (feature
->Title
) strcpyW( title
, feature
->Title
);
1394 if (feature
->Description
) len
= strlenW( feature
->Description
);
1396 if (*help_len
<= len
)
1399 if (help
) r
= ERROR_MORE_DATA
;
1403 if (feature
->Description
) strcpyW( help
, feature
->Description
);
1411 /***********************************************************************
1412 * MsiGetFeatureInfoW (MSI.@)
1414 UINT WINAPI
MsiGetFeatureInfoW( MSIHANDLE handle
, LPCWSTR feature
, LPDWORD attrs
,
1415 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1418 MSIPACKAGE
*package
;
1420 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_w(feature
), attrs
, title
,
1421 title_len
, help
, help_len
);
1423 if (!feature
) return ERROR_INVALID_PARAMETER
;
1425 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1426 return ERROR_INVALID_HANDLE
;
1428 /* features may not have been loaded yet */
1429 msi_load_all_components( package
);
1430 msi_load_all_features( package
);
1432 r
= MSI_GetFeatureInfo( package
, feature
, attrs
, title
, title_len
, help
, help_len
);
1433 msiobj_release( &package
->hdr
);
1437 /***********************************************************************
1438 * MsiSetComponentStateA (MSI.@)
1440 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1441 INSTALLSTATE iState
)
1444 LPWSTR szwComponent
= strdupAtoW(szComponent
);
1446 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
1448 msi_free(szwComponent
);
1453 /***********************************************************************
1454 * MsiGetComponentStateA (MSI.@)
1456 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1457 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1459 LPWSTR szwComponent
= NULL
;
1462 szwComponent
= strdupAtoW(szComponent
);
1464 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
1466 msi_free( szwComponent
);
1471 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1472 INSTALLSTATE iState
)
1476 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
1478 comp
= msi_get_loaded_component(package
, szComponent
);
1480 return ERROR_UNKNOWN_COMPONENT
;
1483 comp
->Action
= iState
;
1485 return ERROR_SUCCESS
;
1488 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1489 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1493 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
1494 piInstalled
, piAction
);
1496 comp
= msi_get_loaded_component(package
,szComponent
);
1498 return ERROR_UNKNOWN_COMPONENT
;
1503 *piInstalled
= comp
->Installed
;
1505 *piInstalled
= INSTALLSTATE_UNKNOWN
;
1511 *piAction
= comp
->Action
;
1513 *piAction
= INSTALLSTATE_UNKNOWN
;
1516 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
1517 return ERROR_SUCCESS
;
1520 /***********************************************************************
1521 * MsiSetComponentStateW (MSI.@)
1523 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1524 INSTALLSTATE iState
)
1526 MSIPACKAGE
* package
;
1529 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1534 IWineMsiRemotePackage
*remote_package
;
1536 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1537 if (!remote_package
)
1538 return ERROR_INVALID_HANDLE
;
1540 component
= SysAllocString(szComponent
);
1543 IWineMsiRemotePackage_Release(remote_package
);
1544 return ERROR_OUTOFMEMORY
;
1547 hr
= IWineMsiRemotePackage_SetComponentState(remote_package
, component
, iState
);
1549 SysFreeString(component
);
1550 IWineMsiRemotePackage_Release(remote_package
);
1554 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1555 return HRESULT_CODE(hr
);
1557 return ERROR_FUNCTION_FAILED
;
1560 return ERROR_SUCCESS
;
1563 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
1564 msiobj_release(&package
->hdr
);
1568 /***********************************************************************
1569 * MsiGetComponentStateW (MSI.@)
1571 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1572 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1574 MSIPACKAGE
* package
;
1577 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szComponent
),
1578 piInstalled
, piAction
);
1580 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1585 IWineMsiRemotePackage
*remote_package
;
1587 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1588 if (!remote_package
)
1589 return ERROR_INVALID_HANDLE
;
1591 component
= SysAllocString(szComponent
);
1594 IWineMsiRemotePackage_Release(remote_package
);
1595 return ERROR_OUTOFMEMORY
;
1598 hr
= IWineMsiRemotePackage_GetComponentState(remote_package
, component
,
1599 piInstalled
, piAction
);
1601 SysFreeString(component
);
1602 IWineMsiRemotePackage_Release(remote_package
);
1606 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1607 return HRESULT_CODE(hr
);
1609 return ERROR_FUNCTION_FAILED
;
1612 return ERROR_SUCCESS
;
1615 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
1616 msiobj_release( &package
->hdr
);
1620 /***********************************************************************
1621 * MsiGetLanguage (MSI.@)
1623 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
1625 MSIPACKAGE
* package
;
1628 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1633 IWineMsiRemotePackage
*remote_package
;
1635 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1636 if (!remote_package
)
1637 return ERROR_INVALID_HANDLE
;
1639 hr
= IWineMsiRemotePackage_GetLanguage(remote_package
, &lang
);
1647 langid
= msi_get_property_int( package
->db
, szProductLanguage
, 0 );
1648 msiobj_release( &package
->hdr
);
1652 UINT
MSI_SetInstallLevel( MSIPACKAGE
*package
, int iInstallLevel
)
1654 static const WCHAR fmt
[] = { '%','d',0 };
1658 TRACE("%p %i\n", package
, iInstallLevel
);
1660 if (iInstallLevel
> 32767)
1661 return ERROR_INVALID_PARAMETER
;
1663 if (iInstallLevel
< 1)
1664 return MSI_SetFeatureStates( package
);
1666 sprintfW( level
, fmt
, iInstallLevel
);
1667 r
= msi_set_property( package
->db
, szInstallLevel
, level
);
1668 if ( r
== ERROR_SUCCESS
)
1669 r
= MSI_SetFeatureStates( package
);
1674 /***********************************************************************
1675 * MsiSetInstallLevel (MSI.@)
1677 UINT WINAPI
MsiSetInstallLevel(MSIHANDLE hInstall
, int iInstallLevel
)
1679 MSIPACKAGE
* package
;
1682 TRACE("%d %i\n", hInstall
, iInstallLevel
);
1684 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1688 IWineMsiRemotePackage
*remote_package
;
1690 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1691 if (!remote_package
)
1692 return ERROR_INVALID_HANDLE
;
1694 hr
= IWineMsiRemotePackage_SetInstallLevel(remote_package
, iInstallLevel
);
1696 IWineMsiRemotePackage_Release(remote_package
);
1700 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1701 return HRESULT_CODE(hr
);
1703 return ERROR_FUNCTION_FAILED
;
1706 return ERROR_SUCCESS
;
1709 r
= MSI_SetInstallLevel( package
, iInstallLevel
);
1711 msiobj_release( &package
->hdr
);
1716 /***********************************************************************
1717 * MsiGetFeatureValidStatesW (MSI.@)
1719 UINT WINAPI
MsiGetFeatureValidStatesW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1720 LPDWORD pInstallState
)
1722 if(pInstallState
) *pInstallState
= 1<<INSTALLSTATE_LOCAL
;
1723 FIXME("%d %s %p stub returning %d\n",
1724 hInstall
, debugstr_w(szFeature
), pInstallState
, pInstallState
? *pInstallState
: 0);
1726 return ERROR_SUCCESS
;
1729 /***********************************************************************
1730 * MsiGetFeatureValidStatesA (MSI.@)
1732 UINT WINAPI
MsiGetFeatureValidStatesA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1733 LPDWORD pInstallState
)
1736 LPWSTR szwFeature
= strdupAtoW(szFeature
);
1738 ret
= MsiGetFeatureValidStatesW(hInstall
, szwFeature
, pInstallState
);
1740 msi_free(szwFeature
);