Added memory allocation inline functions (part 2).
[wine/wine-kai.git] / dlls / msi / install.c
bloba73e0b347a1628d00067fac7e3bbef6a6ca6d69c
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "winuser.h"
33 #include "wine/unicode.h"
34 #include "action.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msi);
38 /***********************************************************************
39 * MsiDoActionA (MSI.@)
41 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
43 LPWSTR szwAction;
44 UINT ret;
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 );
54 return ret;
57 /***********************************************************************
58 * MsiDoActionW (MSI.@)
60 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
62 MSIPACKAGE *package;
63 UINT ret;
65 TRACE("%s\n",debugstr_w(szAction));
67 if (!szAction)
68 return ERROR_INVALID_PARAMETER;
70 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
71 if (!package)
72 return ERROR_INVALID_HANDLE;
74 ret = ACTION_PerformUIAction( package, szAction );
75 msiobj_release( &package->hdr );
77 return ret;
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;
105 if (!sz)
106 return r;
108 if (awbuf->unicode)
110 len = lstrlenW( str );
111 if (awbuf->str.w)
112 lstrcpynW( awbuf->str.w, str, *sz );
114 else
116 len = WideCharToMultiByte( CP_ACP, 0, str, -1,
117 awbuf->str.a, *sz, NULL, NULL );
118 len--;
121 if (len >= *sz)
122 r = ERROR_MORE_DATA;
123 *sz = len;
124 return r;
127 /***********************************************************************
128 * MsiGetTargetPath (internal)
130 UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
131 awstring *szPathBuf, DWORD* pcchPathBuf )
133 MSIPACKAGE *package;
134 LPWSTR path;
135 UINT r;
137 if (!szFolder)
138 return ERROR_INVALID_PARAMETER;
140 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
141 if (!package)
142 return ERROR_INVALID_HANDLE;
144 path = resolve_folder( package, szFolder, FALSE, FALSE, NULL );
145 msiobj_release( &package->hdr );
147 if (!path)
148 return ERROR_DIRECTORY;
150 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
151 msi_free( path );
152 return r;
155 /***********************************************************************
156 * MsiGetTargetPathA (MSI.@)
158 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
159 LPSTR szPathBuf, DWORD* pcchPathBuf )
161 LPWSTR szwFolder;
162 awstring path;
163 UINT r;
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 );
178 return r;
181 /***********************************************************************
182 * MsiGetTargetPathW (MSI.@)
184 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
185 LPWSTR szPathBuf, DWORD* pcchPathBuf )
187 awstring path;
189 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
191 path.unicode = TRUE;
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 )
203 MSIPACKAGE *package;
204 LPWSTR path;
205 UINT r;
207 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
209 if (!szFolder)
210 return ERROR_INVALID_PARAMETER;
212 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
213 if (!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));
226 if (!path)
227 return ERROR_DIRECTORY;
229 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
230 msi_free( path );
231 return r;
234 /***********************************************************************
235 * MsiGetSourcePathA (MSI.@)
237 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
238 LPSTR szPathBuf, DWORD* pcchPathBuf )
240 LPWSTR folder;
241 awstring str;
242 UINT r;
244 TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
246 str.unicode = FALSE;
247 str.str.a = szPathBuf;
249 folder = strdupAtoW( szFolder );
250 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
251 msi_free( folder );
253 return r;
256 /***********************************************************************
257 * MsiGetSourcePathW (MSI.@)
259 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
260 LPWSTR szPathBuf, DWORD* pcchPathBuf )
262 awstring str;
264 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
266 str.unicode = TRUE;
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,
276 LPCSTR szFolderPath)
278 LPWSTR szwFolder;
279 LPWSTR szwFolderPath;
280 UINT rc;
282 if (!szFolder)
283 return ERROR_FUNCTION_FAILED;
284 if (hInstall == 0)
285 return ERROR_FUNCTION_FAILED;
287 szwFolder = strdupAtoW(szFolder);
288 if (!szwFolder)
289 return ERROR_FUNCTION_FAILED;
291 szwFolderPath = strdupAtoW(szFolderPath);
292 if (!szwFolderPath)
294 msi_free(szwFolder);
295 return ERROR_FUNCTION_FAILED;
298 rc = MsiSetTargetPathW(hInstall, szwFolder, szwFolderPath);
300 msi_free(szwFolder);
301 msi_free(szwFolderPath);
303 return rc;
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)
314 DWORD attrib;
315 LPWSTR path = NULL;
316 LPWSTR path2 = NULL;
317 MSIFOLDER *folder;
319 TRACE("(%p %s %s)\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
321 if (package==NULL)
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);
336 if (!path)
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);
358 msi_free(path2);
360 else
362 MSIFOLDER *f;
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);
373 msi_free(path2);
376 msi_free(path);
378 return ERROR_SUCCESS;
381 /***********************************************************************
382 * MsiSetTargetPathW (MSI.@)
384 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
385 LPCWSTR szFolderPath)
387 MSIPACKAGE *package;
388 UINT ret;
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 );
395 return ret;
398 /***********************************************************************
399 * MsiGetMode (MSI.@)
401 * Returns an internal installer state (if it is running in a mode iRunMode)
403 * PARAMS
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
426 * RETURNS
427 * In the state: TRUE
428 * Not in the state: FALSE
432 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
434 FIXME("STUB (iRunMode=%i)\n",iRunMode);
435 return TRUE;
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,
445 INSTALLSTATE iState)
447 LPWSTR szwFeature = NULL;
448 UINT rc;
450 szwFeature = strdupAtoW(szFeature);
452 if (!szwFeature)
453 return ERROR_FUNCTION_FAILED;
455 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
457 msi_free(szwFeature);
459 return rc;
464 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
465 INSTALLSTATE iState)
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);
473 if (!feature)
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);
492 return rc;
495 /***********************************************************************
496 * MsiSetFeatureStateW (MSI.@)
498 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
499 INSTALLSTATE iState)
501 MSIPACKAGE* package;
502 UINT rc = ERROR_SUCCESS;
504 TRACE(" %s to %i\n",debugstr_w(szFeature), iState);
506 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
507 if (!package)
508 return ERROR_INVALID_HANDLE;
510 rc = MSI_SetFeatureStateW(package,szFeature,iState);
512 msiobj_release( &package->hdr );
513 return rc;
516 /***********************************************************************
517 * MsiGetFeatureStateA (MSI.@)
519 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature,
520 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
522 LPWSTR szwFeature = NULL;
523 UINT rc;
525 szwFeature = strdupAtoW(szFeature);
527 rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
529 msi_free( szwFeature);
531 return rc;
534 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPWSTR szFeature,
535 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
537 MSIFEATURE *feature;
539 feature = get_loaded_feature(package,szFeature);
540 if (!feature)
541 return ERROR_UNKNOWN_FEATURE;
543 if (piInstalled)
544 *piInstalled = feature->Installed;
546 if (piAction)
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)
560 MSIPACKAGE* package;
561 UINT ret;
563 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled,
564 piAction);
566 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
567 if (!package)
568 return ERROR_INVALID_HANDLE;
569 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
570 msiobj_release( &package->hdr );
571 return ret;
574 /***********************************************************************
575 * MsiSetComponentStateA (MSI.@)
577 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
578 INSTALLSTATE iState)
580 UINT rc;
581 LPWSTR szwComponent = strdupAtoW(szComponent);
583 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
585 msi_free(szwComponent);
587 return rc;
590 /***********************************************************************
591 * MsiGetComponentStateA (MSI.@)
593 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szComponent,
594 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
596 LPWSTR szwComponent= NULL;
597 UINT rc;
599 szwComponent= strdupAtoW(szComponent);
601 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
603 msi_free( szwComponent);
605 return rc;
608 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
609 INSTALLSTATE iState)
611 MSICOMPONENT *comp;
613 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
615 comp = get_loaded_component(package, szComponent);
616 if (!comp)
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)
627 MSICOMPONENT *comp;
629 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
630 piInstalled, piAction);
632 comp = get_loaded_component(package,szComponent);
633 if (!comp)
634 return ERROR_UNKNOWN_COMPONENT;
636 if (piInstalled)
637 *piInstalled = comp->Installed;
639 if (piAction)
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,
651 INSTALLSTATE iState)
653 MSIPACKAGE* package;
654 UINT ret;
656 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
657 if (!package)
658 return ERROR_INVALID_HANDLE;
659 ret = MSI_SetComponentStateW(package, szComponent, iState);
660 msiobj_release(&package->hdr);
661 return ret;
664 /***********************************************************************
665 * MsiGetComponentStateW (MSI.@)
667 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szComponent,
668 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
670 MSIPACKAGE* package;
671 UINT ret;
673 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
674 piInstalled, piAction);
676 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
677 if (!package)
678 return ERROR_INVALID_HANDLE;
679 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
680 msiobj_release( &package->hdr );
681 return ret;
684 /***********************************************************************
685 * MsiGetLanguage (MSI.@)
687 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
689 MSIPACKAGE* package;
690 LANGID langid;
691 LPWSTR buffer;
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);
696 if (!package)
697 return ERROR_INVALID_HANDLE;
699 buffer = msi_dup_property( package, szProductLanguage );
700 langid = atoiW(buffer);
702 msi_free(buffer);
703 msiobj_release (&package->hdr);
704 return langid;