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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* Msi top level apis directly related to installs */
28 #include "wine/debug.h"
33 #include "wine/unicode.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
38 /***********************************************************************
39 * MsiDoActionA (MSI.@)
41 UINT WINAPI
MsiDoActionA( MSIHANDLE hInstall
, LPCSTR szAction
)
46 TRACE("%s\n", debugstr_a(szAction
));
48 szwAction
= strdupAtoW(szAction
);
49 if (szAction
&& !szwAction
)
50 return ERROR_FUNCTION_FAILED
;
52 ret
= MsiDoActionW( hInstall
, szwAction
);
53 msi_free( szwAction
);
57 /***********************************************************************
58 * MsiDoActionW (MSI.@)
60 UINT WINAPI
MsiDoActionW( MSIHANDLE hInstall
, LPCWSTR szAction
)
65 TRACE("%s\n",debugstr_w(szAction
));
68 return ERROR_INVALID_PARAMETER
;
70 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
72 return ERROR_INVALID_HANDLE
;
74 ret
= ACTION_PerformUIAction( package
, szAction
);
75 msiobj_release( &package
->hdr
);
80 /***********************************************************************
81 * MsiSequenceA (MSI.@)
83 UINT WINAPI
MsiSequenceA( MSIHANDLE hInstall
, LPCSTR szAction
, INT iSequenceMode
)
85 TRACE("%s\n", debugstr_a(szAction
));
86 return ERROR_CALL_NOT_IMPLEMENTED
;
89 /***********************************************************************
90 * MsiSequenceW (MSI.@)
92 UINT WINAPI
MsiSequenceW( MSIHANDLE hInstall
, LPCWSTR szAction
, INT iSequenceMode
)
94 TRACE("%s\n", debugstr_w(szAction
));
95 return ERROR_CALL_NOT_IMPLEMENTED
;
98 static UINT
msi_strcpy_to_awstring( LPCWSTR str
, awstring
*awbuf
, DWORD
*sz
)
100 UINT len
, r
= ERROR_SUCCESS
;
102 if (awbuf
->str
.w
&& !sz
)
103 return ERROR_INVALID_PARAMETER
;
110 len
= lstrlenW( str
);
112 lstrcpynW( awbuf
->str
.w
, str
, *sz
);
116 len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1,
117 awbuf
->str
.a
, *sz
, NULL
, NULL
);
127 /***********************************************************************
128 * MsiGetTargetPath (internal)
130 UINT WINAPI
MSI_GetTargetPath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
131 awstring
*szPathBuf
, DWORD
* pcchPathBuf
)
138 return ERROR_INVALID_PARAMETER
;
140 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
142 return ERROR_INVALID_HANDLE
;
144 path
= resolve_folder( package
, szFolder
, FALSE
, FALSE
, NULL
);
145 msiobj_release( &package
->hdr
);
148 return ERROR_DIRECTORY
;
150 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
155 /***********************************************************************
156 * MsiGetTargetPathA (MSI.@)
158 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
159 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
165 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
167 szwFolder
= strdupAtoW(szFolder
);
168 if (szFolder
&& !szwFolder
)
169 return ERROR_FUNCTION_FAILED
;
171 path
.unicode
= FALSE
;
172 path
.str
.a
= szPathBuf
;
174 r
= MSI_GetTargetPath( hInstall
, szwFolder
, &path
, pcchPathBuf
);
176 msi_free( szwFolder
);
181 /***********************************************************************
182 * MsiGetTargetPathW (MSI.@)
184 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
185 LPWSTR szPathBuf
, DWORD
* pcchPathBuf
)
189 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
192 path
.str
.w
= szPathBuf
;
194 return MSI_GetTargetPath( hInstall
, szFolder
, &path
, pcchPathBuf
);
197 /***********************************************************************
198 * MsiGetSourcePath (internal)
200 static UINT
MSI_GetSourcePath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
201 awstring
*szPathBuf
, DWORD
* pcchPathBuf
)
207 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
210 return ERROR_INVALID_PARAMETER
;
212 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
214 return ERROR_INVALID_HANDLE
;
216 if (szPathBuf
->str
.w
&& !pcchPathBuf
)
218 msiobj_release( &package
->hdr
);
219 return ERROR_INVALID_PARAMETER
;
222 path
= resolve_folder(package
, szFolder
, TRUE
, FALSE
, NULL
);
223 msiobj_release( &package
->hdr
);
225 TRACE("path = %s\n",debugstr_w(path
));
227 return ERROR_DIRECTORY
;
229 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
234 /***********************************************************************
235 * MsiGetSourcePathA (MSI.@)
237 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
238 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
244 TRACE("%s %p %p\n", szFolder
, debugstr_a(szPathBuf
), pcchPathBuf
);
247 str
.str
.a
= szPathBuf
;
249 folder
= strdupAtoW( szFolder
);
250 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
256 /***********************************************************************
257 * MsiGetSourcePathW (MSI.@)
259 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
260 LPWSTR szPathBuf
, DWORD
* pcchPathBuf
)
264 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
267 str
.str
.w
= szPathBuf
;
269 return MSI_GetSourcePath( hInstall
, szFolder
, &str
, pcchPathBuf
);
272 /***********************************************************************
273 * MsiSetTargetPathA (MSI.@)
275 UINT WINAPI
MsiSetTargetPathA(MSIHANDLE hInstall
, LPCSTR szFolder
,
279 LPWSTR szwFolderPath
;
283 return ERROR_FUNCTION_FAILED
;
285 return ERROR_FUNCTION_FAILED
;
287 szwFolder
= strdupAtoW(szFolder
);
289 return ERROR_FUNCTION_FAILED
;
291 szwFolderPath
= strdupAtoW(szFolderPath
);
295 return ERROR_FUNCTION_FAILED
;
298 rc
= MsiSetTargetPathW(hInstall
, szwFolder
, szwFolderPath
);
301 msi_free(szwFolderPath
);
307 * Ok my original interpretation of this was wrong. And it looks like msdn has
308 * changed a bit also. The given folder path does not have to actually already
309 * exist, it just cannot be read only and must be a legal folder path.
311 UINT
MSI_SetTargetPathW(MSIPACKAGE
*package
, LPCWSTR szFolder
,
312 LPCWSTR szFolderPath
)
319 TRACE("(%p %s %s)\n",package
, debugstr_w(szFolder
),debugstr_w(szFolderPath
));
322 return ERROR_INVALID_HANDLE
;
324 if (szFolderPath
[0]==0)
325 return ERROR_FUNCTION_FAILED
;
327 attrib
= GetFileAttributesW(szFolderPath
);
328 if ( attrib
!= INVALID_FILE_ATTRIBUTES
&&
329 (!(attrib
& FILE_ATTRIBUTE_DIRECTORY
) ||
330 attrib
& FILE_ATTRIBUTE_OFFLINE
||
331 attrib
& FILE_ATTRIBUTE_READONLY
))
332 return ERROR_FUNCTION_FAILED
;
334 path
= resolve_folder(package
,szFolder
,FALSE
,FALSE
,&folder
);
337 return ERROR_INVALID_PARAMETER
;
339 if (attrib
== INVALID_FILE_ATTRIBUTES
)
341 if (!CreateDirectoryW(szFolderPath
,NULL
))
342 return ERROR_FUNCTION_FAILED
;
343 RemoveDirectoryW(szFolderPath
);
346 msi_free(folder
->Property
);
347 folder
->Property
= build_directory_name(2, szFolderPath
, NULL
);
349 if (lstrcmpiW(path
, folder
->Property
) == 0)
352 * Resolved Target has not really changed, so just
353 * set this folder and do not recalculate everything.
355 msi_free(folder
->ResolvedTarget
);
356 folder
->ResolvedTarget
= NULL
;
357 path2
= resolve_folder(package
,szFolder
,FALSE
,TRUE
,NULL
);
364 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
366 msi_free(f
->ResolvedTarget
);
367 f
->ResolvedTarget
=NULL
;
370 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
372 path2
= resolve_folder(package
, f
->Directory
, FALSE
, TRUE
, NULL
);
378 return ERROR_SUCCESS
;
381 /***********************************************************************
382 * MsiSetTargetPathW (MSI.@)
384 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
385 LPCWSTR szFolderPath
)
390 TRACE("(%s %s)\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
392 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
393 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
394 msiobj_release( &package
->hdr
);
398 /***********************************************************************
401 * Returns an internal installer state (if it is running in a mode iRunMode)
404 * hInstall [I] Handle to the installation
405 * hRunMode [I] Checking run mode
406 * MSIRUNMODE_ADMIN Administrative mode
407 * MSIRUNMODE_ADVERTISE Advertisement mode
408 * MSIRUNMODE_MAINTENANCE Maintenance mode
409 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
410 * MSIRUNMODE_LOGENABLED Log file is writing
411 * MSIRUNMODE_OPERATIONS Operations in progress??
412 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
413 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
414 * MSIRUNMODE_CABINET Files from cabinet are installed
415 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
416 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
417 * MSIRUNMODE_RESERVED11 Reserved
418 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
419 * MSIRUNMODE_ZAWENABLED Demand installation is supported
420 * MSIRUNMODE_RESERVED14 Reserved
421 * MSIRUNMODE_RESERVED15 Reserved
422 * MSIRUNMODE_SCHEDULED called from install script
423 * MSIRUNMODE_ROLLBACK called from rollback script
424 * MSIRUNMODE_COMMIT called from commit script
428 * Not in the state: FALSE
432 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
434 FIXME("STUB (iRunMode=%i)\n",iRunMode
);
438 /***********************************************************************
439 * MsiSetFeatureStateA (MSI.@)
441 * According to the docs, when this is called it immediately recalculates
442 * all the component states as well
444 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
447 LPWSTR szwFeature
= NULL
;
450 szwFeature
= strdupAtoW(szFeature
);
453 return ERROR_FUNCTION_FAILED
;
455 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
457 msi_free(szwFeature
);
464 UINT WINAPI
MSI_SetFeatureStateW(MSIPACKAGE
* package
, LPCWSTR szFeature
,
467 UINT rc
= ERROR_SUCCESS
;
468 MSIFEATURE
*feature
, *child
;
470 TRACE(" %s to %i\n",debugstr_w(szFeature
), iState
);
472 feature
= get_loaded_feature(package
,szFeature
);
474 return ERROR_UNKNOWN_FEATURE
;
476 if (iState
== INSTALLSTATE_ADVERTISED
&&
477 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
478 return ERROR_FUNCTION_FAILED
;
480 feature
->ActionRequest
= iState
;
481 feature
->Action
= iState
;
483 ACTION_UpdateComponentStates(package
,szFeature
);
485 /* update all the features that are children of this feature */
486 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
488 if (lstrcmpW(szFeature
, child
->Feature_Parent
) == 0)
489 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
495 /***********************************************************************
496 * MsiSetFeatureStateW (MSI.@)
498 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
502 UINT rc
= ERROR_SUCCESS
;
504 TRACE(" %s to %i\n",debugstr_w(szFeature
), iState
);
506 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
508 return ERROR_INVALID_HANDLE
;
510 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
512 msiobj_release( &package
->hdr
);
516 /***********************************************************************
517 * MsiGetFeatureStateA (MSI.@)
519 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPSTR szFeature
,
520 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
522 LPWSTR szwFeature
= NULL
;
525 szwFeature
= strdupAtoW(szFeature
);
527 rc
= MsiGetFeatureStateW(hInstall
,szwFeature
,piInstalled
, piAction
);
529 msi_free( szwFeature
);
534 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPWSTR szFeature
,
535 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
539 feature
= get_loaded_feature(package
,szFeature
);
541 return ERROR_UNKNOWN_FEATURE
;
544 *piInstalled
= feature
->Installed
;
547 *piAction
= feature
->Action
;
549 TRACE("returning %i %i\n", feature
->Installed
, feature
->Action
);
551 return ERROR_SUCCESS
;
554 /***********************************************************************
555 * MsiGetFeatureStateW (MSI.@)
557 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPWSTR szFeature
,
558 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
563 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
,
566 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
568 return ERROR_INVALID_HANDLE
;
569 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
570 msiobj_release( &package
->hdr
);
574 /***********************************************************************
575 * MsiSetComponentStateA (MSI.@)
577 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
581 LPWSTR szwComponent
= strdupAtoW(szComponent
);
583 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
585 msi_free(szwComponent
);
590 /***********************************************************************
591 * MsiGetComponentStateA (MSI.@)
593 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPSTR szComponent
,
594 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
596 LPWSTR szwComponent
= NULL
;
599 szwComponent
= strdupAtoW(szComponent
);
601 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
603 msi_free( szwComponent
);
608 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
613 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
615 comp
= get_loaded_component(package
, szComponent
);
617 return ERROR_UNKNOWN_COMPONENT
;
619 comp
->Installed
= iState
;
621 return ERROR_SUCCESS
;
624 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPWSTR szComponent
,
625 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
629 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
630 piInstalled
, piAction
);
632 comp
= get_loaded_component(package
,szComponent
);
634 return ERROR_UNKNOWN_COMPONENT
;
637 *piInstalled
= comp
->Installed
;
640 *piAction
= comp
->Action
;
642 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
644 return ERROR_SUCCESS
;
647 /***********************************************************************
648 * MsiSetComponentStateW (MSI.@)
650 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
656 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
658 return ERROR_INVALID_HANDLE
;
659 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
660 msiobj_release(&package
->hdr
);
664 /***********************************************************************
665 * MsiGetComponentStateW (MSI.@)
667 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPWSTR szComponent
,
668 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
673 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szComponent
),
674 piInstalled
, piAction
);
676 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
678 return ERROR_INVALID_HANDLE
;
679 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
680 msiobj_release( &package
->hdr
);
684 /***********************************************************************
685 * MsiGetLanguage (MSI.@)
687 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
692 static const WCHAR szProductLanguage
[] =
693 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
695 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
697 return ERROR_INVALID_HANDLE
;
699 buffer
= msi_dup_property( package
, szProductLanguage
);
700 langid
= atoiW(buffer
);
703 msiobj_release (&package
->hdr
);