include: Move the DDE_xxx macros to dde.rh.
[wine/multimedia.git] / dlls / msi / install.c
blob285d7c94655aabc2ed8cbf4f7d6f1914a956e9b9
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 "msiserver.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msi);
42 /***********************************************************************
43 * MsiDoActionA (MSI.@)
45 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
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 HRESULT hr;
78 BSTR action;
79 IWineMsiRemotePackage *remote_package;
81 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
82 if (!remote_package)
83 return ERROR_INVALID_HANDLE;
85 action = SysAllocString( szAction );
86 if (!action)
88 IWineMsiRemotePackage_Release( remote_package );
89 return ERROR_OUTOFMEMORY;
92 hr = IWineMsiRemotePackage_DoAction( remote_package, action );
94 SysFreeString( action );
95 IWineMsiRemotePackage_Release( remote_package );
97 if (FAILED(hr))
99 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
100 return HRESULT_CODE(hr);
102 return ERROR_FUNCTION_FAILED;
105 return ERROR_SUCCESS;
108 ret = ACTION_PerformUIAction( package, szAction, -1 );
109 msiobj_release( &package->hdr );
111 return ret;
114 /***********************************************************************
115 * MsiSequenceA (MSI.@)
117 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
119 LPWSTR szwTable;
120 UINT ret;
122 TRACE("%s, %d\n", debugstr_a(szTable), iSequenceMode);
124 szwTable = strdupAtoW(szTable);
125 if (szTable && !szwTable)
126 return ERROR_FUNCTION_FAILED;
128 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
129 msi_free( szwTable );
130 return ret;
133 /***********************************************************************
134 * MsiSequenceW (MSI.@)
136 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
138 MSIPACKAGE *package;
139 UINT ret;
141 TRACE("%s, %d\n", debugstr_w(szTable), iSequenceMode);
143 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
144 if (!package)
146 HRESULT hr;
147 BSTR table;
148 IWineMsiRemotePackage *remote_package;
150 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
151 if (!remote_package)
152 return ERROR_INVALID_HANDLE;
154 table = SysAllocString( szTable );
155 if (!table)
157 IWineMsiRemotePackage_Release( remote_package );
158 return ERROR_OUTOFMEMORY;
161 hr = IWineMsiRemotePackage_Sequence( remote_package, table, iSequenceMode );
163 SysFreeString( table );
164 IWineMsiRemotePackage_Release( remote_package );
166 if (FAILED(hr))
168 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
169 return HRESULT_CODE(hr);
171 return ERROR_FUNCTION_FAILED;
174 return ERROR_SUCCESS;
176 ret = MSI_Sequence( package, szTable );
177 msiobj_release( &package->hdr );
178 return ret;
181 UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
183 UINT len, r = ERROR_SUCCESS;
185 if (awbuf->str.w && !sz )
186 return ERROR_INVALID_PARAMETER;
188 if (!sz)
189 return r;
191 if (awbuf->unicode)
193 len = lstrlenW( str );
194 if (awbuf->str.w)
195 lstrcpynW( awbuf->str.w, str, *sz );
197 else
199 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
200 if (len)
201 len--;
202 WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL );
203 if ( awbuf->str.a && *sz && (len >= *sz) )
204 awbuf->str.a[*sz - 1] = 0;
207 if (awbuf->str.w && len >= *sz)
208 r = ERROR_MORE_DATA;
209 *sz = len;
210 return r;
213 const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name )
215 MSIFOLDER *folder = msi_get_loaded_folder( package, name );
216 if (folder) return folder->ResolvedTarget;
217 return NULL;
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 HRESULT hr;
237 IWineMsiRemotePackage *remote_package;
238 LPWSTR value = NULL;
239 BSTR folder;
240 DWORD len;
242 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
243 if (!remote_package)
244 return ERROR_INVALID_HANDLE;
246 folder = SysAllocString( szFolder );
247 if (!folder)
249 IWineMsiRemotePackage_Release( remote_package );
250 return ERROR_OUTOFMEMORY;
253 len = 0;
254 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, NULL, &len );
255 if (FAILED(hr))
256 goto done;
258 len++;
259 value = msi_alloc(len * sizeof(WCHAR));
260 if (!value)
262 r = ERROR_OUTOFMEMORY;
263 goto done;
266 hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder, value, &len );
267 if (FAILED(hr))
268 goto done;
270 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
272 done:
273 IWineMsiRemotePackage_Release( remote_package );
274 SysFreeString( folder );
275 msi_free( value );
277 if (FAILED(hr))
279 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
280 return HRESULT_CODE(hr);
282 return ERROR_FUNCTION_FAILED;
285 return r;
288 path = msi_get_target_folder( package, szFolder );
289 msiobj_release( &package->hdr );
291 if (!path)
292 return ERROR_DIRECTORY;
294 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
295 return r;
298 /***********************************************************************
299 * MsiGetTargetPathA (MSI.@)
301 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
302 LPSTR szPathBuf, LPDWORD pcchPathBuf )
304 LPWSTR szwFolder;
305 awstring path;
306 UINT r;
308 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
310 szwFolder = strdupAtoW(szFolder);
311 if (szFolder && !szwFolder)
312 return ERROR_FUNCTION_FAILED;
314 path.unicode = FALSE;
315 path.str.a = szPathBuf;
317 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
319 msi_free( szwFolder );
321 return r;
324 /***********************************************************************
325 * MsiGetTargetPathW (MSI.@)
327 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
328 LPWSTR szPathBuf, LPDWORD pcchPathBuf )
330 awstring path;
332 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
334 path.unicode = TRUE;
335 path.str.w = szPathBuf;
337 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
340 static WCHAR *get_source_root( MSIDATABASE *db )
342 WCHAR *path, *p;
344 if ((path = msi_dup_property( db, szSourceDir ))) return path;
345 if ((path = msi_dup_property( db, szDatabase )))
347 if ((p = strrchrW( path, '\\' ))) p[1] = 0;
349 return path;
352 WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder )
354 MSIFOLDER *f;
355 LPWSTR p, path = NULL, parent;
357 TRACE("working to resolve %s\n", debugstr_w(name));
359 if (!strcmpW( name, szSourceDir )) name = szTargetDir;
360 if (!(f = msi_get_loaded_folder( package, name ))) return NULL;
362 /* special resolving for root dir */
363 if (!strcmpW( name, szTargetDir ) && !f->ResolvedSource)
365 f->ResolvedSource = get_source_root( package->db );
367 if (folder) *folder = f;
368 if (f->ResolvedSource)
370 path = strdupW( f->ResolvedSource );
371 TRACE(" already resolved to %s\n", debugstr_w(path));
372 return path;
374 if (!f->Parent) return path;
375 parent = f->Parent;
376 TRACE(" ! parent is %s\n", debugstr_w(parent));
378 p = msi_resolve_source_folder( package, parent, NULL );
380 if (package->WordCount & msidbSumInfoSourceTypeCompressed)
381 path = get_source_root( package->db );
382 else if (package->WordCount & msidbSumInfoSourceTypeSFN)
383 path = msi_build_directory_name( 3, p, f->SourceShortPath, NULL );
384 else
385 path = msi_build_directory_name( 3, p, f->SourceLongPath, NULL );
387 TRACE("-> %s\n", debugstr_w(path));
388 f->ResolvedSource = strdupW( path );
389 msi_free( p );
391 return path;
394 /***********************************************************************
395 * MSI_GetSourcePath (internal)
397 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
398 awstring *szPathBuf, LPDWORD pcchPathBuf )
400 MSIPACKAGE *package;
401 LPWSTR path;
402 UINT r = ERROR_FUNCTION_FAILED;
404 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
406 if (!szFolder)
407 return ERROR_INVALID_PARAMETER;
409 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
410 if (!package)
412 HRESULT hr;
413 IWineMsiRemotePackage *remote_package;
414 LPWSTR value = NULL;
415 BSTR folder;
416 DWORD len;
418 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
419 if (!remote_package)
420 return ERROR_INVALID_HANDLE;
422 folder = SysAllocString( szFolder );
423 if (!folder)
425 IWineMsiRemotePackage_Release( remote_package );
426 return ERROR_OUTOFMEMORY;
429 len = 0;
430 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, NULL, &len );
431 if (FAILED(hr))
432 goto done;
434 len++;
435 value = msi_alloc(len * sizeof(WCHAR));
436 if (!value)
438 r = ERROR_OUTOFMEMORY;
439 goto done;
442 hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder, value, &len );
443 if (FAILED(hr))
444 goto done;
446 r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
448 done:
449 IWineMsiRemotePackage_Release( remote_package );
450 SysFreeString( folder );
451 msi_free( value );
453 if (FAILED(hr))
455 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
456 return HRESULT_CODE(hr);
458 return ERROR_FUNCTION_FAILED;
461 return r;
464 if (szPathBuf->str.w && !pcchPathBuf )
466 msiobj_release( &package->hdr );
467 return ERROR_INVALID_PARAMETER;
470 path = msi_resolve_source_folder( package, szFolder, NULL );
471 msiobj_release( &package->hdr );
473 TRACE("path = %s\n", debugstr_w(path));
474 if (!path)
475 return ERROR_DIRECTORY;
477 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
478 msi_free( path );
479 return r;
482 /***********************************************************************
483 * MsiGetSourcePathA (MSI.@)
485 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
486 LPSTR szPathBuf, LPDWORD pcchPathBuf )
488 LPWSTR folder;
489 awstring str;
490 UINT r;
492 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
494 str.unicode = FALSE;
495 str.str.a = szPathBuf;
497 folder = strdupAtoW( szFolder );
498 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
499 msi_free( folder );
501 return r;
504 /***********************************************************************
505 * MsiGetSourcePathW (MSI.@)
507 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
508 LPWSTR szPathBuf, LPDWORD pcchPathBuf )
510 awstring str;
512 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
514 str.unicode = TRUE;
515 str.str.w = szPathBuf;
517 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
520 /***********************************************************************
521 * MsiSetTargetPathA (MSI.@)
523 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
524 LPCSTR szFolderPath )
526 LPWSTR szwFolder = NULL, szwFolderPath = NULL;
527 UINT rc = ERROR_OUTOFMEMORY;
529 if ( !szFolder || !szFolderPath )
530 return ERROR_INVALID_PARAMETER;
532 szwFolder = strdupAtoW(szFolder);
533 szwFolderPath = strdupAtoW(szFolderPath);
534 if (!szwFolder || !szwFolderPath)
535 goto end;
537 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
539 end:
540 msi_free(szwFolder);
541 msi_free(szwFolderPath);
543 return rc;
546 static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR *path )
548 FolderList *fl;
549 MSIFOLDER *child;
550 WCHAR *target_path;
552 if (!(target_path = strdupW( path ))) return;
553 msi_clean_path( target_path );
554 if (strcmpW( target_path, folder->ResolvedTarget ))
556 msi_free( folder->ResolvedTarget );
557 folder->ResolvedTarget = target_path;
558 msi_set_property( package->db, folder->Directory, folder->ResolvedTarget );
560 LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry )
562 child = fl->folder;
563 msi_resolve_target_folder( package, child->Directory, FALSE );
566 else msi_free( target_path );
569 UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath )
571 DWORD attrib, len;
572 MSIFOLDER *folder;
573 MSIFILE *file;
575 TRACE("%p %s %s\n", package, debugstr_w(szFolder), debugstr_w(szFolderPath));
577 attrib = GetFileAttributesW(szFolderPath);
578 /* native MSI tests writeability by making temporary files at each drive */
579 if (attrib != INVALID_FILE_ATTRIBUTES &&
580 (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY))
582 return ERROR_FUNCTION_FAILED;
584 if (!(folder = msi_get_loaded_folder( package, szFolder ))) return ERROR_DIRECTORY;
586 len = strlenW( szFolderPath );
587 if (len && szFolderPath[len - 1] != '\\')
589 WCHAR *path = msi_alloc( (len + 2) * sizeof(WCHAR) );
590 memcpy( path, szFolderPath, len * sizeof(WCHAR) );
591 path[len] = '\\';
592 path[len + 1] = 0;
593 set_target_path( package, folder, path );
594 msi_free( path );
596 else set_target_path( package, folder, szFolderPath );
598 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
600 const WCHAR *dir;
601 MSICOMPONENT *comp = file->Component;
603 if (!comp->Enabled || (comp->assembly && !comp->assembly->application)) continue;
605 dir = msi_get_target_folder( package, comp->Directory );
606 msi_free( file->TargetPath );
607 file->TargetPath = msi_build_directory_name( 2, dir, file->FileName );
609 return ERROR_SUCCESS;
612 /***********************************************************************
613 * MsiSetTargetPathW (MSI.@)
615 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
616 LPCWSTR szFolderPath)
618 MSIPACKAGE *package;
619 UINT ret;
621 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
623 if ( !szFolder || !szFolderPath )
624 return ERROR_INVALID_PARAMETER;
626 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
627 if (!package)
629 HRESULT hr;
630 BSTR folder, path;
631 IWineMsiRemotePackage *remote_package;
633 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
634 if (!remote_package)
635 return ERROR_INVALID_HANDLE;
637 folder = SysAllocString( szFolder );
638 path = SysAllocString( szFolderPath );
639 if (!folder || !path)
641 SysFreeString(folder);
642 SysFreeString(path);
643 IWineMsiRemotePackage_Release( remote_package );
644 return ERROR_OUTOFMEMORY;
647 hr = IWineMsiRemotePackage_SetTargetPath( remote_package, folder, path );
649 SysFreeString(folder);
650 SysFreeString(path);
651 IWineMsiRemotePackage_Release( remote_package );
653 if (FAILED(hr))
655 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
656 return HRESULT_CODE(hr);
658 return ERROR_FUNCTION_FAILED;
661 return ERROR_SUCCESS;
664 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
665 msiobj_release( &package->hdr );
666 return ret;
669 /***********************************************************************
670 * MsiGetMode (MSI.@)
672 * Returns an internal installer state (if it is running in a mode iRunMode)
674 * PARAMS
675 * hInstall [I] Handle to the installation
676 * hRunMode [I] Checking run mode
677 * MSIRUNMODE_ADMIN Administrative mode
678 * MSIRUNMODE_ADVERTISE Advertisement mode
679 * MSIRUNMODE_MAINTENANCE Maintenance mode
680 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
681 * MSIRUNMODE_LOGENABLED Log file is writing
682 * MSIRUNMODE_OPERATIONS Operations in progress??
683 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
684 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
685 * MSIRUNMODE_CABINET Files from cabinet are installed
686 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
687 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
688 * MSIRUNMODE_RESERVED11 Reserved
689 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
690 * MSIRUNMODE_ZAWENABLED Demand installation is supported
691 * MSIRUNMODE_RESERVED14 Reserved
692 * MSIRUNMODE_RESERVED15 Reserved
693 * MSIRUNMODE_SCHEDULED called from install script
694 * MSIRUNMODE_ROLLBACK called from rollback script
695 * MSIRUNMODE_COMMIT called from commit script
697 * RETURNS
698 * In the state: TRUE
699 * Not in the state: FALSE
702 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
704 MSIPACKAGE *package;
705 BOOL r = FALSE;
707 TRACE("%d %d\n", hInstall, iRunMode);
709 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
710 if (!package)
712 BOOL ret;
713 HRESULT hr;
714 IWineMsiRemotePackage *remote_package;
716 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
717 if (!remote_package)
718 return FALSE;
720 hr = IWineMsiRemotePackage_GetMode(remote_package, iRunMode, &ret);
721 IWineMsiRemotePackage_Release(remote_package);
723 if (hr == S_OK)
724 return ret;
726 return FALSE;
729 switch (iRunMode)
731 case MSIRUNMODE_ADMIN:
732 FIXME("no support for administrative installs\n");
733 break;
735 case MSIRUNMODE_ADVERTISE:
736 FIXME("no support for advertised installs\n");
737 break;
739 case MSIRUNMODE_WINDOWS9X:
740 if (GetVersion() & 0x80000000)
741 r = TRUE;
742 break;
744 case MSIRUNMODE_OPERATIONS:
745 case MSIRUNMODE_RESERVED11:
746 case MSIRUNMODE_RESERVED14:
747 case MSIRUNMODE_RESERVED15:
748 break;
750 case MSIRUNMODE_SCHEDULED:
751 r = package->scheduled_action_running;
752 break;
754 case MSIRUNMODE_ROLLBACK:
755 r = package->rollback_action_running;
756 break;
758 case MSIRUNMODE_COMMIT:
759 r = package->commit_action_running;
760 break;
762 case MSIRUNMODE_MAINTENANCE:
763 r = msi_get_property_int( package->db, szInstalled, 0 ) != 0;
764 break;
766 case MSIRUNMODE_ROLLBACKENABLED:
767 r = msi_get_property_int( package->db, szRollbackDisabled, 0 ) == 0;
768 break;
770 case MSIRUNMODE_REBOOTATEND:
771 r = package->need_reboot;
772 break;
774 case MSIRUNMODE_LOGENABLED:
775 r = (package->log_file != INVALID_HANDLE_VALUE);
776 break;
778 default:
779 FIXME("unimplemented run mode: %d\n", iRunMode);
780 r = TRUE;
783 msiobj_release( &package->hdr );
784 return r;
787 /***********************************************************************
788 * MsiSetMode (MSI.@)
790 UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
792 MSIPACKAGE *package;
793 UINT r;
795 TRACE("%d %d %d\n", hInstall, iRunMode, fState);
797 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
798 if (!package)
800 HRESULT hr;
801 IWineMsiRemotePackage *remote_package;
803 remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
804 if (!remote_package)
805 return FALSE;
807 hr = IWineMsiRemotePackage_SetMode( remote_package, iRunMode, fState );
808 IWineMsiRemotePackage_Release( remote_package );
810 if (FAILED(hr))
812 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
813 return HRESULT_CODE(hr);
815 return ERROR_FUNCTION_FAILED;
818 return ERROR_SUCCESS;
821 switch (iRunMode)
823 case MSIRUNMODE_REBOOTATEND:
824 package->need_reboot = 1;
825 r = ERROR_SUCCESS;
826 break;
828 case MSIRUNMODE_REBOOTNOW:
829 FIXME("unimplemented run mode: %d\n", iRunMode);
830 r = ERROR_FUNCTION_FAILED;
831 break;
833 default:
834 r = ERROR_ACCESS_DENIED;
837 msiobj_release( &package->hdr );
838 return r;
841 /***********************************************************************
842 * MsiSetFeatureStateA (MSI.@)
844 * According to the docs, when this is called it immediately recalculates
845 * all the component states as well
847 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
848 INSTALLSTATE iState)
850 LPWSTR szwFeature = NULL;
851 UINT rc;
853 szwFeature = strdupAtoW(szFeature);
855 if (!szwFeature)
856 return ERROR_FUNCTION_FAILED;
858 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
860 msi_free(szwFeature);
862 return rc;
865 /* update component state based on a feature change */
866 void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
868 INSTALLSTATE newstate;
869 ComponentList *cl;
871 newstate = feature->ActionRequest;
872 if (newstate == INSTALLSTATE_ABSENT) newstate = INSTALLSTATE_UNKNOWN;
874 LIST_FOR_EACH_ENTRY(cl, &feature->Components, ComponentList, entry)
876 MSICOMPONENT *component = cl->component;
878 if (!component->Enabled) continue;
880 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
881 newstate, debugstr_w(component->Component), component->Installed,
882 component->Action, component->ActionRequest);
884 if (newstate == INSTALLSTATE_LOCAL)
886 component->Action = INSTALLSTATE_LOCAL;
887 component->ActionRequest = INSTALLSTATE_LOCAL;
889 else
891 ComponentList *clist;
892 MSIFEATURE *f;
894 component->hasLocalFeature = FALSE;
896 component->Action = newstate;
897 component->ActionRequest = newstate;
898 /* if any other feature wants it local we need to set it local */
899 LIST_FOR_EACH_ENTRY(f, &package->features, MSIFEATURE, entry)
901 if ( f->ActionRequest != INSTALLSTATE_LOCAL &&
902 f->ActionRequest != INSTALLSTATE_SOURCE )
904 continue;
906 LIST_FOR_EACH_ENTRY(clist, &f->Components, ComponentList, entry)
908 if (clist->component == component &&
909 (f->ActionRequest == INSTALLSTATE_LOCAL ||
910 f->ActionRequest == INSTALLSTATE_SOURCE))
912 TRACE("Saved by %s\n", debugstr_w(f->Feature));
913 component->hasLocalFeature = TRUE;
915 if (component->Attributes & msidbComponentAttributesOptional)
917 if (f->Attributes & msidbFeatureAttributesFavorSource)
919 component->Action = INSTALLSTATE_SOURCE;
920 component->ActionRequest = INSTALLSTATE_SOURCE;
922 else
924 component->Action = INSTALLSTATE_LOCAL;
925 component->ActionRequest = INSTALLSTATE_LOCAL;
928 else if (component->Attributes & msidbComponentAttributesSourceOnly)
930 component->Action = INSTALLSTATE_SOURCE;
931 component->ActionRequest = INSTALLSTATE_SOURCE;
933 else
935 component->Action = INSTALLSTATE_LOCAL;
936 component->ActionRequest = INSTALLSTATE_LOCAL;
942 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
943 newstate, debugstr_w(component->Component), component->Installed,
944 component->Action, component->ActionRequest);
948 UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE iState )
950 UINT rc = ERROR_SUCCESS;
951 MSIFEATURE *feature, *child;
953 TRACE("%s %i\n", debugstr_w(szFeature), iState);
955 feature = msi_get_loaded_feature( package, szFeature );
956 if (!feature)
957 return ERROR_UNKNOWN_FEATURE;
959 if (iState == INSTALLSTATE_ADVERTISED &&
960 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
961 return ERROR_FUNCTION_FAILED;
963 feature->ActionRequest = iState;
965 ACTION_UpdateComponentStates( package, feature );
967 /* update all the features that are children of this feature */
968 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
970 if (child->Feature_Parent && !strcmpW( szFeature, child->Feature_Parent ))
971 MSI_SetFeatureStateW(package, child->Feature, iState);
974 return rc;
977 /***********************************************************************
978 * MsiSetFeatureStateW (MSI.@)
980 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
981 INSTALLSTATE iState)
983 MSIPACKAGE* package;
984 UINT rc = ERROR_SUCCESS;
986 TRACE("%s %i\n",debugstr_w(szFeature), iState);
988 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
989 if (!package)
991 HRESULT hr;
992 BSTR feature;
993 IWineMsiRemotePackage *remote_package;
995 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
996 if (!remote_package)
997 return ERROR_INVALID_HANDLE;
999 feature = SysAllocString(szFeature);
1000 if (!feature)
1002 IWineMsiRemotePackage_Release(remote_package);
1003 return ERROR_OUTOFMEMORY;
1006 hr = IWineMsiRemotePackage_SetFeatureState(remote_package, feature, iState);
1008 SysFreeString(feature);
1009 IWineMsiRemotePackage_Release(remote_package);
1011 if (FAILED(hr))
1013 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1014 return HRESULT_CODE(hr);
1016 return ERROR_FUNCTION_FAILED;
1019 return ERROR_SUCCESS;
1022 rc = MSI_SetFeatureStateW(package,szFeature,iState);
1024 msiobj_release( &package->hdr );
1025 return rc;
1028 /***********************************************************************
1029 * MsiSetFeatureAttributesA (MSI.@)
1031 UINT WINAPI MsiSetFeatureAttributesA( MSIHANDLE handle, LPCSTR feature, DWORD attrs )
1033 UINT r;
1034 WCHAR *featureW = NULL;
1036 TRACE("%u, %s, 0x%08x\n", handle, debugstr_a(feature), attrs);
1038 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;
1040 r = MsiSetFeatureAttributesW( handle, featureW, attrs );
1041 msi_free( featureW );
1042 return r;
1045 static DWORD unmap_feature_attributes( DWORD attrs )
1047 DWORD ret = 0;
1049 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORLOCAL) ret = msidbFeatureAttributesFavorLocal;
1050 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORSOURCE) ret |= msidbFeatureAttributesFavorSource;
1051 if (attrs & INSTALLFEATUREATTRIBUTE_FOLLOWPARENT) ret |= msidbFeatureAttributesFollowParent;
1052 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORADVERTISE) ret |= msidbFeatureAttributesFavorAdvertise;
1053 if (attrs & INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE) ret |= msidbFeatureAttributesDisallowAdvertise;
1054 if (attrs & INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE) ret |= msidbFeatureAttributesNoUnsupportedAdvertise;
1055 return ret;
1058 /***********************************************************************
1059 * MsiSetFeatureAttributesW (MSI.@)
1061 UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attrs )
1063 MSIPACKAGE *package;
1064 MSIFEATURE *feature;
1065 WCHAR *costing;
1067 TRACE("%u, %s, 0x%08x\n", handle, debugstr_w(name), attrs);
1069 if (!name || !name[0]) return ERROR_UNKNOWN_FEATURE;
1071 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
1072 return ERROR_INVALID_HANDLE;
1074 costing = msi_dup_property( package->db, szCostingComplete );
1075 if (!costing || !strcmpW( costing, szOne ))
1077 msi_free( costing );
1078 msiobj_release( &package->hdr );
1079 return ERROR_FUNCTION_FAILED;
1081 msi_free( costing );
1082 if (!(feature = msi_get_loaded_feature( package, name )))
1084 msiobj_release( &package->hdr );
1085 return ERROR_UNKNOWN_FEATURE;
1087 feature->Attributes = unmap_feature_attributes( attrs );
1088 msiobj_release( &package->hdr );
1089 return ERROR_SUCCESS;
1092 /***********************************************************************
1093 * MsiGetFeatureStateA (MSI.@)
1095 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
1096 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1098 LPWSTR szwFeature = NULL;
1099 UINT rc;
1101 if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY;
1103 rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction);
1104 msi_free( szwFeature);
1105 return rc;
1108 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
1109 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1111 MSIFEATURE *feature;
1113 feature = msi_get_loaded_feature(package,szFeature);
1114 if (!feature)
1115 return ERROR_UNKNOWN_FEATURE;
1117 if (piInstalled)
1118 *piInstalled = feature->Installed;
1120 if (piAction)
1121 *piAction = feature->ActionRequest;
1123 TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest);
1125 return ERROR_SUCCESS;
1128 /***********************************************************************
1129 * MsiGetFeatureStateW (MSI.@)
1131 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
1132 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1134 MSIPACKAGE* package;
1135 UINT ret;
1137 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
1139 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1140 if (!package)
1142 HRESULT hr;
1143 BSTR feature;
1144 IWineMsiRemotePackage *remote_package;
1146 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
1147 if (!remote_package)
1148 return ERROR_INVALID_HANDLE;
1150 feature = SysAllocString(szFeature);
1151 if (!feature)
1153 IWineMsiRemotePackage_Release(remote_package);
1154 return ERROR_OUTOFMEMORY;
1157 hr = IWineMsiRemotePackage_GetFeatureState(remote_package, feature,
1158 piInstalled, piAction);
1160 SysFreeString(feature);
1161 IWineMsiRemotePackage_Release(remote_package);
1163 if (FAILED(hr))
1165 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1166 return HRESULT_CODE(hr);
1168 return ERROR_FUNCTION_FAILED;
1171 return ERROR_SUCCESS;
1174 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
1175 msiobj_release( &package->hdr );
1176 return ret;
1179 /***********************************************************************
1180 * MsiGetFeatureCostA (MSI.@)
1182 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
1183 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
1185 LPWSTR szwFeature = NULL;
1186 UINT rc;
1188 szwFeature = strdupAtoW(szFeature);
1190 rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost);
1192 msi_free(szwFeature);
1194 return rc;
1197 static INT feature_cost( MSIFEATURE *feature )
1199 INT cost = 0;
1200 MSICOMPONENT *comp;
1202 LIST_FOR_EACH_ENTRY( comp, &feature->Components, MSICOMPONENT, entry )
1204 cost += comp->Cost;
1206 return cost;
1209 UINT MSI_GetFeatureCost( MSIPACKAGE *package, MSIFEATURE *feature, MSICOSTTREE tree,
1210 INSTALLSTATE state, LPINT cost )
1212 TRACE("%s, %u, %d, %p\n", debugstr_w(feature->Feature), tree, state, cost);
1214 *cost = 0;
1215 switch (tree)
1217 case MSICOSTTREE_CHILDREN:
1219 MSIFEATURE *child;
1221 LIST_FOR_EACH_ENTRY( child, &feature->Children, MSIFEATURE, entry )
1223 if (child->ActionRequest == state)
1224 *cost += feature_cost( child );
1226 break;
1228 case MSICOSTTREE_PARENTS:
1230 const WCHAR *feature_parent = feature->Feature_Parent;
1231 for (;;)
1233 MSIFEATURE *parent = msi_get_loaded_feature( package, feature_parent );
1234 if (!parent)
1235 break;
1237 if (parent->ActionRequest == state)
1238 *cost += feature_cost( parent );
1240 feature_parent = parent->Feature_Parent;
1242 break;
1244 case MSICOSTTREE_SELFONLY:
1245 if (feature->ActionRequest == state)
1246 *cost = feature_cost( feature );
1247 break;
1249 default:
1250 WARN("unhandled cost tree %u\n", tree);
1251 break;
1254 *cost /= 512;
1255 return ERROR_SUCCESS;
1258 /***********************************************************************
1259 * MsiGetFeatureCostW (MSI.@)
1261 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
1262 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
1264 MSIPACKAGE *package;
1265 MSIFEATURE *feature;
1266 UINT ret;
1268 TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature),
1269 iCostTree, iState, piCost);
1271 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1272 if (!package)
1274 HRESULT hr;
1275 BSTR feature;
1276 IWineMsiRemotePackage *remote_package;
1278 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
1279 if (!remote_package)
1280 return ERROR_INVALID_HANDLE;
1282 feature = SysAllocString(szFeature);
1283 if (!feature)
1285 IWineMsiRemotePackage_Release(remote_package);
1286 return ERROR_OUTOFMEMORY;
1289 hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature,
1290 iCostTree, iState, piCost);
1292 SysFreeString(feature);
1293 IWineMsiRemotePackage_Release(remote_package);
1295 if (FAILED(hr))
1297 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1298 return HRESULT_CODE(hr);
1300 return ERROR_FUNCTION_FAILED;
1303 return ERROR_SUCCESS;
1306 feature = msi_get_loaded_feature(package, szFeature);
1308 if (feature)
1309 ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost);
1310 else
1311 ret = ERROR_UNKNOWN_FEATURE;
1313 msiobj_release( &package->hdr );
1314 return ret;
1317 /***********************************************************************
1318 * MsiGetFeatureInfoA (MSI.@)
1320 UINT WINAPI MsiGetFeatureInfoA( MSIHANDLE handle, LPCSTR feature, LPDWORD attrs,
1321 LPSTR title, LPDWORD title_len, LPSTR help, LPDWORD help_len )
1323 UINT r;
1324 WCHAR *titleW = NULL, *helpW = NULL, *featureW = NULL;
1326 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_a(feature), attrs, title,
1327 title_len, help, help_len);
1329 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;
1331 if (title && title_len && !(titleW = msi_alloc( *title_len * sizeof(WCHAR) )))
1333 msi_free( featureW );
1334 return ERROR_OUTOFMEMORY;
1336 if (help && help_len && !(helpW = msi_alloc( *help_len * sizeof(WCHAR) )))
1338 msi_free( featureW );
1339 msi_free( titleW );
1340 return ERROR_OUTOFMEMORY;
1342 r = MsiGetFeatureInfoW( handle, featureW, attrs, titleW, title_len, helpW, help_len );
1343 if (r == ERROR_SUCCESS)
1345 if (titleW) WideCharToMultiByte( CP_ACP, 0, titleW, -1, title, *title_len + 1, NULL, NULL );
1346 if (helpW) WideCharToMultiByte( CP_ACP, 0, helpW, -1, help, *help_len + 1, NULL, NULL );
1348 msi_free( titleW );
1349 msi_free( helpW );
1350 msi_free( featureW );
1351 return r;
1354 static DWORD map_feature_attributes( DWORD attrs )
1356 DWORD ret = 0;
1358 if (attrs == msidbFeatureAttributesFavorLocal) ret |= INSTALLFEATUREATTRIBUTE_FAVORLOCAL;
1359 if (attrs & msidbFeatureAttributesFavorSource) ret |= INSTALLFEATUREATTRIBUTE_FAVORSOURCE;
1360 if (attrs & msidbFeatureAttributesFollowParent) ret |= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT;
1361 if (attrs & msidbFeatureAttributesFavorAdvertise) ret |= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE;
1362 if (attrs & msidbFeatureAttributesDisallowAdvertise) ret |= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE;
1363 if (attrs & msidbFeatureAttributesNoUnsupportedAdvertise) ret |= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE;
1364 return ret;
1367 static UINT MSI_GetFeatureInfo( MSIPACKAGE *package, LPCWSTR name, LPDWORD attrs,
1368 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
1370 UINT r = ERROR_SUCCESS;
1371 MSIFEATURE *feature = msi_get_loaded_feature( package, name );
1372 int len;
1374 if (!feature) return ERROR_UNKNOWN_FEATURE;
1375 if (attrs) *attrs = map_feature_attributes( feature->Attributes );
1376 if (title_len)
1378 if (feature->Title) len = strlenW( feature->Title );
1379 else len = 0;
1380 if (*title_len <= len)
1382 *title_len = len;
1383 if (title) r = ERROR_MORE_DATA;
1385 else if (title)
1387 if (feature->Title) strcpyW( title, feature->Title );
1388 else *title = 0;
1389 *title_len = len;
1392 if (help_len)
1394 if (feature->Description) len = strlenW( feature->Description );
1395 else len = 0;
1396 if (*help_len <= len)
1398 *help_len = len;
1399 if (help) r = ERROR_MORE_DATA;
1401 else if (help)
1403 if (feature->Description) strcpyW( help, feature->Description );
1404 else *help = 0;
1405 *help_len = len;
1408 return r;
1411 /***********************************************************************
1412 * MsiGetFeatureInfoW (MSI.@)
1414 UINT WINAPI MsiGetFeatureInfoW( MSIHANDLE handle, LPCWSTR feature, LPDWORD attrs,
1415 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
1417 UINT r;
1418 MSIPACKAGE *package;
1420 TRACE("%u, %s, %p, %p, %p, %p, %p\n", handle, debugstr_w(feature), attrs, title,
1421 title_len, help, help_len);
1423 if (!feature) return ERROR_INVALID_PARAMETER;
1425 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
1426 return ERROR_INVALID_HANDLE;
1428 /* features may not have been loaded yet */
1429 msi_load_all_components( package );
1430 msi_load_all_features( package );
1432 r = MSI_GetFeatureInfo( package, feature, attrs, title, title_len, help, help_len );
1433 msiobj_release( &package->hdr );
1434 return r;
1437 /***********************************************************************
1438 * MsiSetComponentStateA (MSI.@)
1440 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
1441 INSTALLSTATE iState)
1443 UINT rc;
1444 LPWSTR szwComponent = strdupAtoW(szComponent);
1446 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
1448 msi_free(szwComponent);
1450 return rc;
1453 /***********************************************************************
1454 * MsiGetComponentStateA (MSI.@)
1456 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
1457 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1459 LPWSTR szwComponent= NULL;
1460 UINT rc;
1462 szwComponent= strdupAtoW(szComponent);
1464 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
1466 msi_free( szwComponent);
1468 return rc;
1471 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
1472 INSTALLSTATE iState)
1474 MSICOMPONENT *comp;
1476 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
1478 comp = msi_get_loaded_component(package, szComponent);
1479 if (!comp)
1480 return ERROR_UNKNOWN_COMPONENT;
1482 if (comp->Enabled)
1483 comp->Action = iState;
1485 return ERROR_SUCCESS;
1488 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
1489 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1491 MSICOMPONENT *comp;
1493 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
1494 piInstalled, piAction);
1496 comp = msi_get_loaded_component(package,szComponent);
1497 if (!comp)
1498 return ERROR_UNKNOWN_COMPONENT;
1500 if (piInstalled)
1502 if (comp->Enabled)
1503 *piInstalled = comp->Installed;
1504 else
1505 *piInstalled = INSTALLSTATE_UNKNOWN;
1508 if (piAction)
1510 if (comp->Enabled)
1511 *piAction = comp->Action;
1512 else
1513 *piAction = INSTALLSTATE_UNKNOWN;
1516 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
1517 return ERROR_SUCCESS;
1520 /***********************************************************************
1521 * MsiSetComponentStateW (MSI.@)
1523 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
1524 INSTALLSTATE iState)
1526 MSIPACKAGE* package;
1527 UINT ret;
1529 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1530 if (!package)
1532 HRESULT hr;
1533 BSTR component;
1534 IWineMsiRemotePackage *remote_package;
1536 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
1537 if (!remote_package)
1538 return ERROR_INVALID_HANDLE;
1540 component = SysAllocString(szComponent);
1541 if (!component)
1543 IWineMsiRemotePackage_Release(remote_package);
1544 return ERROR_OUTOFMEMORY;
1547 hr = IWineMsiRemotePackage_SetComponentState(remote_package, component, iState);
1549 SysFreeString(component);
1550 IWineMsiRemotePackage_Release(remote_package);
1552 if (FAILED(hr))
1554 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1555 return HRESULT_CODE(hr);
1557 return ERROR_FUNCTION_FAILED;
1560 return ERROR_SUCCESS;
1563 ret = MSI_SetComponentStateW(package, szComponent, iState);
1564 msiobj_release(&package->hdr);
1565 return ret;
1568 /***********************************************************************
1569 * MsiGetComponentStateW (MSI.@)
1571 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
1572 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1574 MSIPACKAGE* package;
1575 UINT ret;
1577 TRACE("%d %s %p %p\n", hInstall, debugstr_w(szComponent),
1578 piInstalled, piAction);
1580 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1581 if (!package)
1583 HRESULT hr;
1584 BSTR component;
1585 IWineMsiRemotePackage *remote_package;
1587 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
1588 if (!remote_package)
1589 return ERROR_INVALID_HANDLE;
1591 component = SysAllocString(szComponent);
1592 if (!component)
1594 IWineMsiRemotePackage_Release(remote_package);
1595 return ERROR_OUTOFMEMORY;
1598 hr = IWineMsiRemotePackage_GetComponentState(remote_package, component,
1599 piInstalled, piAction);
1601 SysFreeString(component);
1602 IWineMsiRemotePackage_Release(remote_package);
1604 if (FAILED(hr))
1606 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1607 return HRESULT_CODE(hr);
1609 return ERROR_FUNCTION_FAILED;
1612 return ERROR_SUCCESS;
1615 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
1616 msiobj_release( &package->hdr );
1617 return ret;
1620 /***********************************************************************
1621 * MsiGetLanguage (MSI.@)
1623 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
1625 MSIPACKAGE* package;
1626 LANGID langid;
1628 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1629 if (!package)
1631 HRESULT hr;
1632 LANGID lang;
1633 IWineMsiRemotePackage *remote_package;
1635 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
1636 if (!remote_package)
1637 return ERROR_INVALID_HANDLE;
1639 hr = IWineMsiRemotePackage_GetLanguage(remote_package, &lang);
1641 if (SUCCEEDED(hr))
1642 return lang;
1644 return 0;
1647 langid = msi_get_property_int( package->db, szProductLanguage, 0 );
1648 msiobj_release( &package->hdr );
1649 return langid;
1652 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
1654 static const WCHAR fmt[] = { '%','d',0 };
1655 WCHAR level[6];
1656 UINT r;
1658 TRACE("%p %i\n", package, iInstallLevel);
1660 if (iInstallLevel > 32767)
1661 return ERROR_INVALID_PARAMETER;
1663 if (iInstallLevel < 1)
1664 return MSI_SetFeatureStates( package );
1666 sprintfW( level, fmt, iInstallLevel );
1667 r = msi_set_property( package->db, szInstallLevel, level );
1668 if ( r == ERROR_SUCCESS )
1669 r = MSI_SetFeatureStates( package );
1671 return r;
1674 /***********************************************************************
1675 * MsiSetInstallLevel (MSI.@)
1677 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
1679 MSIPACKAGE* package;
1680 UINT r;
1682 TRACE("%d %i\n", hInstall, iInstallLevel);
1684 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1685 if (!package)
1687 HRESULT hr;
1688 IWineMsiRemotePackage *remote_package;
1690 remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
1691 if (!remote_package)
1692 return ERROR_INVALID_HANDLE;
1694 hr = IWineMsiRemotePackage_SetInstallLevel(remote_package, iInstallLevel);
1696 IWineMsiRemotePackage_Release(remote_package);
1698 if (FAILED(hr))
1700 if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
1701 return HRESULT_CODE(hr);
1703 return ERROR_FUNCTION_FAILED;
1706 return ERROR_SUCCESS;
1709 r = MSI_SetInstallLevel( package, iInstallLevel );
1711 msiobj_release( &package->hdr );
1713 return r;
1716 /***********************************************************************
1717 * MsiGetFeatureValidStatesW (MSI.@)
1719 UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature,
1720 LPDWORD pInstallState)
1722 if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL;
1723 FIXME("%d %s %p stub returning %d\n",
1724 hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0);
1726 return ERROR_SUCCESS;
1729 /***********************************************************************
1730 * MsiGetFeatureValidStatesA (MSI.@)
1732 UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature,
1733 LPDWORD pInstallState)
1735 UINT ret;
1736 LPWSTR szwFeature = strdupAtoW(szFeature);
1738 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);
1740 msi_free(szwFeature);
1742 return ret;