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 */
28 #include "wine/debug.h"
33 #include "wine/unicode.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
37 /***********************************************************************
38 * MsiDoActionA (MSI.@)
40 UINT WINAPI
MsiDoActionA( MSIHANDLE hInstall
, LPCSTR szAction
)
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
);
56 /***********************************************************************
57 * MsiDoActionW (MSI.@)
59 UINT WINAPI
MsiDoActionW( MSIHANDLE hInstall
, LPCWSTR szAction
)
64 TRACE("%s\n",debugstr_w(szAction
));
67 return ERROR_INVALID_PARAMETER
;
69 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
71 return ERROR_INVALID_HANDLE
;
73 ret
= ACTION_PerformUIAction( package
, szAction
);
74 msiobj_release( &package
->hdr
);
79 /***********************************************************************
80 * MsiSequenceA (MSI.@)
82 UINT WINAPI
MsiSequenceA( MSIHANDLE hInstall
, LPCSTR szTable
, INT iSequenceMode
)
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
);
98 /***********************************************************************
99 * MsiSequenceW (MSI.@)
101 UINT WINAPI
MsiSequenceW( MSIHANDLE hInstall
, LPCWSTR szTable
, INT iSequenceMode
)
106 TRACE("%s\n", debugstr_w(szTable
));
108 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
110 return ERROR_INVALID_HANDLE
;
112 ret
= MSI_Sequence( package
, szTable
, iSequenceMode
);
113 msiobj_release( &package
->hdr
);
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
;
130 len
= lstrlenW( str
);
132 lstrcpynW( awbuf
->str
.w
, str
, *sz
);
136 len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1, NULL
, 0, NULL
, NULL
);
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
)
150 /***********************************************************************
151 * MsiGetTargetPath (internal)
153 UINT WINAPI
MSI_GetTargetPath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
154 awstring
*szPathBuf
, DWORD
* pcchPathBuf
)
161 return ERROR_INVALID_PARAMETER
;
163 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
165 return ERROR_INVALID_HANDLE
;
167 path
= resolve_folder( package
, szFolder
, FALSE
, FALSE
, NULL
);
168 msiobj_release( &package
->hdr
);
171 return ERROR_DIRECTORY
;
173 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
178 /***********************************************************************
179 * MsiGetTargetPathA (MSI.@)
181 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
182 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
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
);
204 /***********************************************************************
205 * MsiGetTargetPathW (MSI.@)
207 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
208 LPWSTR szPathBuf
, DWORD
* pcchPathBuf
)
212 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
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
)
230 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
233 return ERROR_INVALID_PARAMETER
;
235 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_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
));
250 return ERROR_DIRECTORY
;
252 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
257 /***********************************************************************
258 * MsiGetSourcePathA (MSI.@)
260 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
261 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
267 TRACE("%s %p %p\n", szFolder
, debugstr_a(szPathBuf
), pcchPathBuf
);
270 str
.str
.a
= szPathBuf
;
272 folder
= strdupAtoW( szFolder
);
273 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
279 /***********************************************************************
280 * MsiGetSourcePathW (MSI.@)
282 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
283 LPWSTR szPathBuf
, DWORD
* pcchPathBuf
)
287 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
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
)
312 rc
= MsiSetTargetPathW( hInstall
, szwFolder
, szwFolderPath
);
316 msi_free(szwFolderPath
);
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
)
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
);
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
);
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
);
378 LIST_FOR_EACH_ENTRY( file
, &package
->files
, MSIFILE
, entry
)
380 MSICOMPONENT
*comp
= file
->Component
;
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
);
395 return ERROR_SUCCESS
;
398 /***********************************************************************
399 * MsiSetTargetPathW (MSI.@)
401 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
402 LPCWSTR szFolderPath
)
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
);
414 return ERROR_INVALID_HANDLE
;
416 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
417 msiobj_release( &package
->hdr
);
421 /***********************************************************************
424 * Returns an internal installer state (if it is running in a mode iRunMode)
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
451 * Not in the state: FALSE
454 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
460 case MSIRUNMODE_WINDOWS9X
:
461 if (GetVersion() & 0x80000000)
465 case MSIRUNMODE_RESERVED11
:
466 case MSIRUNMODE_RESERVED14
:
467 case MSIRUNMODE_RESERVED15
:
470 case MSIRUNMODE_SCHEDULED
:
471 case MSIRUNMODE_ROLLBACK
:
472 case MSIRUNMODE_COMMIT
:
476 FIXME("%ld %d\n", hInstall
, iRunMode
);
483 /***********************************************************************
486 BOOL WINAPI
MsiSetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
, BOOL fState
)
490 case MSIRUNMODE_RESERVED11
:
491 case MSIRUNMODE_WINDOWS9X
:
492 case MSIRUNMODE_RESERVED14
:
493 case MSIRUNMODE_RESERVED15
:
496 FIXME("%ld %d %d\n", hInstall
, iRunMode
, fState
);
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
,
510 LPWSTR szwFeature
= NULL
;
513 szwFeature
= strdupAtoW(szFeature
);
516 return ERROR_FUNCTION_FAILED
;
518 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
520 msi_free(szwFeature
);
527 UINT WINAPI
MSI_SetFeatureStateW(MSIPACKAGE
* package
, LPCWSTR szFeature
,
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
);
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
);
558 /***********************************************************************
559 * MsiSetFeatureStateW (MSI.@)
561 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
565 UINT rc
= ERROR_SUCCESS
;
567 TRACE("%s %i\n",debugstr_w(szFeature
), iState
);
569 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
571 return ERROR_INVALID_HANDLE
;
573 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
575 msiobj_release( &package
->hdr
);
579 /***********************************************************************
580 * MsiGetFeatureStateA (MSI.@)
582 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
583 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
585 LPWSTR szwFeature
= NULL
;
588 szwFeature
= strdupAtoW(szFeature
);
590 rc
= MsiGetFeatureStateW(hInstall
,szwFeature
,piInstalled
, piAction
);
592 msi_free( szwFeature
);
597 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPCWSTR szFeature
,
598 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
602 feature
= get_loaded_feature(package
,szFeature
);
604 return ERROR_UNKNOWN_FEATURE
;
607 *piInstalled
= feature
->Installed
;
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
)
626 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
, piAction
);
628 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
630 return ERROR_INVALID_HANDLE
;
631 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
632 msiobj_release( &package
->hdr
);
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
,
667 LPWSTR szwComponent
= strdupAtoW(szComponent
);
669 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
671 msi_free(szwComponent
);
676 /***********************************************************************
677 * MsiGetComponentStateA (MSI.@)
679 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
680 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
682 LPWSTR szwComponent
= NULL
;
685 szwComponent
= strdupAtoW(szComponent
);
687 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
689 msi_free( szwComponent
);
694 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
699 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
701 comp
= get_loaded_component(package
, szComponent
);
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
)
715 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
716 piInstalled
, piAction
);
718 comp
= get_loaded_component(package
,szComponent
);
720 return ERROR_UNKNOWN_COMPONENT
;
723 *piInstalled
= comp
->Installed
;
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
,
742 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
744 return ERROR_INVALID_HANDLE
;
745 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
746 msiobj_release(&package
->hdr
);
750 /***********************************************************************
751 * MsiGetComponentStateW (MSI.@)
753 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
754 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
759 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szComponent
),
760 piInstalled
, piAction
);
762 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
764 return ERROR_INVALID_HANDLE
;
765 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
766 msiobj_release( &package
->hdr
);
770 /***********************************************************************
771 * MsiGetLanguage (MSI.@)
773 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
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
);
782 return ERROR_INVALID_HANDLE
;
784 langid
= msi_get_property_int( package
, szProductLanguage
, 0 );
785 msiobj_release( &package
->hdr
);
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 };
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
);
812 /***********************************************************************
813 * MsiSetInstallLevel (MSI.@)
815 UINT WINAPI
MsiSetInstallLevel(MSIHANDLE hInstall
, int iInstallLevel
)
820 TRACE("%ld %i\n", hInstall
, iInstallLevel
);
822 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
824 return ERROR_INVALID_HANDLE
;
826 r
= MSI_SetInstallLevel( package
, iInstallLevel
);
828 msiobj_release( &package
->hdr
);