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 szTable
, INT iSequenceMode
)
88 TRACE("%s\n", debugstr_a(szTable
));
90 szwTable
= strdupAtoW(szTable
);
91 if (szTable
&& !szwTable
)
92 return ERROR_FUNCTION_FAILED
;
94 ret
= MsiSequenceW( hInstall
, szwTable
, iSequenceMode
);
99 /***********************************************************************
100 * MsiSequenceW (MSI.@)
102 UINT WINAPI
MsiSequenceW( MSIHANDLE hInstall
, LPCWSTR szTable
, INT iSequenceMode
)
107 TRACE("%s\n", debugstr_w(szTable
));
109 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
111 return ERROR_INVALID_HANDLE
;
113 ret
= MSI_Sequence( package
, szTable
, iSequenceMode
);
114 msiobj_release( &package
->hdr
);
119 static UINT
msi_strcpy_to_awstring( LPCWSTR str
, awstring
*awbuf
, DWORD
*sz
)
121 UINT len
, r
= ERROR_SUCCESS
;
123 if (awbuf
->str
.w
&& !sz
)
124 return ERROR_INVALID_PARAMETER
;
131 len
= lstrlenW( str
);
133 lstrcpynW( awbuf
->str
.w
, str
, *sz
);
137 len
= WideCharToMultiByte( CP_ACP
, 0, str
, -1,
138 awbuf
->str
.a
, *sz
, NULL
, NULL
);
148 /***********************************************************************
149 * MsiGetTargetPath (internal)
151 UINT WINAPI
MSI_GetTargetPath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
152 awstring
*szPathBuf
, DWORD
* pcchPathBuf
)
159 return ERROR_INVALID_PARAMETER
;
161 package
= msihandle2msiinfo( hInstall
, MSIHANDLETYPE_PACKAGE
);
163 return ERROR_INVALID_HANDLE
;
165 path
= resolve_folder( package
, szFolder
, FALSE
, FALSE
, NULL
);
166 msiobj_release( &package
->hdr
);
169 return ERROR_DIRECTORY
;
171 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
176 /***********************************************************************
177 * MsiGetTargetPathA (MSI.@)
179 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
180 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
186 TRACE("%s %p %p\n", debugstr_a(szFolder
), szPathBuf
, pcchPathBuf
);
188 szwFolder
= strdupAtoW(szFolder
);
189 if (szFolder
&& !szwFolder
)
190 return ERROR_FUNCTION_FAILED
;
192 path
.unicode
= FALSE
;
193 path
.str
.a
= szPathBuf
;
195 r
= MSI_GetTargetPath( hInstall
, szwFolder
, &path
, pcchPathBuf
);
197 msi_free( szwFolder
);
202 /***********************************************************************
203 * MsiGetTargetPathW (MSI.@)
205 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
206 LPWSTR szPathBuf
, DWORD
* pcchPathBuf
)
210 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
213 path
.str
.w
= szPathBuf
;
215 return MSI_GetTargetPath( hInstall
, szFolder
, &path
, pcchPathBuf
);
218 /***********************************************************************
219 * MsiGetSourcePath (internal)
221 static UINT
MSI_GetSourcePath( MSIHANDLE hInstall
, LPCWSTR szFolder
,
222 awstring
*szPathBuf
, DWORD
* pcchPathBuf
)
228 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
231 return ERROR_INVALID_PARAMETER
;
233 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
235 return ERROR_INVALID_HANDLE
;
237 if (szPathBuf
->str
.w
&& !pcchPathBuf
)
239 msiobj_release( &package
->hdr
);
240 return ERROR_INVALID_PARAMETER
;
243 path
= resolve_folder(package
, szFolder
, TRUE
, FALSE
, NULL
);
244 msiobj_release( &package
->hdr
);
246 TRACE("path = %s\n",debugstr_w(path
));
248 return ERROR_DIRECTORY
;
250 r
= msi_strcpy_to_awstring( path
, szPathBuf
, pcchPathBuf
);
255 /***********************************************************************
256 * MsiGetSourcePathA (MSI.@)
258 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
259 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
265 TRACE("%s %p %p\n", szFolder
, debugstr_a(szPathBuf
), pcchPathBuf
);
268 str
.str
.a
= szPathBuf
;
270 folder
= strdupAtoW( szFolder
);
271 r
= MSI_GetSourcePath( hInstall
, folder
, &str
, pcchPathBuf
);
277 /***********************************************************************
278 * MsiGetSourcePathW (MSI.@)
280 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
,
281 LPWSTR szPathBuf
, DWORD
* pcchPathBuf
)
285 TRACE("%s %p %p\n", debugstr_w(szFolder
), szPathBuf
, pcchPathBuf
);
288 str
.str
.w
= szPathBuf
;
290 return MSI_GetSourcePath( hInstall
, szFolder
, &str
, pcchPathBuf
);
293 /***********************************************************************
294 * MsiSetTargetPathA (MSI.@)
296 UINT WINAPI
MsiSetTargetPathA(MSIHANDLE hInstall
, LPCSTR szFolder
,
300 LPWSTR szwFolderPath
;
304 return ERROR_FUNCTION_FAILED
;
306 return ERROR_FUNCTION_FAILED
;
308 szwFolder
= strdupAtoW(szFolder
);
310 return ERROR_FUNCTION_FAILED
;
312 szwFolderPath
= strdupAtoW(szFolderPath
);
316 return ERROR_FUNCTION_FAILED
;
319 rc
= MsiSetTargetPathW(hInstall
, szwFolder
, szwFolderPath
);
322 msi_free(szwFolderPath
);
328 * Ok my original interpretation of this was wrong. And it looks like msdn has
329 * changed a bit also. The given folder path does not have to actually already
330 * exist, it just cannot be read only and must be a legal folder path.
332 UINT
MSI_SetTargetPathW(MSIPACKAGE
*package
, LPCWSTR szFolder
,
333 LPCWSTR szFolderPath
)
340 TRACE("(%p %s %s)\n",package
, debugstr_w(szFolder
),debugstr_w(szFolderPath
));
343 return ERROR_INVALID_HANDLE
;
345 if (szFolderPath
[0]==0)
346 return ERROR_FUNCTION_FAILED
;
348 attrib
= GetFileAttributesW(szFolderPath
);
349 if ( attrib
!= INVALID_FILE_ATTRIBUTES
&&
350 (!(attrib
& FILE_ATTRIBUTE_DIRECTORY
) ||
351 attrib
& FILE_ATTRIBUTE_OFFLINE
||
352 attrib
& FILE_ATTRIBUTE_READONLY
))
353 return ERROR_FUNCTION_FAILED
;
355 path
= resolve_folder(package
,szFolder
,FALSE
,FALSE
,&folder
);
358 return ERROR_INVALID_PARAMETER
;
360 if (attrib
== INVALID_FILE_ATTRIBUTES
)
362 if (!CreateDirectoryW(szFolderPath
,NULL
))
363 return ERROR_FUNCTION_FAILED
;
364 RemoveDirectoryW(szFolderPath
);
367 msi_free(folder
->Property
);
368 folder
->Property
= build_directory_name(2, szFolderPath
, NULL
);
370 if (lstrcmpiW(path
, folder
->Property
) == 0)
373 * Resolved Target has not really changed, so just
374 * set this folder and do not recalculate everything.
376 msi_free(folder
->ResolvedTarget
);
377 folder
->ResolvedTarget
= NULL
;
378 path2
= resolve_folder(package
,szFolder
,FALSE
,TRUE
,NULL
);
385 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
387 msi_free(f
->ResolvedTarget
);
388 f
->ResolvedTarget
=NULL
;
391 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
393 path2
= resolve_folder(package
, f
->Directory
, FALSE
, TRUE
, NULL
);
399 return ERROR_SUCCESS
;
402 /***********************************************************************
403 * MsiSetTargetPathW (MSI.@)
405 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
406 LPCWSTR szFolderPath
)
411 TRACE("(%s %s)\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
413 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
414 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
415 msiobj_release( &package
->hdr
);
419 /***********************************************************************
422 * Returns an internal installer state (if it is running in a mode iRunMode)
425 * hInstall [I] Handle to the installation
426 * hRunMode [I] Checking run mode
427 * MSIRUNMODE_ADMIN Administrative mode
428 * MSIRUNMODE_ADVERTISE Advertisement mode
429 * MSIRUNMODE_MAINTENANCE Maintenance mode
430 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
431 * MSIRUNMODE_LOGENABLED Log file is writing
432 * MSIRUNMODE_OPERATIONS Operations in progress??
433 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
434 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
435 * MSIRUNMODE_CABINET Files from cabinet are installed
436 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
437 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
438 * MSIRUNMODE_RESERVED11 Reserved
439 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
440 * MSIRUNMODE_ZAWENABLED Demand installation is supported
441 * MSIRUNMODE_RESERVED14 Reserved
442 * MSIRUNMODE_RESERVED15 Reserved
443 * MSIRUNMODE_SCHEDULED called from install script
444 * MSIRUNMODE_ROLLBACK called from rollback script
445 * MSIRUNMODE_COMMIT called from commit script
449 * Not in the state: FALSE
453 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
455 FIXME("STUB (iRunMode=%i)\n",iRunMode
);
459 /***********************************************************************
460 * MsiSetFeatureStateA (MSI.@)
462 * According to the docs, when this is called it immediately recalculates
463 * all the component states as well
465 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
468 LPWSTR szwFeature
= NULL
;
471 szwFeature
= strdupAtoW(szFeature
);
474 return ERROR_FUNCTION_FAILED
;
476 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
478 msi_free(szwFeature
);
485 UINT WINAPI
MSI_SetFeatureStateW(MSIPACKAGE
* package
, LPCWSTR szFeature
,
488 UINT rc
= ERROR_SUCCESS
;
489 MSIFEATURE
*feature
, *child
;
491 TRACE(" %s to %i\n",debugstr_w(szFeature
), iState
);
493 feature
= get_loaded_feature(package
,szFeature
);
495 return ERROR_UNKNOWN_FEATURE
;
497 if (iState
== INSTALLSTATE_ADVERTISED
&&
498 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
499 return ERROR_FUNCTION_FAILED
;
501 feature
->ActionRequest
= iState
;
502 feature
->Action
= iState
;
504 ACTION_UpdateComponentStates(package
,szFeature
);
506 /* update all the features that are children of this feature */
507 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
509 if (lstrcmpW(szFeature
, child
->Feature_Parent
) == 0)
510 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
516 /***********************************************************************
517 * MsiSetFeatureStateW (MSI.@)
519 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
523 UINT rc
= ERROR_SUCCESS
;
525 TRACE(" %s to %i\n",debugstr_w(szFeature
), iState
);
527 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
529 return ERROR_INVALID_HANDLE
;
531 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
533 msiobj_release( &package
->hdr
);
537 /***********************************************************************
538 * MsiGetFeatureStateA (MSI.@)
540 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPSTR szFeature
,
541 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
543 LPWSTR szwFeature
= NULL
;
546 szwFeature
= strdupAtoW(szFeature
);
548 rc
= MsiGetFeatureStateW(hInstall
,szwFeature
,piInstalled
, piAction
);
550 msi_free( szwFeature
);
555 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPWSTR szFeature
,
556 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
560 feature
= get_loaded_feature(package
,szFeature
);
562 return ERROR_UNKNOWN_FEATURE
;
565 *piInstalled
= feature
->Installed
;
568 *piAction
= feature
->Action
;
570 TRACE("returning %i %i\n", feature
->Installed
, feature
->Action
);
572 return ERROR_SUCCESS
;
575 /***********************************************************************
576 * MsiGetFeatureStateW (MSI.@)
578 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPWSTR szFeature
,
579 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
584 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
,
587 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
589 return ERROR_INVALID_HANDLE
;
590 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
591 msiobj_release( &package
->hdr
);
595 /***********************************************************************
596 * MsiSetComponentStateA (MSI.@)
598 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
602 LPWSTR szwComponent
= strdupAtoW(szComponent
);
604 rc
= MsiSetComponentStateW(hInstall
, szwComponent
, iState
);
606 msi_free(szwComponent
);
611 /***********************************************************************
612 * MsiGetComponentStateA (MSI.@)
614 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPSTR szComponent
,
615 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
617 LPWSTR szwComponent
= NULL
;
620 szwComponent
= strdupAtoW(szComponent
);
622 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
624 msi_free( szwComponent
);
629 static UINT
MSI_SetComponentStateW(MSIPACKAGE
*package
, LPCWSTR szComponent
,
634 TRACE("%p %s %d\n", package
, debugstr_w(szComponent
), iState
);
636 comp
= get_loaded_component(package
, szComponent
);
638 return ERROR_UNKNOWN_COMPONENT
;
640 comp
->Installed
= iState
;
642 return ERROR_SUCCESS
;
645 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPWSTR szComponent
,
646 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
650 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
651 piInstalled
, piAction
);
653 comp
= get_loaded_component(package
,szComponent
);
655 return ERROR_UNKNOWN_COMPONENT
;
658 *piInstalled
= comp
->Installed
;
661 *piAction
= comp
->Action
;
663 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
665 return ERROR_SUCCESS
;
668 /***********************************************************************
669 * MsiSetComponentStateW (MSI.@)
671 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
677 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
679 return ERROR_INVALID_HANDLE
;
680 ret
= MSI_SetComponentStateW(package
, szComponent
, iState
);
681 msiobj_release(&package
->hdr
);
685 /***********************************************************************
686 * MsiGetComponentStateW (MSI.@)
688 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPWSTR szComponent
,
689 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
694 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szComponent
),
695 piInstalled
, piAction
);
697 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
699 return ERROR_INVALID_HANDLE
;
700 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
701 msiobj_release( &package
->hdr
);
705 /***********************************************************************
706 * MsiGetLanguage (MSI.@)
708 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
713 static const WCHAR szProductLanguage
[] =
714 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
716 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
718 return ERROR_INVALID_HANDLE
;
720 buffer
= msi_dup_property( package
, szProductLanguage
);
721 langid
= atoiW(buffer
);
724 msiobj_release (&package
->hdr
);