regedit: Remove dead code.
[wine/hacks.git] / dlls / msi / install.c
blobf80f68a5f0852d402c1a0d153caca83b4389c377
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 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "wine/debug.h"
29 #include "msi.h"
30 #include "msidefs.h"
31 #include "msipriv.h"
32 #include "action.h"
33 #include "wine/unicode.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msi);
37 /***********************************************************************
38 * MsiDoActionA (MSI.@)
40 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
42 LPWSTR szwAction;
43 UINT ret;
45 TRACE("%s\n", debugstr_a(szAction));
47 szwAction = strdupAtoW(szAction);
48 if (szAction && !szwAction)
49 return ERROR_FUNCTION_FAILED;
51 ret = MsiDoActionW( hInstall, szwAction );
52 msi_free( szwAction );
53 return ret;
56 /***********************************************************************
57 * MsiDoActionW (MSI.@)
59 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
61 MSIPACKAGE *package;
62 UINT ret;
64 TRACE("%s\n",debugstr_w(szAction));
66 if (!szAction)
67 return ERROR_INVALID_PARAMETER;
69 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
70 if (!package)
71 return ERROR_INVALID_HANDLE;
73 ret = ACTION_PerformUIAction( package, szAction );
74 msiobj_release( &package->hdr );
76 return ret;
79 /***********************************************************************
80 * MsiSequenceA (MSI.@)
82 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
84 LPWSTR szwTable;
85 UINT ret;
87 TRACE("%s\n", debugstr_a(szTable));
89 szwTable = strdupAtoW(szTable);
90 if (szTable && !szwTable)
91 return ERROR_FUNCTION_FAILED;
93 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
94 msi_free( szwTable );
95 return ret;
98 /***********************************************************************
99 * MsiSequenceW (MSI.@)
101 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
103 MSIPACKAGE *package;
104 UINT ret;
106 TRACE("%s\n", debugstr_w(szTable));
108 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
109 if (!package)
110 return ERROR_INVALID_HANDLE;
112 ret = MSI_Sequence( package, szTable, iSequenceMode );
113 msiobj_release( &package->hdr );
115 return ret;
118 UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
120 UINT len, r = ERROR_SUCCESS;
122 if (awbuf->str.w && !sz )
123 return ERROR_INVALID_PARAMETER;
125 if (!sz)
126 return r;
128 if (awbuf->unicode)
130 len = lstrlenW( str );
131 if (awbuf->str.w)
132 lstrcpynW( awbuf->str.w, str, *sz );
134 else
136 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
137 if (len)
138 len--;
139 WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL );
140 if ( *sz && (len >= *sz) )
141 awbuf->str.a[*sz - 1] = 0;
144 if (awbuf->str.w && len >= *sz)
145 r = ERROR_MORE_DATA;
146 *sz = len;
147 return r;
150 /***********************************************************************
151 * MsiGetTargetPath (internal)
153 UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
154 awstring *szPathBuf, DWORD* pcchPathBuf )
156 MSIPACKAGE *package;
157 LPWSTR path;
158 UINT r;
160 if (!szFolder)
161 return ERROR_INVALID_PARAMETER;
163 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
164 if (!package)
165 return ERROR_INVALID_HANDLE;
167 path = resolve_folder( package, szFolder, FALSE, FALSE, NULL );
168 msiobj_release( &package->hdr );
170 if (!path)
171 return ERROR_DIRECTORY;
173 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
174 msi_free( path );
175 return r;
178 /***********************************************************************
179 * MsiGetTargetPathA (MSI.@)
181 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
182 LPSTR szPathBuf, DWORD* pcchPathBuf )
184 LPWSTR szwFolder;
185 awstring path;
186 UINT r;
188 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
190 szwFolder = strdupAtoW(szFolder);
191 if (szFolder && !szwFolder)
192 return ERROR_FUNCTION_FAILED;
194 path.unicode = FALSE;
195 path.str.a = szPathBuf;
197 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
199 msi_free( szwFolder );
201 return r;
204 /***********************************************************************
205 * MsiGetTargetPathW (MSI.@)
207 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
208 LPWSTR szPathBuf, DWORD* pcchPathBuf )
210 awstring path;
212 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
214 path.unicode = TRUE;
215 path.str.w = szPathBuf;
217 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
220 /***********************************************************************
221 * MsiGetSourcePath (internal)
223 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
224 awstring *szPathBuf, DWORD* pcchPathBuf )
226 MSIPACKAGE *package;
227 LPWSTR path;
228 UINT r;
230 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
232 if (!szFolder)
233 return ERROR_INVALID_PARAMETER;
235 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
236 if (!package)
237 return ERROR_INVALID_HANDLE;
239 if (szPathBuf->str.w && !pcchPathBuf )
241 msiobj_release( &package->hdr );
242 return ERROR_INVALID_PARAMETER;
245 path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
246 msiobj_release( &package->hdr );
248 TRACE("path = %s\n",debugstr_w(path));
249 if (!path)
250 return ERROR_DIRECTORY;
252 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
253 msi_free( path );
254 return r;
257 /***********************************************************************
258 * MsiGetSourcePathA (MSI.@)
260 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
261 LPSTR szPathBuf, DWORD* pcchPathBuf )
263 LPWSTR folder;
264 awstring str;
265 UINT r;
267 TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
269 str.unicode = FALSE;
270 str.str.a = szPathBuf;
272 folder = strdupAtoW( szFolder );
273 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
274 msi_free( folder );
276 return r;
279 /***********************************************************************
280 * MsiGetSourcePathW (MSI.@)
282 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
283 LPWSTR szPathBuf, DWORD* pcchPathBuf )
285 awstring str;
287 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
289 str.unicode = TRUE;
290 str.str.w = szPathBuf;
292 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
295 /***********************************************************************
296 * MsiSetTargetPathA (MSI.@)
298 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
299 LPCSTR szFolderPath )
301 LPWSTR szwFolder = NULL, szwFolderPath = NULL;
302 UINT rc = ERROR_OUTOFMEMORY;
304 if ( !szFolder || !szFolderPath )
305 return ERROR_INVALID_PARAMETER;
307 szwFolder = strdupAtoW(szFolder);
308 szwFolderPath = strdupAtoW(szFolderPath);
309 if (!szwFolder || !szwFolderPath)
310 goto end;
312 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
314 end:
315 msi_free(szwFolder);
316 msi_free(szwFolderPath);
318 return rc;
322 * Ok my original interpretation of this was wrong. And it looks like msdn has
323 * changed a bit also. The given folder path does not have to actually already
324 * exist, it just cannot be read only and must be a legal folder path.
326 UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
327 LPCWSTR szFolderPath)
329 DWORD attrib;
330 LPWSTR path = NULL;
331 LPWSTR path2 = NULL;
332 MSIFOLDER *folder;
333 MSIFILE *file;
335 TRACE("%p %s %s\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
337 attrib = GetFileAttributesW(szFolderPath);
338 /* native MSI tests writeability by making temporary files at each drive */
339 if ( attrib != INVALID_FILE_ATTRIBUTES &&
340 (attrib & FILE_ATTRIBUTE_OFFLINE ||
341 attrib & FILE_ATTRIBUTE_READONLY))
342 return ERROR_FUNCTION_FAILED;
344 path = resolve_folder(package,szFolder,FALSE,FALSE,&folder);
345 if (!path)
346 return ERROR_DIRECTORY;
348 msi_free(folder->Property);
349 folder->Property = build_directory_name(2, szFolderPath, NULL);
351 if (lstrcmpiW(path, folder->Property) == 0)
354 * Resolved Target has not really changed, so just
355 * set this folder and do not recalculate everything.
357 msi_free(folder->ResolvedTarget);
358 folder->ResolvedTarget = NULL;
359 path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);
360 msi_free(path2);
362 else
364 MSIFOLDER *f;
366 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
368 msi_free(f->ResolvedTarget);
369 f->ResolvedTarget=NULL;
372 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
374 path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL);
375 msi_free(path2);
378 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
380 MSICOMPONENT *comp = file->Component;
381 LPWSTR p;
383 if (!comp)
384 continue;
386 p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
387 msi_free(file->TargetPath);
389 file->TargetPath = build_directory_name(2, p, file->FileName);
390 msi_free(p);
393 msi_free(path);
395 return ERROR_SUCCESS;
398 /***********************************************************************
399 * MsiSetTargetPathW (MSI.@)
401 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
402 LPCWSTR szFolderPath)
404 MSIPACKAGE *package;
405 UINT ret;
407 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
409 if ( !szFolder || !szFolderPath )
410 return ERROR_INVALID_PARAMETER;
412 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
413 if (!package)
414 return ERROR_INVALID_HANDLE;
416 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
417 msiobj_release( &package->hdr );
418 return ret;
421 /***********************************************************************
422 * MsiGetMode (MSI.@)
424 * Returns an internal installer state (if it is running in a mode iRunMode)
426 * PARAMS
427 * hInstall [I] Handle to the installation
428 * hRunMode [I] Checking run mode
429 * MSIRUNMODE_ADMIN Administrative mode
430 * MSIRUNMODE_ADVERTISE Advertisement mode
431 * MSIRUNMODE_MAINTENANCE Maintenance mode
432 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
433 * MSIRUNMODE_LOGENABLED Log file is writing
434 * MSIRUNMODE_OPERATIONS Operations in progress??
435 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
436 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
437 * MSIRUNMODE_CABINET Files from cabinet are installed
438 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
439 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
440 * MSIRUNMODE_RESERVED11 Reserved
441 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
442 * MSIRUNMODE_ZAWENABLED Demand installation is supported
443 * MSIRUNMODE_RESERVED14 Reserved
444 * MSIRUNMODE_RESERVED15 Reserved
445 * MSIRUNMODE_SCHEDULED called from install script
446 * MSIRUNMODE_ROLLBACK called from rollback script
447 * MSIRUNMODE_COMMIT called from commit script
449 * RETURNS
450 * In the state: TRUE
451 * Not in the state: FALSE
454 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
456 BOOL r = FALSE;
458 switch (iRunMode)
460 case MSIRUNMODE_WINDOWS9X:
461 if (GetVersion() & 0x80000000)
462 r = TRUE;
463 break;
465 case MSIRUNMODE_RESERVED11:
466 case MSIRUNMODE_RESERVED14:
467 case MSIRUNMODE_RESERVED15:
468 break;
470 case MSIRUNMODE_SCHEDULED:
471 case MSIRUNMODE_ROLLBACK:
472 case MSIRUNMODE_COMMIT:
473 break;
475 default:
476 FIXME("%ld %d\n", hInstall, iRunMode);
477 r = TRUE;
480 return r;
483 /***********************************************************************
484 * MsiSetMode (MSI.@)
486 BOOL WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
488 switch (iRunMode)
490 case MSIRUNMODE_RESERVED11:
491 case MSIRUNMODE_WINDOWS9X:
492 case MSIRUNMODE_RESERVED14:
493 case MSIRUNMODE_RESERVED15:
494 return FALSE;
495 default:
496 FIXME("%ld %d %d\n", hInstall, iRunMode, fState);
498 return TRUE;
501 /***********************************************************************
502 * MsiSetFeatureStateA (MSI.@)
504 * According to the docs, when this is called it immediately recalculates
505 * all the component states as well
507 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
508 INSTALLSTATE iState)
510 LPWSTR szwFeature = NULL;
511 UINT rc;
513 szwFeature = strdupAtoW(szFeature);
515 if (!szwFeature)
516 return ERROR_FUNCTION_FAILED;
518 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
520 msi_free(szwFeature);
522 return rc;
527 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
528 INSTALLSTATE iState)
530 UINT rc = ERROR_SUCCESS;
531 MSIFEATURE *feature, *child;
533 TRACE("%s %i\n", debugstr_w(szFeature), iState);
535 feature = get_loaded_feature(package,szFeature);
536 if (!feature)
537 return ERROR_UNKNOWN_FEATURE;
539 if (iState == INSTALLSTATE_ADVERTISED &&
540 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
541 return ERROR_FUNCTION_FAILED;
543 feature->ActionRequest = iState;
544 feature->Action = iState;
546 ACTION_UpdateComponentStates(package,szFeature);
548 /* update all the features that are children of this feature */
549 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
551 if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
552 MSI_SetFeatureStateW(package, child->Feature, iState);
555 return rc;
558 /***********************************************************************
559 * MsiSetFeatureStateW (MSI.@)
561 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
562 INSTALLSTATE iState)
564 MSIPACKAGE* package;
565 UINT rc = ERROR_SUCCESS;
567 TRACE("%s %i\n",debugstr_w(szFeature), iState);
569 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
570 if (!package)
571 return ERROR_INVALID_HANDLE;
573 rc = MSI_SetFeatureStateW(package,szFeature,iState);
575 msiobj_release( &package->hdr );
576 return rc;
579 /***********************************************************************
580 * MsiGetFeatureStateA (MSI.@)
582 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
583 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
585 LPWSTR szwFeature = NULL;
586 UINT rc;
588 szwFeature = strdupAtoW(szFeature);
590 rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
592 msi_free( szwFeature);
594 return rc;
597 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
598 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
600 MSIFEATURE *feature;
602 feature = get_loaded_feature(package,szFeature);
603 if (!feature)
604 return ERROR_UNKNOWN_FEATURE;
606 if (piInstalled)
607 *piInstalled = feature->Installed;
609 if (piAction)
610 *piAction = feature->Action;
612 TRACE("returning %i %i\n", feature->Installed, feature->Action);
614 return ERROR_SUCCESS;
617 /***********************************************************************
618 * MsiGetFeatureStateW (MSI.@)
620 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
621 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
623 MSIPACKAGE* package;
624 UINT ret;
626 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
628 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
629 if (!package)
630 return ERROR_INVALID_HANDLE;
631 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
632 msiobj_release( &package->hdr );
633 return ret;
636 /***********************************************************************
637 * MsiGetFeatureCostA (MSI.@)
639 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
640 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
642 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature),
643 iCostTree, iState, piCost);
644 if (piCost) *piCost = 0;
645 return ERROR_SUCCESS;
648 /***********************************************************************
649 * MsiGetFeatureCostW (MSI.@)
651 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
652 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
654 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
655 iCostTree, iState, piCost);
656 if (piCost) *piCost = 0;
657 return ERROR_SUCCESS;
660 /***********************************************************************
661 * MsiSetComponentStateA (MSI.@)
663 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
664 INSTALLSTATE iState)
666 UINT rc;
667 LPWSTR szwComponent = strdupAtoW(szComponent);
669 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
671 msi_free(szwComponent);
673 return rc;
676 /***********************************************************************
677 * MsiGetComponentStateA (MSI.@)
679 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
680 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
682 LPWSTR szwComponent= NULL;
683 UINT rc;
685 szwComponent= strdupAtoW(szComponent);
687 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
689 msi_free( szwComponent);
691 return rc;
694 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
695 INSTALLSTATE iState)
697 MSICOMPONENT *comp;
699 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
701 comp = get_loaded_component(package, szComponent);
702 if (!comp)
703 return ERROR_UNKNOWN_COMPONENT;
705 comp->Installed = iState;
707 return ERROR_SUCCESS;
710 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
711 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
713 MSICOMPONENT *comp;
715 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
716 piInstalled, piAction);
718 comp = get_loaded_component(package,szComponent);
719 if (!comp)
720 return ERROR_UNKNOWN_COMPONENT;
722 if (piInstalled)
723 *piInstalled = comp->Installed;
725 if (piAction)
726 *piAction = comp->Action;
728 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
730 return ERROR_SUCCESS;
733 /***********************************************************************
734 * MsiSetComponentStateW (MSI.@)
736 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
737 INSTALLSTATE iState)
739 MSIPACKAGE* package;
740 UINT ret;
742 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
743 if (!package)
744 return ERROR_INVALID_HANDLE;
745 ret = MSI_SetComponentStateW(package, szComponent, iState);
746 msiobj_release(&package->hdr);
747 return ret;
750 /***********************************************************************
751 * MsiGetComponentStateW (MSI.@)
753 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
754 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
756 MSIPACKAGE* package;
757 UINT ret;
759 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
760 piInstalled, piAction);
762 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
763 if (!package)
764 return ERROR_INVALID_HANDLE;
765 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
766 msiobj_release( &package->hdr );
767 return ret;
770 /***********************************************************************
771 * MsiGetLanguage (MSI.@)
773 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
775 MSIPACKAGE* package;
776 LANGID langid;
777 static const WCHAR szProductLanguage[] =
778 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
780 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
781 if (!package)
782 return ERROR_INVALID_HANDLE;
784 langid = msi_get_property_int( package, szProductLanguage, 0 );
785 msiobj_release( &package->hdr );
786 return langid;
789 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
791 static const WCHAR szInstallLevel[] = {
792 'I','N','S','T','A','L','L','L','E','V','E','L',0 };
793 static const WCHAR fmt[] = { '%','d',0 };
794 WCHAR level[6];
795 UINT r;
797 TRACE("%p %i\n", package, iInstallLevel);
799 if (iInstallLevel<1 || iInstallLevel>32767)
800 return ERROR_INVALID_PARAMETER;
802 sprintfW( level, fmt, iInstallLevel );
803 r = MSI_SetPropertyW( package, szInstallLevel, level );
804 if ( r == ERROR_SUCCESS )
806 r = MSI_SetFeatureStates( package );
809 return r;
812 /***********************************************************************
813 * MsiSetInstallLevel (MSI.@)
815 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
817 MSIPACKAGE* package;
818 UINT r;
820 TRACE("%ld %i\n", hInstall, iInstallLevel);
822 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
823 if ( !package )
824 return ERROR_INVALID_HANDLE;
826 r = MSI_SetInstallLevel( package, iInstallLevel );
828 msiobj_release( &package->hdr );
830 return r;