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(" exteral attempt at action %s\n",szAction
);
49 return ERROR_FUNCTION_FAILED
;
51 return ERROR_FUNCTION_FAILED
;
53 szwAction
= strdupAtoW(szAction
);
56 return ERROR_FUNCTION_FAILED
;
59 rc
= MsiDoActionW(hInstall
, szwAction
);
60 HeapFree(GetProcessHeap(),0,szwAction
);
64 /***********************************************************************
65 * MsiDoActionW (MSI.@)
67 UINT WINAPI
MsiDoActionW( MSIHANDLE hInstall
, LPCWSTR szAction
)
70 UINT ret
= ERROR_INVALID_HANDLE
;
72 TRACE(" external attempt at action %s \n",debugstr_w(szAction
));
74 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
77 ret
= ACTION_PerformUIAction(package
,szAction
);
78 msiobj_release( &package
->hdr
);
83 /***********************************************************************
84 * MsiGetTargetPathA (MSI.@)
86 UINT WINAPI
MsiGetTargetPathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
87 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
93 TRACE("getting folder %s %p %li\n",szFolder
,szPathBuf
, *pcchPathBuf
);
96 return ERROR_FUNCTION_FAILED
;
98 return ERROR_FUNCTION_FAILED
;
100 szwFolder
= strdupAtoW(szFolder
);
103 return ERROR_FUNCTION_FAILED
;
105 szwPathBuf
= HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf
* sizeof(WCHAR
));
107 rc
= MsiGetTargetPathW(hInstall
, szwFolder
, szwPathBuf
,pcchPathBuf
);
109 WideCharToMultiByte( CP_ACP
, 0, szwPathBuf
, *pcchPathBuf
, szPathBuf
,
110 *pcchPathBuf
, NULL
, NULL
);
112 HeapFree(GetProcessHeap(),0,szwFolder
);
113 HeapFree(GetProcessHeap(),0,szwPathBuf
);
118 /***********************************************************************
119 * MsiGetTargetPathW (MSI.@)
121 UINT WINAPI
MsiGetTargetPathW( MSIHANDLE hInstall
, LPCWSTR szFolder
, LPWSTR
122 szPathBuf
, DWORD
* pcchPathBuf
)
125 UINT rc
= ERROR_FUNCTION_FAILED
;
128 TRACE("(%s %p %li)\n",debugstr_w(szFolder
),szPathBuf
,*pcchPathBuf
);
130 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
132 return ERROR_INVALID_HANDLE
;
133 path
= resolve_folder(package
, szFolder
, FALSE
, FALSE
, NULL
);
134 msiobj_release( &package
->hdr
);
136 if (path
&& (strlenW(path
) > *pcchPathBuf
))
138 *pcchPathBuf
= strlenW(path
)+1;
139 rc
= ERROR_MORE_DATA
;
143 *pcchPathBuf
= strlenW(path
)+1;
144 strcpyW(szPathBuf
,path
);
145 TRACE("Returning Path %s\n",debugstr_w(path
));
148 HeapFree(GetProcessHeap(),0,path
);
154 /***********************************************************************
155 * MsiGetSourcePathA (MSI.@)
157 UINT WINAPI
MsiGetSourcePathA( MSIHANDLE hInstall
, LPCSTR szFolder
,
158 LPSTR szPathBuf
, DWORD
* pcchPathBuf
)
164 TRACE("getting source %s %p %li\n",szFolder
,szPathBuf
, *pcchPathBuf
);
167 return ERROR_FUNCTION_FAILED
;
169 return ERROR_FUNCTION_FAILED
;
171 szwFolder
= strdupAtoW(szFolder
);
173 return ERROR_FUNCTION_FAILED
;
175 szwPathBuf
= HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf
* sizeof(WCHAR
));
177 rc
= MsiGetSourcePathW(hInstall
, szwFolder
, szwPathBuf
,pcchPathBuf
);
179 WideCharToMultiByte( CP_ACP
, 0, szwPathBuf
, *pcchPathBuf
, szPathBuf
,
180 *pcchPathBuf
, NULL
, NULL
);
182 HeapFree(GetProcessHeap(),0,szwFolder
);
183 HeapFree(GetProcessHeap(),0,szwPathBuf
);
188 /***********************************************************************
189 * MsiGetSourcePathW (MSI.@)
191 UINT WINAPI
MsiGetSourcePathW( MSIHANDLE hInstall
, LPCWSTR szFolder
, LPWSTR
192 szPathBuf
, DWORD
* pcchPathBuf
)
195 UINT rc
= ERROR_FUNCTION_FAILED
;
198 TRACE("(%s %p %li)\n",debugstr_w(szFolder
),szPathBuf
,*pcchPathBuf
);
200 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
202 return ERROR_INVALID_HANDLE
;
203 path
= resolve_folder(package
, szFolder
, TRUE
, FALSE
, NULL
);
204 msiobj_release( &package
->hdr
);
206 if (path
&& strlenW(path
) > *pcchPathBuf
)
208 *pcchPathBuf
= strlenW(path
)+1;
209 rc
= ERROR_MORE_DATA
;
213 *pcchPathBuf
= strlenW(path
)+1;
214 strcpyW(szPathBuf
,path
);
215 TRACE("Returning Path %s\n",debugstr_w(path
));
218 HeapFree(GetProcessHeap(),0,path
);
224 /***********************************************************************
225 * MsiSetTargetPathA (MSI.@)
227 UINT WINAPI
MsiSetTargetPathA(MSIHANDLE hInstall
, LPCSTR szFolder
,
231 LPWSTR szwFolderPath
;
235 return ERROR_FUNCTION_FAILED
;
237 return ERROR_FUNCTION_FAILED
;
239 szwFolder
= strdupAtoW(szFolder
);
241 return ERROR_FUNCTION_FAILED
;
243 szwFolderPath
= strdupAtoW(szFolderPath
);
246 HeapFree(GetProcessHeap(),0,szwFolder
);
247 return ERROR_FUNCTION_FAILED
;
250 rc
= MsiSetTargetPathW(hInstall
, szwFolder
, szwFolderPath
);
252 HeapFree(GetProcessHeap(),0,szwFolder
);
253 HeapFree(GetProcessHeap(),0,szwFolderPath
);
259 * Ok my original interpretation of this was wrong. And it looks like msdn has
260 * changed a bit also. The given folder path does not have to actually already
261 * exist, it just cannot be read only and must be a legal folder path.
263 UINT
MSI_SetTargetPathW(MSIPACKAGE
*package
, LPCWSTR szFolder
,
264 LPCWSTR szFolderPath
)
271 TRACE("(%p %s %s)\n",package
, debugstr_w(szFolder
),debugstr_w(szFolderPath
));
274 return ERROR_INVALID_HANDLE
;
276 if (szFolderPath
[0]==0)
277 return ERROR_FUNCTION_FAILED
;
279 attrib
= GetFileAttributesW(szFolderPath
);
280 if ( attrib
!= INVALID_FILE_ATTRIBUTES
&&
281 (!(attrib
& FILE_ATTRIBUTE_DIRECTORY
) ||
282 attrib
& FILE_ATTRIBUTE_OFFLINE
||
283 attrib
& FILE_ATTRIBUTE_READONLY
))
284 return ERROR_FUNCTION_FAILED
;
286 path
= resolve_folder(package
,szFolder
,FALSE
,FALSE
,&folder
);
289 return ERROR_INVALID_PARAMETER
;
291 if (attrib
== INVALID_FILE_ATTRIBUTES
)
293 if (!CreateDirectoryW(szFolderPath
,NULL
))
294 return ERROR_FUNCTION_FAILED
;
295 RemoveDirectoryW(szFolderPath
);
298 HeapFree(GetProcessHeap(),0,folder
->Property
);
299 folder
->Property
= build_directory_name(2, szFolderPath
, NULL
);
301 if (lstrcmpiW(path
, folder
->Property
) == 0)
304 * Resolved Target has not really changed, so just
305 * set this folder and do not recalculate everything.
307 HeapFree(GetProcessHeap(),0,folder
->ResolvedTarget
);
308 folder
->ResolvedTarget
= NULL
;
309 path2
= resolve_folder(package
,szFolder
,FALSE
,TRUE
,NULL
);
310 HeapFree(GetProcessHeap(),0,path2
);
316 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
318 HeapFree( GetProcessHeap(),0,f
->ResolvedTarget
);
319 f
->ResolvedTarget
=NULL
;
322 LIST_FOR_EACH_ENTRY( f
, &package
->folders
, MSIFOLDER
, entry
)
324 path2
= resolve_folder(package
, f
->Directory
, FALSE
, TRUE
, NULL
);
325 HeapFree(GetProcessHeap(),0,path2
);
328 HeapFree(GetProcessHeap(),0,path
);
330 return ERROR_SUCCESS
;
333 /***********************************************************************
334 * MsiSetTargetPathW (MSI.@)
336 UINT WINAPI
MsiSetTargetPathW(MSIHANDLE hInstall
, LPCWSTR szFolder
,
337 LPCWSTR szFolderPath
)
342 TRACE("(%s %s)\n",debugstr_w(szFolder
),debugstr_w(szFolderPath
));
344 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
345 ret
= MSI_SetTargetPathW( package
, szFolder
, szFolderPath
);
346 msiobj_release( &package
->hdr
);
350 /***********************************************************************
353 * Returns an internal installer state (if it is running in a mode iRunMode)
356 * hInstall [I] Handle to the installation
357 * hRunMode [I] Checking run mode
358 * MSIRUNMODE_ADMIN Administrative mode
359 * MSIRUNMODE_ADVERTISE Advertisement mode
360 * MSIRUNMODE_MAINTENANCE Maintenance mode
361 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
362 * MSIRUNMODE_LOGENABLED Log file is writing
363 * MSIRUNMODE_OPERATIONS Operations in progress??
364 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
365 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
366 * MSIRUNMODE_CABINET Files from cabinet are installed
367 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
368 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
369 * MSIRUNMODE_RESERVED11 Reserved
370 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
371 * MSIRUNMODE_ZAWENABLED Demand installation is supported
372 * MSIRUNMODE_RESERVED14 Reserved
373 * MSIRUNMODE_RESERVED15 Reserved
374 * MSIRUNMODE_SCHEDULED called from install script
375 * MSIRUNMODE_ROLLBACK called from rollback script
376 * MSIRUNMODE_COMMIT called from commit script
380 * Not in the state: FALSE
384 BOOL WINAPI
MsiGetMode(MSIHANDLE hInstall
, MSIRUNMODE iRunMode
)
386 FIXME("STUB (iRunMode=%i)\n",iRunMode
);
390 /***********************************************************************
391 * MsiSetFeatureStateA (MSI.@)
393 * According to the docs, when this is called it immediately recalculates
394 * all the component states as well
396 UINT WINAPI
MsiSetFeatureStateA(MSIHANDLE hInstall
, LPCSTR szFeature
,
399 LPWSTR szwFeature
= NULL
;
402 szwFeature
= strdupAtoW(szFeature
);
405 return ERROR_FUNCTION_FAILED
;
407 rc
= MsiSetFeatureStateW(hInstall
,szwFeature
, iState
);
409 HeapFree(GetProcessHeap(),0,szwFeature
);
416 UINT WINAPI
MSI_SetFeatureStateW(MSIPACKAGE
* package
, LPCWSTR szFeature
,
419 UINT rc
= ERROR_SUCCESS
;
420 MSIFEATURE
*feature
, *child
;
422 TRACE(" %s to %i\n",debugstr_w(szFeature
), iState
);
424 feature
= get_loaded_feature(package
,szFeature
);
426 return ERROR_UNKNOWN_FEATURE
;
428 if (iState
== INSTALLSTATE_ADVERTISED
&&
429 feature
->Attributes
& msidbFeatureAttributesDisallowAdvertise
)
430 return ERROR_FUNCTION_FAILED
;
432 feature
->ActionRequest
= iState
;
433 feature
->Action
= iState
;
435 ACTION_UpdateComponentStates(package
,szFeature
);
437 /* update all the features that are children of this feature */
438 LIST_FOR_EACH_ENTRY( child
, &package
->features
, MSIFEATURE
, entry
)
440 if (lstrcmpW(szFeature
, child
->Feature_Parent
) == 0)
441 MSI_SetFeatureStateW(package
, child
->Feature
, iState
);
447 /***********************************************************************
448 * MsiSetFeatureStateW (MSI.@)
450 UINT WINAPI
MsiSetFeatureStateW(MSIHANDLE hInstall
, LPCWSTR szFeature
,
454 UINT rc
= ERROR_SUCCESS
;
456 TRACE(" %s to %i\n",debugstr_w(szFeature
), iState
);
458 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
460 return ERROR_INVALID_HANDLE
;
462 rc
= MSI_SetFeatureStateW(package
,szFeature
,iState
);
464 msiobj_release( &package
->hdr
);
468 /***********************************************************************
469 * MsiGetFeatureStateA (MSI.@)
471 UINT WINAPI
MsiGetFeatureStateA(MSIHANDLE hInstall
, LPSTR szFeature
,
472 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
474 LPWSTR szwFeature
= NULL
;
477 szwFeature
= strdupAtoW(szFeature
);
479 rc
= MsiGetFeatureStateW(hInstall
,szwFeature
,piInstalled
, piAction
);
481 HeapFree( GetProcessHeap(), 0 , szwFeature
);
486 UINT
MSI_GetFeatureStateW(MSIPACKAGE
*package
, LPWSTR szFeature
,
487 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
491 feature
= get_loaded_feature(package
,szFeature
);
493 return ERROR_UNKNOWN_FEATURE
;
496 *piInstalled
= feature
->Installed
;
499 *piAction
= feature
->Action
;
501 TRACE("returning %i %i\n", feature
->Installed
, feature
->Action
);
503 return ERROR_SUCCESS
;
506 /***********************************************************************
507 * MsiGetFeatureStateW (MSI.@)
509 UINT WINAPI
MsiGetFeatureStateW(MSIHANDLE hInstall
, LPWSTR szFeature
,
510 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
515 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szFeature
), piInstalled
,
518 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
520 return ERROR_INVALID_HANDLE
;
521 ret
= MSI_GetFeatureStateW(package
, szFeature
, piInstalled
, piAction
);
522 msiobj_release( &package
->hdr
);
526 /***********************************************************************
527 * MsiSetComponentStateA (MSI.@)
529 UINT WINAPI
MsiSetComponentStateA(MSIHANDLE hInstall
, LPCSTR szComponent
,
532 FIXME("STUB (szComponent=%s,iState=%i)\n",debugstr_a(szComponent
),iState
);
533 return ERROR_SUCCESS
;
536 /***********************************************************************
537 * MsiGetComponentStateA (MSI.@)
539 UINT WINAPI
MsiGetComponentStateA(MSIHANDLE hInstall
, LPSTR szComponent
,
540 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
542 LPWSTR szwComponent
= NULL
;
545 szwComponent
= strdupAtoW(szComponent
);
547 rc
= MsiGetComponentStateW(hInstall
,szwComponent
,piInstalled
, piAction
);
549 HeapFree( GetProcessHeap(), 0 , szwComponent
);
554 UINT
MSI_GetComponentStateW(MSIPACKAGE
*package
, LPWSTR szComponent
,
555 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
559 TRACE("%p %s %p %p\n", package
, debugstr_w(szComponent
),
560 piInstalled
, piAction
);
562 comp
= get_loaded_component(package
,szComponent
);
564 return ERROR_UNKNOWN_COMPONENT
;
567 *piInstalled
= comp
->Installed
;
570 *piAction
= comp
->Action
;
572 TRACE("states (%i, %i)\n", comp
->Installed
, comp
->Action
);
574 return ERROR_SUCCESS
;
577 /***********************************************************************
578 * MsiSetComponentStateW (MSI.@)
580 UINT WINAPI
MsiSetComponentStateW(MSIHANDLE hInstall
, LPCWSTR szComponent
,
583 FIXME("STUB (szComponent=%s,iState=%i)\n",debugstr_w(szComponent
),iState
);
584 return ERROR_SUCCESS
;
587 /***********************************************************************
588 * MsiGetComponentStateW (MSI.@)
590 UINT WINAPI
MsiGetComponentStateW(MSIHANDLE hInstall
, LPWSTR szComponent
,
591 INSTALLSTATE
*piInstalled
, INSTALLSTATE
*piAction
)
596 TRACE("%ld %s %p %p\n", hInstall
, debugstr_w(szComponent
),
597 piInstalled
, piAction
);
599 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
601 return ERROR_INVALID_HANDLE
;
602 ret
= MSI_GetComponentStateW( package
, szComponent
, piInstalled
, piAction
);
603 msiobj_release( &package
->hdr
);
607 /***********************************************************************
608 * MsiGetLanguage (MSI.@)
610 LANGID WINAPI
MsiGetLanguage(MSIHANDLE hInstall
)
615 static const WCHAR szProductLanguage
[] =
616 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
618 package
= msihandle2msiinfo(hInstall
, MSIHANDLETYPE_PACKAGE
);
620 return ERROR_INVALID_HANDLE
;
622 buffer
= load_dynamic_property(package
,szProductLanguage
,NULL
);
623 langid
= atoiW(buffer
);
625 HeapFree(GetProcessHeap(),0,buffer
);
626 msiobj_release (&package
->hdr
);