msi: Handle remote calls to MsiSetFeatureState.
[wine/wine-kai.git] / dlls / msi / install.c
blobc9a34cc3d9da061f01020843a8eab5b061456bf5
1 /*
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 */
23 #define COBJMACROS
25 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "wine/debug.h"
31 #include "msi.h"
32 #include "msidefs.h"
34 #include "msipriv.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 )
45 LPWSTR szwAction;
46 UINT ret;
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 );
56 return ret;
59 /***********************************************************************
60 * MsiDoActionW (MSI.@)
62 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
64 MSIPACKAGE *package;
65 UINT ret;
67 TRACE("%s\n",debugstr_w(szAction));
69 if (!szAction)
70 return ERROR_INVALID_PARAMETER;
72 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
73 if (!package)
75 HRESULT hr;
76 IWineMsiRemotePackage *remote_package;
78 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
79 if (!remote_package)
80 return ERROR_INVALID_HANDLE;
82 hr = IWineMsiRemotePackage_DoAction( remote_package, (BSTR *)szAction );
84 IWineMsiRemotePackage_Release( remote_package );
86 if (FAILED(hr))
88 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
89 return HRESULT_CODE(hr);
91 return ERROR_FUNCTION_FAILED;
94 return ERROR_SUCCESS;
97 ret = ACTION_PerformUIAction( package, szAction, -1 );
98 msiobj_release( &package->hdr );
100 return ret;
103 /***********************************************************************
104 * MsiSequenceA (MSI.@)
106 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
108 LPWSTR szwTable;
109 UINT ret;
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 );
119 return ret;
122 /***********************************************************************
123 * MsiSequenceW (MSI.@)
125 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
127 MSIPACKAGE *package;
128 UINT ret;
130 TRACE("%s\n", debugstr_w(szTable));
132 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
133 if (!package)
135 HRESULT hr;
136 IWineMsiRemotePackage *remote_package;
138 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
139 if (!remote_package)
140 return ERROR_INVALID_HANDLE;
142 hr = IWineMsiRemotePackage_Sequence( remote_package, (BSTR *)szTable, iSequenceMode );
144 IWineMsiRemotePackage_Release( remote_package );
146 if (FAILED(hr))
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 );
160 return ret;
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;
170 if (!sz)
171 return r;
173 if (awbuf->unicode)
175 len = lstrlenW( str );
176 if (awbuf->str.w)
177 lstrcpynW( awbuf->str.w, str, *sz );
179 else
181 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
182 if (len)
183 len--;
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)
190 r = ERROR_MORE_DATA;
191 *sz = len;
192 return r;
195 /***********************************************************************
196 * MsiGetTargetPath (internal)
198 static UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
199 awstring *szPathBuf, DWORD* pcchPathBuf )
201 MSIPACKAGE *package;
202 LPWSTR path;
203 UINT r = ERROR_FUNCTION_FAILED;
205 if (!szFolder)
206 return ERROR_INVALID_PARAMETER;
208 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
209 if (!package)
211 HRESULT hr;
212 IWineMsiRemotePackage *remote_package;
213 LPWSTR value = NULL;
214 DWORD len;
216 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
217 if (!remote_package)
218 return ERROR_INVALID_HANDLE;
220 len = 0;
221 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, (BSTR *)szFolder,
222 NULL, &len );
223 if (FAILED(hr))
224 goto done;
226 len++;
227 value = msi_alloc(len * sizeof(WCHAR));
228 if (!value)
230 r = ERROR_OUTOFMEMORY;
231 goto done;
234 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, (BSTR *)szFolder,
235 (BSTR *)value, &len);
236 if (FAILED(hr))
237 goto done;
239 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
241 done:
242 IWineMsiRemotePackage_Release( remote_package );
243 msi_free( value );
245 if (FAILED(hr))
247 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
248 return HRESULT_CODE(hr);
250 return ERROR_FUNCTION_FAILED;
253 return r;
256 path = resolve_folder( package, szFolder, FALSE, FALSE, TRUE, NULL );
257 msiobj_release( &package->hdr );
259 if (!path)
260 return ERROR_DIRECTORY;
262 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
263 msi_free( path );
264 return r;
267 /***********************************************************************
268 * MsiGetTargetPathA (MSI.@)
270 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
271 LPSTR szPathBuf, DWORD* pcchPathBuf )
273 LPWSTR szwFolder;
274 awstring path;
275 UINT r;
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 );
290 return r;
293 /***********************************************************************
294 * MsiGetTargetPathW (MSI.@)
296 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
297 LPWSTR szPathBuf, DWORD* pcchPathBuf )
299 awstring path;
301 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
303 path.unicode = TRUE;
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 )
315 MSIPACKAGE *package;
316 LPWSTR path;
317 UINT r = ERROR_FUNCTION_FAILED;
319 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
321 if (!szFolder)
322 return ERROR_INVALID_PARAMETER;
324 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
325 if (!package)
327 HRESULT hr;
328 IWineMsiRemotePackage *remote_package;
329 LPWSTR value = NULL;
330 DWORD len;
332 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
333 if (!remote_package)
334 return ERROR_INVALID_HANDLE;
336 len = 0;
337 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, (BSTR *)szFolder,
338 NULL, &len );
339 if (FAILED(hr))
340 goto done;
342 len++;
343 value = msi_alloc(len * sizeof(WCHAR));
344 if (!value)
346 r = ERROR_OUTOFMEMORY;
347 goto done;
350 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, (BSTR *)szFolder,
351 (BSTR *)value, &len);
352 if (FAILED(hr))
353 goto done;
355 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
357 done:
358 IWineMsiRemotePackage_Release( remote_package );
359 msi_free( value );
361 if (FAILED(hr))
363 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
364 return HRESULT_CODE(hr);
366 return ERROR_FUNCTION_FAILED;
369 return r;
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));
382 if (!path)
383 return ERROR_DIRECTORY;
385 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
386 msi_free( path );
387 return r;
390 /***********************************************************************
391 * MsiGetSourcePathA (MSI.@)
393 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
394 LPSTR szPathBuf, DWORD* pcchPathBuf )
396 LPWSTR folder;
397 awstring str;
398 UINT r;
400 TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
402 str.unicode = FALSE;
403 str.str.a = szPathBuf;
405 folder = strdupAtoW( szFolder );
406 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
407 msi_free( folder );
409 return r;
412 /***********************************************************************
413 * MsiGetSourcePathW (MSI.@)
415 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
416 LPWSTR szPathBuf, DWORD* pcchPathBuf )
418 awstring str;
420 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
422 str.unicode = TRUE;
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)
443 goto end;
445 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
447 end:
448 msi_free(szwFolder);
449 msi_free(szwFolderPath);
451 return rc;
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)
462 DWORD attrib;
463 LPWSTR path = NULL;
464 LPWSTR path2 = NULL;
465 MSIFOLDER *folder;
466 MSIFILE *file;
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);
478 if (!path)
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);
493 msi_free(path2);
495 else
497 MSIFOLDER *f;
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);
508 msi_free(path2);
511 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
513 MSICOMPONENT *comp = file->Component;
514 LPWSTR p;
516 if (!comp)
517 continue;
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);
523 msi_free(p);
526 msi_free(path);
528 return ERROR_SUCCESS;
531 /***********************************************************************
532 * MsiSetTargetPathW (MSI.@)
534 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
535 LPCWSTR szFolderPath)
537 MSIPACKAGE *package;
538 UINT ret;
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);
546 if (!package)
548 HRESULT hr;
549 IWineMsiRemotePackage *remote_package;
551 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
552 if (!remote_package)
553 return ERROR_INVALID_HANDLE;
555 hr = IWineMsiRemotePackage_SetTargetPath( remote_package, (BSTR *)szFolder, (BSTR *)szFolderPath );
557 IWineMsiRemotePackage_Release( remote_package );
559 if (FAILED(hr))
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 );
572 return ret;
575 /***********************************************************************
576 * MsiGetMode (MSI.@)
578 * Returns an internal installer state (if it is running in a mode iRunMode)
580 * PARAMS
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
603 * RETURNS
604 * In the state: TRUE
605 * Not in the state: FALSE
608 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
610 MSIPACKAGE *package;
611 BOOL r = FALSE;
613 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
614 if (!package)
616 BOOL ret;
617 HRESULT hr;
618 IWineMsiRemotePackage *remote_package;
620 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
621 if (!remote_package)
622 return FALSE;
624 hr = IWineMsiRemotePackage_GetMode(remote_package, iRunMode, &ret);
625 IWineMsiRemotePackage_Release(remote_package);
627 if (hr == S_OK)
628 return ret;
630 return FALSE;
633 switch (iRunMode)
635 case MSIRUNMODE_WINDOWS9X:
636 if (GetVersion() & 0x80000000)
637 r = TRUE;
638 break;
640 case MSIRUNMODE_RESERVED11:
641 case MSIRUNMODE_RESERVED14:
642 case MSIRUNMODE_RESERVED15:
643 break;
645 case MSIRUNMODE_SCHEDULED:
646 r = package->scheduled_action_running;
647 break;
649 case MSIRUNMODE_ROLLBACK:
650 r = package->rollback_action_running;
651 break;
653 case MSIRUNMODE_COMMIT:
654 r = package->commit_action_running;
655 break;
657 default:
658 FIXME("%ld %d\n", hInstall, iRunMode);
659 r = TRUE;
662 return r;
665 /***********************************************************************
666 * MsiSetMode (MSI.@)
668 BOOL WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
670 switch (iRunMode)
672 case MSIRUNMODE_RESERVED11:
673 case MSIRUNMODE_WINDOWS9X:
674 case MSIRUNMODE_RESERVED14:
675 case MSIRUNMODE_RESERVED15:
676 return FALSE;
677 default:
678 FIXME("%ld %d %d\n", hInstall, iRunMode, fState);
680 return TRUE;
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,
690 INSTALLSTATE iState)
692 LPWSTR szwFeature = NULL;
693 UINT rc;
695 szwFeature = strdupAtoW(szFeature);
697 if (!szwFeature)
698 return ERROR_FUNCTION_FAILED;
700 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
702 msi_free(szwFeature);
704 return rc;
709 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
710 INSTALLSTATE iState)
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);
718 if (!feature)
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);
736 return rc;
739 /***********************************************************************
740 * MsiSetFeatureStateW (MSI.@)
742 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
743 INSTALLSTATE iState)
745 MSIPACKAGE* package;
746 UINT rc = ERROR_SUCCESS;
748 TRACE("%s %i\n",debugstr_w(szFeature), iState);
750 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
751 if (!package)
753 HRESULT hr;
754 IWineMsiRemotePackage *remote_package;
756 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
757 if (!remote_package)
758 return ERROR_INVALID_HANDLE;
760 hr = IWineMsiRemotePackage_SetFeatureState(remote_package, (BSTR *)szFeature, iState);
762 IWineMsiRemotePackage_Release(remote_package);
764 if (FAILED(hr))
766 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
767 return HRESULT_CODE(hr);
769 return ERROR_FUNCTION_FAILED;
772 return ERROR_SUCCESS;
775 rc = MSI_SetFeatureStateW(package,szFeature,iState);
777 msiobj_release( &package->hdr );
778 return rc;
781 /***********************************************************************
782 * MsiGetFeatureStateA (MSI.@)
784 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
785 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
787 LPWSTR szwFeature = NULL;
788 UINT rc;
790 szwFeature = strdupAtoW(szFeature);
792 rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
794 msi_free( szwFeature);
796 return rc;
799 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
800 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
802 MSIFEATURE *feature;
804 feature = get_loaded_feature(package,szFeature);
805 if (!feature)
806 return ERROR_UNKNOWN_FEATURE;
808 if (piInstalled)
809 *piInstalled = feature->Installed;
811 if (piAction)
812 *piAction = feature->Action;
814 TRACE("returning %i %i\n", feature->Installed, feature->Action);
816 return ERROR_SUCCESS;
819 /***********************************************************************
820 * MsiGetFeatureStateW (MSI.@)
822 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
823 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
825 MSIPACKAGE* package;
826 UINT ret;
828 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
830 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
831 if (!package)
832 return ERROR_INVALID_HANDLE;
833 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
834 msiobj_release( &package->hdr );
835 return ret;
838 /***********************************************************************
839 * MsiGetFeatureCostA (MSI.@)
841 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
842 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
844 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature),
845 iCostTree, iState, piCost);
846 if (piCost) *piCost = 0;
847 return ERROR_SUCCESS;
850 /***********************************************************************
851 * MsiGetFeatureCostW (MSI.@)
853 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
854 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
856 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
857 iCostTree, iState, piCost);
858 if (piCost) *piCost = 0;
859 return ERROR_SUCCESS;
862 /***********************************************************************
863 * MsiSetComponentStateA (MSI.@)
865 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
866 INSTALLSTATE iState)
868 UINT rc;
869 LPWSTR szwComponent = strdupAtoW(szComponent);
871 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
873 msi_free(szwComponent);
875 return rc;
878 /***********************************************************************
879 * MsiGetComponentStateA (MSI.@)
881 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
882 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
884 LPWSTR szwComponent= NULL;
885 UINT rc;
887 szwComponent= strdupAtoW(szComponent);
889 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
891 msi_free( szwComponent);
893 return rc;
896 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
897 INSTALLSTATE iState)
899 MSICOMPONENT *comp;
901 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
903 comp = get_loaded_component(package, szComponent);
904 if (!comp)
905 return ERROR_UNKNOWN_COMPONENT;
907 comp->Installed = iState;
909 return ERROR_SUCCESS;
912 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
913 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
915 MSICOMPONENT *comp;
917 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
918 piInstalled, piAction);
920 comp = get_loaded_component(package,szComponent);
921 if (!comp)
922 return ERROR_UNKNOWN_COMPONENT;
924 if (piInstalled)
925 *piInstalled = comp->Installed;
927 if (piAction)
928 *piAction = comp->Action;
930 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
932 return ERROR_SUCCESS;
935 /***********************************************************************
936 * MsiSetComponentStateW (MSI.@)
938 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
939 INSTALLSTATE iState)
941 MSIPACKAGE* package;
942 UINT ret;
944 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
945 if (!package)
946 return ERROR_INVALID_HANDLE;
947 ret = MSI_SetComponentStateW(package, szComponent, iState);
948 msiobj_release(&package->hdr);
949 return ret;
952 /***********************************************************************
953 * MsiGetComponentStateW (MSI.@)
955 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
956 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
958 MSIPACKAGE* package;
959 UINT ret;
961 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
962 piInstalled, piAction);
964 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
965 if (!package)
966 return ERROR_INVALID_HANDLE;
967 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
968 msiobj_release( &package->hdr );
969 return ret;
972 /***********************************************************************
973 * MsiGetLanguage (MSI.@)
975 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
977 MSIPACKAGE* package;
978 LANGID langid;
979 static const WCHAR szProductLanguage[] =
980 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
982 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
983 if (!package)
984 return ERROR_INVALID_HANDLE;
986 langid = msi_get_property_int( package, szProductLanguage, 0 );
987 msiobj_release( &package->hdr );
988 return langid;
991 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
993 static const WCHAR szInstallLevel[] = {
994 'I','N','S','T','A','L','L','L','E','V','E','L',0 };
995 static const WCHAR fmt[] = { '%','d',0 };
996 WCHAR level[6];
997 UINT r;
999 TRACE("%p %i\n", package, iInstallLevel);
1001 if (iInstallLevel<1 || iInstallLevel>32767)
1002 return ERROR_INVALID_PARAMETER;
1004 sprintfW( level, fmt, iInstallLevel );
1005 r = MSI_SetPropertyW( package, szInstallLevel, level );
1006 if ( r == ERROR_SUCCESS )
1008 r = MSI_SetFeatureStates( package );
1011 return r;
1014 /***********************************************************************
1015 * MsiSetInstallLevel (MSI.@)
1017 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
1019 MSIPACKAGE* package;
1020 UINT r;
1022 TRACE("%ld %i\n", hInstall, iInstallLevel);
1024 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
1025 if ( !package )
1026 return ERROR_INVALID_HANDLE;
1028 r = MSI_SetInstallLevel( package, iInstallLevel );
1030 msiobj_release( &package->hdr );
1032 return r;
1035 /***********************************************************************
1036 * MsiGetFeatureValidStatesW (MSI.@)
1038 UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature,
1039 DWORD* pInstallState)
1041 if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL;
1042 FIXME("%ld %s %p stub returning %d\n",
1043 hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0);
1045 return ERROR_SUCCESS;
1048 /***********************************************************************
1049 * MsiGetFeatureValidStatesA (MSI.@)
1051 UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature,
1052 DWORD* pInstallState)
1054 UINT ret;
1055 LPWSTR szwFeature = strdupAtoW(szFeature);
1057 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);
1059 msi_free(szwFeature);
1061 return ret;