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( const WCHAR
*str
, int len
, awstring
*awbuf
, DWORD
*sz
)
183 UINT r
= ERROR_SUCCESS
;
185 if (awbuf
->str
.w
&& !sz
)
186 return ERROR_INVALID_PARAMETER
;
188 return ERROR_SUCCESS
;
190 if (len
< 0) len
= strlenW( str
);
192 if (awbuf
->unicode
&& awbuf
->str
.w
)
193 memcpy( awbuf
->str
.w
, str
, min(len
+ 1, *sz
) * sizeof(WCHAR
) );
196 int lenA
= WideCharToMultiByte( CP_ACP
, 0, str
, len
+ 1, NULL
, 0, NULL
, NULL
);
198 WideCharToMultiByte( CP_ACP
, 0, str
, len
+ 1, awbuf
->str
.a
, *sz
, NULL
, NULL
);
199 if (awbuf
->str
.a
&& *sz
&& lenA
>= *sz
)
200 awbuf
->str
.a
[*sz
- 1] = 0;
203 if (awbuf
->str
.w
&& len
>= *sz
)
209 const WCHAR
*msi_get_target_folder( MSIPACKAGE
*package
, const WCHAR
*name
)
211 MSIFOLDER
*folder
= msi_get_loaded_folder( package
, name
);
213 if (!folder
) return NULL
;
214 if (!folder
->ResolvedTarget
)
216 MSIFOLDER
*parent
= folder
;
217 while (parent
->Parent
&& strcmpW( parent
->Parent
, parent
->Directory
))
219 parent
= msi_get_loaded_folder( package
, parent
->Parent
);
221 msi_resolve_target_folder( package
, parent
->Directory
, TRUE
);
223 return folder
->ResolvedTarget
;
226 /***********************************************************************
227 * MsiGetTargetPath (internal)
229 static UINT
MSI_GetTargetPath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
230 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
234 UINT r
= ERROR_FUNCTION_FAILED
;
237 return ERROR_INVALID_PARAMETER
;
239 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
243 IWineMsiRemotePackage
*remote_package
;
248 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
250 return ERROR_INVALID_HANDLE
;
252 folder
= SysAllocString( szFolder
);
255 IWineMsiRemotePackage_Release( remote_package
);
256 return ERROR_OUTOFMEMORY
;
260 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
, NULL
, &len
);
265 value
= msi_alloc(len
* sizeof(WCHAR
));
268 r
= ERROR_OUTOFMEMORY
;
272 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
, value
, &len
);
276 r
= msi_strcpy_to_awstring( value
, len
, szPathBuf
, pcchPathBuf
);
279 IWineMsiRemotePackage_Release( remote_package
);
280 SysFreeString( folder
);
285 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
286 return HRESULT_CODE(hr
);
288 return ERROR_FUNCTION_FAILED
;
294 path
= msi_get_target_folder( package
, szFolder
);
295 msiobj_release( &package
->hdr
);
298 return ERROR_DIRECTORY
;
300 return msi_strcpy_to_awstring( path
, -1, szPathBuf
, pcchPathBuf
);
303 /***********************************************************************
304 * MsiGetTargetPathA (MSI.@)
306 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
307 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
313 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
315 szwFolder
= strdupAtoW(szFolder
);
316 if (szFolder
&& !szwFolder
)
317 return ERROR_FUNCTION_FAILED
;
319 path
.unicode
= FALSE
;
320 path
.str
.a
= szPathBuf
;
322 r
= MSI_GetTargetPath( hInstall
, szwFolder
, &path
, pcchPathBuf
);
324 msi_free( szwFolder
);
329 /***********************************************************************
330 * MsiGetTargetPathW (MSI.@)
332 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
333 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
337 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
340 path
.str
.w
= szPathBuf
;
342 return MSI_GetTargetPath( hInstall
, szFolder
, &path
, pcchPathBuf
);
345 static WCHAR
*get_source_root( MSIPACKAGE
*package
)
347 msi_set_sourcedir_props( package
, FALSE
);
348 return msi_dup_property( package
->db
, szSourceDir
);
351 WCHAR
*msi_resolve_source_folder( MSIPACKAGE
*package
, const WCHAR
*name
, MSIFOLDER
**folder
)
354 LPWSTR p
, path
= NULL
, parent
;
356 TRACE("working to resolve %s\n", debugstr_w(name
));
358 if (!strcmpW( name
, szSourceDir
)) name
= szTargetDir
;
359 if (!(f
= msi_get_loaded_folder( package
, name
))) return NULL
;
361 /* special resolving for root dir */
362 if (!strcmpW( name
, szTargetDir
) && !f
->ResolvedSource
)
364 f
->ResolvedSource
= get_source_root( package
);
366 if (folder
) *folder
= f
;
367 if (f
->ResolvedSource
)
369 path
= strdupW( f
->ResolvedSource
);
370 TRACE(" already resolved to %s\n", debugstr_w(path
));
373 if (!f
->Parent
) return path
;
375 TRACE(" ! parent is %s\n", debugstr_w(parent
));
377 p
= msi_resolve_source_folder( package
, parent
, NULL
);
379 if (package
->WordCount
& msidbSumInfoSourceTypeCompressed
)
380 path
= get_source_root( package
);
381 else if (package
->WordCount
& msidbSumInfoSourceTypeSFN
)
382 path
= msi_build_directory_name( 3, p
, f
->SourceShortPath
, NULL
);
384 path
= msi_build_directory_name( 3, p
, f
->SourceLongPath
, NULL
);
386 TRACE("-> %s\n", debugstr_w(path
));
387 f
->ResolvedSource
= strdupW( path
);
393 /***********************************************************************
394 * MSI_GetSourcePath (internal)
396 static UINT
MSI_GetSourcePath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
397 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
401 UINT r
= ERROR_FUNCTION_FAILED
;
403 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
406 return ERROR_INVALID_PARAMETER
;
408 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
412 IWineMsiRemotePackage
*remote_package
;
417 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
419 return ERROR_INVALID_HANDLE
;
421 folder
= SysAllocString( szFolder
);
424 IWineMsiRemotePackage_Release( remote_package
);
425 return ERROR_OUTOFMEMORY
;
429 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, NULL
, &len
);
434 value
= msi_alloc(len
* sizeof(WCHAR
));
437 r
= ERROR_OUTOFMEMORY
;
441 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
, value
, &len
);
445 r
= msi_strcpy_to_awstring( value
, len
, szPathBuf
, pcchPathBuf
);
448 IWineMsiRemotePackage_Release( remote_package
);
449 SysFreeString( folder
);
454 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
455 return HRESULT_CODE(hr
);
457 return ERROR_FUNCTION_FAILED
;
463 if (szPathBuf
->str
.w
&& !pcchPathBuf
)
465 msiobj_release( &package
->hdr
);
466 return ERROR_INVALID_PARAMETER
;
469 path
= msi_resolve_source_folder( package
, szFolder
, NULL
);
470 msiobj_release( &package
->hdr
);
472 TRACE("path = %s\n", debugstr_w(path
));
474 return ERROR_DIRECTORY
;
476 r
= msi_strcpy_to_awstring( path
, -1, szPathBuf
, pcchPathBuf
);
481 /***********************************************************************
482 * MsiGetSourcePathA (MSI.@)
484 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
485 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
491 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
494 str
.str
.a
= szPathBuf
;
496 folder
= strdupAtoW( szFolder
);
497 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
503 /***********************************************************************
504 * MsiGetSourcePathW (MSI.@)
506 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
507 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
511 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
514 str
.str
.w
= szPathBuf
;
516 return MSI_GetSourcePath( hInstall
, szFolder
, &str
, pcchPathBuf
);
519 /***********************************************************************
520 * MsiSetTargetPathA (MSI.@)
522 UINT WINAPI
MsiSetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
523 LPCSTR szFolderPath
)
525 LPWSTR szwFolder
= NULL
, szwFolderPath
= NULL
;
526 UINT rc
= ERROR_OUTOFMEMORY
;
528 if ( !szFolder
|| !szFolderPath
)
529 return ERROR_INVALID_PARAMETER
;
531 szwFolder
= strdupAtoW(szFolder
);
532 szwFolderPath
= strdupAtoW(szFolderPath
);
533 if (!szwFolder
|| !szwFolderPath
)
536 rc
= MsiSetTargetPathW( hInstall
, szwFolder
, szwFolderPath
);
540 msi_free(szwFolderPath
);
545 static void set_target_path( MSIPACKAGE
*package
, MSIFOLDER
*folder
, const WCHAR
*path
)
551 if (!(target_path
= msi_normalize_path( path
))) return;
552 if (strcmpW( target_path
, folder
->ResolvedTarget
))
554 msi_free( folder
->ResolvedTarget
);
555 folder
->ResolvedTarget
= target_path
;
556 msi_set_property( package
->db
, folder
->Directory
, folder
->ResolvedTarget
, -1 );
558 LIST_FOR_EACH_ENTRY( fl
, &folder
->children
, FolderList
, entry
)
561 msi_resolve_target_folder( package
, child
->Directory
, FALSE
);
564 else msi_free( target_path
);
567 UINT
MSI_SetTargetPathW( MSIPACKAGE
*package
, LPCWSTR szFolder
, LPCWSTR szFolderPath
)
573 TRACE("%p %s %s\n", package
, debugstr_w(szFolder
), debugstr_w(szFolderPath
));
575 attrib
= GetFileAttributesW(szFolderPath
);
576 /* native MSI tests writeability by making temporary files at each drive */
577 if (attrib
!= INVALID_FILE_ATTRIBUTES
&&
578 (attrib
& FILE_ATTRIBUTE_OFFLINE
|| attrib
& FILE_ATTRIBUTE_READONLY
))
580 return ERROR_FUNCTION_FAILED
;
582 if (!(folder
= msi_get_loaded_folder( package
, szFolder
))) return ERROR_DIRECTORY
;
584 set_target_path( package
, folder
, szFolderPath
);
586 LIST_FOR_EACH_ENTRY( file
, &package
->files
, MSIFILE
, entry
)
589 MSICOMPONENT
*comp
= file
->Component
;
591 if (!comp
->Enabled
|| (comp
->assembly
&& !comp
->assembly
->application
)) continue;
593 dir
= msi_get_target_folder( package
, comp
->Directory
);
594 msi_free( file
->TargetPath
);
595 file
->TargetPath
= msi_build_directory_name( 2, dir
, file
->FileName
);
597 return ERROR_SUCCESS
;
600 /***********************************************************************
601 * MsiSetTargetPathW (MSI.@)
603 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
604 LPCWSTR szFolderPath
)
609 TRACE("%s %s\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
611 if ( !szFolder
|| !szFolderPath
)
612 return ERROR_INVALID_PARAMETER
;
614 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
619 IWineMsiRemotePackage
*remote_package
;
621 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
623 return ERROR_INVALID_HANDLE
;
625 folder
= SysAllocString( szFolder
);
626 path
= SysAllocString( szFolderPath
);
627 if (!folder
|| !path
)
629 SysFreeString(folder
);
631 IWineMsiRemotePackage_Release( remote_package
);
632 return ERROR_OUTOFMEMORY
;
635 hr
= IWineMsiRemotePackage_SetTargetPath( remote_package
, folder
, path
);
637 SysFreeString(folder
);
639 IWineMsiRemotePackage_Release( remote_package
);
643 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
644 return HRESULT_CODE(hr
);
646 return ERROR_FUNCTION_FAILED
;
649 return ERROR_SUCCESS
;
652 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
653 msiobj_release( &package
->hdr
);
657 /***********************************************************************
660 * Returns an internal installer state (if it is running in a mode iRunMode)
663 * hInstall [I] Handle to the installation
664 * hRunMode [I] Checking run mode
665 * MSIRUNMODE_ADMIN Administrative mode
666 * MSIRUNMODE_ADVERTISE Advertisement mode
667 * MSIRUNMODE_MAINTENANCE Maintenance mode
668 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
669 * MSIRUNMODE_LOGENABLED Log file is writing
670 * MSIRUNMODE_OPERATIONS Operations in progress??
671 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
672 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
673 * MSIRUNMODE_CABINET Files from cabinet are installed
674 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
675 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
676 * MSIRUNMODE_RESERVED11 Reserved
677 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
678 * MSIRUNMODE_ZAWENABLED Demand installation is supported
679 * MSIRUNMODE_RESERVED14 Reserved
680 * MSIRUNMODE_RESERVED15 Reserved
681 * MSIRUNMODE_SCHEDULED called from install script
682 * MSIRUNMODE_ROLLBACK called from rollback script
683 * MSIRUNMODE_COMMIT called from commit script
687 * Not in the state: FALSE
690 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
695 TRACE("%d %d\n", hInstall
, iRunMode
);
697 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
702 IWineMsiRemotePackage
*remote_package
;
704 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
708 hr
= IWineMsiRemotePackage_GetMode(remote_package
, iRunMode
, &ret
);
709 IWineMsiRemotePackage_Release(remote_package
);
719 case MSIRUNMODE_ADMIN
:
720 FIXME("no support for administrative installs\n");
723 case MSIRUNMODE_ADVERTISE
:
724 FIXME("no support for advertised installs\n");
727 case MSIRUNMODE_WINDOWS9X
:
728 if (GetVersion() & 0x80000000)
732 case MSIRUNMODE_OPERATIONS
:
733 case MSIRUNMODE_RESERVED11
:
734 case MSIRUNMODE_RESERVED14
:
735 case MSIRUNMODE_RESERVED15
:
738 case MSIRUNMODE_SCHEDULED
:
739 r
= package
->scheduled_action_running
;
742 case MSIRUNMODE_ROLLBACK
:
743 r
= package
->rollback_action_running
;
746 case MSIRUNMODE_COMMIT
:
747 r
= package
->commit_action_running
;
750 case MSIRUNMODE_MAINTENANCE
:
751 r
= msi_get_property_int( package
->db
, szInstalled
, 0 ) != 0;
754 case MSIRUNMODE_ROLLBACKENABLED
:
755 r
= msi_get_property_int( package
->db
, szRollbackDisabled
, 0 ) == 0;
758 case MSIRUNMODE_REBOOTATEND
:
759 r
= package
->need_reboot_at_end
;
762 case MSIRUNMODE_REBOOTNOW
:
763 r
= package
->need_reboot_now
;
766 case MSIRUNMODE_LOGENABLED
:
767 r
= (package
->log_file
!= INVALID_HANDLE_VALUE
);
771 FIXME("unimplemented run mode: %d\n", iRunMode
);
775 msiobj_release( &package
->hdr
);
779 /***********************************************************************
782 UINT WINAPI
MsiSetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
, BOOL fState
)
787 TRACE("%d %d %d\n", hInstall
, iRunMode
, fState
);
789 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
793 IWineMsiRemotePackage
*remote_package
;
795 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
799 hr
= IWineMsiRemotePackage_SetMode( remote_package
, iRunMode
, fState
);
800 IWineMsiRemotePackage_Release( remote_package
);
804 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
805 return HRESULT_CODE(hr
);
807 return ERROR_FUNCTION_FAILED
;
810 return ERROR_SUCCESS
;
815 case MSIRUNMODE_REBOOTATEND
:
816 package
->need_reboot_at_end
= (fState
!= 0);
820 case MSIRUNMODE_REBOOTNOW
:
821 package
->need_reboot_now
= (fState
!= 0);
826 r
= ERROR_ACCESS_DENIED
;
829 msiobj_release( &package
->hdr
);
833 /***********************************************************************
834 * MsiSetFeatureStateA (MSI.@)
836 * According to the docs, when this is called it immediately recalculates
837 * all the component states as well
839 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
842 LPWSTR szwFeature
= NULL
;
845 szwFeature
= strdupAtoW(szFeature
);
848 return ERROR_FUNCTION_FAILED
;
850 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
852 msi_free(szwFeature
);
857 /* update component state based on a feature change */
858 void ACTION_UpdateComponentStates( MSIPACKAGE
*package
, MSIFEATURE
*feature
)
860 INSTALLSTATE newstate
;
863 newstate
= feature
->ActionRequest
;
864 if (newstate
== INSTALLSTATE_ABSENT
) newstate
= INSTALLSTATE_UNKNOWN
;
866 LIST_FOR_EACH_ENTRY(cl
, &feature
->Components
, ComponentList
, entry
)
868 MSICOMPONENT
*component
= cl
->component
;
870 if (!component
->Enabled
) continue;
872 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
873 newstate
, debugstr_w(component
->Component
), component
->Installed
,
874 component
->Action
, component
->ActionRequest
);
876 if (newstate
== INSTALLSTATE_LOCAL
)
878 component
->Action
= INSTALLSTATE_LOCAL
;
879 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
883 ComponentList
*clist
;
886 component
->hasLocalFeature
= FALSE
;
888 component
->Action
= newstate
;
889 component
->ActionRequest
= newstate
;
890 /* if any other feature wants it local we need to set it local */
891 LIST_FOR_EACH_ENTRY(f
, &package
->features
, MSIFEATURE
, entry
)
893 if ( f
->ActionRequest
!= INSTALLSTATE_LOCAL
&&
894 f
->ActionRequest
!= INSTALLSTATE_SOURCE
)
898 LIST_FOR_EACH_ENTRY(clist
, &f
->Components
, ComponentList
, entry
)
900 if (clist
->component
== component
&&
901 (f
->ActionRequest
== INSTALLSTATE_LOCAL
||
902 f
->ActionRequest
== INSTALLSTATE_SOURCE
))
904 TRACE("Saved by %s\n", debugstr_w(f
->Feature
));
905 component
->hasLocalFeature
= TRUE
;
907 if (component
->Attributes
& msidbComponentAttributesOptional
)
909 if (f
->Attributes
& msidbFeatureAttributesFavorSource
)
911 component
->Action
= INSTALLSTATE_SOURCE
;
912 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
916 component
->Action
= INSTALLSTATE_LOCAL
;
917 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
920 else if (component
->Attributes
& msidbComponentAttributesSourceOnly
)
922 component
->Action
= INSTALLSTATE_SOURCE
;
923 component
->ActionRequest
= INSTALLSTATE_SOURCE
;
927 component
->Action
= INSTALLSTATE_LOCAL
;
928 component
->ActionRequest
= INSTALLSTATE_LOCAL
;
934 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
935 newstate
, debugstr_w(component
->Component
), component
->Installed
,
936 component
->Action
, component
->ActionRequest
);
940 UINT
MSI_SetFeatureStateW( MSIPACKAGE
*package
, LPCWSTR szFeature
, INSTALLSTATE iState
)
942 UINT rc
= ERROR_SUCCESS
;
943 MSIFEATURE
*feature
, *child
;
945 TRACE("%s %i\n", debugstr_w(szFeature
), iState
);
947 feature
= msi_get_loaded_feature( package
, szFeature
);
949 return ERROR_UNKNOWN_FEATURE
;
951 if (iState
== INSTALLSTATE_ADVERTISED
&&
952 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
953 return ERROR_FUNCTION_FAILED
;
955 feature
->ActionRequest
= iState
;
957 ACTION_UpdateComponentStates( package
, feature
);
959 /* update all the features that are children of this feature */
960 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
962 if (child
->Feature_Parent
&& !strcmpW( szFeature
, child
->Feature_Parent
))
963 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
969 /***********************************************************************
970 * MsiSetFeatureStateW (MSI.@)
972 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
976 UINT rc
= ERROR_SUCCESS
;
978 TRACE("%s %i\n",debugstr_w(szFeature
), iState
);
980 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
985 IWineMsiRemotePackage
*remote_package
;
987 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
989 return ERROR_INVALID_HANDLE
;
991 feature
= SysAllocString(szFeature
);
994 IWineMsiRemotePackage_Release(remote_package
);
995 return ERROR_OUTOFMEMORY
;
998 hr
= IWineMsiRemotePackage_SetFeatureState(remote_package
, feature
, iState
);
1000 SysFreeString(feature
);
1001 IWineMsiRemotePackage_Release(remote_package
);
1005 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1006 return HRESULT_CODE(hr
);
1008 return ERROR_FUNCTION_FAILED
;
1011 return ERROR_SUCCESS
;
1014 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
1016 msiobj_release( &package
->hdr
);
1020 /***********************************************************************
1021 * MsiSetFeatureAttributesA (MSI.@)
1023 UINT WINAPI
MsiSetFeatureAttributesA( MSIHANDLE handle
, LPCSTR feature
, DWORD attrs
)
1026 WCHAR
*featureW
= NULL
;
1028 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_a(feature
), attrs
);
1030 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1032 r
= MsiSetFeatureAttributesW( handle
, featureW
, attrs
);
1033 msi_free( featureW
);
1037 static DWORD
unmap_feature_attributes( DWORD attrs
)
1041 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORLOCAL
) ret
= msidbFeatureAttributesFavorLocal
;
1042 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORSOURCE
) ret
|= msidbFeatureAttributesFavorSource
;
1043 if (attrs
& INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
) ret
|= msidbFeatureAttributesFollowParent
;
1044 if (attrs
& INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
) ret
|= msidbFeatureAttributesFavorAdvertise
;
1045 if (attrs
& INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
) ret
|= msidbFeatureAttributesDisallowAdvertise
;
1046 if (attrs
& INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
) ret
|= msidbFeatureAttributesNoUnsupportedAdvertise
;
1050 /***********************************************************************
1051 * MsiSetFeatureAttributesW (MSI.@)
1053 UINT WINAPI
MsiSetFeatureAttributesW( MSIHANDLE handle
, LPCWSTR name
, DWORD attrs
)
1055 MSIPACKAGE
*package
;
1056 MSIFEATURE
*feature
;
1059 TRACE("%u, %s, 0x%08x\n", handle
, debugstr_w(name
), attrs
);
1061 if (!name
|| !name
[0]) return ERROR_UNKNOWN_FEATURE
;
1063 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1064 return ERROR_INVALID_HANDLE
;
1066 costing
= msi_dup_property( package
->db
, szCostingComplete
);
1067 if (!costing
|| !strcmpW( costing
, szOne
))
1069 msi_free( costing
);
1070 msiobj_release( &package
->hdr
);
1071 return ERROR_FUNCTION_FAILED
;
1073 msi_free( costing
);
1074 if (!(feature
= msi_get_loaded_feature( package
, name
)))
1076 msiobj_release( &package
->hdr
);
1077 return ERROR_UNKNOWN_FEATURE
;
1079 feature
->Attributes
= unmap_feature_attributes( attrs
);
1080 msiobj_release( &package
->hdr
);
1081 return ERROR_SUCCESS
;
1084 /***********************************************************************
1085 * MsiGetFeatureStateA (MSI.@)
1087 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1088 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1090 LPWSTR szwFeature
= NULL
;
1093 if (szFeature
&& !(szwFeature
= strdupAtoW(szFeature
))) return ERROR_OUTOFMEMORY
;
1095 rc
= MsiGetFeatureStateW(hInstall
, szwFeature
, piInstalled
, piAction
);
1096 msi_free( szwFeature
);
1100 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPCWSTR szFeature
,
1101 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1103 MSIFEATURE
*feature
;
1105 feature
= msi_get_loaded_feature(package
,szFeature
);
1107 return ERROR_UNKNOWN_FEATURE
;
1110 *piInstalled
= feature
->Installed
;
1113 *piAction
= feature
->ActionRequest
;
1115 TRACE("returning %i %i\n", feature
->Installed
, feature
->ActionRequest
);
1117 return ERROR_SUCCESS
;
1120 /***********************************************************************
1121 * MsiGetFeatureStateW (MSI.@)
1123 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1124 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1126 MSIPACKAGE
* package
;
1129 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
, piAction
);
1131 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1136 IWineMsiRemotePackage
*remote_package
;
1138 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1139 if (!remote_package
)
1140 return ERROR_INVALID_HANDLE
;
1142 feature
= SysAllocString(szFeature
);
1145 IWineMsiRemotePackage_Release(remote_package
);
1146 return ERROR_OUTOFMEMORY
;
1149 hr
= IWineMsiRemotePackage_GetFeatureState(remote_package
, feature
,
1150 piInstalled
, piAction
);
1152 SysFreeString(feature
);
1153 IWineMsiRemotePackage_Release(remote_package
);
1157 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1158 return HRESULT_CODE(hr
);
1160 return ERROR_FUNCTION_FAILED
;
1163 return ERROR_SUCCESS
;
1166 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
1167 msiobj_release( &package
->hdr
);
1171 /***********************************************************************
1172 * MsiGetFeatureCostA (MSI.@)
1174 UINT WINAPI
MsiGetFeatureCostA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1175 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1177 LPWSTR szwFeature
= NULL
;
1180 szwFeature
= strdupAtoW(szFeature
);
1182 rc
= MsiGetFeatureCostW(hInstall
, szwFeature
, iCostTree
, iState
, piCost
);
1184 msi_free(szwFeature
);
1189 static INT
feature_cost( MSIFEATURE
*feature
)
1194 LIST_FOR_EACH_ENTRY( comp
, &feature
->Components
, MSICOMPONENT
, entry
)
1201 UINT
MSI_GetFeatureCost( MSIPACKAGE
*package
, MSIFEATURE
*feature
, MSICOSTTREE tree
,
1202 INSTALLSTATE state
, LPINT cost
)
1204 TRACE("%s, %u, %d, %p\n", debugstr_w(feature
->Feature
), tree
, state
, cost
);
1209 case MSICOSTTREE_CHILDREN
:
1213 LIST_FOR_EACH_ENTRY( child
, &feature
->Children
, MSIFEATURE
, entry
)
1215 if (child
->ActionRequest
== state
)
1216 *cost
+= feature_cost( child
);
1220 case MSICOSTTREE_PARENTS
:
1222 const WCHAR
*feature_parent
= feature
->Feature_Parent
;
1225 MSIFEATURE
*parent
= msi_get_loaded_feature( package
, feature_parent
);
1229 if (parent
->ActionRequest
== state
)
1230 *cost
+= feature_cost( parent
);
1232 feature_parent
= parent
->Feature_Parent
;
1236 case MSICOSTTREE_SELFONLY
:
1237 if (feature
->ActionRequest
== state
)
1238 *cost
= feature_cost( feature
);
1242 WARN("unhandled cost tree %u\n", tree
);
1247 return ERROR_SUCCESS
;
1250 /***********************************************************************
1251 * MsiGetFeatureCostW (MSI.@)
1253 UINT WINAPI
MsiGetFeatureCostW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1254 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1256 MSIPACKAGE
*package
;
1257 MSIFEATURE
*feature
;
1260 TRACE("(%d %s %i %i %p)\n", hInstall
, debugstr_w(szFeature
),
1261 iCostTree
, iState
, piCost
);
1263 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1268 IWineMsiRemotePackage
*remote_package
;
1270 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1271 if (!remote_package
)
1272 return ERROR_INVALID_HANDLE
;
1274 feature
= SysAllocString(szFeature
);
1277 IWineMsiRemotePackage_Release(remote_package
);
1278 return ERROR_OUTOFMEMORY
;
1281 hr
= IWineMsiRemotePackage_GetFeatureCost(remote_package
, feature
,
1282 iCostTree
, iState
, piCost
);
1284 SysFreeString(feature
);
1285 IWineMsiRemotePackage_Release(remote_package
);
1289 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1290 return HRESULT_CODE(hr
);
1292 return ERROR_FUNCTION_FAILED
;
1295 return ERROR_SUCCESS
;
1298 feature
= msi_get_loaded_feature(package
, szFeature
);
1301 ret
= MSI_GetFeatureCost(package
, feature
, iCostTree
, iState
, piCost
);
1303 ret
= ERROR_UNKNOWN_FEATURE
;
1305 msiobj_release( &package
->hdr
);
1309 /***********************************************************************
1310 * MsiGetFeatureInfoA (MSI.@)
1312 UINT WINAPI
MsiGetFeatureInfoA( MSIHANDLE handle
, LPCSTR feature
, LPDWORD attrs
,
1313 LPSTR title
, LPDWORD title_len
, LPSTR help
, LPDWORD help_len
)
1316 WCHAR
*titleW
= NULL
, *helpW
= NULL
, *featureW
= NULL
;
1318 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_a(feature
), attrs
, title
,
1319 title_len
, help
, help_len
);
1321 if (feature
&& !(featureW
= strdupAtoW( feature
))) return ERROR_OUTOFMEMORY
;
1323 if (title
&& title_len
&& !(titleW
= msi_alloc( *title_len
* sizeof(WCHAR
) )))
1325 msi_free( featureW
);
1326 return ERROR_OUTOFMEMORY
;
1328 if (help
&& help_len
&& !(helpW
= msi_alloc( *help_len
* sizeof(WCHAR
) )))
1330 msi_free( featureW
);
1332 return ERROR_OUTOFMEMORY
;
1334 r
= MsiGetFeatureInfoW( handle
, featureW
, attrs
, titleW
, title_len
, helpW
, help_len
);
1335 if (r
== ERROR_SUCCESS
)
1337 if (titleW
) WideCharToMultiByte( CP_ACP
, 0, titleW
, -1, title
, *title_len
+ 1, NULL
, NULL
);
1338 if (helpW
) WideCharToMultiByte( CP_ACP
, 0, helpW
, -1, help
, *help_len
+ 1, NULL
, NULL
);
1342 msi_free( featureW
);
1346 static DWORD
map_feature_attributes( DWORD attrs
)
1350 if (attrs
== msidbFeatureAttributesFavorLocal
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORLOCAL
;
1351 if (attrs
& msidbFeatureAttributesFavorSource
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORSOURCE
;
1352 if (attrs
& msidbFeatureAttributesFollowParent
) ret
|= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT
;
1353 if (attrs
& msidbFeatureAttributesFavorAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE
;
1354 if (attrs
& msidbFeatureAttributesDisallowAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE
;
1355 if (attrs
& msidbFeatureAttributesNoUnsupportedAdvertise
) ret
|= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE
;
1359 static UINT
MSI_GetFeatureInfo( MSIPACKAGE
*package
, LPCWSTR name
, LPDWORD attrs
,
1360 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1362 UINT r
= ERROR_SUCCESS
;
1363 MSIFEATURE
*feature
= msi_get_loaded_feature( package
, name
);
1366 if (!feature
) return ERROR_UNKNOWN_FEATURE
;
1367 if (attrs
) *attrs
= map_feature_attributes( feature
->Attributes
);
1370 if (feature
->Title
) len
= strlenW( feature
->Title
);
1372 if (*title_len
<= len
)
1375 if (title
) r
= ERROR_MORE_DATA
;
1379 if (feature
->Title
) strcpyW( title
, feature
->Title
);
1386 if (feature
->Description
) len
= strlenW( feature
->Description
);
1388 if (*help_len
<= len
)
1391 if (help
) r
= ERROR_MORE_DATA
;
1395 if (feature
->Description
) strcpyW( help
, feature
->Description
);
1403 /***********************************************************************
1404 * MsiGetFeatureInfoW (MSI.@)
1406 UINT WINAPI
MsiGetFeatureInfoW( MSIHANDLE handle
, LPCWSTR feature
, LPDWORD attrs
,
1407 LPWSTR title
, LPDWORD title_len
, LPWSTR help
, LPDWORD help_len
)
1410 MSIPACKAGE
*package
;
1412 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle
, debugstr_w(feature
), attrs
, title
,
1413 title_len
, help
, help_len
);
1415 if (!feature
) return ERROR_INVALID_PARAMETER
;
1417 if (!(package
= msihandle2msiinfo( handle
, MSIHANDLETYPE_PACKAGE
)))
1418 return ERROR_INVALID_HANDLE
;
1420 /* features may not have been loaded yet */
1421 msi_load_all_components( package
);
1422 msi_load_all_features( package
);
1424 r
= MSI_GetFeatureInfo( package
, feature
, attrs
, title
, title_len
, help
, help_len
);
1425 msiobj_release( &package
->hdr
);
1429 /***********************************************************************
1430 * MsiSetComponentStateA (MSI.@)
1432 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1433 INSTALLSTATE iState
)
1436 LPWSTR szwComponent
= strdupAtoW(szComponent
);
1438 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
1440 msi_free(szwComponent
);
1445 /***********************************************************************
1446 * MsiGetComponentStateA (MSI.@)
1448 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1449 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1451 LPWSTR szwComponent
= NULL
;
1454 szwComponent
= strdupAtoW(szComponent
);
1456 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
1458 msi_free( szwComponent
);
1463 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1464 INSTALLSTATE iState
)
1468 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
1470 comp
= msi_get_loaded_component(package
, szComponent
);
1472 return ERROR_UNKNOWN_COMPONENT
;
1475 comp
->Action
= iState
;
1477 return ERROR_SUCCESS
;
1480 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1481 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1485 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
1486 piInstalled
, piAction
);
1488 comp
= msi_get_loaded_component(package
,szComponent
);
1490 return ERROR_UNKNOWN_COMPONENT
;
1495 *piInstalled
= comp
->Installed
;
1497 *piInstalled
= INSTALLSTATE_UNKNOWN
;
1503 *piAction
= comp
->Action
;
1505 *piAction
= INSTALLSTATE_UNKNOWN
;
1508 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
1509 return ERROR_SUCCESS
;
1512 /***********************************************************************
1513 * MsiSetComponentStateW (MSI.@)
1515 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1516 INSTALLSTATE iState
)
1518 MSIPACKAGE
* package
;
1521 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1526 IWineMsiRemotePackage
*remote_package
;
1528 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1529 if (!remote_package
)
1530 return ERROR_INVALID_HANDLE
;
1532 component
= SysAllocString(szComponent
);
1535 IWineMsiRemotePackage_Release(remote_package
);
1536 return ERROR_OUTOFMEMORY
;
1539 hr
= IWineMsiRemotePackage_SetComponentState(remote_package
, component
, iState
);
1541 SysFreeString(component
);
1542 IWineMsiRemotePackage_Release(remote_package
);
1546 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1547 return HRESULT_CODE(hr
);
1549 return ERROR_FUNCTION_FAILED
;
1552 return ERROR_SUCCESS
;
1555 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
1556 msiobj_release(&package
->hdr
);
1560 /***********************************************************************
1561 * MsiGetComponentStateW (MSI.@)
1563 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1564 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1566 MSIPACKAGE
* package
;
1569 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szComponent
),
1570 piInstalled
, piAction
);
1572 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1577 IWineMsiRemotePackage
*remote_package
;
1579 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1580 if (!remote_package
)
1581 return ERROR_INVALID_HANDLE
;
1583 component
= SysAllocString(szComponent
);
1586 IWineMsiRemotePackage_Release(remote_package
);
1587 return ERROR_OUTOFMEMORY
;
1590 hr
= IWineMsiRemotePackage_GetComponentState(remote_package
, component
,
1591 piInstalled
, piAction
);
1593 SysFreeString(component
);
1594 IWineMsiRemotePackage_Release(remote_package
);
1598 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1599 return HRESULT_CODE(hr
);
1601 return ERROR_FUNCTION_FAILED
;
1604 return ERROR_SUCCESS
;
1607 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
1608 msiobj_release( &package
->hdr
);
1612 /***********************************************************************
1613 * MsiGetLanguage (MSI.@)
1615 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
1617 MSIPACKAGE
* package
;
1620 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1625 IWineMsiRemotePackage
*remote_package
;
1627 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1628 if (!remote_package
)
1629 return ERROR_INVALID_HANDLE
;
1631 hr
= IWineMsiRemotePackage_GetLanguage(remote_package
, &lang
);
1639 langid
= msi_get_property_int( package
->db
, szProductLanguage
, 0 );
1640 msiobj_release( &package
->hdr
);
1644 UINT
MSI_SetInstallLevel( MSIPACKAGE
*package
, int iInstallLevel
)
1646 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 len
= sprintfW( level
, fmt
, iInstallLevel
);
1660 r
= msi_set_property( package
->db
, szInstallLevel
, level
, len
);
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
);