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"
35 #include "msiserver.h"
36 #include "wine/unicode.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msi);
40 /***********************************************************************
41 * MsiDoActionA (MSI.@)
43 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
48 TRACE("%s\n", debugstr_a(szAction));
50 szwAction = strdupAtoW(szAction);
51 if (szAction && !szwAction)
52 return ERROR_FUNCTION_FAILED;
54 ret = MsiDoActionW( hInstall, szwAction );
55 msi_free( szwAction );
59 /***********************************************************************
60 * MsiDoActionW (MSI.@)
62 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
67 TRACE("%s\n",debugstr_w(szAction));
70 return ERROR_INVALID_PARAMETER;
72 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
76 IWineMsiRemotePackage *remote_package;
78 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
80 return ERROR_INVALID_HANDLE;
82 hr = IWineMsiRemotePackage_DoAction( remote_package, (BSTR *)szAction );
84 IWineMsiRemotePackage_Release( remote_package );
88 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
89 return HRESULT_CODE(hr);
91 return ERROR_FUNCTION_FAILED;
97 ret = ACTION_PerformUIAction( package, szAction, -1 );
98 msiobj_release( &package->hdr );
103 /***********************************************************************
104 * MsiSequenceA (MSI.@)
106 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
111 TRACE("%s\n", debugstr_a(szTable));
113 szwTable = strdupAtoW(szTable);
114 if (szTable && !szwTable)
115 return ERROR_FUNCTION_FAILED;
117 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
118 msi_free( szwTable );
122 /***********************************************************************
123 * MsiSequenceW (MSI.@)
125 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
130 TRACE("%s\n", debugstr_w(szTable));
132 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
136 IWineMsiRemotePackage *remote_package;
138 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
140 return ERROR_INVALID_HANDLE;
142 hr = IWineMsiRemotePackage_Sequence( remote_package, (BSTR *)szTable, iSequenceMode );
144 IWineMsiRemotePackage_Release( remote_package );
148 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
149 return HRESULT_CODE(hr);
151 return ERROR_FUNCTION_FAILED;
154 return ERROR_SUCCESS;
157 ret = MSI_Sequence( package, szTable, iSequenceMode );
158 msiobj_release( &package->hdr );
163 UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
165 UINT len, r = ERROR_SUCCESS;
167 if (awbuf->str.w && !sz )
168 return ERROR_INVALID_PARAMETER;
175 len = lstrlenW( str );
177 lstrcpynW( awbuf->str.w, str, *sz );
181 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
184 WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL );
185 if ( awbuf->str.a && *sz && (len >= *sz) )
186 awbuf->str.a[*sz - 1] = 0;
189 if (awbuf->str.w && len >= *sz)
195 /***********************************************************************
196 * MsiGetTargetPath (internal)
198 static UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
199 awstring *szPathBuf, DWORD* pcchPathBuf )
203 UINT r = ERROR_FUNCTION_FAILED;
206 return ERROR_INVALID_PARAMETER;
208 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
212 IWineMsiRemotePackage *remote_package;
216 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
218 return ERROR_INVALID_HANDLE;
221 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, (BSTR *)szFolder,
227 value = msi_alloc(len * sizeof(WCHAR));
230 r = ERROR_OUTOFMEMORY;
234 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, (BSTR *)szFolder,
235 (BSTR *)value, &len);
239 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
242 IWineMsiRemotePackage_Release( remote_package );
247 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
248 return HRESULT_CODE(hr);
250 return ERROR_FUNCTION_FAILED;
256 path = resolve_folder( package, szFolder, FALSE, FALSE, TRUE, NULL );
257 msiobj_release( &package->hdr );
260 return ERROR_DIRECTORY;
262 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
267 /***********************************************************************
268 * MsiGetTargetPathA (MSI.@)
270 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
271 LPSTR szPathBuf, DWORD* pcchPathBuf )
277 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
279 szwFolder = strdupAtoW(szFolder);
280 if (szFolder && !szwFolder)
281 return ERROR_FUNCTION_FAILED;
283 path.unicode = FALSE;
284 path.str.a = szPathBuf;
286 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
288 msi_free( szwFolder );
293 /***********************************************************************
294 * MsiGetTargetPathW (MSI.@)
296 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
297 LPWSTR szPathBuf, DWORD* pcchPathBuf )
301 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
304 path.str.w = szPathBuf;
306 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
309 /***********************************************************************
310 * MsiGetSourcePath (internal)
312 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
313 awstring *szPathBuf, DWORD* pcchPathBuf )
317 UINT r = ERROR_FUNCTION_FAILED;
319 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
322 return ERROR_INVALID_PARAMETER;
324 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
328 IWineMsiRemotePackage *remote_package;
332 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
334 return ERROR_INVALID_HANDLE;
337 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, (BSTR *)szFolder,
343 value = msi_alloc(len * sizeof(WCHAR));
346 r = ERROR_OUTOFMEMORY;
350 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, (BSTR *)szFolder,
351 (BSTR *)value, &len);
355 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
358 IWineMsiRemotePackage_Release( remote_package );
363 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
364 return HRESULT_CODE(hr);
366 return ERROR_FUNCTION_FAILED;
372 if (szPathBuf->str.w && !pcchPathBuf )
374 msiobj_release( &package->hdr );
375 return ERROR_INVALID_PARAMETER;
378 path = resolve_folder(package, szFolder, TRUE, FALSE, TRUE, NULL);
379 msiobj_release( &package->hdr );
381 TRACE("path = %s\n",debugstr_w(path));
383 return ERROR_DIRECTORY;
385 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
390 /***********************************************************************
391 * MsiGetSourcePathA (MSI.@)
393 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
394 LPSTR szPathBuf, DWORD* pcchPathBuf )
400 TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
403 str.str.a = szPathBuf;
405 folder = strdupAtoW( szFolder );
406 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
412 /***********************************************************************
413 * MsiGetSourcePathW (MSI.@)
415 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
416 LPWSTR szPathBuf, DWORD* pcchPathBuf )
420 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
423 str.str.w = szPathBuf;
425 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
428 /***********************************************************************
429 * MsiSetTargetPathA (MSI.@)
431 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
432 LPCSTR szFolderPath )
434 LPWSTR szwFolder = NULL, szwFolderPath = NULL;
435 UINT rc = ERROR_OUTOFMEMORY;
437 if ( !szFolder || !szFolderPath )
438 return ERROR_INVALID_PARAMETER;
440 szwFolder = strdupAtoW(szFolder);
441 szwFolderPath = strdupAtoW(szFolderPath);
442 if (!szwFolder || !szwFolderPath)
445 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
449 msi_free(szwFolderPath);
455 * Ok my original interpretation of this was wrong. And it looks like msdn has
456 * changed a bit also. The given folder path does not have to actually already
457 * exist, it just cannot be read only and must be a legal folder path.
459 UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
460 LPCWSTR szFolderPath)
468 TRACE("%p %s %s\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
470 attrib = GetFileAttributesW(szFolderPath);
471 /* native MSI tests writeability by making temporary files at each drive */
472 if ( attrib != INVALID_FILE_ATTRIBUTES &&
473 (attrib & FILE_ATTRIBUTE_OFFLINE ||
474 attrib & FILE_ATTRIBUTE_READONLY))
475 return ERROR_FUNCTION_FAILED;
477 path = resolve_folder(package,szFolder,FALSE,FALSE,FALSE,&folder);
479 return ERROR_DIRECTORY;
481 msi_free(folder->Property);
482 folder->Property = build_directory_name(2, szFolderPath, NULL);
484 if (lstrcmpiW(path, folder->Property) == 0)
487 * Resolved Target has not really changed, so just
488 * set this folder and do not recalculate everything.
490 msi_free(folder->ResolvedTarget);
491 folder->ResolvedTarget = NULL;
492 path2 = resolve_folder(package,szFolder,FALSE,TRUE,FALSE,NULL);
499 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
501 msi_free(f->ResolvedTarget);
502 f->ResolvedTarget=NULL;
505 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
507 path2 = resolve_folder(package, f->Directory, FALSE, TRUE, FALSE, NULL);
511 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
513 MSICOMPONENT *comp = file->Component;
519 p = resolve_folder(package, comp->Directory, FALSE, FALSE, FALSE, NULL);
520 msi_free(file->TargetPath);
522 file->TargetPath = build_directory_name(2, p, file->FileName);
528 return ERROR_SUCCESS;
531 /***********************************************************************
532 * MsiSetTargetPathW (MSI.@)
534 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
535 LPCWSTR szFolderPath)
540 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
542 if ( !szFolder || !szFolderPath )
543 return ERROR_INVALID_PARAMETER;
545 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
549 IWineMsiRemotePackage *remote_package;
551 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
553 return ERROR_INVALID_HANDLE;
555 hr = IWineMsiRemotePackage_SetTargetPath( remote_package, (BSTR *)szFolder, (BSTR *)szFolderPath );
557 IWineMsiRemotePackage_Release( remote_package );
561 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
562 return HRESULT_CODE(hr);
564 return ERROR_FUNCTION_FAILED;
567 return ERROR_SUCCESS;
570 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
571 msiobj_release( &package->hdr );
575 /***********************************************************************
578 * Returns an internal installer state (if it is running in a mode iRunMode)
581 * hInstall [I] Handle to the installation
582 * hRunMode [I] Checking run mode
583 * MSIRUNMODE_ADMIN Administrative mode
584 * MSIRUNMODE_ADVERTISE Advertisement mode
585 * MSIRUNMODE_MAINTENANCE Maintenance mode
586 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
587 * MSIRUNMODE_LOGENABLED Log file is writing
588 * MSIRUNMODE_OPERATIONS Operations in progress??
589 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
590 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
591 * MSIRUNMODE_CABINET Files from cabinet are installed
592 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
593 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
594 * MSIRUNMODE_RESERVED11 Reserved
595 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
596 * MSIRUNMODE_ZAWENABLED Demand installation is supported
597 * MSIRUNMODE_RESERVED14 Reserved
598 * MSIRUNMODE_RESERVED15 Reserved
599 * MSIRUNMODE_SCHEDULED called from install script
600 * MSIRUNMODE_ROLLBACK called from rollback script
601 * MSIRUNMODE_COMMIT called from commit script
605 * Not in the state: FALSE
608 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
613 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
618 IWineMsiRemotePackage *remote_package;
620 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
624 hr = IWineMsiRemotePackage_GetMode(remote_package, iRunMode, &ret);
625 IWineMsiRemotePackage_Release(remote_package);
635 case MSIRUNMODE_WINDOWS9X:
636 if (GetVersion() & 0x80000000)
640 case MSIRUNMODE_RESERVED11:
641 case MSIRUNMODE_RESERVED14:
642 case MSIRUNMODE_RESERVED15:
645 case MSIRUNMODE_SCHEDULED:
646 r = package->scheduled_action_running;
649 case MSIRUNMODE_ROLLBACK:
650 r = package->rollback_action_running;
653 case MSIRUNMODE_COMMIT:
654 r = package->commit_action_running;
658 FIXME("%ld %d\n", hInstall, iRunMode);
665 /***********************************************************************
668 BOOL WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
672 case MSIRUNMODE_RESERVED11:
673 case MSIRUNMODE_WINDOWS9X:
674 case MSIRUNMODE_RESERVED14:
675 case MSIRUNMODE_RESERVED15:
678 FIXME("%ld %d %d\n", hInstall, iRunMode, fState);
683 /***********************************************************************
684 * MsiSetFeatureStateA (MSI.@)
686 * According to the docs, when this is called it immediately recalculates
687 * all the component states as well
689 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
692 LPWSTR szwFeature = NULL;
695 szwFeature = strdupAtoW(szFeature);
698 return ERROR_FUNCTION_FAILED;
700 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
702 msi_free(szwFeature);
709 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
712 UINT rc = ERROR_SUCCESS;
713 MSIFEATURE *feature, *child;
715 TRACE("%s %i\n", debugstr_w(szFeature), iState);
717 feature = get_loaded_feature(package,szFeature);
719 return ERROR_UNKNOWN_FEATURE;
721 if (iState == INSTALLSTATE_ADVERTISED &&
722 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
723 return ERROR_FUNCTION_FAILED;
725 msi_feature_set_state( feature, iState );
727 ACTION_UpdateComponentStates(package,szFeature);
729 /* update all the features that are children of this feature */
730 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
732 if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
733 MSI_SetFeatureStateW(package, child->Feature, iState);
739 /***********************************************************************
740 * MsiSetFeatureStateW (MSI.@)
742 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
746 UINT rc = ERROR_SUCCESS;
748 TRACE("%s %i\n",debugstr_w(szFeature), iState);
750 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
752 return ERROR_INVALID_HANDLE;
754 rc = MSI_SetFeatureStateW(package,szFeature,iState);
756 msiobj_release( &package->hdr );
760 /***********************************************************************
761 * MsiGetFeatureStateA (MSI.@)
763 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
764 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
766 LPWSTR szwFeature = NULL;
769 szwFeature = strdupAtoW(szFeature);
771 rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
773 msi_free( szwFeature);
778 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
779 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
783 feature = get_loaded_feature(package,szFeature);
785 return ERROR_UNKNOWN_FEATURE;
788 *piInstalled = feature->Installed;
791 *piAction = feature->Action;
793 TRACE("returning %i %i\n", feature->Installed, feature->Action);
795 return ERROR_SUCCESS;
798 /***********************************************************************
799 * MsiGetFeatureStateW (MSI.@)
801 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
802 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
807 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
809 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
811 return ERROR_INVALID_HANDLE;
812 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
813 msiobj_release( &package->hdr );
817 /***********************************************************************
818 * MsiGetFeatureCostA (MSI.@)
820 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
821 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
823 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature),
824 iCostTree, iState, piCost);
825 if (piCost) *piCost = 0;
826 return ERROR_SUCCESS;
829 /***********************************************************************
830 * MsiGetFeatureCostW (MSI.@)
832 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
833 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
835 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
836 iCostTree, iState, piCost);
837 if (piCost) *piCost = 0;
838 return ERROR_SUCCESS;
841 /***********************************************************************
842 * MsiSetComponentStateA (MSI.@)
844 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
848 LPWSTR szwComponent = strdupAtoW(szComponent);
850 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
852 msi_free(szwComponent);
857 /***********************************************************************
858 * MsiGetComponentStateA (MSI.@)
860 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
861 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
863 LPWSTR szwComponent= NULL;
866 szwComponent= strdupAtoW(szComponent);
868 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
870 msi_free( szwComponent);
875 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
880 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
882 comp = get_loaded_component(package, szComponent);
884 return ERROR_UNKNOWN_COMPONENT;
886 comp->Installed = iState;
888 return ERROR_SUCCESS;
891 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
892 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
896 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
897 piInstalled, piAction);
899 comp = get_loaded_component(package,szComponent);
901 return ERROR_UNKNOWN_COMPONENT;
904 *piInstalled = comp->Installed;
907 *piAction = comp->Action;
909 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
911 return ERROR_SUCCESS;
914 /***********************************************************************
915 * MsiSetComponentStateW (MSI.@)
917 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
923 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
925 return ERROR_INVALID_HANDLE;
926 ret = MSI_SetComponentStateW(package, szComponent, iState);
927 msiobj_release(&package->hdr);
931 /***********************************************************************
932 * MsiGetComponentStateW (MSI.@)
934 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
935 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
940 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
941 piInstalled, piAction);
943 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
945 return ERROR_INVALID_HANDLE;
946 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
947 msiobj_release( &package->hdr );
951 /***********************************************************************
952 * MsiGetLanguage (MSI.@)
954 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
958 static const WCHAR szProductLanguage[] =
959 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
961 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
963 return ERROR_INVALID_HANDLE;
965 langid = msi_get_property_int( package, szProductLanguage, 0 );
966 msiobj_release( &package->hdr );
970 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
972 static const WCHAR szInstallLevel[] = {
973 'I','N','S','T','A','L','L','L','E','V','E','L',0 };
974 static const WCHAR fmt[] = { '%','d',0 };
978 TRACE("%p %i\n", package, iInstallLevel);
980 if (iInstallLevel<1 || iInstallLevel>32767)
981 return ERROR_INVALID_PARAMETER;
983 sprintfW( level, fmt, iInstallLevel );
984 r = MSI_SetPropertyW( package, szInstallLevel, level );
985 if ( r == ERROR_SUCCESS )
987 r = MSI_SetFeatureStates( package );
993 /***********************************************************************
994 * MsiSetInstallLevel (MSI.@)
996 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
1001 TRACE("%ld %i\n", hInstall, iInstallLevel);
1003 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
1005 return ERROR_INVALID_HANDLE;
1007 r = MSI_SetInstallLevel( package, iInstallLevel );
1009 msiobj_release( &package->hdr );
1014 /***********************************************************************
1015 * MsiGetFeatureValidStatesW (MSI.@)
1017 UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature,
1018 DWORD* pInstallState)
1020 if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL;
1021 FIXME("%ld %s %p stub returning %d\n",
1022 hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0);
1024 return ERROR_SUCCESS;
1027 /***********************************************************************
1028 * MsiGetFeatureValidStatesA (MSI.@)
1030 UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature,
1031 DWORD* pInstallState)
1034 LPWSTR szwFeature = strdupAtoW(szFeature);
1036 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);
1038 msi_free(szwFeature);