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( MSIPACKAGE
*package
)
352 msi_set_sourcedir_props( package
, FALSE
);
353 return msi_dup_property( package
->db
, szSourceDir
);
356 WCHAR
*msi_resolve_source_folder( MSIPACKAGE
*package
, const WCHAR
*name
, MSIFOLDER
**folder
)
359 LPWSTR p
, path
= NULL
, parent
;
361 TRACE("working to resolve %s\n", debugstr_w(name
));
363 if (!strcmpW( name
, szSourceDir
)) name
= szTargetDir
;
364 if (!(f
= msi_get_loaded_folder( package
, name
))) return NULL
;
366 /* special resolving for root dir */
367 if (!strcmpW( name
, szTargetDir
) && !f
->ResolvedSource
)
369 f
->ResolvedSource
= get_source_root( package
);
371 if (folder
) *folder
= f
;
372 if (f
->ResolvedSource
)
374 path
= strdupW( f
->ResolvedSource
);
375 TRACE(" already resolved to %s\n", debugstr_w(path
));
378 if (!f
->Parent
) return path
;
380 TRACE(" ! parent is %s\n", debugstr_w(parent
));
382 p
= msi_resolve_source_folder( package
, parent
, NULL
);
384 if (package
->WordCount
& msidbSumInfoSourceTypeCompressed
)
385 path
= get_source_root( package
);
386 else if (package
->WordCount
& msidbSumInfoSourceTypeSFN
)
387 path
= msi_build_directory_name( 3, p
, f
->SourceShortPath
, NULL
);
389 path
= msi_build_directory_name( 3, p
, f
->SourceLongPath
, NULL
);
391 TRACE("-> %s\n", debugstr_w(path
));
392 f
->ResolvedSource
= strdupW( path
);
398 /***********************************************************************
399 * MSI_GetSourcePath (internal)
401 static UINT
MSI_GetSourcePath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
402 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
406 UINT r
= ERROR_FUNCTION_FAILED
;
408 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
411 return ERROR_INVALID_PARAMETER
;
413 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
417 IWineMsiRemotePackage
*remote_package
;
422 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
424 return ERROR_INVALID_HANDLE
;
426 folder
= SysAllocString( szFolder
);
429 IWineMsiRemotePackage_Release( remote_package
);
430 return ERROR_OUTOFMEMORY
;
434 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, NULL
, &len
);
439 value
= msi_alloc(len
* sizeof(WCHAR
));
442 r
= ERROR_OUTOFMEMORY
;
446 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, value
, &len
);
450 r
= msi_strcpy_to_awstring( value
, szPathBuf
, pcchPathBuf
);
453 IWineMsiRemotePackage_Release( remote_package
);
454 SysFreeString( folder
);
459 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
460 return HRESULT_CODE(hr
);
462 return ERROR_FUNCTION_FAILED
;
468 if (szPathBuf
->str
.w
&& !pcchPathBuf
)
470 msiobj_release( &package
->hdr
);
471 return ERROR_INVALID_PARAMETER
;
474 path
= msi_resolve_source_folder( package
, szFolder
, NULL
);
475 msiobj_release( &package
->hdr
);
477 TRACE("path = %s\n", debugstr_w(path
));
479 return ERROR_DIRECTORY
;
481 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
486 /***********************************************************************
487 * MsiGetSourcePathA (MSI.@)
489 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
490 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
496 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
499 str
.str
.a
= szPathBuf
;
501 folder
= strdupAtoW( szFolder
);
502 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
508 /***********************************************************************
509 * MsiGetSourcePathW (MSI.@)
511 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
512 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
516 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
519 str
.str
.w
= szPathBuf
;
521 return MSI_GetSourcePath( hInstall
, szFolder
, &str
, pcchPathBuf
);
524 /***********************************************************************
525 * MsiSetTargetPathA (MSI.@)
527 UINT WINAPI
MsiSetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
528 LPCSTR szFolderPath
)
530 LPWSTR szwFolder
= NULL
, szwFolderPath
= NULL
;
531 UINT rc
= ERROR_OUTOFMEMORY
;
533 if ( !szFolder
|| !szFolderPath
)
534 return ERROR_INVALID_PARAMETER
;
536 szwFolder
= strdupAtoW(szFolder
);
537 szwFolderPath
= strdupAtoW(szFolderPath
);
538 if (!szwFolder
|| !szwFolderPath
)
541 rc
= MsiSetTargetPathW( hInstall
, szwFolder
, szwFolderPath
);
545 msi_free(szwFolderPath
);
550 static void set_target_path( MSIPACKAGE
*package
, MSIFOLDER
*folder
, const WCHAR
*path
)
556 if (!(target_path
= msi_normalize_path( path
))) return;
557 if (strcmpW( target_path
, folder
->ResolvedTarget
))
559 msi_free( folder
->ResolvedTarget
);
560 folder
->ResolvedTarget
= target_path
;
561 msi_set_property( package
->db
, folder
->Directory
, folder
->ResolvedTarget
);
563 LIST_FOR_EACH_ENTRY( fl
, &folder
->children
, FolderList
, entry
)
566 msi_resolve_target_folder( package
, child
->Directory
, FALSE
);
569 else msi_free( target_path
);
572 UINT
MSI_SetTargetPathW( MSIPACKAGE
*package
, LPCWSTR szFolder
, LPCWSTR szFolderPath
)
578 TRACE("%p %s %s\n", package
, debugstr_w(szFolder
), debugstr_w(szFolderPath
));
580 attrib
= GetFileAttributesW(szFolderPath
);
581 /* native MSI tests writeability by making temporary files at each drive */
582 if (attrib
!= INVALID_FILE_ATTRIBUTES
&&
583 (attrib
& FILE_ATTRIBUTE_OFFLINE
|| attrib
& FILE_ATTRIBUTE_READONLY
))
585 return ERROR_FUNCTION_FAILED
;
587 if (!(folder
= msi_get_loaded_folder( package
, szFolder
))) return ERROR_DIRECTORY
;
589 set_target_path( package
, folder
, szFolderPath
);
591 LIST_FOR_EACH_ENTRY( file
, &package
->files
, MSIFILE
, entry
)
594 MSICOMPONENT
*comp
= file
->Component
;
596 if (!comp
->Enabled
|| (comp
->assembly
&& !comp
->assembly
->application
)) continue;
598 dir
= msi_get_target_folder( package
, comp
->Directory
);
599 msi_free( file
->TargetPath
);
600 file
->TargetPath
= msi_build_directory_name( 2, dir
, file
->FileName
);
602 return ERROR_SUCCESS
;
605 /***********************************************************************
606 * MsiSetTargetPathW (MSI.@)
608 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
609 LPCWSTR szFolderPath
)
614 TRACE("%s %s\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
616 if ( !szFolder
|| !szFolderPath
)
617 return ERROR_INVALID_PARAMETER
;
619 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
624 IWineMsiRemotePackage
*remote_package
;
626 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
628 return ERROR_INVALID_HANDLE
;
630 folder
= SysAllocString( szFolder
);
631 path
= SysAllocString( szFolderPath
);
632 if (!folder
|| !path
)
634 SysFreeString(folder
);
636 IWineMsiRemotePackage_Release( remote_package
);
637 return ERROR_OUTOFMEMORY
;
640 hr
= IWineMsiRemotePackage_SetTargetPath( remote_package
, folder
, path
);
642 SysFreeString(folder
);
644 IWineMsiRemotePackage_Release( remote_package
);
648 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
649 return HRESULT_CODE(hr
);
651 return ERROR_FUNCTION_FAILED
;
654 return ERROR_SUCCESS
;
657 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
658 msiobj_release( &package
->hdr
);
662 /***********************************************************************
665 * Returns an internal installer state (if it is running in a mode iRunMode)
668 * hInstall [I] Handle to the installation
669 * hRunMode [I] Checking run mode
670 * MSIRUNMODE_ADMIN Administrative mode
671 * MSIRUNMODE_ADVERTISE Advertisement mode
672 * MSIRUNMODE_MAINTENANCE Maintenance mode
673 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
674 * MSIRUNMODE_LOGENABLED Log file is writing
675 * MSIRUNMODE_OPERATIONS Operations in progress??
676 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
677 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
678 * MSIRUNMODE_CABINET Files from cabinet are installed
679 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
680 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
681 * MSIRUNMODE_RESERVED11 Reserved
682 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
683 * MSIRUNMODE_ZAWENABLED Demand installation is supported
684 * MSIRUNMODE_RESERVED14 Reserved
685 * MSIRUNMODE_RESERVED15 Reserved
686 * MSIRUNMODE_SCHEDULED called from install script
687 * MSIRUNMODE_ROLLBACK called from rollback script
688 * MSIRUNMODE_COMMIT called from commit script
692 * Not in the state: FALSE
695 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
700 TRACE("%d %d\n", hInstall
, iRunMode
);
702 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
707 IWineMsiRemotePackage
*remote_package
;
709 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
713 hr
= IWineMsiRemotePackage_GetMode(remote_package
, iRunMode
, &ret
);
714 IWineMsiRemotePackage_Release(remote_package
);
724 case MSIRUNMODE_ADMIN
:
725 FIXME("no support for administrative installs\n");
728 case MSIRUNMODE_ADVERTISE
:
729 FIXME("no support for advertised installs\n");
732 case MSIRUNMODE_WINDOWS9X
:
733 if (GetVersion() & 0x80000000)
737 case MSIRUNMODE_OPERATIONS
:
738 case MSIRUNMODE_RESERVED11
:
739 case MSIRUNMODE_RESERVED14
:
740 case MSIRUNMODE_RESERVED15
:
743 case MSIRUNMODE_SCHEDULED
:
744 r
= package
->scheduled_action_running
;
747 case MSIRUNMODE_ROLLBACK
:
748 r
= package
->rollback_action_running
;
751 case MSIRUNMODE_COMMIT
:
752 r
= package
->commit_action_running
;
755 case MSIRUNMODE_MAINTENANCE
:
756 r
= msi_get_property_int( package
->db
, szInstalled
, 0 ) != 0;
759 case MSIRUNMODE_ROLLBACKENABLED
:
760 r
= msi_get_property_int( package
->db
, szRollbackDisabled
, 0 ) == 0;
763 case MSIRUNMODE_REBOOTATEND
:
764 r
= package
->need_reboot
;
767 case MSIRUNMODE_LOGENABLED
:
768 r
= (package
->log_file
!= INVALID_HANDLE_VALUE
);
772 FIXME("unimplemented run mode: %d\n", iRunMode
);
776 msiobj_release( &package
->hdr
);
780 /***********************************************************************
783 UINT WINAPI
MsiSetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
, BOOL fState
)
788 TRACE("%d %d %d\n", hInstall
, iRunMode
, fState
);
790 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
794 IWineMsiRemotePackage
*remote_package
;
796 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
800 hr
= IWineMsiRemotePackage_SetMode( remote_package
, iRunMode
, fState
);
801 IWineMsiRemotePackage_Release( remote_package
);
805 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
806 return HRESULT_CODE(hr
);
808 return ERROR_FUNCTION_FAILED
;
811 return ERROR_SUCCESS
;
816 case MSIRUNMODE_REBOOTATEND
:
817 package
->need_reboot
= 1;
821 case MSIRUNMODE_REBOOTNOW
:
822 FIXME("unimplemented run mode: %d\n", iRunMode
);
823 r
= ERROR_FUNCTION_FAILED
;
827 r
= ERROR_ACCESS_DENIED
;
830 msiobj_release( &package
->hdr
);
834 /***********************************************************************
835 * MsiSetFeatureStateA (MSI.@)
837 * According to the docs, when this is called it immediately recalculates
838 * all the component states as well
840 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
843 LPWSTR szwFeature
= NULL
;
846 szwFeature
= strdupAtoW(szFeature
);
849 return ERROR_FUNCTION_FAILED
;
851 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
853 msi_free(szwFeature
);
858 /* update component state based on a feature change */
859 void ACTION_UpdateComponentStates( MSIPACKAGE
*package
, MSIFEATURE
*feature
)
861 INSTALLSTATE newstate
;
864 newstate
= feature
->ActionRequest
;
865 if (newstate
== INSTALLSTATE_ABSENT
) newstate
= INSTALLSTATE_UNKNOWN
;
867 LIST_FOR_EACH_ENTRY(cl
, &feature
->Components
, ComponentList
, entry
)
869 MSICOMPONENT
*component
= cl
->component
;
871 if (!component
->Enabled
) continue;
873 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
874 newstate
, debugstr_w(component
->Component
), component
->Installed
,
875 component
->Action
, component
->ActionRequest
);
877 if (newstate
== INSTALLSTATE_LOCAL
)
879 component
->Action
= INSTALLSTATE_LOCAL
;
880 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
884 ComponentList
*clist
;
887 component
->hasLocalFeature
= FALSE
;
889 component
->Action
= newstate
;
890 component
->ActionRequest
= newstate
;
891 /* if any other feature wants it local we need to set it local */
892 LIST_FOR_EACH_ENTRY(f
, &package
->features
, MSIFEATURE
, entry
)
894 if ( f
->ActionRequest
!= INSTALLSTATE_LOCAL
&&
895 f
->ActionRequest
!= INSTALLSTATE_SOURCE
)
899 LIST_FOR_EACH_ENTRY(clist
, &f
->Components
, ComponentList
, entry
)
901 if (clist
->component
== component
&&
902 (f
->ActionRequest
== INSTALLSTATE_LOCAL
||
903 f
->ActionRequest
== INSTALLSTATE_SOURCE
))
905 TRACE("Saved by %s\n", debugstr_w(f
->Feature
));
906 component
->hasLocalFeature
= TRUE
;
908 if (component
->Attributes
& msidbComponentAttributesOptional
)
910 if (f
->Attributes
& msidbFeatureAttributesFavorSource
)
912 component
->Action
= INSTALLSTATE_SOURCE
;
913 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
917 component
->Action
= INSTALLSTATE_LOCAL
;
918 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
921 else if (component
->Attributes
& msidbComponentAttributesSourceOnly
)
923 component
->Action
= INSTALLSTATE_SOURCE
;
924 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
928 component
->Action
= INSTALLSTATE_LOCAL
;
929 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
935 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
936 newstate
, debugstr_w(component
->Component
), component
->Installed
,
937 component
->Action
, component
->ActionRequest
);
941 UINT
MSI_SetFeatureStateW( MSIPACKAGE
*package
, LPCWSTR szFeature
, INSTALLSTATE iState
)
943 UINT rc
= ERROR_SUCCESS
;
944 MSIFEATURE
*feature
, *child
;
946 TRACE("%s %i\n", debugstr_w(szFeature
), iState
);
948 feature
= msi_get_loaded_feature( package
, szFeature
);
950 return ERROR_UNKNOWN_FEATURE
;
952 if (iState
== INSTALLSTATE_ADVERTISED
&&
953 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
954 return ERROR_FUNCTION_FAILED
;
956 feature
->ActionRequest
= iState
;
958 ACTION_UpdateComponentStates( package
, feature
);
960 /* update all the features that are children of this feature */
961 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
963 if (child
->Feature_Parent
&& !strcmpW( szFeature
, child
->Feature_Parent
))
964 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
970 /***********************************************************************
971 * MsiSetFeatureStateW (MSI.@)
973 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
977 UINT rc
= ERROR_SUCCESS
;
979 TRACE("%s %i\n",debugstr_w(szFeature
), iState
);
981 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
986 IWineMsiRemotePackage
*remote_package
;
988 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
990 return ERROR_INVALID_HANDLE
;
992 feature
= SysAllocString(szFeature
);
995 IWineMsiRemotePackage_Release(remote_package
);
996 return ERROR_OUTOFMEMORY
;
999 hr
= IWineMsiRemotePackage_SetFeatureState(remote_package
, feature
, iState
);
1001 SysFreeString(feature
);
1002 IWineMsiRemotePackage_Release(remote_package
);
1006 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1007 return HRESULT_CODE(hr
);
1009 return ERROR_FUNCTION_FAILED
;
1012 return ERROR_SUCCESS
;
1015 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
1017 msiobj_release( &package
->hdr
);
1021 /***********************************************************************
1022 * MsiSetFeatureAttributesA (MSI.@)
1024 UINT WINAPI
MsiSetFeatureAttributesA( MSIHANDLE handle
, LPCSTR feature
, DWORD attrs
)
1027 WCHAR
*featureW
= NULL
;
1029 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_a(feature
), attrs
);
1031 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1033 r
= MsiSetFeatureAttributesW( handle
, featureW
, attrs
);
1034 msi_free( featureW
);
1038 static DWORD
unmap_feature_attributes( DWORD attrs
)
1042 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORLOCAL
) ret
= msidbFeatureAttributesFavorLocal
;
1043 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORSOURCE
) ret
|= msidbFeatureAttributesFavorSource
;
1044 if (attrs
& INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
) ret
|= msidbFeatureAttributesFollowParent
;
1045 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
) ret
|= msidbFeatureAttributesFavorAdvertise
;
1046 if (attrs
& INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
) ret
|= msidbFeatureAttributesDisallowAdvertise
;
1047 if (attrs
& INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
) ret
|= msidbFeatureAttributesNoUnsupportedAdvertise
;
1051 /***********************************************************************
1052 * MsiSetFeatureAttributesW (MSI.@)
1054 UINT WINAPI
MsiSetFeatureAttributesW( MSIHANDLE handle
, LPCWSTR name
, DWORD attrs
)
1056 MSIPACKAGE
*package
;
1057 MSIFEATURE
*feature
;
1060 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_w(name
), attrs
);
1062 if (!name
|| !name
[0]) return ERROR_UNKNOWN_FEATURE
;
1064 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1065 return ERROR_INVALID_HANDLE
;
1067 costing
= msi_dup_property( package
->db
, szCostingComplete
);
1068 if (!costing
|| !strcmpW( costing
, szOne
))
1070 msi_free( costing
);
1071 msiobj_release( &package
->hdr
);
1072 return ERROR_FUNCTION_FAILED
;
1074 msi_free( costing
);
1075 if (!(feature
= msi_get_loaded_feature( package
, name
)))
1077 msiobj_release( &package
->hdr
);
1078 return ERROR_UNKNOWN_FEATURE
;
1080 feature
->Attributes
= unmap_feature_attributes( attrs
);
1081 msiobj_release( &package
->hdr
);
1082 return ERROR_SUCCESS
;
1085 /***********************************************************************
1086 * MsiGetFeatureStateA (MSI.@)
1088 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1089 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1091 LPWSTR szwFeature
= NULL
;
1094 if (szFeature
&& !(szwFeature
= strdupAtoW(szFeature
))) return ERROR_OUTOFMEMORY
;
1096 rc
= MsiGetFeatureStateW(hInstall
, szwFeature
, piInstalled
, piAction
);
1097 msi_free( szwFeature
);
1101 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPCWSTR szFeature
,
1102 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1104 MSIFEATURE
*feature
;
1106 feature
= msi_get_loaded_feature(package
,szFeature
);
1108 return ERROR_UNKNOWN_FEATURE
;
1111 *piInstalled
= feature
->Installed
;
1114 *piAction
= feature
->ActionRequest
;
1116 TRACE("returning %i %i\n", feature
->Installed
, feature
->ActionRequest
);
1118 return ERROR_SUCCESS
;
1121 /***********************************************************************
1122 * MsiGetFeatureStateW (MSI.@)
1124 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1125 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1127 MSIPACKAGE
* package
;
1130 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
, piAction
);
1132 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1137 IWineMsiRemotePackage
*remote_package
;
1139 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1140 if (!remote_package
)
1141 return ERROR_INVALID_HANDLE
;
1143 feature
= SysAllocString(szFeature
);
1146 IWineMsiRemotePackage_Release(remote_package
);
1147 return ERROR_OUTOFMEMORY
;
1150 hr
= IWineMsiRemotePackage_GetFeatureState(remote_package
, feature
,
1151 piInstalled
, piAction
);
1153 SysFreeString(feature
);
1154 IWineMsiRemotePackage_Release(remote_package
);
1158 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1159 return HRESULT_CODE(hr
);
1161 return ERROR_FUNCTION_FAILED
;
1164 return ERROR_SUCCESS
;
1167 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
1168 msiobj_release( &package
->hdr
);
1172 /***********************************************************************
1173 * MsiGetFeatureCostA (MSI.@)
1175 UINT WINAPI
MsiGetFeatureCostA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1176 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1178 LPWSTR szwFeature
= NULL
;
1181 szwFeature
= strdupAtoW(szFeature
);
1183 rc
= MsiGetFeatureCostW(hInstall
, szwFeature
, iCostTree
, iState
, piCost
);
1185 msi_free(szwFeature
);
1190 static INT
feature_cost( MSIFEATURE
*feature
)
1195 LIST_FOR_EACH_ENTRY( comp
, &feature
->Components
, MSICOMPONENT
, entry
)
1202 UINT
MSI_GetFeatureCost( MSIPACKAGE
*package
, MSIFEATURE
*feature
, MSICOSTTREE tree
,
1203 INSTALLSTATE state
, LPINT cost
)
1205 TRACE("%s, %u, %d, %p\n", debugstr_w(feature
->Feature
), tree
, state
, cost
);
1210 case MSICOSTTREE_CHILDREN
:
1214 LIST_FOR_EACH_ENTRY( child
, &feature
->Children
, MSIFEATURE
, entry
)
1216 if (child
->ActionRequest
== state
)
1217 *cost
+= feature_cost( child
);
1221 case MSICOSTTREE_PARENTS
:
1223 const WCHAR
*feature_parent
= feature
->Feature_Parent
;
1226 MSIFEATURE
*parent
= msi_get_loaded_feature( package
, feature_parent
);
1230 if (parent
->ActionRequest
== state
)
1231 *cost
+= feature_cost( parent
);
1233 feature_parent
= parent
->Feature_Parent
;
1237 case MSICOSTTREE_SELFONLY
:
1238 if (feature
->ActionRequest
== state
)
1239 *cost
= feature_cost( feature
);
1243 WARN("unhandled cost tree %u\n", tree
);
1248 return ERROR_SUCCESS
;
1251 /***********************************************************************
1252 * MsiGetFeatureCostW (MSI.@)
1254 UINT WINAPI
MsiGetFeatureCostW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1255 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1257 MSIPACKAGE
*package
;
1258 MSIFEATURE
*feature
;
1261 TRACE("(%d %s %i %i %p)\n", hInstall
, debugstr_w(szFeature
),
1262 iCostTree
, iState
, piCost
);
1264 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1269 IWineMsiRemotePackage
*remote_package
;
1271 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1272 if (!remote_package
)
1273 return ERROR_INVALID_HANDLE
;
1275 feature
= SysAllocString(szFeature
);
1278 IWineMsiRemotePackage_Release(remote_package
);
1279 return ERROR_OUTOFMEMORY
;
1282 hr
= IWineMsiRemotePackage_GetFeatureCost(remote_package
, feature
,
1283 iCostTree
, iState
, piCost
);
1285 SysFreeString(feature
);
1286 IWineMsiRemotePackage_Release(remote_package
);
1290 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1291 return HRESULT_CODE(hr
);
1293 return ERROR_FUNCTION_FAILED
;
1296 return ERROR_SUCCESS
;
1299 feature
= msi_get_loaded_feature(package
, szFeature
);
1302 ret
= MSI_GetFeatureCost(package
, feature
, iCostTree
, iState
, piCost
);
1304 ret
= ERROR_UNKNOWN_FEATURE
;
1306 msiobj_release( &package
->hdr
);
1310 /***********************************************************************
1311 * MsiGetFeatureInfoA (MSI.@)
1313 UINT WINAPI
MsiGetFeatureInfoA( MSIHANDLE handle
, LPCSTR feature
, LPDWORD attrs
,
1314 LPSTR title
, LPDWORD title_len
, LPSTR help
, LPDWORD help_len
)
1317 WCHAR
*titleW
= NULL
, *helpW
= NULL
, *featureW
= NULL
;
1319 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_a(feature
), attrs
, title
,
1320 title_len
, help
, help_len
);
1322 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1324 if (title
&& title_len
&& !(titleW
= msi_alloc( *title_len
* sizeof(WCHAR
) )))
1326 msi_free( featureW
);
1327 return ERROR_OUTOFMEMORY
;
1329 if (help
&& help_len
&& !(helpW
= msi_alloc( *help_len
* sizeof(WCHAR
) )))
1331 msi_free( featureW
);
1333 return ERROR_OUTOFMEMORY
;
1335 r
= MsiGetFeatureInfoW( handle
, featureW
, attrs
, titleW
, title_len
, helpW
, help_len
);
1336 if (r
== ERROR_SUCCESS
)
1338 if (titleW
) WideCharToMultiByte( CP_ACP
, 0, titleW
, -1, title
, *title_len
+ 1, NULL
, NULL
);
1339 if (helpW
) WideCharToMultiByte( CP_ACP
, 0, helpW
, -1, help
, *help_len
+ 1, NULL
, NULL
);
1343 msi_free( featureW
);
1347 static DWORD
map_feature_attributes( DWORD attrs
)
1351 if (attrs
== msidbFeatureAttributesFavorLocal
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORLOCAL
;
1352 if (attrs
& msidbFeatureAttributesFavorSource
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORSOURCE
;
1353 if (attrs
& msidbFeatureAttributesFollowParent
) ret
|= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
;
1354 if (attrs
& msidbFeatureAttributesFavorAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
;
1355 if (attrs
& msidbFeatureAttributesDisallowAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
;
1356 if (attrs
& msidbFeatureAttributesNoUnsupportedAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
;
1360 static UINT
MSI_GetFeatureInfo( MSIPACKAGE
*package
, LPCWSTR name
, LPDWORD attrs
,
1361 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1363 UINT r
= ERROR_SUCCESS
;
1364 MSIFEATURE
*feature
= msi_get_loaded_feature( package
, name
);
1367 if (!feature
) return ERROR_UNKNOWN_FEATURE
;
1368 if (attrs
) *attrs
= map_feature_attributes( feature
->Attributes
);
1371 if (feature
->Title
) len
= strlenW( feature
->Title
);
1373 if (*title_len
<= len
)
1376 if (title
) r
= ERROR_MORE_DATA
;
1380 if (feature
->Title
) strcpyW( title
, feature
->Title
);
1387 if (feature
->Description
) len
= strlenW( feature
->Description
);
1389 if (*help_len
<= len
)
1392 if (help
) r
= ERROR_MORE_DATA
;
1396 if (feature
->Description
) strcpyW( help
, feature
->Description
);
1404 /***********************************************************************
1405 * MsiGetFeatureInfoW (MSI.@)
1407 UINT WINAPI
MsiGetFeatureInfoW( MSIHANDLE handle
, LPCWSTR feature
, LPDWORD attrs
,
1408 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1411 MSIPACKAGE
*package
;
1413 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_w(feature
), attrs
, title
,
1414 title_len
, help
, help_len
);
1416 if (!feature
) return ERROR_INVALID_PARAMETER
;
1418 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1419 return ERROR_INVALID_HANDLE
;
1421 /* features may not have been loaded yet */
1422 msi_load_all_components( package
);
1423 msi_load_all_features( package
);
1425 r
= MSI_GetFeatureInfo( package
, feature
, attrs
, title
, title_len
, help
, help_len
);
1426 msiobj_release( &package
->hdr
);
1430 /***********************************************************************
1431 * MsiSetComponentStateA (MSI.@)
1433 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1434 INSTALLSTATE iState
)
1437 LPWSTR szwComponent
= strdupAtoW(szComponent
);
1439 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
1441 msi_free(szwComponent
);
1446 /***********************************************************************
1447 * MsiGetComponentStateA (MSI.@)
1449 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1450 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1452 LPWSTR szwComponent
= NULL
;
1455 szwComponent
= strdupAtoW(szComponent
);
1457 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
1459 msi_free( szwComponent
);
1464 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1465 INSTALLSTATE iState
)
1469 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
1471 comp
= msi_get_loaded_component(package
, szComponent
);
1473 return ERROR_UNKNOWN_COMPONENT
;
1476 comp
->Action
= iState
;
1478 return ERROR_SUCCESS
;
1481 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1482 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1486 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
1487 piInstalled
, piAction
);
1489 comp
= msi_get_loaded_component(package
,szComponent
);
1491 return ERROR_UNKNOWN_COMPONENT
;
1496 *piInstalled
= comp
->Installed
;
1498 *piInstalled
= INSTALLSTATE_UNKNOWN
;
1504 *piAction
= comp
->Action
;
1506 *piAction
= INSTALLSTATE_UNKNOWN
;
1509 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
1510 return ERROR_SUCCESS
;
1513 /***********************************************************************
1514 * MsiSetComponentStateW (MSI.@)
1516 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1517 INSTALLSTATE iState
)
1519 MSIPACKAGE
* package
;
1522 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1527 IWineMsiRemotePackage
*remote_package
;
1529 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1530 if (!remote_package
)
1531 return ERROR_INVALID_HANDLE
;
1533 component
= SysAllocString(szComponent
);
1536 IWineMsiRemotePackage_Release(remote_package
);
1537 return ERROR_OUTOFMEMORY
;
1540 hr
= IWineMsiRemotePackage_SetComponentState(remote_package
, component
, iState
);
1542 SysFreeString(component
);
1543 IWineMsiRemotePackage_Release(remote_package
);
1547 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1548 return HRESULT_CODE(hr
);
1550 return ERROR_FUNCTION_FAILED
;
1553 return ERROR_SUCCESS
;
1556 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
1557 msiobj_release(&package
->hdr
);
1561 /***********************************************************************
1562 * MsiGetComponentStateW (MSI.@)
1564 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1565 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1567 MSIPACKAGE
* package
;
1570 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szComponent
),
1571 piInstalled
, piAction
);
1573 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1578 IWineMsiRemotePackage
*remote_package
;
1580 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1581 if (!remote_package
)
1582 return ERROR_INVALID_HANDLE
;
1584 component
= SysAllocString(szComponent
);
1587 IWineMsiRemotePackage_Release(remote_package
);
1588 return ERROR_OUTOFMEMORY
;
1591 hr
= IWineMsiRemotePackage_GetComponentState(remote_package
, component
,
1592 piInstalled
, piAction
);
1594 SysFreeString(component
);
1595 IWineMsiRemotePackage_Release(remote_package
);
1599 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1600 return HRESULT_CODE(hr
);
1602 return ERROR_FUNCTION_FAILED
;
1605 return ERROR_SUCCESS
;
1608 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
1609 msiobj_release( &package
->hdr
);
1613 /***********************************************************************
1614 * MsiGetLanguage (MSI.@)
1616 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
1618 MSIPACKAGE
* package
;
1621 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1626 IWineMsiRemotePackage
*remote_package
;
1628 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1629 if (!remote_package
)
1630 return ERROR_INVALID_HANDLE
;
1632 hr
= IWineMsiRemotePackage_GetLanguage(remote_package
, &lang
);
1640 langid
= msi_get_property_int( package
->db
, szProductLanguage
, 0 );
1641 msiobj_release( &package
->hdr
);
1645 UINT
MSI_SetInstallLevel( MSIPACKAGE
*package
, int iInstallLevel
)
1647 static const WCHAR fmt
[] = { '%','d',0 };
1651 TRACE("%p %i\n", package
, iInstallLevel
);
1653 if (iInstallLevel
> 32767)
1654 return ERROR_INVALID_PARAMETER
;
1656 if (iInstallLevel
< 1)
1657 return MSI_SetFeatureStates( package
);
1659 sprintfW( level
, fmt
, iInstallLevel
);
1660 r
= msi_set_property( package
->db
, szInstallLevel
, level
);
1661 if ( r
== ERROR_SUCCESS
)
1662 r
= MSI_SetFeatureStates( package
);
1667 /***********************************************************************
1668 * MsiSetInstallLevel (MSI.@)
1670 UINT WINAPI
MsiSetInstallLevel(MSIHANDLE hInstall
, int iInstallLevel
)
1672 MSIPACKAGE
* package
;
1675 TRACE("%d %i\n", hInstall
, iInstallLevel
);
1677 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1681 IWineMsiRemotePackage
*remote_package
;
1683 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1684 if (!remote_package
)
1685 return ERROR_INVALID_HANDLE
;
1687 hr
= IWineMsiRemotePackage_SetInstallLevel(remote_package
, iInstallLevel
);
1689 IWineMsiRemotePackage_Release(remote_package
);
1693 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1694 return HRESULT_CODE(hr
);
1696 return ERROR_FUNCTION_FAILED
;
1699 return ERROR_SUCCESS
;
1702 r
= MSI_SetInstallLevel( package
, iInstallLevel
);
1704 msiobj_release( &package
->hdr
);
1709 /***********************************************************************
1710 * MsiGetFeatureValidStatesW (MSI.@)
1712 UINT WINAPI
MsiGetFeatureValidStatesW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1713 LPDWORD pInstallState
)
1715 if(pInstallState
) *pInstallState
= 1<<INSTALLSTATE_LOCAL
;
1716 FIXME("%d %s %p stub returning %d\n",
1717 hInstall
, debugstr_w(szFeature
), pInstallState
, pInstallState
? *pInstallState
: 0);
1719 return ERROR_SUCCESS
;
1722 /***********************************************************************
1723 * MsiGetFeatureValidStatesA (MSI.@)
1725 UINT WINAPI
MsiGetFeatureValidStatesA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1726 LPDWORD pInstallState
)
1729 LPWSTR szwFeature
= strdupAtoW(szFeature
);
1731 ret
= MsiGetFeatureValidStatesW(hInstall
, szwFeature
, pInstallState
);
1733 msi_free(szwFeature
);