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
, SCRIPT_NONE
);
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
);
217 if (!folder
) return NULL
;
218 if (!folder
->ResolvedTarget
)
220 MSIFOLDER
*parent
= folder
;
221 while (parent
->Parent
&& strcmpW( parent
->Parent
, parent
->Directory
))
223 parent
= msi_get_loaded_folder( package
, parent
->Parent
);
225 msi_resolve_target_folder( package
, parent
->Directory
, TRUE
);
227 return folder
->ResolvedTarget
;
230 /***********************************************************************
231 * MsiGetTargetPath (internal)
233 static UINT
MSI_GetTargetPath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
234 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
238 UINT r
= ERROR_FUNCTION_FAILED
;
241 return ERROR_INVALID_PARAMETER
;
243 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
247 IWineMsiRemotePackage
*remote_package
;
252 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
254 return ERROR_INVALID_HANDLE
;
256 folder
= SysAllocString( szFolder
);
259 IWineMsiRemotePackage_Release( remote_package
);
260 return ERROR_OUTOFMEMORY
;
264 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
, NULL
, &len
);
269 value
= msi_alloc(len
* sizeof(WCHAR
));
272 r
= ERROR_OUTOFMEMORY
;
276 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
, value
, &len
);
280 r
= msi_strcpy_to_awstring( value
, szPathBuf
, pcchPathBuf
);
283 IWineMsiRemotePackage_Release( remote_package
);
284 SysFreeString( folder
);
289 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
290 return HRESULT_CODE(hr
);
292 return ERROR_FUNCTION_FAILED
;
298 path
= msi_get_target_folder( package
, szFolder
);
299 msiobj_release( &package
->hdr
);
302 return ERROR_DIRECTORY
;
304 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
308 /***********************************************************************
309 * MsiGetTargetPathA (MSI.@)
311 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
312 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
318 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
320 szwFolder
= strdupAtoW(szFolder
);
321 if (szFolder
&& !szwFolder
)
322 return ERROR_FUNCTION_FAILED
;
324 path
.unicode
= FALSE
;
325 path
.str
.a
= szPathBuf
;
327 r
= MSI_GetTargetPath( hInstall
, szwFolder
, &path
, pcchPathBuf
);
329 msi_free( szwFolder
);
334 /***********************************************************************
335 * MsiGetTargetPathW (MSI.@)
337 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
338 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
342 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
345 path
.str
.w
= szPathBuf
;
347 return MSI_GetTargetPath( hInstall
, szFolder
, &path
, pcchPathBuf
);
350 static WCHAR
*get_source_root( MSIDATABASE
*db
)
354 if ((path
= msi_dup_property( db
, szSourceDir
))) return path
;
355 if ((path
= msi_dup_property( db
, szDatabase
)))
357 if ((p
= strrchrW( path
, '\\' ))) p
[1] = 0;
362 WCHAR
*msi_resolve_source_folder( MSIPACKAGE
*package
, const WCHAR
*name
, MSIFOLDER
**folder
)
365 LPWSTR p
, path
= NULL
, parent
;
367 TRACE("working to resolve %s\n", debugstr_w(name
));
369 if (!strcmpW( name
, szSourceDir
)) name
= szTargetDir
;
370 if (!(f
= msi_get_loaded_folder( package
, name
))) return NULL
;
372 /* special resolving for root dir */
373 if (!strcmpW( name
, szTargetDir
) && !f
->ResolvedSource
)
375 f
->ResolvedSource
= get_source_root( package
->db
);
377 if (folder
) *folder
= f
;
378 if (f
->ResolvedSource
)
380 path
= strdupW( f
->ResolvedSource
);
381 TRACE(" already resolved to %s\n", debugstr_w(path
));
384 if (!f
->Parent
) return path
;
386 TRACE(" ! parent is %s\n", debugstr_w(parent
));
388 p
= msi_resolve_source_folder( package
, parent
, NULL
);
390 if (package
->WordCount
& msidbSumInfoSourceTypeCompressed
)
391 path
= get_source_root( package
->db
);
392 else if (package
->WordCount
& msidbSumInfoSourceTypeSFN
)
393 path
= msi_build_directory_name( 3, p
, f
->SourceShortPath
, NULL
);
395 path
= msi_build_directory_name( 3, p
, f
->SourceLongPath
, NULL
);
397 TRACE("-> %s\n", debugstr_w(path
));
398 f
->ResolvedSource
= strdupW( path
);
404 /***********************************************************************
405 * MSI_GetSourcePath (internal)
407 static UINT
MSI_GetSourcePath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
408 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
412 UINT r
= ERROR_FUNCTION_FAILED
;
414 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
417 return ERROR_INVALID_PARAMETER
;
419 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
423 IWineMsiRemotePackage
*remote_package
;
428 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
430 return ERROR_INVALID_HANDLE
;
432 folder
= SysAllocString( szFolder
);
435 IWineMsiRemotePackage_Release( remote_package
);
436 return ERROR_OUTOFMEMORY
;
440 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, NULL
, &len
);
445 value
= msi_alloc(len
* sizeof(WCHAR
));
448 r
= ERROR_OUTOFMEMORY
;
452 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, value
, &len
);
456 r
= msi_strcpy_to_awstring( value
, szPathBuf
, pcchPathBuf
);
459 IWineMsiRemotePackage_Release( remote_package
);
460 SysFreeString( folder
);
465 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
466 return HRESULT_CODE(hr
);
468 return ERROR_FUNCTION_FAILED
;
474 if (szPathBuf
->str
.w
&& !pcchPathBuf
)
476 msiobj_release( &package
->hdr
);
477 return ERROR_INVALID_PARAMETER
;
480 path
= msi_resolve_source_folder( package
, szFolder
, NULL
);
481 msiobj_release( &package
->hdr
);
483 TRACE("path = %s\n", debugstr_w(path
));
485 return ERROR_DIRECTORY
;
487 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
492 /***********************************************************************
493 * MsiGetSourcePathA (MSI.@)
495 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
496 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
502 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
505 str
.str
.a
= szPathBuf
;
507 folder
= strdupAtoW( szFolder
);
508 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
514 /***********************************************************************
515 * MsiGetSourcePathW (MSI.@)
517 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
518 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
522 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
525 str
.str
.w
= szPathBuf
;
527 return MSI_GetSourcePath( hInstall
, szFolder
, &str
, pcchPathBuf
);
530 /***********************************************************************
531 * MsiSetTargetPathA (MSI.@)
533 UINT WINAPI
MsiSetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
534 LPCSTR szFolderPath
)
536 LPWSTR szwFolder
= NULL
, szwFolderPath
= NULL
;
537 UINT rc
= ERROR_OUTOFMEMORY
;
539 if ( !szFolder
|| !szFolderPath
)
540 return ERROR_INVALID_PARAMETER
;
542 szwFolder
= strdupAtoW(szFolder
);
543 szwFolderPath
= strdupAtoW(szFolderPath
);
544 if (!szwFolder
|| !szwFolderPath
)
547 rc
= MsiSetTargetPathW( hInstall
, szwFolder
, szwFolderPath
);
551 msi_free(szwFolderPath
);
556 static void set_target_path( MSIPACKAGE
*package
, MSIFOLDER
*folder
, const WCHAR
*path
)
562 if (!(target_path
= strdupW( path
))) return;
563 msi_clean_path( target_path
);
564 if (strcmpW( target_path
, folder
->ResolvedTarget
))
566 msi_free( folder
->ResolvedTarget
);
567 folder
->ResolvedTarget
= target_path
;
568 msi_set_property( package
->db
, folder
->Directory
, folder
->ResolvedTarget
);
570 LIST_FOR_EACH_ENTRY( fl
, &folder
->children
, FolderList
, entry
)
573 msi_resolve_target_folder( package
, child
->Directory
, FALSE
);
576 else msi_free( target_path
);
579 UINT
MSI_SetTargetPathW( MSIPACKAGE
*package
, LPCWSTR szFolder
, LPCWSTR szFolderPath
)
585 TRACE("%p %s %s\n", package
, debugstr_w(szFolder
), debugstr_w(szFolderPath
));
587 attrib
= GetFileAttributesW(szFolderPath
);
588 /* native MSI tests writeability by making temporary files at each drive */
589 if (attrib
!= INVALID_FILE_ATTRIBUTES
&&
590 (attrib
& FILE_ATTRIBUTE_OFFLINE
|| attrib
& FILE_ATTRIBUTE_READONLY
))
592 return ERROR_FUNCTION_FAILED
;
594 if (!(folder
= msi_get_loaded_folder( package
, szFolder
))) return ERROR_DIRECTORY
;
596 len
= strlenW( szFolderPath
);
597 if (len
&& szFolderPath
[len
- 1] != '\\')
599 WCHAR
*path
= msi_alloc( (len
+ 2) * sizeof(WCHAR
) );
600 memcpy( path
, szFolderPath
, len
* sizeof(WCHAR
) );
603 set_target_path( package
, folder
, path
);
606 else set_target_path( package
, folder
, szFolderPath
);
608 LIST_FOR_EACH_ENTRY( file
, &package
->files
, MSIFILE
, entry
)
611 MSICOMPONENT
*comp
= file
->Component
;
613 if (!comp
->Enabled
|| (comp
->assembly
&& !comp
->assembly
->application
)) continue;
615 dir
= msi_get_target_folder( package
, comp
->Directory
);
616 msi_free( file
->TargetPath
);
617 file
->TargetPath
= msi_build_directory_name( 2, dir
, file
->FileName
);
619 return ERROR_SUCCESS
;
622 /***********************************************************************
623 * MsiSetTargetPathW (MSI.@)
625 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
626 LPCWSTR szFolderPath
)
631 TRACE("%s %s\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
633 if ( !szFolder
|| !szFolderPath
)
634 return ERROR_INVALID_PARAMETER
;
636 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
641 IWineMsiRemotePackage
*remote_package
;
643 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
645 return ERROR_INVALID_HANDLE
;
647 folder
= SysAllocString( szFolder
);
648 path
= SysAllocString( szFolderPath
);
649 if (!folder
|| !path
)
651 SysFreeString(folder
);
653 IWineMsiRemotePackage_Release( remote_package
);
654 return ERROR_OUTOFMEMORY
;
657 hr
= IWineMsiRemotePackage_SetTargetPath( remote_package
, folder
, path
);
659 SysFreeString(folder
);
661 IWineMsiRemotePackage_Release( remote_package
);
665 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
666 return HRESULT_CODE(hr
);
668 return ERROR_FUNCTION_FAILED
;
671 return ERROR_SUCCESS
;
674 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
675 msiobj_release( &package
->hdr
);
679 /***********************************************************************
682 * Returns an internal installer state (if it is running in a mode iRunMode)
685 * hInstall [I] Handle to the installation
686 * hRunMode [I] Checking run mode
687 * MSIRUNMODE_ADMIN Administrative mode
688 * MSIRUNMODE_ADVERTISE Advertisement mode
689 * MSIRUNMODE_MAINTENANCE Maintenance mode
690 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
691 * MSIRUNMODE_LOGENABLED Log file is writing
692 * MSIRUNMODE_OPERATIONS Operations in progress??
693 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
694 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
695 * MSIRUNMODE_CABINET Files from cabinet are installed
696 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
697 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
698 * MSIRUNMODE_RESERVED11 Reserved
699 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
700 * MSIRUNMODE_ZAWENABLED Demand installation is supported
701 * MSIRUNMODE_RESERVED14 Reserved
702 * MSIRUNMODE_RESERVED15 Reserved
703 * MSIRUNMODE_SCHEDULED called from install script
704 * MSIRUNMODE_ROLLBACK called from rollback script
705 * MSIRUNMODE_COMMIT called from commit script
709 * Not in the state: FALSE
712 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
717 TRACE("%d %d\n", hInstall
, iRunMode
);
719 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
724 IWineMsiRemotePackage
*remote_package
;
726 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
730 hr
= IWineMsiRemotePackage_GetMode(remote_package
, iRunMode
, &ret
);
731 IWineMsiRemotePackage_Release(remote_package
);
741 case MSIRUNMODE_ADMIN
:
742 FIXME("no support for administrative installs\n");
745 case MSIRUNMODE_ADVERTISE
:
746 FIXME("no support for advertised installs\n");
749 case MSIRUNMODE_WINDOWS9X
:
750 if (GetVersion() & 0x80000000)
754 case MSIRUNMODE_OPERATIONS
:
755 case MSIRUNMODE_RESERVED11
:
756 case MSIRUNMODE_RESERVED14
:
757 case MSIRUNMODE_RESERVED15
:
760 case MSIRUNMODE_SCHEDULED
:
761 r
= package
->scheduled_action_running
;
764 case MSIRUNMODE_ROLLBACK
:
765 r
= package
->rollback_action_running
;
768 case MSIRUNMODE_COMMIT
:
769 r
= package
->commit_action_running
;
772 case MSIRUNMODE_MAINTENANCE
:
773 r
= msi_get_property_int( package
->db
, szInstalled
, 0 ) != 0;
776 case MSIRUNMODE_ROLLBACKENABLED
:
777 r
= msi_get_property_int( package
->db
, szRollbackDisabled
, 0 ) == 0;
780 case MSIRUNMODE_REBOOTATEND
:
781 r
= package
->need_reboot
;
784 case MSIRUNMODE_LOGENABLED
:
785 r
= (package
->log_file
!= INVALID_HANDLE_VALUE
);
789 FIXME("unimplemented run mode: %d\n", iRunMode
);
793 msiobj_release( &package
->hdr
);
797 /***********************************************************************
800 UINT WINAPI
MsiSetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
, BOOL fState
)
805 TRACE("%d %d %d\n", hInstall
, iRunMode
, fState
);
807 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
811 IWineMsiRemotePackage
*remote_package
;
813 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
817 hr
= IWineMsiRemotePackage_SetMode( remote_package
, iRunMode
, fState
);
818 IWineMsiRemotePackage_Release( remote_package
);
822 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
823 return HRESULT_CODE(hr
);
825 return ERROR_FUNCTION_FAILED
;
828 return ERROR_SUCCESS
;
833 case MSIRUNMODE_REBOOTATEND
:
834 package
->need_reboot
= 1;
838 case MSIRUNMODE_REBOOTNOW
:
839 FIXME("unimplemented run mode: %d\n", iRunMode
);
840 r
= ERROR_FUNCTION_FAILED
;
844 r
= ERROR_ACCESS_DENIED
;
847 msiobj_release( &package
->hdr
);
851 /***********************************************************************
852 * MsiSetFeatureStateA (MSI.@)
854 * According to the docs, when this is called it immediately recalculates
855 * all the component states as well
857 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
860 LPWSTR szwFeature
= NULL
;
863 szwFeature
= strdupAtoW(szFeature
);
866 return ERROR_FUNCTION_FAILED
;
868 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
870 msi_free(szwFeature
);
875 /* update component state based on a feature change */
876 void ACTION_UpdateComponentStates( MSIPACKAGE
*package
, MSIFEATURE
*feature
)
878 INSTALLSTATE newstate
;
881 newstate
= feature
->ActionRequest
;
882 if (newstate
== INSTALLSTATE_ABSENT
) newstate
= INSTALLSTATE_UNKNOWN
;
884 LIST_FOR_EACH_ENTRY(cl
, &feature
->Components
, ComponentList
, entry
)
886 MSICOMPONENT
*component
= cl
->component
;
888 if (!component
->Enabled
) continue;
890 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
891 newstate
, debugstr_w(component
->Component
), component
->Installed
,
892 component
->Action
, component
->ActionRequest
);
894 if (newstate
== INSTALLSTATE_LOCAL
)
896 component
->Action
= INSTALLSTATE_LOCAL
;
897 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
901 ComponentList
*clist
;
904 component
->hasLocalFeature
= FALSE
;
906 component
->Action
= newstate
;
907 component
->ActionRequest
= newstate
;
908 /* if any other feature wants it local we need to set it local */
909 LIST_FOR_EACH_ENTRY(f
, &package
->features
, MSIFEATURE
, entry
)
911 if ( f
->ActionRequest
!= INSTALLSTATE_LOCAL
&&
912 f
->ActionRequest
!= INSTALLSTATE_SOURCE
)
916 LIST_FOR_EACH_ENTRY(clist
, &f
->Components
, ComponentList
, entry
)
918 if (clist
->component
== component
&&
919 (f
->ActionRequest
== INSTALLSTATE_LOCAL
||
920 f
->ActionRequest
== INSTALLSTATE_SOURCE
))
922 TRACE("Saved by %s\n", debugstr_w(f
->Feature
));
923 component
->hasLocalFeature
= TRUE
;
925 if (component
->Attributes
& msidbComponentAttributesOptional
)
927 if (f
->Attributes
& msidbFeatureAttributesFavorSource
)
929 component
->Action
= INSTALLSTATE_SOURCE
;
930 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
934 component
->Action
= INSTALLSTATE_LOCAL
;
935 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
938 else if (component
->Attributes
& msidbComponentAttributesSourceOnly
)
940 component
->Action
= INSTALLSTATE_SOURCE
;
941 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
945 component
->Action
= INSTALLSTATE_LOCAL
;
946 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
952 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
953 newstate
, debugstr_w(component
->Component
), component
->Installed
,
954 component
->Action
, component
->ActionRequest
);
958 UINT
MSI_SetFeatureStateW( MSIPACKAGE
*package
, LPCWSTR szFeature
, INSTALLSTATE iState
)
960 UINT rc
= ERROR_SUCCESS
;
961 MSIFEATURE
*feature
, *child
;
963 TRACE("%s %i\n", debugstr_w(szFeature
), iState
);
965 feature
= msi_get_loaded_feature( package
, szFeature
);
967 return ERROR_UNKNOWN_FEATURE
;
969 if (iState
== INSTALLSTATE_ADVERTISED
&&
970 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
971 return ERROR_FUNCTION_FAILED
;
973 feature
->ActionRequest
= iState
;
975 ACTION_UpdateComponentStates( package
, feature
);
977 /* update all the features that are children of this feature */
978 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
980 if (child
->Feature_Parent
&& !strcmpW( szFeature
, child
->Feature_Parent
))
981 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
987 /***********************************************************************
988 * MsiSetFeatureStateW (MSI.@)
990 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
994 UINT rc
= ERROR_SUCCESS
;
996 TRACE("%s %i\n",debugstr_w(szFeature
), iState
);
998 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1003 IWineMsiRemotePackage
*remote_package
;
1005 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1006 if (!remote_package
)
1007 return ERROR_INVALID_HANDLE
;
1009 feature
= SysAllocString(szFeature
);
1012 IWineMsiRemotePackage_Release(remote_package
);
1013 return ERROR_OUTOFMEMORY
;
1016 hr
= IWineMsiRemotePackage_SetFeatureState(remote_package
, feature
, iState
);
1018 SysFreeString(feature
);
1019 IWineMsiRemotePackage_Release(remote_package
);
1023 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1024 return HRESULT_CODE(hr
);
1026 return ERROR_FUNCTION_FAILED
;
1029 return ERROR_SUCCESS
;
1032 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
1034 msiobj_release( &package
->hdr
);
1038 /***********************************************************************
1039 * MsiSetFeatureAttributesA (MSI.@)
1041 UINT WINAPI
MsiSetFeatureAttributesA( MSIHANDLE handle
, LPCSTR feature
, DWORD attrs
)
1044 WCHAR
*featureW
= NULL
;
1046 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_a(feature
), attrs
);
1048 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1050 r
= MsiSetFeatureAttributesW( handle
, featureW
, attrs
);
1051 msi_free( featureW
);
1055 static DWORD
unmap_feature_attributes( DWORD attrs
)
1059 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORLOCAL
) ret
= msidbFeatureAttributesFavorLocal
;
1060 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORSOURCE
) ret
|= msidbFeatureAttributesFavorSource
;
1061 if (attrs
& INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
) ret
|= msidbFeatureAttributesFollowParent
;
1062 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
) ret
|= msidbFeatureAttributesFavorAdvertise
;
1063 if (attrs
& INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
) ret
|= msidbFeatureAttributesDisallowAdvertise
;
1064 if (attrs
& INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
) ret
|= msidbFeatureAttributesNoUnsupportedAdvertise
;
1068 /***********************************************************************
1069 * MsiSetFeatureAttributesW (MSI.@)
1071 UINT WINAPI
MsiSetFeatureAttributesW( MSIHANDLE handle
, LPCWSTR name
, DWORD attrs
)
1073 MSIPACKAGE
*package
;
1074 MSIFEATURE
*feature
;
1077 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_w(name
), attrs
);
1079 if (!name
|| !name
[0]) return ERROR_UNKNOWN_FEATURE
;
1081 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1082 return ERROR_INVALID_HANDLE
;
1084 costing
= msi_dup_property( package
->db
, szCostingComplete
);
1085 if (!costing
|| !strcmpW( costing
, szOne
))
1087 msi_free( costing
);
1088 msiobj_release( &package
->hdr
);
1089 return ERROR_FUNCTION_FAILED
;
1091 msi_free( costing
);
1092 if (!(feature
= msi_get_loaded_feature( package
, name
)))
1094 msiobj_release( &package
->hdr
);
1095 return ERROR_UNKNOWN_FEATURE
;
1097 feature
->Attributes
= unmap_feature_attributes( attrs
);
1098 msiobj_release( &package
->hdr
);
1099 return ERROR_SUCCESS
;
1102 /***********************************************************************
1103 * MsiGetFeatureStateA (MSI.@)
1105 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1106 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1108 LPWSTR szwFeature
= NULL
;
1111 if (szFeature
&& !(szwFeature
= strdupAtoW(szFeature
))) return ERROR_OUTOFMEMORY
;
1113 rc
= MsiGetFeatureStateW(hInstall
, szwFeature
, piInstalled
, piAction
);
1114 msi_free( szwFeature
);
1118 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPCWSTR szFeature
,
1119 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1121 MSIFEATURE
*feature
;
1123 feature
= msi_get_loaded_feature(package
,szFeature
);
1125 return ERROR_UNKNOWN_FEATURE
;
1128 *piInstalled
= feature
->Installed
;
1131 *piAction
= feature
->ActionRequest
;
1133 TRACE("returning %i %i\n", feature
->Installed
, feature
->ActionRequest
);
1135 return ERROR_SUCCESS
;
1138 /***********************************************************************
1139 * MsiGetFeatureStateW (MSI.@)
1141 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1142 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1144 MSIPACKAGE
* package
;
1147 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
, piAction
);
1149 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1154 IWineMsiRemotePackage
*remote_package
;
1156 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1157 if (!remote_package
)
1158 return ERROR_INVALID_HANDLE
;
1160 feature
= SysAllocString(szFeature
);
1163 IWineMsiRemotePackage_Release(remote_package
);
1164 return ERROR_OUTOFMEMORY
;
1167 hr
= IWineMsiRemotePackage_GetFeatureState(remote_package
, feature
,
1168 piInstalled
, piAction
);
1170 SysFreeString(feature
);
1171 IWineMsiRemotePackage_Release(remote_package
);
1175 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1176 return HRESULT_CODE(hr
);
1178 return ERROR_FUNCTION_FAILED
;
1181 return ERROR_SUCCESS
;
1184 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
1185 msiobj_release( &package
->hdr
);
1189 /***********************************************************************
1190 * MsiGetFeatureCostA (MSI.@)
1192 UINT WINAPI
MsiGetFeatureCostA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1193 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1195 LPWSTR szwFeature
= NULL
;
1198 szwFeature
= strdupAtoW(szFeature
);
1200 rc
= MsiGetFeatureCostW(hInstall
, szwFeature
, iCostTree
, iState
, piCost
);
1202 msi_free(szwFeature
);
1207 static INT
feature_cost( MSIFEATURE
*feature
)
1212 LIST_FOR_EACH_ENTRY( comp
, &feature
->Components
, MSICOMPONENT
, entry
)
1219 UINT
MSI_GetFeatureCost( MSIPACKAGE
*package
, MSIFEATURE
*feature
, MSICOSTTREE tree
,
1220 INSTALLSTATE state
, LPINT cost
)
1222 TRACE("%s, %u, %d, %p\n", debugstr_w(feature
->Feature
), tree
, state
, cost
);
1227 case MSICOSTTREE_CHILDREN
:
1231 LIST_FOR_EACH_ENTRY( child
, &feature
->Children
, MSIFEATURE
, entry
)
1233 if (child
->ActionRequest
== state
)
1234 *cost
+= feature_cost( child
);
1238 case MSICOSTTREE_PARENTS
:
1240 const WCHAR
*feature_parent
= feature
->Feature_Parent
;
1243 MSIFEATURE
*parent
= msi_get_loaded_feature( package
, feature_parent
);
1247 if (parent
->ActionRequest
== state
)
1248 *cost
+= feature_cost( parent
);
1250 feature_parent
= parent
->Feature_Parent
;
1254 case MSICOSTTREE_SELFONLY
:
1255 if (feature
->ActionRequest
== state
)
1256 *cost
= feature_cost( feature
);
1260 WARN("unhandled cost tree %u\n", tree
);
1265 return ERROR_SUCCESS
;
1268 /***********************************************************************
1269 * MsiGetFeatureCostW (MSI.@)
1271 UINT WINAPI
MsiGetFeatureCostW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1272 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1274 MSIPACKAGE
*package
;
1275 MSIFEATURE
*feature
;
1278 TRACE("(%d %s %i %i %p)\n", hInstall
, debugstr_w(szFeature
),
1279 iCostTree
, iState
, piCost
);
1281 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1286 IWineMsiRemotePackage
*remote_package
;
1288 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1289 if (!remote_package
)
1290 return ERROR_INVALID_HANDLE
;
1292 feature
= SysAllocString(szFeature
);
1295 IWineMsiRemotePackage_Release(remote_package
);
1296 return ERROR_OUTOFMEMORY
;
1299 hr
= IWineMsiRemotePackage_GetFeatureCost(remote_package
, feature
,
1300 iCostTree
, iState
, piCost
);
1302 SysFreeString(feature
);
1303 IWineMsiRemotePackage_Release(remote_package
);
1307 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1308 return HRESULT_CODE(hr
);
1310 return ERROR_FUNCTION_FAILED
;
1313 return ERROR_SUCCESS
;
1316 feature
= msi_get_loaded_feature(package
, szFeature
);
1319 ret
= MSI_GetFeatureCost(package
, feature
, iCostTree
, iState
, piCost
);
1321 ret
= ERROR_UNKNOWN_FEATURE
;
1323 msiobj_release( &package
->hdr
);
1327 /***********************************************************************
1328 * MsiGetFeatureInfoA (MSI.@)
1330 UINT WINAPI
MsiGetFeatureInfoA( MSIHANDLE handle
, LPCSTR feature
, LPDWORD attrs
,
1331 LPSTR title
, LPDWORD title_len
, LPSTR help
, LPDWORD help_len
)
1334 WCHAR
*titleW
= NULL
, *helpW
= NULL
, *featureW
= NULL
;
1336 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_a(feature
), attrs
, title
,
1337 title_len
, help
, help_len
);
1339 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1341 if (title
&& title_len
&& !(titleW
= msi_alloc( *title_len
* sizeof(WCHAR
) )))
1343 msi_free( featureW
);
1344 return ERROR_OUTOFMEMORY
;
1346 if (help
&& help_len
&& !(helpW
= msi_alloc( *help_len
* sizeof(WCHAR
) )))
1348 msi_free( featureW
);
1350 return ERROR_OUTOFMEMORY
;
1352 r
= MsiGetFeatureInfoW( handle
, featureW
, attrs
, titleW
, title_len
, helpW
, help_len
);
1353 if (r
== ERROR_SUCCESS
)
1355 if (titleW
) WideCharToMultiByte( CP_ACP
, 0, titleW
, -1, title
, *title_len
+ 1, NULL
, NULL
);
1356 if (helpW
) WideCharToMultiByte( CP_ACP
, 0, helpW
, -1, help
, *help_len
+ 1, NULL
, NULL
);
1360 msi_free( featureW
);
1364 static DWORD
map_feature_attributes( DWORD attrs
)
1368 if (attrs
== msidbFeatureAttributesFavorLocal
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORLOCAL
;
1369 if (attrs
& msidbFeatureAttributesFavorSource
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORSOURCE
;
1370 if (attrs
& msidbFeatureAttributesFollowParent
) ret
|= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
;
1371 if (attrs
& msidbFeatureAttributesFavorAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
;
1372 if (attrs
& msidbFeatureAttributesDisallowAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
;
1373 if (attrs
& msidbFeatureAttributesNoUnsupportedAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
;
1377 static UINT
MSI_GetFeatureInfo( MSIPACKAGE
*package
, LPCWSTR name
, LPDWORD attrs
,
1378 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1380 UINT r
= ERROR_SUCCESS
;
1381 MSIFEATURE
*feature
= msi_get_loaded_feature( package
, name
);
1384 if (!feature
) return ERROR_UNKNOWN_FEATURE
;
1385 if (attrs
) *attrs
= map_feature_attributes( feature
->Attributes
);
1388 if (feature
->Title
) len
= strlenW( feature
->Title
);
1390 if (*title_len
<= len
)
1393 if (title
) r
= ERROR_MORE_DATA
;
1397 if (feature
->Title
) strcpyW( title
, feature
->Title
);
1404 if (feature
->Description
) len
= strlenW( feature
->Description
);
1406 if (*help_len
<= len
)
1409 if (help
) r
= ERROR_MORE_DATA
;
1413 if (feature
->Description
) strcpyW( help
, feature
->Description
);
1421 /***********************************************************************
1422 * MsiGetFeatureInfoW (MSI.@)
1424 UINT WINAPI
MsiGetFeatureInfoW( MSIHANDLE handle
, LPCWSTR feature
, LPDWORD attrs
,
1425 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1428 MSIPACKAGE
*package
;
1430 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_w(feature
), attrs
, title
,
1431 title_len
, help
, help_len
);
1433 if (!feature
) return ERROR_INVALID_PARAMETER
;
1435 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1436 return ERROR_INVALID_HANDLE
;
1438 /* features may not have been loaded yet */
1439 msi_load_all_components( package
);
1440 msi_load_all_features( package
);
1442 r
= MSI_GetFeatureInfo( package
, feature
, attrs
, title
, title_len
, help
, help_len
);
1443 msiobj_release( &package
->hdr
);
1447 /***********************************************************************
1448 * MsiSetComponentStateA (MSI.@)
1450 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1451 INSTALLSTATE iState
)
1454 LPWSTR szwComponent
= strdupAtoW(szComponent
);
1456 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
1458 msi_free(szwComponent
);
1463 /***********************************************************************
1464 * MsiGetComponentStateA (MSI.@)
1466 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1467 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1469 LPWSTR szwComponent
= NULL
;
1472 szwComponent
= strdupAtoW(szComponent
);
1474 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
1476 msi_free( szwComponent
);
1481 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1482 INSTALLSTATE iState
)
1486 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
1488 comp
= msi_get_loaded_component(package
, szComponent
);
1490 return ERROR_UNKNOWN_COMPONENT
;
1493 comp
->Action
= iState
;
1495 return ERROR_SUCCESS
;
1498 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1499 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1503 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
1504 piInstalled
, piAction
);
1506 comp
= msi_get_loaded_component(package
,szComponent
);
1508 return ERROR_UNKNOWN_COMPONENT
;
1513 *piInstalled
= comp
->Installed
;
1515 *piInstalled
= INSTALLSTATE_UNKNOWN
;
1521 *piAction
= comp
->Action
;
1523 *piAction
= INSTALLSTATE_UNKNOWN
;
1526 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
1527 return ERROR_SUCCESS
;
1530 /***********************************************************************
1531 * MsiSetComponentStateW (MSI.@)
1533 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1534 INSTALLSTATE iState
)
1536 MSIPACKAGE
* package
;
1539 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1544 IWineMsiRemotePackage
*remote_package
;
1546 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1547 if (!remote_package
)
1548 return ERROR_INVALID_HANDLE
;
1550 component
= SysAllocString(szComponent
);
1553 IWineMsiRemotePackage_Release(remote_package
);
1554 return ERROR_OUTOFMEMORY
;
1557 hr
= IWineMsiRemotePackage_SetComponentState(remote_package
, component
, iState
);
1559 SysFreeString(component
);
1560 IWineMsiRemotePackage_Release(remote_package
);
1564 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1565 return HRESULT_CODE(hr
);
1567 return ERROR_FUNCTION_FAILED
;
1570 return ERROR_SUCCESS
;
1573 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
1574 msiobj_release(&package
->hdr
);
1578 /***********************************************************************
1579 * MsiGetComponentStateW (MSI.@)
1581 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1582 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1584 MSIPACKAGE
* package
;
1587 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szComponent
),
1588 piInstalled
, piAction
);
1590 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1595 IWineMsiRemotePackage
*remote_package
;
1597 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1598 if (!remote_package
)
1599 return ERROR_INVALID_HANDLE
;
1601 component
= SysAllocString(szComponent
);
1604 IWineMsiRemotePackage_Release(remote_package
);
1605 return ERROR_OUTOFMEMORY
;
1608 hr
= IWineMsiRemotePackage_GetComponentState(remote_package
, component
,
1609 piInstalled
, piAction
);
1611 SysFreeString(component
);
1612 IWineMsiRemotePackage_Release(remote_package
);
1616 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1617 return HRESULT_CODE(hr
);
1619 return ERROR_FUNCTION_FAILED
;
1622 return ERROR_SUCCESS
;
1625 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
1626 msiobj_release( &package
->hdr
);
1630 /***********************************************************************
1631 * MsiGetLanguage (MSI.@)
1633 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
1635 MSIPACKAGE
* package
;
1638 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1643 IWineMsiRemotePackage
*remote_package
;
1645 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1646 if (!remote_package
)
1647 return ERROR_INVALID_HANDLE
;
1649 hr
= IWineMsiRemotePackage_GetLanguage(remote_package
, &lang
);
1657 langid
= msi_get_property_int( package
->db
, szProductLanguage
, 0 );
1658 msiobj_release( &package
->hdr
);
1662 UINT
MSI_SetInstallLevel( MSIPACKAGE
*package
, int iInstallLevel
)
1664 static const WCHAR fmt
[] = { '%','d',0 };
1668 TRACE("%p %i\n", package
, iInstallLevel
);
1670 if (iInstallLevel
> 32767)
1671 return ERROR_INVALID_PARAMETER
;
1673 if (iInstallLevel
< 1)
1674 return MSI_SetFeatureStates( package
);
1676 sprintfW( level
, fmt
, iInstallLevel
);
1677 r
= msi_set_property( package
->db
, szInstallLevel
, level
);
1678 if ( r
== ERROR_SUCCESS
)
1679 r
= MSI_SetFeatureStates( package
);
1684 /***********************************************************************
1685 * MsiSetInstallLevel (MSI.@)
1687 UINT WINAPI
MsiSetInstallLevel(MSIHANDLE hInstall
, int iInstallLevel
)
1689 MSIPACKAGE
* package
;
1692 TRACE("%d %i\n", hInstall
, iInstallLevel
);
1694 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1698 IWineMsiRemotePackage
*remote_package
;
1700 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1701 if (!remote_package
)
1702 return ERROR_INVALID_HANDLE
;
1704 hr
= IWineMsiRemotePackage_SetInstallLevel(remote_package
, iInstallLevel
);
1706 IWineMsiRemotePackage_Release(remote_package
);
1710 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1711 return HRESULT_CODE(hr
);
1713 return ERROR_FUNCTION_FAILED
;
1716 return ERROR_SUCCESS
;
1719 r
= MSI_SetInstallLevel( package
, iInstallLevel
);
1721 msiobj_release( &package
->hdr
);
1726 /***********************************************************************
1727 * MsiGetFeatureValidStatesW (MSI.@)
1729 UINT WINAPI
MsiGetFeatureValidStatesW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1730 LPDWORD pInstallState
)
1732 if(pInstallState
) *pInstallState
= 1<<INSTALLSTATE_LOCAL
;
1733 FIXME("%d %s %p stub returning %d\n",
1734 hInstall
, debugstr_w(szFeature
), pInstallState
, pInstallState
? *pInstallState
: 0);
1736 return ERROR_SUCCESS
;
1739 /***********************************************************************
1740 * MsiGetFeatureValidStatesA (MSI.@)
1742 UINT WINAPI
MsiGetFeatureValidStatesA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1743 LPDWORD pInstallState
)
1746 LPWSTR szwFeature
= strdupAtoW(szFeature
);
1748 ret
= MsiGetFeatureValidStatesW(hInstall
, szwFeature
, pInstallState
);
1750 msi_free(szwFeature
);