2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2005 Aric Stewart for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* Msi top level apis directly related to installs */
30 #include "wine/debug.h"
37 #include "msiserver.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
42 /***********************************************************************
43 * MsiDoActionA (MSI.@)
45 UINT WINAPI
MsiDoActionA( MSIHANDLE hInstall
, LPCSTR szAction
)
50 TRACE("%s\n", debugstr_a(szAction
));
52 szwAction
= strdupAtoW(szAction
);
53 if (szAction
&& !szwAction
)
54 return ERROR_FUNCTION_FAILED
;
56 ret
= MsiDoActionW( hInstall
, szwAction
);
57 msi_free( szwAction
);
61 /***********************************************************************
62 * MsiDoActionW (MSI.@)
64 UINT WINAPI
MsiDoActionW( MSIHANDLE hInstall
, LPCWSTR szAction
)
69 TRACE("%s\n",debugstr_w(szAction
));
72 return ERROR_INVALID_PARAMETER
;
74 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
79 IWineMsiRemotePackage
*remote_package
;
81 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
83 return ERROR_INVALID_HANDLE
;
85 action
= SysAllocString( szAction
);
88 IWineMsiRemotePackage_Release( remote_package
);
89 return ERROR_OUTOFMEMORY
;
92 hr
= IWineMsiRemotePackage_DoAction( remote_package
, action
);
94 SysFreeString( action
);
95 IWineMsiRemotePackage_Release( remote_package
);
99 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
100 return HRESULT_CODE(hr
);
102 return ERROR_FUNCTION_FAILED
;
105 return ERROR_SUCCESS
;
108 ret
= ACTION_PerformUIAction( package
, szAction
, -1 );
109 msiobj_release( &package
->hdr
);
114 /***********************************************************************
115 * MsiSequenceA (MSI.@)
117 UINT WINAPI
MsiSequenceA( MSIHANDLE hInstall
, LPCSTR szTable
, INT iSequenceMode
)
122 TRACE("%s\n", debugstr_a(szTable
));
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\n", debugstr_w(szTable
));
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
;
177 ret
= MSI_Sequence( package
, szTable
, iSequenceMode
);
178 msiobj_release( &package
->hdr
);
183 UINT
msi_strcpy_to_awstring( LPCWSTR str
, awstring
*awbuf
, DWORD
*sz
)
185 UINT len
, r
= ERROR_SUCCESS
;
187 if (awbuf
->str
.w
&& !sz
)
188 return ERROR_INVALID_PARAMETER
;
195 len
= lstrlenW( str
);
197 lstrcpynW( awbuf
->str
.w
, str
, *sz
);
201 len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1, NULL
, 0, NULL
, NULL
);
204 WideCharToMultiByte( CP_ACP
, 0, str
, -1, awbuf
->str
.a
, *sz
, NULL
, NULL
);
205 if ( awbuf
->str
.a
&& *sz
&& (len
>= *sz
) )
206 awbuf
->str
.a
[*sz
- 1] = 0;
209 if (awbuf
->str
.w
&& len
>= *sz
)
215 /***********************************************************************
216 * MsiGetTargetPath (internal)
218 static UINT
MSI_GetTargetPath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
219 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
223 UINT r
= ERROR_FUNCTION_FAILED
;
226 return ERROR_INVALID_PARAMETER
;
228 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
232 IWineMsiRemotePackage
*remote_package
;
237 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
239 return ERROR_INVALID_HANDLE
;
241 folder
= SysAllocString( szFolder
);
244 IWineMsiRemotePackage_Release( remote_package
);
245 return ERROR_OUTOFMEMORY
;
249 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
,
255 value
= msi_alloc(len
* sizeof(WCHAR
));
258 r
= ERROR_OUTOFMEMORY
;
262 hr
= IWineMsiRemotePackage_GetTargetPath( remote_package
, folder
,
263 (BSTR
*)value
, &len
);
267 r
= msi_strcpy_to_awstring( value
, szPathBuf
, pcchPathBuf
);
270 IWineMsiRemotePackage_Release( remote_package
);
271 SysFreeString( folder
);
276 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
277 return HRESULT_CODE(hr
);
279 return ERROR_FUNCTION_FAILED
;
285 path
= resolve_target_folder( package
, szFolder
, FALSE
, TRUE
, NULL
);
286 msiobj_release( &package
->hdr
);
289 return ERROR_DIRECTORY
;
291 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
296 /***********************************************************************
297 * MsiGetTargetPathA (MSI.@)
299 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
300 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
306 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
308 szwFolder
= strdupAtoW(szFolder
);
309 if (szFolder
&& !szwFolder
)
310 return ERROR_FUNCTION_FAILED
;
312 path
.unicode
= FALSE
;
313 path
.str
.a
= szPathBuf
;
315 r
= MSI_GetTargetPath( hInstall
, szwFolder
, &path
, pcchPathBuf
);
317 msi_free( szwFolder
);
322 /***********************************************************************
323 * MsiGetTargetPathW (MSI.@)
325 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
326 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
330 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
333 path
.str
.w
= szPathBuf
;
335 return MSI_GetTargetPath( hInstall
, szFolder
, &path
, pcchPathBuf
);
338 /***********************************************************************
339 * MSI_GetSourcePath (internal)
341 static UINT
MSI_GetSourcePath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
342 awstring
*szPathBuf
, LPDWORD pcchPathBuf
)
346 UINT r
= ERROR_FUNCTION_FAILED
;
348 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
351 return ERROR_INVALID_PARAMETER
;
353 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
357 IWineMsiRemotePackage
*remote_package
;
362 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
364 return ERROR_INVALID_HANDLE
;
366 folder
= SysAllocString( szFolder
);
369 IWineMsiRemotePackage_Release( remote_package
);
370 return ERROR_OUTOFMEMORY
;
374 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
,
380 value
= msi_alloc(len
* sizeof(WCHAR
));
383 r
= ERROR_OUTOFMEMORY
;
387 hr
= IWineMsiRemotePackage_GetSourcePath( remote_package
, folder
,
388 (BSTR
*)value
, &len
);
392 r
= msi_strcpy_to_awstring( value
, szPathBuf
, pcchPathBuf
);
395 IWineMsiRemotePackage_Release( remote_package
);
396 SysFreeString( folder
);
401 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
402 return HRESULT_CODE(hr
);
404 return ERROR_FUNCTION_FAILED
;
410 if (szPathBuf
->str
.w
&& !pcchPathBuf
)
412 msiobj_release( &package
->hdr
);
413 return ERROR_INVALID_PARAMETER
;
416 path
= resolve_source_folder( package
, szFolder
, NULL
);
417 msiobj_release( &package
->hdr
);
419 TRACE("path = %s\n", debugstr_w(path
));
421 return ERROR_DIRECTORY
;
423 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
428 /***********************************************************************
429 * MsiGetSourcePathA (MSI.@)
431 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
432 LPSTR szPathBuf
, LPDWORD pcchPathBuf
)
438 TRACE("%s %p %p\n", szFolder
, debugstr_a(szPathBuf
), pcchPathBuf
);
441 str
.str
.a
= szPathBuf
;
443 folder
= strdupAtoW( szFolder
);
444 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
450 /***********************************************************************
451 * MsiGetSourcePathW (MSI.@)
453 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
454 LPWSTR szPathBuf
, LPDWORD pcchPathBuf
)
458 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
461 str
.str
.w
= szPathBuf
;
463 return MSI_GetSourcePath( hInstall
, szFolder
, &str
, pcchPathBuf
);
466 /***********************************************************************
467 * MsiSetTargetPathA (MSI.@)
469 UINT WINAPI
MsiSetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
470 LPCSTR szFolderPath
)
472 LPWSTR szwFolder
= NULL
, szwFolderPath
= NULL
;
473 UINT rc
= ERROR_OUTOFMEMORY
;
475 if ( !szFolder
|| !szFolderPath
)
476 return ERROR_INVALID_PARAMETER
;
478 szwFolder
= strdupAtoW(szFolder
);
479 szwFolderPath
= strdupAtoW(szFolderPath
);
480 if (!szwFolder
|| !szwFolderPath
)
483 rc
= MsiSetTargetPathW( hInstall
, szwFolder
, szwFolderPath
);
487 msi_free(szwFolderPath
);
493 * Ok my original interpretation of this was wrong. And it looks like msdn has
494 * changed a bit also. The given folder path does not have to actually already
495 * exist, it just cannot be read only and must be a legal folder path.
497 UINT
MSI_SetTargetPathW(MSIPACKAGE
*package
, LPCWSTR szFolder
,
498 LPCWSTR szFolderPath
)
506 TRACE("%p %s %s\n",package
, debugstr_w(szFolder
),debugstr_w(szFolderPath
));
508 attrib
= GetFileAttributesW(szFolderPath
);
509 /* native MSI tests writeability by making temporary files at each drive */
510 if ( attrib
!= INVALID_FILE_ATTRIBUTES
&&
511 (attrib
& FILE_ATTRIBUTE_OFFLINE
||
512 attrib
& FILE_ATTRIBUTE_READONLY
))
513 return ERROR_FUNCTION_FAILED
;
515 path
= resolve_target_folder( package
, szFolder
, FALSE
, FALSE
, &folder
);
517 return ERROR_DIRECTORY
;
519 msi_free(folder
->Property
);
520 folder
->Property
= build_directory_name(2, szFolderPath
, NULL
);
522 if (!strcmpiW( path
, folder
->Property
))
525 * Resolved Target has not really changed, so just
526 * set this folder and do not recalculate everything.
528 msi_free(folder
->ResolvedTarget
);
529 folder
->ResolvedTarget
= NULL
;
530 path2
= resolve_target_folder( package
, szFolder
, TRUE
, FALSE
, NULL
);
537 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
539 msi_free(f
->ResolvedTarget
);
540 f
->ResolvedTarget
=NULL
;
543 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
545 path2
= resolve_target_folder( package
, f
->Directory
, TRUE
, FALSE
, NULL
);
549 LIST_FOR_EACH_ENTRY( file
, &package
->files
, MSIFILE
, entry
)
551 MSICOMPONENT
*comp
= file
->Component
;
554 if (!comp
->Enabled
|| (comp
->assembly
&& !comp
->assembly
->application
))
557 dir
= resolve_target_folder( package
, comp
->Directory
, FALSE
, FALSE
, NULL
);
558 msi_free(file
->TargetPath
);
560 file
->TargetPath
= build_directory_name(2, dir
, file
->FileName
);
566 return ERROR_SUCCESS
;
569 /***********************************************************************
570 * MsiSetTargetPathW (MSI.@)
572 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
573 LPCWSTR szFolderPath
)
578 TRACE("%s %s\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
580 if ( !szFolder
|| !szFolderPath
)
581 return ERROR_INVALID_PARAMETER
;
583 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
588 IWineMsiRemotePackage
*remote_package
;
590 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
592 return ERROR_INVALID_HANDLE
;
594 folder
= SysAllocString( szFolder
);
595 path
= SysAllocString( szFolderPath
);
596 if (!folder
|| !path
)
598 SysFreeString(folder
);
600 IWineMsiRemotePackage_Release( remote_package
);
601 return ERROR_OUTOFMEMORY
;
604 hr
= IWineMsiRemotePackage_SetTargetPath( remote_package
, folder
, path
);
606 SysFreeString(folder
);
608 IWineMsiRemotePackage_Release( remote_package
);
612 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
613 return HRESULT_CODE(hr
);
615 return ERROR_FUNCTION_FAILED
;
618 return ERROR_SUCCESS
;
621 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
622 msiobj_release( &package
->hdr
);
626 /***********************************************************************
629 * Returns an internal installer state (if it is running in a mode iRunMode)
632 * hInstall [I] Handle to the installation
633 * hRunMode [I] Checking run mode
634 * MSIRUNMODE_ADMIN Administrative mode
635 * MSIRUNMODE_ADVERTISE Advertisement mode
636 * MSIRUNMODE_MAINTENANCE Maintenance mode
637 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
638 * MSIRUNMODE_LOGENABLED Log file is writing
639 * MSIRUNMODE_OPERATIONS Operations in progress??
640 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
641 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
642 * MSIRUNMODE_CABINET Files from cabinet are installed
643 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
644 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
645 * MSIRUNMODE_RESERVED11 Reserved
646 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
647 * MSIRUNMODE_ZAWENABLED Demand installation is supported
648 * MSIRUNMODE_RESERVED14 Reserved
649 * MSIRUNMODE_RESERVED15 Reserved
650 * MSIRUNMODE_SCHEDULED called from install script
651 * MSIRUNMODE_ROLLBACK called from rollback script
652 * MSIRUNMODE_COMMIT called from commit script
656 * Not in the state: FALSE
659 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
664 TRACE("%d %d\n", hInstall
, iRunMode
);
666 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
671 IWineMsiRemotePackage
*remote_package
;
673 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
677 hr
= IWineMsiRemotePackage_GetMode(remote_package
, iRunMode
, &ret
);
678 IWineMsiRemotePackage_Release(remote_package
);
688 case MSIRUNMODE_WINDOWS9X
:
689 if (GetVersion() & 0x80000000)
693 case MSIRUNMODE_OPERATIONS
:
694 case MSIRUNMODE_RESERVED11
:
695 case MSIRUNMODE_RESERVED14
:
696 case MSIRUNMODE_RESERVED15
:
699 case MSIRUNMODE_SCHEDULED
:
700 r
= package
->scheduled_action_running
;
703 case MSIRUNMODE_ROLLBACK
:
704 r
= package
->rollback_action_running
;
707 case MSIRUNMODE_COMMIT
:
708 r
= package
->commit_action_running
;
711 case MSIRUNMODE_MAINTENANCE
:
712 r
= msi_get_property_int( package
->db
, szInstalled
, 0 ) != 0;
715 case MSIRUNMODE_REBOOTATEND
:
716 r
= package
->need_reboot
;
719 case MSIRUNMODE_LOGENABLED
:
720 r
= (package
->log_file
!= INVALID_HANDLE_VALUE
);
724 FIXME("unimplemented run mode: %d\n", iRunMode
);
728 msiobj_release( &package
->hdr
);
732 /***********************************************************************
735 UINT WINAPI
MsiSetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
, BOOL fState
)
740 TRACE("%d %d %d\n", hInstall
, iRunMode
, fState
);
742 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
746 IWineMsiRemotePackage
*remote_package
;
748 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote( hInstall
);
752 hr
= IWineMsiRemotePackage_SetMode( remote_package
, iRunMode
, fState
);
753 IWineMsiRemotePackage_Release( remote_package
);
757 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
758 return HRESULT_CODE(hr
);
760 return ERROR_FUNCTION_FAILED
;
763 return ERROR_SUCCESS
;
768 case MSIRUNMODE_REBOOTATEND
:
769 package
->need_reboot
= 1;
773 case MSIRUNMODE_REBOOTNOW
:
774 FIXME("unimplemented run mode: %d\n", iRunMode
);
775 r
= ERROR_FUNCTION_FAILED
;
779 r
= ERROR_ACCESS_DENIED
;
782 msiobj_release( &package
->hdr
);
786 /***********************************************************************
787 * MsiSetFeatureStateA (MSI.@)
789 * According to the docs, when this is called it immediately recalculates
790 * all the component states as well
792 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
795 LPWSTR szwFeature
= NULL
;
798 szwFeature
= strdupAtoW(szFeature
);
801 return ERROR_FUNCTION_FAILED
;
803 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
805 msi_free(szwFeature
);
812 UINT WINAPI
MSI_SetFeatureStateW(MSIPACKAGE
* package
, LPCWSTR szFeature
,
815 UINT rc
= ERROR_SUCCESS
;
816 MSIFEATURE
*feature
, *child
;
818 TRACE("%s %i\n", debugstr_w(szFeature
), iState
);
820 feature
= get_loaded_feature(package
,szFeature
);
822 return ERROR_UNKNOWN_FEATURE
;
824 if (iState
== INSTALLSTATE_ADVERTISED
&&
825 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
826 return ERROR_FUNCTION_FAILED
;
828 feature
->ActionRequest
= iState
;
830 ACTION_UpdateComponentStates( package
, feature
);
832 /* update all the features that are children of this feature */
833 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
835 if (child
->Feature_Parent
&& !strcmpW( szFeature
, child
->Feature_Parent
))
836 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
842 /***********************************************************************
843 * MsiSetFeatureStateW (MSI.@)
845 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
849 UINT rc
= ERROR_SUCCESS
;
851 TRACE("%s %i\n",debugstr_w(szFeature
), iState
);
853 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
858 IWineMsiRemotePackage
*remote_package
;
860 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
862 return ERROR_INVALID_HANDLE
;
864 feature
= SysAllocString(szFeature
);
867 IWineMsiRemotePackage_Release(remote_package
);
868 return ERROR_OUTOFMEMORY
;
871 hr
= IWineMsiRemotePackage_SetFeatureState(remote_package
, feature
, iState
);
873 SysFreeString(feature
);
874 IWineMsiRemotePackage_Release(remote_package
);
878 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
879 return HRESULT_CODE(hr
);
881 return ERROR_FUNCTION_FAILED
;
884 return ERROR_SUCCESS
;
887 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
889 msiobj_release( &package
->hdr
);
893 /***********************************************************************
894 * MsiGetFeatureStateA (MSI.@)
896 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
897 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
899 LPWSTR szwFeature
= NULL
;
902 szwFeature
= strdupAtoW(szFeature
);
904 rc
= MsiGetFeatureStateW(hInstall
,szwFeature
,piInstalled
, piAction
);
906 msi_free( szwFeature
);
911 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPCWSTR szFeature
,
912 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
916 feature
= get_loaded_feature(package
,szFeature
);
918 return ERROR_UNKNOWN_FEATURE
;
921 *piInstalled
= feature
->Installed
;
924 *piAction
= feature
->ActionRequest
;
926 TRACE("returning %i %i\n", feature
->Installed
, feature
->ActionRequest
);
928 return ERROR_SUCCESS
;
931 /***********************************************************************
932 * MsiGetFeatureStateW (MSI.@)
934 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
935 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
940 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
, piAction
);
942 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
947 IWineMsiRemotePackage
*remote_package
;
949 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
951 return ERROR_INVALID_HANDLE
;
953 feature
= SysAllocString(szFeature
);
956 IWineMsiRemotePackage_Release(remote_package
);
957 return ERROR_OUTOFMEMORY
;
960 hr
= IWineMsiRemotePackage_GetFeatureState(remote_package
, feature
,
961 piInstalled
, piAction
);
963 SysFreeString(feature
);
964 IWineMsiRemotePackage_Release(remote_package
);
968 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
969 return HRESULT_CODE(hr
);
971 return ERROR_FUNCTION_FAILED
;
974 return ERROR_SUCCESS
;
977 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
978 msiobj_release( &package
->hdr
);
982 /***********************************************************************
983 * MsiGetFeatureCostA (MSI.@)
985 UINT WINAPI
MsiGetFeatureCostA(MSIHANDLE hInstall
, LPCSTR szFeature
,
986 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
988 LPWSTR szwFeature
= NULL
;
991 szwFeature
= strdupAtoW(szFeature
);
993 rc
= MsiGetFeatureCostW(hInstall
, szwFeature
, iCostTree
, iState
, piCost
);
995 msi_free(szwFeature
);
1000 static INT
feature_cost( MSIFEATURE
*feature
)
1005 LIST_FOR_EACH_ENTRY( comp
, &feature
->Components
, MSICOMPONENT
, entry
)
1012 UINT
MSI_GetFeatureCost( MSIPACKAGE
*package
, MSIFEATURE
*feature
, MSICOSTTREE tree
,
1013 INSTALLSTATE state
, LPINT cost
)
1015 TRACE("%s, %u, %d, %p\n", debugstr_w(feature
->Feature
), tree
, state
, cost
);
1020 case MSICOSTTREE_CHILDREN
:
1024 LIST_FOR_EACH_ENTRY( child
, &feature
->Children
, MSIFEATURE
, entry
)
1026 if (child
->ActionRequest
== state
)
1027 *cost
+= feature_cost( child
);
1031 case MSICOSTTREE_PARENTS
:
1033 const WCHAR
*feature_parent
= feature
->Feature_Parent
;
1036 MSIFEATURE
*parent
= get_loaded_feature( package
, feature_parent
);
1040 if (parent
->ActionRequest
== state
)
1041 *cost
+= feature_cost( parent
);
1043 feature_parent
= parent
->Feature_Parent
;
1047 case MSICOSTTREE_SELFONLY
:
1048 if (feature
->ActionRequest
== state
)
1049 *cost
= feature_cost( feature
);
1053 WARN("unhandled cost tree %u\n", tree
);
1058 return ERROR_SUCCESS
;
1061 /***********************************************************************
1062 * MsiGetFeatureCostW (MSI.@)
1064 UINT WINAPI
MsiGetFeatureCostW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1065 MSICOSTTREE iCostTree
, INSTALLSTATE iState
, LPINT piCost
)
1067 MSIPACKAGE
*package
;
1068 MSIFEATURE
*feature
;
1071 TRACE("(%d %s %i %i %p)\n", hInstall
, debugstr_w(szFeature
),
1072 iCostTree
, iState
, piCost
);
1074 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1079 IWineMsiRemotePackage
*remote_package
;
1081 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1082 if (!remote_package
)
1083 return ERROR_INVALID_HANDLE
;
1085 feature
= SysAllocString(szFeature
);
1088 IWineMsiRemotePackage_Release(remote_package
);
1089 return ERROR_OUTOFMEMORY
;
1092 hr
= IWineMsiRemotePackage_GetFeatureCost(remote_package
, feature
,
1093 iCostTree
, iState
, piCost
);
1095 SysFreeString(feature
);
1096 IWineMsiRemotePackage_Release(remote_package
);
1100 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1101 return HRESULT_CODE(hr
);
1103 return ERROR_FUNCTION_FAILED
;
1106 return ERROR_SUCCESS
;
1109 feature
= get_loaded_feature(package
, szFeature
);
1112 ret
= MSI_GetFeatureCost(package
, feature
, iCostTree
, iState
, piCost
);
1114 ret
= ERROR_UNKNOWN_FEATURE
;
1116 msiobj_release( &package
->hdr
);
1120 /***********************************************************************
1121 * MsiSetComponentStateA (MSI.@)
1123 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1124 INSTALLSTATE iState
)
1127 LPWSTR szwComponent
= strdupAtoW(szComponent
);
1129 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
1131 msi_free(szwComponent
);
1136 /***********************************************************************
1137 * MsiGetComponentStateA (MSI.@)
1139 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
1140 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1142 LPWSTR szwComponent
= NULL
;
1145 szwComponent
= strdupAtoW(szComponent
);
1147 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
1149 msi_free( szwComponent
);
1154 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1155 INSTALLSTATE iState
)
1159 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
1161 comp
= get_loaded_component(package
, szComponent
);
1163 return ERROR_UNKNOWN_COMPONENT
;
1166 comp
->Action
= iState
;
1168 return ERROR_SUCCESS
;
1171 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
1172 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1176 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
1177 piInstalled
, piAction
);
1179 comp
= get_loaded_component(package
,szComponent
);
1181 return ERROR_UNKNOWN_COMPONENT
;
1186 *piInstalled
= comp
->Installed
;
1188 *piInstalled
= INSTALLSTATE_UNKNOWN
;
1194 *piAction
= comp
->Action
;
1196 *piAction
= INSTALLSTATE_UNKNOWN
;
1199 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
1200 return ERROR_SUCCESS
;
1203 /***********************************************************************
1204 * MsiSetComponentStateW (MSI.@)
1206 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1207 INSTALLSTATE iState
)
1209 MSIPACKAGE
* package
;
1212 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1217 IWineMsiRemotePackage
*remote_package
;
1219 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1220 if (!remote_package
)
1221 return ERROR_INVALID_HANDLE
;
1223 component
= SysAllocString(szComponent
);
1226 IWineMsiRemotePackage_Release(remote_package
);
1227 return ERROR_OUTOFMEMORY
;
1230 hr
= IWineMsiRemotePackage_SetComponentState(remote_package
, component
, iState
);
1232 SysFreeString(component
);
1233 IWineMsiRemotePackage_Release(remote_package
);
1237 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1238 return HRESULT_CODE(hr
);
1240 return ERROR_FUNCTION_FAILED
;
1243 return ERROR_SUCCESS
;
1246 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
1247 msiobj_release(&package
->hdr
);
1251 /***********************************************************************
1252 * MsiGetComponentStateW (MSI.@)
1254 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
1255 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
1257 MSIPACKAGE
* package
;
1260 TRACE("%d %s %p %p\n", hInstall
, debugstr_w(szComponent
),
1261 piInstalled
, piAction
);
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 component
= SysAllocString(szComponent
);
1277 IWineMsiRemotePackage_Release(remote_package
);
1278 return ERROR_OUTOFMEMORY
;
1281 hr
= IWineMsiRemotePackage_GetComponentState(remote_package
, component
,
1282 piInstalled
, piAction
);
1284 SysFreeString(component
);
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 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
1299 msiobj_release( &package
->hdr
);
1303 /***********************************************************************
1304 * MsiGetLanguage (MSI.@)
1306 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
1308 MSIPACKAGE
* package
;
1310 static const WCHAR szProductLanguage
[] =
1311 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
1313 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1318 IWineMsiRemotePackage
*remote_package
;
1320 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1321 if (!remote_package
)
1322 return ERROR_INVALID_HANDLE
;
1324 hr
= IWineMsiRemotePackage_GetLanguage(remote_package
, &lang
);
1332 langid
= msi_get_property_int( package
->db
, szProductLanguage
, 0 );
1333 msiobj_release( &package
->hdr
);
1337 UINT
MSI_SetInstallLevel( MSIPACKAGE
*package
, int iInstallLevel
)
1339 static const WCHAR szInstallLevel
[] = {
1340 'I','N','S','T','A','L','L','L','E','V','E','L',0 };
1341 static const WCHAR fmt
[] = { '%','d',0 };
1345 TRACE("%p %i\n", package
, iInstallLevel
);
1347 if (iInstallLevel
> 32767)
1348 return ERROR_INVALID_PARAMETER
;
1350 if (iInstallLevel
< 1)
1351 return MSI_SetFeatureStates( package
);
1353 sprintfW( level
, fmt
, iInstallLevel
);
1354 r
= msi_set_property( package
->db
, szInstallLevel
, level
);
1355 if ( r
== ERROR_SUCCESS
)
1356 r
= MSI_SetFeatureStates( package
);
1361 /***********************************************************************
1362 * MsiSetInstallLevel (MSI.@)
1364 UINT WINAPI
MsiSetInstallLevel(MSIHANDLE hInstall
, int iInstallLevel
)
1366 MSIPACKAGE
* package
;
1369 TRACE("%d %i\n", hInstall
, iInstallLevel
);
1371 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
1375 IWineMsiRemotePackage
*remote_package
;
1377 remote_package
= (IWineMsiRemotePackage
*)msi_get_remote(hInstall
);
1378 if (!remote_package
)
1379 return ERROR_INVALID_HANDLE
;
1381 hr
= IWineMsiRemotePackage_SetInstallLevel(remote_package
, iInstallLevel
);
1383 IWineMsiRemotePackage_Release(remote_package
);
1387 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
1388 return HRESULT_CODE(hr
);
1390 return ERROR_FUNCTION_FAILED
;
1393 return ERROR_SUCCESS
;
1396 r
= MSI_SetInstallLevel( package
, iInstallLevel
);
1398 msiobj_release( &package
->hdr
);
1403 /***********************************************************************
1404 * MsiGetFeatureValidStatesW (MSI.@)
1406 UINT WINAPI
MsiGetFeatureValidStatesW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
1407 LPDWORD pInstallState
)
1409 if(pInstallState
) *pInstallState
= 1<<INSTALLSTATE_LOCAL
;
1410 FIXME("%d %s %p stub returning %d\n",
1411 hInstall
, debugstr_w(szFeature
), pInstallState
, pInstallState
? *pInstallState
: 0);
1413 return ERROR_SUCCESS
;
1416 /***********************************************************************
1417 * MsiGetFeatureValidStatesA (MSI.@)
1419 UINT WINAPI
MsiGetFeatureValidStatesA(MSIHANDLE hInstall
, LPCSTR szFeature
,
1420 LPDWORD pInstallState
)
1423 LPWSTR szwFeature
= strdupAtoW(szFeature
);
1425 ret
= MsiGetFeatureValidStatesW(hInstall
, szwFeature
, pInstallState
);
1427 msi_free(szwFeature
);