msi: Make MsiProcessMessage() RPC-compatible.
[wine.git] / dlls / msi / install.c
blob814addc402f391a0c733a8327ac443362d9327ae
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"
33 #include "objbase.h"
34 #include "oleauto.h"
36 #include "msipriv.h"
37 #include "winemsi.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msi);
42 /***********************************************************************
43 * MsiDoActionA (MSI.@)
45 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
47 LPWSTR szwAction;
48 UINT ret;
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 );
58 return ret;
61 /***********************************************************************
62 * MsiDoActionW (MSI.@)
64 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
66 MSIPACKAGE *package;
67 UINT ret;
69 TRACE("%s\n",debugstr_w(szAction));
71 if (!szAction)
72 return ERROR_INVALID_PARAMETER;
74 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
75 if (!package)
77 MSIHANDLE remote;
78 HRESULT hr;
79 BSTR action;
81 if (!(remote = msi_get_remote(hInstall)))
82 return ERROR_INVALID_HANDLE;
84 action = SysAllocString( szAction );
85 if (!action)
86 return ERROR_OUTOFMEMORY;
88 hr = remote_DoAction(remote, action);
90 SysFreeString( action );
92 if (FAILED(hr))
94 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
95 return HRESULT_CODE(hr);
97 return ERROR_FUNCTION_FAILED;
100 return ERROR_SUCCESS;
103 ret = ACTION_PerformAction( package, szAction, SCRIPT_NONE );
104 msiobj_release( &package->hdr );
106 return ret;
109 /***********************************************************************
110 * MsiSequenceA (MSI.@)
112 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
114 LPWSTR szwTable;
115 UINT ret;
117 TRACE("%s, %d\n", debugstr_a(szTable), iSequenceMode);
119 szwTable = strdupAtoW(szTable);
120 if (szTable && !szwTable)
121 return ERROR_FUNCTION_FAILED;
123 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
124 msi_free( szwTable );
125 return ret;
128 /***********************************************************************
129 * MsiSequenceW (MSI.@)
131 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
133 MSIPACKAGE *package;
134 UINT ret;
136 TRACE("%s, %d\n", debugstr_w(szTable), iSequenceMode);
138 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
139 if (!package)
141 MSIHANDLE remote;
142 HRESULT hr;
143 BSTR table;
145 if (!(remote = msi_get_remote(hInstall)))
146 return ERROR_INVALID_HANDLE;
148 table = SysAllocString( szTable );
149 if (!table)
150 return ERROR_OUTOFMEMORY;
152 hr = remote_Sequence(remote, table, iSequenceMode);
154 SysFreeString( table );
156 if (FAILED(hr))
158 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
159 return HRESULT_CODE(hr);
161 return ERROR_FUNCTION_FAILED;
164 return ERROR_SUCCESS;
166 ret = MSI_Sequence( package, szTable );
167 msiobj_release( &package->hdr );
168 return ret;
171 UINT msi_strcpy_to_awstring( const WCHAR *str, int len, awstring *awbuf, DWORD *sz )
173 UINT r = ERROR_SUCCESS;
175 if (awbuf->str.w && !sz)
176 return ERROR_INVALID_PARAMETER;
177 if (!sz)
178 return ERROR_SUCCESS;
180 if (len < 0) len = strlenW( str );
182 if (awbuf->unicode && awbuf->str.w)
184 memcpy( awbuf->str.w, str, min(len + 1, *sz) * sizeof(WCHAR) );
185 if (*sz && len >= *sz)
186 awbuf->str.w[*sz - 1] = 0;
188 else
190 int lenA = WideCharToMultiByte( CP_ACP, 0, str, len + 1, NULL, 0, NULL, NULL );
191 if (lenA) lenA--;
192 WideCharToMultiByte( CP_ACP, 0, str, len + 1, awbuf->str.a, *sz, NULL, NULL );
193 if (awbuf->str.a && *sz && lenA >= *sz)
194 awbuf->str.a[*sz - 1] = 0;
195 len = lenA;
197 if (awbuf->str.w && len >= *sz)
198 r = ERROR_MORE_DATA;
199 *sz = len;
200 return r;
203 const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name )
205 MSIFOLDER *folder = msi_get_loaded_folder( package, name );
207 if (!folder) return NULL;
208 if (!folder->ResolvedTarget)
210 MSIFOLDER *parent = folder;
211 while (parent->Parent && strcmpW( parent->Parent, parent->Directory ))
213 parent = msi_get_loaded_folder( package, parent->Parent );
215 msi_resolve_target_folder( package, parent->Directory, TRUE );
217 return folder->ResolvedTarget;
220 /***********************************************************************
221 * MsiGetTargetPath (internal)
223 static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
224 awstring *szPathBuf, LPDWORD pcchPathBuf )
226 MSIPACKAGE *package;
227 const WCHAR *path;
228 UINT r = ERROR_FUNCTION_FAILED;
230 if (!szFolder)
231 return ERROR_INVALID_PARAMETER;
233 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
234 if (!package)
236 MSIHANDLE remote;
237 HRESULT hr;
238 LPWSTR value = NULL;
239 BSTR folder;
240 DWORD len;
242 if (!(remote = msi_get_remote(hInstall)))
243 return ERROR_INVALID_HANDLE;
245 folder = SysAllocString( szFolder );
246 if (!folder)
247 return ERROR_OUTOFMEMORY;
249 len = 0;
250 hr = remote_GetTargetPath(remote, folder, NULL, &len);
251 if (FAILED(hr))
252 goto done;
254 len++;
255 value = msi_alloc(len * sizeof(WCHAR));
256 if (!value)
258 r = ERROR_OUTOFMEMORY;
259 goto done;
262 hr = remote_GetTargetPath(remote, folder, value, &len);
263 if (FAILED(hr))
264 goto done;
266 r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf );
268 done:
269 SysFreeString( folder );
270 msi_free( value );
272 if (FAILED(hr))
274 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
275 return HRESULT_CODE(hr);
277 return ERROR_FUNCTION_FAILED;
280 return r;
283 path = msi_get_target_folder( package, szFolder );
284 msiobj_release( &package->hdr );
286 if (!path)
287 return ERROR_DIRECTORY;
289 return msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf );
292 /***********************************************************************
293 * MsiGetTargetPathA (MSI.@)
295 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
296 LPSTR szPathBuf, LPDWORD pcchPathBuf )
298 LPWSTR szwFolder;
299 awstring path;
300 UINT r;
302 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
304 szwFolder = strdupAtoW(szFolder);
305 if (szFolder && !szwFolder)
306 return ERROR_FUNCTION_FAILED;
308 path.unicode = FALSE;
309 path.str.a = szPathBuf;
311 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
313 msi_free( szwFolder );
315 return r;
318 /***********************************************************************
319 * MsiGetTargetPathW (MSI.@)
321 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
322 LPWSTR szPathBuf, LPDWORD pcchPathBuf )
324 awstring path;
326 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
328 path.unicode = TRUE;
329 path.str.w = szPathBuf;
331 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
334 static WCHAR *get_source_root( MSIPACKAGE *package )
336 msi_set_sourcedir_props( package, FALSE );
337 return msi_dup_property( package->db, szSourceDir );
340 WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder )
342 MSIFOLDER *f;
343 LPWSTR p, path = NULL, parent;
345 TRACE("working to resolve %s\n", debugstr_w(name));
347 if (!strcmpW( name, szSourceDir )) name = szTargetDir;
348 if (!(f = msi_get_loaded_folder( package, name ))) return NULL;
350 /* special resolving for root dir */
351 if (!strcmpW( name, szTargetDir ) && !f->ResolvedSource)
353 f->ResolvedSource = get_source_root( package );
355 if (folder) *folder = f;
356 if (f->ResolvedSource)
358 path = strdupW( f->ResolvedSource );
359 TRACE(" already resolved to %s\n", debugstr_w(path));
360 return path;
362 if (!f->Parent) return path;
363 parent = f->Parent;
364 TRACE(" ! parent is %s\n", debugstr_w(parent));
366 p = msi_resolve_source_folder( package, parent, NULL );
368 if (package->WordCount & msidbSumInfoSourceTypeCompressed)
369 path = get_source_root( package );
370 else if (package->WordCount & msidbSumInfoSourceTypeSFN)
371 path = msi_build_directory_name( 3, p, f->SourceShortPath, NULL );
372 else
373 path = msi_build_directory_name( 3, p, f->SourceLongPath, NULL );
375 TRACE("-> %s\n", debugstr_w(path));
376 f->ResolvedSource = strdupW( path );
377 msi_free( p );
379 return path;
382 /***********************************************************************
383 * MSI_GetSourcePath (internal)
385 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
386 awstring *szPathBuf, LPDWORD pcchPathBuf )
388 MSIPACKAGE *package;
389 LPWSTR path;
390 UINT r = ERROR_FUNCTION_FAILED;
392 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
394 if (!szFolder)
395 return ERROR_INVALID_PARAMETER;
397 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
398 if (!package)
400 HRESULT hr;
401 LPWSTR value = NULL;
402 MSIHANDLE remote;
403 BSTR folder;
404 DWORD len;
406 if (!(remote = msi_get_remote(hInstall)))
407 return ERROR_INVALID_HANDLE;
409 folder = SysAllocString( szFolder );
410 if (!folder)
411 return ERROR_OUTOFMEMORY;
413 len = 0;
414 hr = remote_GetSourcePath(remote, folder, NULL, &len);
415 if (FAILED(hr))
416 goto done;
418 len++;
419 value = msi_alloc(len * sizeof(WCHAR));
420 if (!value)
422 r = ERROR_OUTOFMEMORY;
423 goto done;
426 hr = remote_GetSourcePath(remote, folder, value, &len);
427 if (FAILED(hr))
428 goto done;
430 r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf );
432 done:
433 SysFreeString( folder );
434 msi_free( value );
436 if (FAILED(hr))
438 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
439 return HRESULT_CODE(hr);
441 return ERROR_FUNCTION_FAILED;
444 return r;
447 if (szPathBuf->str.w && !pcchPathBuf )
449 msiobj_release( &package->hdr );
450 return ERROR_INVALID_PARAMETER;
453 path = msi_resolve_source_folder( package, szFolder, NULL );
454 msiobj_release( &package->hdr );
456 TRACE("path = %s\n", debugstr_w(path));
457 if (!path)
458 return ERROR_DIRECTORY;
460 r = msi_strcpy_to_awstring( path, -1, szPathBuf, pcchPathBuf );
461 msi_free( path );
462 return r;
465 /***********************************************************************
466 * MsiGetSourcePathA (MSI.@)
468 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
469 LPSTR szPathBuf, LPDWORD pcchPathBuf )
471 LPWSTR folder;
472 awstring str;
473 UINT r;
475 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
477 str.unicode = FALSE;
478 str.str.a = szPathBuf;
480 folder = strdupAtoW( szFolder );
481 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
482 msi_free( folder );
484 return r;
487 /***********************************************************************
488 * MsiGetSourcePathW (MSI.@)
490 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
491 LPWSTR szPathBuf, LPDWORD pcchPathBuf )
493 awstring str;
495 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
497 str.unicode = TRUE;
498 str.str.w = szPathBuf;
500 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
503 /***********************************************************************
504 * MsiSetTargetPathA (MSI.@)
506 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
507 LPCSTR szFolderPath )
509 LPWSTR szwFolder = NULL, szwFolderPath = NULL;
510 UINT rc = ERROR_OUTOFMEMORY;
512 if ( !szFolder || !szFolderPath )
513 return ERROR_INVALID_PARAMETER;
515 szwFolder = strdupAtoW(szFolder);
516 szwFolderPath = strdupAtoW(szFolderPath);
517 if (!szwFolder || !szwFolderPath)
518 goto end;
520 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
522 end:
523 msi_free(szwFolder);
524 msi_free(szwFolderPath);
526 return rc;
529 static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR *path )
531 FolderList *fl;
532 MSIFOLDER *child;
533 WCHAR *target_path;
535 if (!(target_path = msi_normalize_path( path ))) return;
536 if (strcmpW( target_path, folder->ResolvedTarget ))
538 msi_free( folder->ResolvedTarget );
539 folder->ResolvedTarget = target_path;
540 msi_set_property( package->db, folder->Directory, folder->ResolvedTarget, -1 );
542 LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry )
544 child = fl->folder;
545 msi_resolve_target_folder( package, child->Directory, FALSE );
548 else msi_free( target_path );
551 UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath )
553 DWORD attrib;
554 MSIFOLDER *folder;
555 MSIFILE *file;
557 TRACE("%p %s %s\n", package, debugstr_w(szFolder), debugstr_w(szFolderPath));
559 attrib = GetFileAttributesW(szFolderPath);
560 /* native MSI tests writeability by making temporary files at each drive */
561 if (attrib != INVALID_FILE_ATTRIBUTES &&
562 (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY))
564 return ERROR_FUNCTION_FAILED;
566 if (!(folder = msi_get_loaded_folder( package, szFolder ))) return ERROR_DIRECTORY;
568 set_target_path( package, folder, szFolderPath );
570 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
572 const WCHAR *dir;
573 MSICOMPONENT *comp = file->Component;
575 if (!comp->Enabled || msi_is_global_assembly( comp )) continue;
577 dir = msi_get_target_folder( package, comp->Directory );
578 msi_free( file->TargetPath );
579 file->TargetPath = msi_build_directory_name( 2, dir, file->FileName );
581 return ERROR_SUCCESS;
584 /***********************************************************************
585 * MsiSetTargetPathW (MSI.@)
587 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
588 LPCWSTR szFolderPath)
590 MSIPACKAGE *package;
591 UINT ret;
593 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
595 if ( !szFolder || !szFolderPath )
596 return ERROR_INVALID_PARAMETER;
598 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
599 if (!package)
601 HRESULT hr;
602 BSTR folder, path;
603 MSIHANDLE remote;
605 if (!(remote = msi_get_remote(hInstall)))
606 return ERROR_INVALID_HANDLE;
608 folder = SysAllocString( szFolder );
609 path = SysAllocString( szFolderPath );
610 if (!folder || !path)
612 SysFreeString(folder);
613 SysFreeString(path);
614 return ERROR_OUTOFMEMORY;
617 hr = remote_SetTargetPath(remote, folder, path);
619 SysFreeString(folder);
620 SysFreeString(path);
622 if (FAILED(hr))
624 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
625 return HRESULT_CODE(hr);
627 return ERROR_FUNCTION_FAILED;
630 return ERROR_SUCCESS;
633 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
634 msiobj_release( &package->hdr );
635 return ret;
638 /***********************************************************************
639 * MsiGetMode (MSI.@)
641 * Returns an internal installer state (if it is running in a mode iRunMode)
643 * PARAMS
644 * hInstall [I] Handle to the installation
645 * hRunMode [I] Checking run mode
646 * MSIRUNMODE_ADMIN Administrative mode
647 * MSIRUNMODE_ADVERTISE Advertisement mode
648 * MSIRUNMODE_MAINTENANCE Maintenance mode
649 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
650 * MSIRUNMODE_LOGENABLED Log file is writing
651 * MSIRUNMODE_OPERATIONS Operations in progress??
652 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
653 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
654 * MSIRUNMODE_CABINET Files from cabinet are installed
655 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
656 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
657 * MSIRUNMODE_RESERVED11 Reserved
658 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
659 * MSIRUNMODE_ZAWENABLED Demand installation is supported
660 * MSIRUNMODE_RESERVED14 Reserved
661 * MSIRUNMODE_RESERVED15 Reserved
662 * MSIRUNMODE_SCHEDULED called from install script
663 * MSIRUNMODE_ROLLBACK called from rollback script
664 * MSIRUNMODE_COMMIT called from commit script
666 * RETURNS
667 * In the state: TRUE
668 * Not in the state: FALSE
671 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
673 MSIPACKAGE *package;
674 BOOL r = FALSE;
676 TRACE("%d %d\n", hInstall, iRunMode);
678 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
679 if (!package)
681 MSIHANDLE remote;
682 BOOL ret;
683 HRESULT hr;
685 if (!(remote = msi_get_remote(hInstall)))
686 return FALSE;
688 hr = remote_GetMode(remote, iRunMode, &ret);
690 if (hr == S_OK)
691 return ret;
693 return FALSE;
696 switch (iRunMode)
698 case MSIRUNMODE_ADMIN:
699 FIXME("no support for administrative installs\n");
700 break;
702 case MSIRUNMODE_ADVERTISE:
703 FIXME("no support for advertised installs\n");
704 break;
706 case MSIRUNMODE_WINDOWS9X:
707 if (GetVersion() & 0x80000000)
708 r = TRUE;
709 break;
711 case MSIRUNMODE_OPERATIONS:
712 case MSIRUNMODE_RESERVED11:
713 case MSIRUNMODE_RESERVED14:
714 case MSIRUNMODE_RESERVED15:
715 break;
717 case MSIRUNMODE_SCHEDULED:
718 r = package->scheduled_action_running;
719 break;
721 case MSIRUNMODE_ROLLBACK:
722 r = package->rollback_action_running;
723 break;
725 case MSIRUNMODE_COMMIT:
726 r = package->commit_action_running;
727 break;
729 case MSIRUNMODE_MAINTENANCE:
730 r = msi_get_property_int( package->db, szInstalled, 0 ) != 0;
731 break;
733 case MSIRUNMODE_ROLLBACKENABLED:
734 r = msi_get_property_int( package->db, szRollbackDisabled, 0 ) == 0;
735 break;
737 case MSIRUNMODE_REBOOTATEND:
738 r = package->need_reboot_at_end;
739 break;
741 case MSIRUNMODE_REBOOTNOW:
742 r = package->need_reboot_now;
743 break;
745 case MSIRUNMODE_LOGENABLED:
746 r = (package->log_file != INVALID_HANDLE_VALUE);
747 break;
749 default:
750 FIXME("unimplemented run mode: %d\n", iRunMode);
751 r = TRUE;
754 msiobj_release( &package->hdr );
755 return r;
758 /***********************************************************************
759 * MsiSetMode (MSI.@)
761 UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
763 MSIPACKAGE *package;
764 UINT r;
766 TRACE("%d %d %d\n", hInstall, iRunMode, fState);
768 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
769 if (!package)
771 MSIHANDLE remote;
772 HRESULT hr;
774 if (!(remote = msi_get_remote(hInstall)))
775 return FALSE;
777 hr = remote_SetMode(remote, iRunMode, fState);
779 if (FAILED(hr))
781 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
782 return HRESULT_CODE(hr);
784 return ERROR_FUNCTION_FAILED;
787 return ERROR_SUCCESS;
790 switch (iRunMode)
792 case MSIRUNMODE_REBOOTATEND:
793 package->need_reboot_at_end = (fState != 0);
794 r = ERROR_SUCCESS;
795 break;
797 case MSIRUNMODE_REBOOTNOW:
798 package->need_reboot_now = (fState != 0);
799 r = ERROR_SUCCESS;
800 break;
802 default:
803 r = ERROR_ACCESS_DENIED;
806 msiobj_release( &package->hdr );
807 return r;
810 /***********************************************************************
811 * MsiSetFeatureStateA (MSI.@)
813 * According to the docs, when this is called it immediately recalculates
814 * all the component states as well
816 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
817 INSTALLSTATE iState)
819 LPWSTR szwFeature = NULL;
820 UINT rc;
822 szwFeature = strdupAtoW(szFeature);
824 if (!szwFeature)
825 return ERROR_FUNCTION_FAILED;
827 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
829 msi_free(szwFeature);
831 return rc;
834 /* update component state based on a feature change */
835 void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
837 INSTALLSTATE newstate;
838 ComponentList *cl;
840 newstate = feature->ActionRequest;
841 if (newstate == INSTALLSTATE_ABSENT) newstate = INSTALLSTATE_UNKNOWN;
843 LIST_FOR_EACH_ENTRY(cl, &feature->Components, ComponentList, entry)
845 MSICOMPONENT *component = cl->component;
847 if (!component->Enabled) continue;
849 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
850 newstate, debugstr_w(component->Component), component->Installed,
851 component->Action, component->ActionRequest);
853 if (newstate == INSTALLSTATE_LOCAL)
855 component->Action = INSTALLSTATE_LOCAL;
856 component->ActionRequest = INSTALLSTATE_LOCAL;
858 else
860 ComponentList *clist;
861 MSIFEATURE *f;
863 component->hasLocalFeature = FALSE;
865 component->Action = newstate;
866 component->ActionRequest = newstate;
867 /* if any other feature wants it local we need to set it local */
868 LIST_FOR_EACH_ENTRY(f, &package->features, MSIFEATURE, entry)
870 if ( f->ActionRequest != INSTALLSTATE_LOCAL &&
871 f->ActionRequest != INSTALLSTATE_SOURCE )
873 continue;
875 LIST_FOR_EACH_ENTRY(clist, &f->Components, ComponentList, entry)
877 if (clist->component == component &&
878 (f->ActionRequest == INSTALLSTATE_LOCAL ||
879 f->ActionRequest == INSTALLSTATE_SOURCE))
881 TRACE("Saved by %s\n", debugstr_w(f->Feature));
882 component->hasLocalFeature = TRUE;
884 if (component->Attributes & msidbComponentAttributesOptional)
886 if (f->Attributes & msidbFeatureAttributesFavorSource)
888 component->Action = INSTALLSTATE_SOURCE;
889 component->ActionRequest = INSTALLSTATE_SOURCE;
891 else
893 component->Action = INSTALLSTATE_LOCAL;
894 component->ActionRequest = INSTALLSTATE_LOCAL;
897 else if (component->Attributes & msidbComponentAttributesSourceOnly)
899 component->Action = INSTALLSTATE_SOURCE;
900 component->ActionRequest = INSTALLSTATE_SOURCE;
902 else
904 component->Action = INSTALLSTATE_LOCAL;
905 component->ActionRequest = INSTALLSTATE_LOCAL;
911 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
912 newstate, debugstr_w(component->Component), component->Installed,
913 component->Action, component->ActionRequest);
917 UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE iState )
919 UINT rc = ERROR_SUCCESS;
920 MSIFEATURE *feature, *child;
922 TRACE("%s %i\n", debugstr_w(szFeature), iState);
924 feature = msi_get_loaded_feature( package, szFeature );
925 if (!feature)
926 return ERROR_UNKNOWN_FEATURE;
928 if (iState == INSTALLSTATE_ADVERTISED &&
929 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
930 return ERROR_FUNCTION_FAILED;
932 feature->ActionRequest = iState;
934 ACTION_UpdateComponentStates( package, feature );
936 /* update all the features that are children of this feature */
937 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
939 if (child->Feature_Parent && !strcmpW( szFeature, child->Feature_Parent ))
940 MSI_SetFeatureStateW(package, child->Feature, iState);
943 return rc;
946 /***********************************************************************
947 * MsiSetFeatureStateW (MSI.@)
949 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
950 INSTALLSTATE iState)
952 MSIPACKAGE* package;
953 UINT rc = ERROR_SUCCESS;
955 TRACE("%s %i\n",debugstr_w(szFeature), iState);
957 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
958 if (!package)
960 MSIHANDLE remote;
961 HRESULT hr;
962 BSTR feature;
964 if (!(remote = msi_get_remote(hInstall)))
965 return ERROR_INVALID_HANDLE;
967 feature = SysAllocString(szFeature);
968 if (!feature)
969 return ERROR_OUTOFMEMORY;
971 hr = remote_SetFeatureState(remote, feature, iState);
973 SysFreeString(feature);
975 if (FAILED(hr))
977 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
978 return HRESULT_CODE(hr);
980 return ERROR_FUNCTION_FAILED;
983 return ERROR_SUCCESS;
986 rc = MSI_SetFeatureStateW(package,szFeature,iState);
988 msiobj_release( &package->hdr );
989 return rc;
992 /***********************************************************************
993 * MsiSetFeatureAttributesA (MSI.@)
995 UINT WINAPI MsiSetFeatureAttributesA( MSIHANDLE handle, LPCSTR feature, DWORD attrs )
997 UINT r;
998 WCHAR *featureW = NULL;
1000 TRACE("%u, %s, 0x%08x\n", handle, debugstr_a(feature), attrs);
1002 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;
1004 r = MsiSetFeatureAttributesW( handle, featureW, attrs );
1005 msi_free( featureW );
1006 return r;
1009 static DWORD unmap_feature_attributes( DWORD attrs )
1011 DWORD ret = 0;
1013 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORLOCAL) ret = msidbFeatureAttributesFavorLocal;
1014 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORSOURCE) ret |= msidbFeatureAttributesFavorSource;
1015 if (attrs & INSTALLFEATUREATTRIBUTE_FOLLOWPARENT) ret |= msidbFeatureAttributesFollowParent;
1016 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORADVERTISE) ret |= msidbFeatureAttributesFavorAdvertise;
1017 if (attrs & INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE) ret |= msidbFeatureAttributesDisallowAdvertise;
1018 if (attrs & INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE) ret |= msidbFeatureAttributesNoUnsupportedAdvertise;
1019 return ret;
1022 /***********************************************************************
1023 * MsiSetFeatureAttributesW (MSI.@)
1025 UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attrs )
1027 MSIPACKAGE *package;
1028 MSIFEATURE *feature;
1029 WCHAR *costing;
1031 TRACE("%u, %s, 0x%08x\n", handle, debugstr_w(name), attrs);
1033 if (!name || !name[0]) return ERROR_UNKNOWN_FEATURE;
1035 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
1036 return ERROR_INVALID_HANDLE;
1038 costing = msi_dup_property( package->db, szCostingComplete );
1039 if (!costing || !strcmpW( costing, szOne ))
1041 msi_free( costing );
1042 msiobj_release( &package->hdr );
1043 return ERROR_FUNCTION_FAILED;
1045 msi_free( costing );
1046 if (!(feature = msi_get_loaded_feature( package, name )))
1048 msiobj_release( &package->hdr );
1049 return ERROR_UNKNOWN_FEATURE;
1051 feature->Attributes = unmap_feature_attributes( attrs );
1052 msiobj_release( &package->hdr );
1053 return ERROR_SUCCESS;
1056 /***********************************************************************
1057 * MsiGetFeatureStateA (MSI.@)
1059 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
1060 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1062 LPWSTR szwFeature = NULL;
1063 UINT rc;
1065 if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY;
1067 rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction);
1068 msi_free( szwFeature);
1069 return rc;
1072 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
1073 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1075 MSIFEATURE *feature;
1077 feature = msi_get_loaded_feature(package,szFeature);
1078 if (!feature)
1079 return ERROR_UNKNOWN_FEATURE;
1081 if (piInstalled)
1082 *piInstalled = feature->Installed;
1084 if (piAction)
1085 *piAction = feature->ActionRequest;
1087 TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest);
1089 return ERROR_SUCCESS;
1092 /***********************************************************************
1093 * MsiGetFeatureStateW (MSI.@)
1095 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
1096 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1098 MSIPACKAGE* package;
1099 UINT ret;
1101 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
1103 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1104 if (!package)
1106 MSIHANDLE remote;
1107 HRESULT hr;
1108 BSTR feature;
1110 if (!(remote = msi_get_remote(hInstall)))
1111 return ERROR_INVALID_HANDLE;
1113 feature = SysAllocString(szFeature);
1114 if (!feature)
1115 return ERROR_OUTOFMEMORY;
1117 hr = remote_GetFeatureState(remote, feature, piInstalled, piAction);
1119 SysFreeString(feature);
1121 if (FAILED(hr))
1123 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1124 return HRESULT_CODE(hr);
1126 return ERROR_FUNCTION_FAILED;
1129 return ERROR_SUCCESS;
1132 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
1133 msiobj_release( &package->hdr );
1134 return ret;
1137 /***********************************************************************
1138 * MsiGetFeatureCostA (MSI.@)
1140 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
1141 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
1143 LPWSTR szwFeature = NULL;
1144 UINT rc;
1146 szwFeature = strdupAtoW(szFeature);
1148 rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost);
1150 msi_free(szwFeature);
1152 return rc;
1155 static INT feature_cost( MSIFEATURE *feature )
1157 INT cost = 0;
1158 ComponentList *cl;
1160 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
1162 cost += cl->component->Cost;
1164 return cost;
1167 UINT MSI_GetFeatureCost( MSIPACKAGE *package, MSIFEATURE *feature, MSICOSTTREE tree,
1168 INSTALLSTATE state, LPINT cost )
1170 TRACE("%s, %u, %d, %p\n", debugstr_w(feature->Feature), tree, state, cost);
1172 *cost = 0;
1173 switch (tree)
1175 case MSICOSTTREE_CHILDREN:
1177 MSIFEATURE *child;
1179 LIST_FOR_EACH_ENTRY( child, &feature->Children, MSIFEATURE, entry )
1181 if (child->ActionRequest == state)
1182 *cost += feature_cost( child );
1184 break;
1186 case MSICOSTTREE_PARENTS:
1188 const WCHAR *feature_parent = feature->Feature_Parent;
1189 for (;;)
1191 MSIFEATURE *parent = msi_get_loaded_feature( package, feature_parent );
1192 if (!parent)
1193 break;
1195 if (parent->ActionRequest == state)
1196 *cost += feature_cost( parent );
1198 feature_parent = parent->Feature_Parent;
1200 break;
1202 case MSICOSTTREE_SELFONLY:
1203 if (feature->ActionRequest == state)
1204 *cost = feature_cost( feature );
1205 break;
1207 default:
1208 WARN("unhandled cost tree %u\n", tree);
1209 break;
1212 *cost /= 512;
1213 return ERROR_SUCCESS;
1216 /***********************************************************************
1217 * MsiGetFeatureCostW (MSI.@)
1219 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
1220 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
1222 MSIPACKAGE *package;
1223 MSIFEATURE *feature;
1224 UINT ret;
1226 TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature),
1227 iCostTree, iState, piCost);
1229 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1230 if (!package)
1232 MSIHANDLE remote;
1233 HRESULT hr;
1234 BSTR feature;
1236 if (!(remote = msi_get_remote(hInstall)))
1237 return ERROR_INVALID_HANDLE;
1239 feature = SysAllocString(szFeature);
1240 if (!feature)
1241 return ERROR_OUTOFMEMORY;
1243 hr = remote_GetFeatureCost(remote, feature, iCostTree, iState, piCost);
1245 SysFreeString(feature);
1247 if (FAILED(hr))
1249 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1250 return HRESULT_CODE(hr);
1252 return ERROR_FUNCTION_FAILED;
1255 return ERROR_SUCCESS;
1258 feature = msi_get_loaded_feature(package, szFeature);
1260 if (feature)
1261 ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost);
1262 else
1263 ret = ERROR_UNKNOWN_FEATURE;
1265 msiobj_release( &package->hdr );
1266 return ret;
1269 /***********************************************************************
1270 * MsiGetFeatureInfoA (MSI.@)
1272 UINT WINAPI MsiGetFeatureInfoA( MSIHANDLE handle, LPCSTR feature, LPDWORD attrs,
1273 LPSTR title, LPDWORD title_len, LPSTR help, LPDWORD help_len )
1275 UINT r;
1276 WCHAR *titleW = NULL, *helpW = NULL, *featureW = NULL;
1278 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_a(feature), attrs, title,
1279 title_len, help, help_len);
1281 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;
1283 if (title && title_len && !(titleW = msi_alloc( *title_len * sizeof(WCHAR) )))
1285 msi_free( featureW );
1286 return ERROR_OUTOFMEMORY;
1288 if (help && help_len && !(helpW = msi_alloc( *help_len * sizeof(WCHAR) )))
1290 msi_free( featureW );
1291 msi_free( titleW );
1292 return ERROR_OUTOFMEMORY;
1294 r = MsiGetFeatureInfoW( handle, featureW, attrs, titleW, title_len, helpW, help_len );
1295 if (r == ERROR_SUCCESS)
1297 if (titleW) WideCharToMultiByte( CP_ACP, 0, titleW, -1, title, *title_len + 1, NULL, NULL );
1298 if (helpW) WideCharToMultiByte( CP_ACP, 0, helpW, -1, help, *help_len + 1, NULL, NULL );
1300 msi_free( titleW );
1301 msi_free( helpW );
1302 msi_free( featureW );
1303 return r;
1306 static DWORD map_feature_attributes( DWORD attrs )
1308 DWORD ret = 0;
1310 if (attrs == msidbFeatureAttributesFavorLocal) ret |= INSTALLFEATUREATTRIBUTE_FAVORLOCAL;
1311 if (attrs & msidbFeatureAttributesFavorSource) ret |= INSTALLFEATUREATTRIBUTE_FAVORSOURCE;
1312 if (attrs & msidbFeatureAttributesFollowParent) ret |= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT;
1313 if (attrs & msidbFeatureAttributesFavorAdvertise) ret |= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE;
1314 if (attrs & msidbFeatureAttributesDisallowAdvertise) ret |= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE;
1315 if (attrs & msidbFeatureAttributesNoUnsupportedAdvertise) ret |= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE;
1316 return ret;
1319 static UINT MSI_GetFeatureInfo( MSIPACKAGE *package, LPCWSTR name, LPDWORD attrs,
1320 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
1322 UINT r = ERROR_SUCCESS;
1323 MSIFEATURE *feature = msi_get_loaded_feature( package, name );
1324 int len;
1326 if (!feature) return ERROR_UNKNOWN_FEATURE;
1327 if (attrs) *attrs = map_feature_attributes( feature->Attributes );
1328 if (title_len)
1330 if (feature->Title) len = strlenW( feature->Title );
1331 else len = 0;
1332 if (*title_len <= len)
1334 *title_len = len;
1335 if (title) r = ERROR_MORE_DATA;
1337 else if (title)
1339 if (feature->Title) strcpyW( title, feature->Title );
1340 else *title = 0;
1341 *title_len = len;
1344 if (help_len)
1346 if (feature->Description) len = strlenW( feature->Description );
1347 else len = 0;
1348 if (*help_len <= len)
1350 *help_len = len;
1351 if (help) r = ERROR_MORE_DATA;
1353 else if (help)
1355 if (feature->Description) strcpyW( help, feature->Description );
1356 else *help = 0;
1357 *help_len = len;
1360 return r;
1363 /***********************************************************************
1364 * MsiGetFeatureInfoW (MSI.@)
1366 UINT WINAPI MsiGetFeatureInfoW( MSIHANDLE handle, LPCWSTR feature, LPDWORD attrs,
1367 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
1369 UINT r;
1370 MSIPACKAGE *package;
1372 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_w(feature), attrs, title,
1373 title_len, help, help_len);
1375 if (!feature) return ERROR_INVALID_PARAMETER;
1377 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
1378 return ERROR_INVALID_HANDLE;
1380 /* features may not have been loaded yet */
1381 msi_load_all_components( package );
1382 msi_load_all_features( package );
1384 r = MSI_GetFeatureInfo( package, feature, attrs, title, title_len, help, help_len );
1385 msiobj_release( &package->hdr );
1386 return r;
1389 /***********************************************************************
1390 * MsiSetComponentStateA (MSI.@)
1392 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
1393 INSTALLSTATE iState)
1395 UINT rc;
1396 LPWSTR szwComponent = strdupAtoW(szComponent);
1398 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
1400 msi_free(szwComponent);
1402 return rc;
1405 /***********************************************************************
1406 * MsiGetComponentStateA (MSI.@)
1408 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
1409 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1411 LPWSTR szwComponent= NULL;
1412 UINT rc;
1414 szwComponent= strdupAtoW(szComponent);
1416 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
1418 msi_free( szwComponent);
1420 return rc;
1423 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
1424 INSTALLSTATE iState)
1426 MSICOMPONENT *comp;
1428 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
1430 comp = msi_get_loaded_component(package, szComponent);
1431 if (!comp)
1432 return ERROR_UNKNOWN_COMPONENT;
1434 if (comp->Enabled)
1435 comp->Action = iState;
1437 return ERROR_SUCCESS;
1440 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
1441 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1443 MSICOMPONENT *comp;
1445 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
1446 piInstalled, piAction);
1448 comp = msi_get_loaded_component(package,szComponent);
1449 if (!comp)
1450 return ERROR_UNKNOWN_COMPONENT;
1452 if (piInstalled)
1454 if (comp->Enabled)
1455 *piInstalled = comp->Installed;
1456 else
1457 *piInstalled = INSTALLSTATE_UNKNOWN;
1460 if (piAction)
1462 if (comp->Enabled)
1463 *piAction = comp->Action;
1464 else
1465 *piAction = INSTALLSTATE_UNKNOWN;
1468 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
1469 return ERROR_SUCCESS;
1472 /***********************************************************************
1473 * MsiSetComponentStateW (MSI.@)
1475 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
1476 INSTALLSTATE iState)
1478 MSIPACKAGE* package;
1479 UINT ret;
1481 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1482 if (!package)
1484 MSIHANDLE remote;
1485 HRESULT hr;
1486 BSTR component;
1488 if (!(remote = msi_get_remote(hInstall)))
1489 return ERROR_INVALID_HANDLE;
1491 component = SysAllocString(szComponent);
1492 if (!component)
1493 return ERROR_OUTOFMEMORY;
1495 hr = remote_SetComponentState(remote, component, iState);
1497 SysFreeString(component);
1499 if (FAILED(hr))
1501 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1502 return HRESULT_CODE(hr);
1504 return ERROR_FUNCTION_FAILED;
1507 return ERROR_SUCCESS;
1510 ret = MSI_SetComponentStateW(package, szComponent, iState);
1511 msiobj_release(&package->hdr);
1512 return ret;
1515 /***********************************************************************
1516 * MsiGetComponentStateW (MSI.@)
1518 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
1519 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1521 MSIPACKAGE* package;
1522 UINT ret;
1524 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szComponent),
1525 piInstalled, piAction);
1527 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1528 if (!package)
1530 MSIHANDLE remote;
1531 HRESULT hr;
1532 BSTR component;
1534 if (!(remote = msi_get_remote(hInstall)))
1535 return ERROR_INVALID_HANDLE;
1537 component = SysAllocString(szComponent);
1538 if (!component)
1539 return ERROR_OUTOFMEMORY;
1541 hr = remote_GetComponentState(remote, component, piInstalled, piAction);
1543 SysFreeString(component);
1545 if (FAILED(hr))
1547 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1548 return HRESULT_CODE(hr);
1550 return ERROR_FUNCTION_FAILED;
1553 return ERROR_SUCCESS;
1556 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
1557 msiobj_release( &package->hdr );
1558 return ret;
1561 /***********************************************************************
1562 * MsiGetLanguage (MSI.@)
1564 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
1566 MSIPACKAGE* package;
1567 LANGID langid;
1569 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1570 if (!package)
1572 MSIHANDLE remote;
1573 HRESULT hr;
1574 LANGID lang;
1576 if (!(remote = msi_get_remote(hInstall)))
1577 return ERROR_INVALID_HANDLE;
1579 hr = remote_GetLanguage(remote, &lang);
1581 if (SUCCEEDED(hr))
1582 return lang;
1584 return 0;
1587 langid = msi_get_property_int( package->db, szProductLanguage, 0 );
1588 msiobj_release( &package->hdr );
1589 return langid;
1592 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
1594 static const WCHAR fmt[] = { '%','d',0 };
1595 WCHAR level[6];
1596 int len;
1597 UINT r;
1599 TRACE("%p %i\n", package, iInstallLevel);
1601 if (iInstallLevel > 32767)
1602 return ERROR_INVALID_PARAMETER;
1604 if (iInstallLevel < 1)
1605 return MSI_SetFeatureStates( package );
1607 len = sprintfW( level, fmt, iInstallLevel );
1608 r = msi_set_property( package->db, szInstallLevel, level, len );
1609 if ( r == ERROR_SUCCESS )
1610 r = MSI_SetFeatureStates( package );
1612 return r;
1615 /***********************************************************************
1616 * MsiSetInstallLevel (MSI.@)
1618 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
1620 MSIPACKAGE* package;
1621 UINT r;
1623 TRACE("%d %i\n", hInstall, iInstallLevel);
1625 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1626 if (!package)
1628 MSIHANDLE remote;
1629 HRESULT hr;
1631 if (!(remote = msi_get_remote(hInstall)))
1632 return ERROR_INVALID_HANDLE;
1634 hr = remote_SetInstallLevel(remote, iInstallLevel);
1636 if (FAILED(hr))
1638 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1639 return HRESULT_CODE(hr);
1641 return ERROR_FUNCTION_FAILED;
1644 return ERROR_SUCCESS;
1647 r = MSI_SetInstallLevel( package, iInstallLevel );
1649 msiobj_release( &package->hdr );
1651 return r;
1654 /***********************************************************************
1655 * MsiGetFeatureValidStatesW (MSI.@)
1657 UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature,
1658 LPDWORD pInstallState)
1660 if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL;
1661 FIXME("%d %s %p stub returning %d\n",
1662 hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0);
1664 return ERROR_SUCCESS;
1667 /***********************************************************************
1668 * MsiGetFeatureValidStatesA (MSI.@)
1670 UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature,
1671 LPDWORD pInstallState)
1673 UINT ret;
1674 LPWSTR szwFeature = strdupAtoW(szFeature);
1676 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);
1678 msi_free(szwFeature);
1680 return ret;