~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/msi/install.c

Version: ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  * Implementation of the Microsoft Installer (msi.dll)
  3  *
  4  * Copyright 2005 Aric Stewart for CodeWeavers
  5  *
  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.
 10  *
 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.
 15  *
 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
 19  */
 20 
 21 /* Msi top level apis directly related to installs */
 22 
 23 #define COBJMACROS
 24 
 25 #include <stdarg.h>
 26 
 27 #include "windef.h"
 28 #include "winbase.h"
 29 #include "winerror.h"
 30 #include "wine/debug.h"
 31 #include "msi.h"
 32 #include "msidefs.h"
 33 #include "objbase.h"
 34 #include "oleauto.h"
 35 
 36 #include "msipriv.h"
 37 #include "msiserver.h"
 38 #include "wine/unicode.h"
 39 
 40 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 41 
 42 /***********************************************************************
 43  * MsiDoActionA       (MSI.@)
 44  */
 45 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
 46 {
 47     LPWSTR szwAction;
 48     UINT ret;
 49 
 50     TRACE("%s\n", debugstr_a(szAction));
 51 
 52     szwAction = strdupAtoW(szAction);
 53     if (szAction && !szwAction)
 54         return ERROR_FUNCTION_FAILED; 
 55 
 56     ret = MsiDoActionW( hInstall, szwAction );
 57     msi_free( szwAction );
 58     return ret;
 59 }
 60 
 61 /***********************************************************************
 62  * MsiDoActionW       (MSI.@)
 63  */
 64 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
 65 {
 66     MSIPACKAGE *package;
 67     UINT ret;
 68 
 69     TRACE("%s\n",debugstr_w(szAction));
 70 
 71     if (!szAction)
 72         return ERROR_INVALID_PARAMETER;
 73 
 74     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
 75     if (!package)
 76     {
 77         HRESULT hr;
 78         BSTR action;
 79         IWineMsiRemotePackage *remote_package;
 80 
 81         remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
 82         if (!remote_package)
 83             return ERROR_INVALID_HANDLE;
 84 
 85         action = SysAllocString( szAction );
 86         if (!action)
 87         {
 88             IWineMsiRemotePackage_Release( remote_package );
 89             return ERROR_OUTOFMEMORY;
 90         }
 91 
 92         hr = IWineMsiRemotePackage_DoAction( remote_package, action );
 93 
 94         SysFreeString( action );
 95         IWineMsiRemotePackage_Release( remote_package );
 96 
 97         if (FAILED(hr))
 98         {
 99             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
100                 return HRESULT_CODE(hr);
101 
102             return ERROR_FUNCTION_FAILED;
103         }
104 
105         return ERROR_SUCCESS;
106     }
107  
108     ret = ACTION_PerformUIAction( package, szAction, -1 );
109     msiobj_release( &package->hdr );
110 
111     return ret;
112 }
113 
114 /***********************************************************************
115  * MsiSequenceA       (MSI.@)
116  */
117 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
118 {
119     LPWSTR szwTable;
120     UINT ret;
121 
122     TRACE("%s\n", debugstr_a(szTable));
123 
124     szwTable = strdupAtoW(szTable);
125     if (szTable && !szwTable)
126         return ERROR_FUNCTION_FAILED; 
127 
128     ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
129     msi_free( szwTable );
130     return ret;
131 }
132 
133 /***********************************************************************
134  * MsiSequenceW       (MSI.@)
135  */
136 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
137 {
138     MSIPACKAGE *package;
139     UINT ret;
140 
141     TRACE("%s\n", debugstr_w(szTable));
142 
143     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
144     if (!package)
145     {
146         HRESULT hr;
147         BSTR table;
148         IWineMsiRemotePackage *remote_package;
149 
150         remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
151         if (!remote_package)
152             return ERROR_INVALID_HANDLE;
153 
154         table = SysAllocString( szTable );
155         if (!table)
156         {
157             IWineMsiRemotePackage_Release( remote_package );
158             return ERROR_OUTOFMEMORY;
159         }
160 
161         hr = IWineMsiRemotePackage_Sequence( remote_package, table, iSequenceMode );
162 
163         SysFreeString( table );
164         IWineMsiRemotePackage_Release( remote_package );
165 
166         if (FAILED(hr))
167         {
168             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
169                 return HRESULT_CODE(hr);
170 
171             return ERROR_FUNCTION_FAILED;
172         }
173 
174         return ERROR_SUCCESS;
175     }
176 
177     ret = MSI_Sequence( package, szTable, iSequenceMode );
178     msiobj_release( &package->hdr );
179  
180     return ret;
181 }
182 
183 UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
184 {
185     UINT len, r = ERROR_SUCCESS;
186 
187     if (awbuf->str.w && !sz )
188         return ERROR_INVALID_PARAMETER;
189 
190     if (!sz)
191         return r;
192  
193     if (awbuf->unicode)
194     {
195         len = lstrlenW( str );
196         if (awbuf->str.w) 
197             lstrcpynW( awbuf->str.w, str, *sz );
198     }
199     else
200     {
201         len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
202         if (len)
203             len--;
204         WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL );
205         if ( awbuf->str.a && *sz && (len >= *sz) )
206             awbuf->str.a[*sz - 1] = 0;
207     }
208 
209     if (awbuf->str.w && len >= *sz)
210         r = ERROR_MORE_DATA;
211     *sz = len;
212     return r;
213 }
214 
215 /***********************************************************************
216  * MsiGetTargetPath   (internal)
217  */
218 static UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
219                                       awstring *szPathBuf, LPDWORD pcchPathBuf )
220 {
221     MSIPACKAGE *package;
222     LPWSTR path;
223     UINT r = ERROR_FUNCTION_FAILED;
224 
225     if (!szFolder)
226         return ERROR_INVALID_PARAMETER;
227 
228     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
229     if (!package)
230     {
231         HRESULT hr;
232         IWineMsiRemotePackage *remote_package;
233         LPWSTR value = NULL;
234         BSTR folder;
235         DWORD len;
236 
237         remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
238         if (!remote_package)
239             return ERROR_INVALID_HANDLE;
240 
241         folder = SysAllocString( szFolder );
242         if (!folder)
243         {
244             IWineMsiRemotePackage_Release( remote_package );
245             return ERROR_OUTOFMEMORY;
246         }
247 
248         len = 0;
249         hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder,
250                                                   NULL, &len );
251         if (FAILED(hr))
252             goto done;
253 
254         len++;
255         value = msi_alloc(len * sizeof(WCHAR));
256         if (!value)
257         {
258             r = ERROR_OUTOFMEMORY;
259             goto done;
260         }
261 
262         hr = IWineMsiRemotePackage_GetTargetPath( remote_package, folder,
263                                                   (BSTR *)value, &len);
264         if (FAILED(hr))
265             goto done;
266 
267         r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
268 
269 done:
270         IWineMsiRemotePackage_Release( remote_package );
271         SysFreeString( folder );
272         msi_free( value );
273 
274         if (FAILED(hr))
275         {
276             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
277                 return HRESULT_CODE(hr);
278 
279             return ERROR_FUNCTION_FAILED;
280         }
281 
282         return r;
283     }
284 
285     path = resolve_folder( package, szFolder, FALSE, FALSE, TRUE, NULL );
286     msiobj_release( &package->hdr );
287 
288     if (!path)
289         return ERROR_DIRECTORY;
290 
291     r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
292     msi_free( path );
293     return r;
294 }
295 
296 /***********************************************************************
297  * MsiGetTargetPathA        (MSI.@)
298  */
299 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, 
300                                LPSTR szPathBuf, LPDWORD pcchPathBuf )
301 {
302     LPWSTR szwFolder;
303     awstring path;
304     UINT r;
305 
306     TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
307 
308     szwFolder = strdupAtoW(szFolder);
309     if (szFolder && !szwFolder)
310         return ERROR_FUNCTION_FAILED; 
311 
312     path.unicode = FALSE;
313     path.str.a = szPathBuf;
314 
315     r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
316 
317     msi_free( szwFolder );
318 
319     return r;
320 }
321 
322 /***********************************************************************
323  * MsiGetTargetPathW        (MSI.@)
324  */
325 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
326                                LPWSTR szPathBuf, LPDWORD pcchPathBuf )
327 {
328     awstring path;
329 
330     TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
331 
332     path.unicode = TRUE;
333     path.str.w = szPathBuf;
334 
335     return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
336 }
337 
338 /***********************************************************************
339  * MsiGetSourcePath   (internal)
340  */
341 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
342                                awstring *szPathBuf, LPDWORD pcchPathBuf )
343 {
344     MSIPACKAGE *package;
345     LPWSTR path;
346     UINT r = ERROR_FUNCTION_FAILED;
347 
348     TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
349 
350     if (!szFolder)
351         return ERROR_INVALID_PARAMETER;
352 
353     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
354     if (!package)
355     {
356         HRESULT hr;
357         IWineMsiRemotePackage *remote_package;
358         LPWSTR value = NULL;
359         BSTR folder;
360         DWORD len;
361 
362         remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
363         if (!remote_package)
364             return ERROR_INVALID_HANDLE;
365 
366         folder = SysAllocString( szFolder );
367         if (!folder)
368         {
369             IWineMsiRemotePackage_Release( remote_package );
370             return ERROR_OUTOFMEMORY;
371         }
372 
373         len = 0;
374         hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder,
375                                                   NULL, &len );
376         if (FAILED(hr))
377             goto done;
378 
379         len++;
380         value = msi_alloc(len * sizeof(WCHAR));
381         if (!value)
382         {
383             r = ERROR_OUTOFMEMORY;
384             goto done;
385         }
386 
387         hr = IWineMsiRemotePackage_GetSourcePath( remote_package, folder,
388                                                   (BSTR *)value, &len);
389         if (FAILED(hr))
390             goto done;
391 
392         r = msi_strcpy_to_awstring( value, szPathBuf, pcchPathBuf );
393 
394 done:
395         IWineMsiRemotePackage_Release( remote_package );
396         SysFreeString( folder );
397         msi_free( value );
398 
399         if (FAILED(hr))
400         {
401             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
402                 return HRESULT_CODE(hr);
403 
404             return ERROR_FUNCTION_FAILED;
405         }
406 
407         return r;
408     }
409 
410     if (szPathBuf->str.w && !pcchPathBuf )
411     {
412         msiobj_release( &package->hdr );
413         return ERROR_INVALID_PARAMETER;
414     }
415 
416     path = resolve_folder(package, szFolder, TRUE, FALSE, TRUE, NULL);
417     msiobj_release( &package->hdr );
418 
419     TRACE("path = %s\n",debugstr_w(path));
420     if (!path)
421         return ERROR_DIRECTORY;
422 
423     r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
424     msi_free( path );
425     return r;
426 }
427 
428 /***********************************************************************
429  * MsiGetSourcePathA     (MSI.@)
430  */
431 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder, 
432                                LPSTR szPathBuf, LPDWORD pcchPathBuf )
433 {
434     LPWSTR folder;
435     awstring str;
436     UINT r;
437 
438     TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
439 
440     str.unicode = FALSE;
441     str.str.a = szPathBuf;
442 
443     folder = strdupAtoW( szFolder );
444     r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
445     msi_free( folder );
446 
447     return r;
448 }
449 
450 /***********************************************************************
451  * MsiGetSourcePathW     (MSI.@)
452  */
453 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
454                                LPWSTR szPathBuf, LPDWORD pcchPathBuf )
455 {
456     awstring str;
457 
458     TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
459 
460     str.unicode = TRUE;
461     str.str.w = szPathBuf;
462 
463     return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
464 }
465 
466 /***********************************************************************
467  * MsiSetTargetPathA  (MSI.@)
468  */
469 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
470                                LPCSTR szFolderPath )
471 {
472     LPWSTR szwFolder = NULL, szwFolderPath = NULL;
473     UINT rc = ERROR_OUTOFMEMORY;
474 
475     if ( !szFolder || !szFolderPath )
476         return ERROR_INVALID_PARAMETER;
477 
478     szwFolder = strdupAtoW(szFolder);
479     szwFolderPath = strdupAtoW(szFolderPath);
480     if (!szwFolder || !szwFolderPath)
481         goto end;
482 
483     rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
484 
485 end:
486     msi_free(szwFolder);
487     msi_free(szwFolderPath);
488 
489     return rc;
490 }
491 
492 /*
493  * Ok my original interpretation of this was wrong. And it looks like msdn has
494  * changed a bit also. The given folder path does not have to actually already
495  * exist, it just cannot be read only and must be a legal folder path.
496  */
497 UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, 
498                              LPCWSTR szFolderPath)
499 {
500     DWORD attrib;
501     LPWSTR path = NULL;
502     LPWSTR path2 = NULL;
503     MSIFOLDER *folder;
504     MSIFILE *file;
505 
506     TRACE("%p %s %s\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
507 
508     attrib = GetFileAttributesW(szFolderPath);
509     /* native MSI tests writeability by making temporary files at each drive */
510     if ( attrib != INVALID_FILE_ATTRIBUTES &&
511           (attrib & FILE_ATTRIBUTE_OFFLINE ||
512            attrib & FILE_ATTRIBUTE_READONLY))
513         return ERROR_FUNCTION_FAILED;
514 
515     path = resolve_folder(package,szFolder,FALSE,FALSE,FALSE,&folder);
516     if (!path)
517         return ERROR_DIRECTORY;
518 
519     msi_free(folder->Property);
520     folder->Property = build_directory_name(2, szFolderPath, NULL);
521 
522     if (lstrcmpiW(path, folder->Property) == 0)
523     {
524         /*
525          *  Resolved Target has not really changed, so just 
526          *  set this folder and do not recalculate everything.
527          */
528         msi_free(folder->ResolvedTarget);
529         folder->ResolvedTarget = NULL;
530         path2 = resolve_folder(package,szFolder,FALSE,TRUE,FALSE,NULL);
531         msi_free(path2);
532     }
533     else
534     {
535         MSIFOLDER *f;
536 
537         LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
538         {
539             msi_free(f->ResolvedTarget);
540             f->ResolvedTarget=NULL;
541         }
542 
543         LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
544         {
545             path2 = resolve_folder(package, f->Directory, FALSE, TRUE, FALSE, NULL);
546             msi_free(path2);
547         }
548 
549         LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
550         {
551             MSICOMPONENT *comp = file->Component;
552             LPWSTR p;
553 
554             if (!comp)
555                 continue;
556 
557             p = resolve_folder(package, comp->Directory, FALSE, FALSE, FALSE, NULL);
558             msi_free(file->TargetPath);
559 
560             file->TargetPath = build_directory_name(2, p, file->FileName);
561             msi_free(p);
562         }
563     }
564     msi_free(path);
565 
566     return ERROR_SUCCESS;
567 }
568 
569 /***********************************************************************
570  * MsiSetTargetPathW  (MSI.@)
571  */
572 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, 
573                              LPCWSTR szFolderPath)
574 {
575     MSIPACKAGE *package;
576     UINT ret;
577 
578     TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
579 
580     if ( !szFolder || !szFolderPath )
581         return ERROR_INVALID_PARAMETER;
582 
583     package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
584     if (!package)
585     {
586         HRESULT hr;
587         BSTR folder, path;
588         IWineMsiRemotePackage *remote_package;
589 
590         remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
591         if (!remote_package)
592             return ERROR_INVALID_HANDLE;
593 
594         folder = SysAllocString( szFolder );
595         path = SysAllocString( szFolderPath );
596         if (!folder || !path)
597         {
598             SysFreeString(folder);
599             SysFreeString(path);
600             IWineMsiRemotePackage_Release( remote_package );
601             return ERROR_OUTOFMEMORY;
602         }
603 
604         hr = IWineMsiRemotePackage_SetTargetPath( remote_package, folder, path );
605 
606         SysFreeString(folder);
607         SysFreeString(path);
608         IWineMsiRemotePackage_Release( remote_package );
609 
610         if (FAILED(hr))
611         {
612             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
613                 return HRESULT_CODE(hr);
614 
615             return ERROR_FUNCTION_FAILED;
616         }
617 
618         return ERROR_SUCCESS;
619     }
620 
621     ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
622     msiobj_release( &package->hdr );
623     return ret;
624 }
625 
626 /***********************************************************************
627  *           MsiGetMode    (MSI.@)
628  *
629  * Returns an internal installer state (if it is running in a mode iRunMode)
630  *
631  * PARAMS
632  *   hInstall    [I]  Handle to the installation
633  *   hRunMode    [I]  Checking run mode
634  *        MSIRUNMODE_ADMIN             Administrative mode
635  *        MSIRUNMODE_ADVERTISE         Advertisement mode
636  *        MSIRUNMODE_MAINTENANCE       Maintenance mode
637  *        MSIRUNMODE_ROLLBACKENABLED   Rollback is enabled
638  *        MSIRUNMODE_LOGENABLED        Log file is writing
639  *        MSIRUNMODE_OPERATIONS        Operations in progress??
640  *        MSIRUNMODE_REBOOTATEND       We need to reboot after installation completed
641  *        MSIRUNMODE_REBOOTNOW         We need to reboot to continue the installation
642  *        MSIRUNMODE_CABINET           Files from cabinet are installed
643  *        MSIRUNMODE_SOURCESHORTNAMES  Long names in source files is suppressed
644  *        MSIRUNMODE_TARGETSHORTNAMES  Long names in destination files is suppressed
645  *        MSIRUNMODE_RESERVED11        Reserved
646  *        MSIRUNMODE_WINDOWS9X         Running under Windows95/98
647  *        MSIRUNMODE_ZAWENABLED        Demand installation is supported
648  *        MSIRUNMODE_RESERVED14        Reserved
649  *        MSIRUNMODE_RESERVED15        Reserved
650  *        MSIRUNMODE_SCHEDULED         called from install script
651  *        MSIRUNMODE_ROLLBACK          called from rollback script
652  *        MSIRUNMODE_COMMIT            called from commit script
653  *
654  * RETURNS
655  *    In the state: TRUE
656  *    Not in the state: FALSE
657  *
658  */
659 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
660 {
661     MSIPACKAGE *package;
662     BOOL r = FALSE;
663 
664     package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
665     if (!package)
666     {
667         BOOL ret;
668         HRESULT hr;
669         IWineMsiRemotePackage *remote_package;
670 
671         remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
672         if (!remote_package)
673             return FALSE;
674 
675         hr = IWineMsiRemotePackage_GetMode(remote_package, iRunMode, &ret);
676         IWineMsiRemotePackage_Release(remote_package);
677 
678         if (hr == S_OK)
679             return ret;
680 
681         return FALSE;
682     }
683 
684     switch (iRunMode)
685     {
686     case MSIRUNMODE_WINDOWS9X:
687         if (GetVersion() & 0x80000000)
688             r = TRUE;
689         break;
690 
691     case MSIRUNMODE_OPERATIONS:
692     case MSIRUNMODE_RESERVED11:
693     case MSIRUNMODE_RESERVED14:
694     case MSIRUNMODE_RESERVED15:
695         break;
696 
697     case MSIRUNMODE_SCHEDULED:
698         r = package->scheduled_action_running;
699         break;
700 
701     case MSIRUNMODE_ROLLBACK:
702         r = package->rollback_action_running;
703         break;
704 
705     case MSIRUNMODE_COMMIT:
706         r = package->commit_action_running;
707         break;
708 
709     default:
710         FIXME("%ld %d\n", hInstall, iRunMode);
711         r = TRUE;
712     }
713 
714     return r;
715 }
716 
717 /***********************************************************************
718  *           MsiSetMode    (MSI.@)
719  */
720 BOOL WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
721 {
722     switch (iRunMode)
723     {
724     case MSIRUNMODE_RESERVED11:
725     case MSIRUNMODE_WINDOWS9X:
726     case MSIRUNMODE_RESERVED14:
727     case MSIRUNMODE_RESERVED15:
728         return FALSE;
729     default:
730         FIXME("%ld %d %d\n", hInstall, iRunMode, fState);
731     }
732     return TRUE;
733 }
734 
735 /***********************************************************************
736  * MsiSetFeatureStateA (MSI.@)
737  *
738  * According to the docs, when this is called it immediately recalculates
739  * all the component states as well
740  */
741 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
742                                 INSTALLSTATE iState)
743 {
744     LPWSTR szwFeature = NULL;
745     UINT rc;
746 
747     szwFeature = strdupAtoW(szFeature);
748 
749     if (!szwFeature)
750         return ERROR_FUNCTION_FAILED;
751    
752     rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); 
753 
754     msi_free(szwFeature);
755 
756     return rc;
757 }
758 
759 
760 
761 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
762                                 INSTALLSTATE iState)
763 {
764     UINT rc = ERROR_SUCCESS;
765     MSIFEATURE *feature, *child;
766 
767     TRACE("%s %i\n", debugstr_w(szFeature), iState);
768 
769     feature = get_loaded_feature(package,szFeature);
770     if (!feature)
771         return ERROR_UNKNOWN_FEATURE;
772 
773     if (iState == INSTALLSTATE_ADVERTISED && 
774         feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
775         return ERROR_FUNCTION_FAILED;
776 
777     msi_feature_set_state(package, feature, iState);
778 
779     ACTION_UpdateComponentStates(package,szFeature);
780 
781     /* update all the features that are children of this feature */
782     LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
783     {
784         if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
785             MSI_SetFeatureStateW(package, child->Feature, iState);
786     }
787     
788     return rc;
789 }
790 
791 /***********************************************************************
792  * MsiSetFeatureStateW (MSI.@)
793  */
794 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
795                                 INSTALLSTATE iState)
796 {
797     MSIPACKAGE* package;
798     UINT rc = ERROR_SUCCESS;
799 
800     TRACE("%s %i\n",debugstr_w(szFeature), iState);
801 
802     package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
803     if (!package)
804     {
805         HRESULT hr;
806         BSTR feature;
807         IWineMsiRemotePackage *remote_package;
808 
809         remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
810         if (!remote_package)
811             return ERROR_INVALID_HANDLE;
812 
813         feature = SysAllocString(szFeature);
814         if (!feature)
815         {
816             IWineMsiRemotePackage_Release(remote_package);
817             return ERROR_OUTOFMEMORY;
818         }
819 
820         hr = IWineMsiRemotePackage_SetFeatureState(remote_package, feature, iState);
821 
822         SysFreeString(feature);
823         IWineMsiRemotePackage_Release(remote_package);
824 
825         if (FAILED(hr))
826         {
827             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
828                 return HRESULT_CODE(hr);
829 
830             return ERROR_FUNCTION_FAILED;
831         }
832 
833         return ERROR_SUCCESS;
834     }
835 
836     rc = MSI_SetFeatureStateW(package,szFeature,iState);
837 
838     msiobj_release( &package->hdr );
839     return rc;
840 }
841 
842 /***********************************************************************
843 * MsiGetFeatureStateA   (MSI.@)
844 */
845 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
846                   INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
847 {
848     LPWSTR szwFeature = NULL;
849     UINT rc;
850     
851     szwFeature = strdupAtoW(szFeature);
852 
853     rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
854 
855     msi_free( szwFeature);
856 
857     return rc;
858 }
859 
860 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
861                   INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
862 {
863     MSIFEATURE *feature;
864 
865     feature = get_loaded_feature(package,szFeature);
866     if (!feature)
867         return ERROR_UNKNOWN_FEATURE;
868 
869     if (piInstalled)
870         *piInstalled = feature->Installed;
871 
872     if (piAction)
873         *piAction = feature->Action;
874 
875     TRACE("returning %i %i\n", feature->Installed, feature->Action);
876 
877     return ERROR_SUCCESS;
878 }
879 
880 /***********************************************************************
881 * MsiGetFeatureStateW   (MSI.@)
882 */
883 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
884                   INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
885 {
886     MSIPACKAGE* package;
887     UINT ret;
888 
889     TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
890 
891     package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
892     if (!package)
893     {
894         HRESULT hr;
895         BSTR feature;
896         IWineMsiRemotePackage *remote_package;
897 
898         remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
899         if (!remote_package)
900             return ERROR_INVALID_HANDLE;
901 
902         feature = SysAllocString(szFeature);
903         if (!feature)
904         {
905             IWineMsiRemotePackage_Release(remote_package);
906             return ERROR_OUTOFMEMORY;
907         }
908 
909         hr = IWineMsiRemotePackage_GetFeatureState(remote_package, feature,
910                                                    piInstalled, piAction);
911 
912         SysFreeString(feature);
913         IWineMsiRemotePackage_Release(remote_package);
914 
915         if (FAILED(hr))
916         {
917             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
918                 return HRESULT_CODE(hr);
919 
920             return ERROR_FUNCTION_FAILED;
921         }
922 
923         return ERROR_SUCCESS;
924     }
925 
926     ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
927     msiobj_release( &package->hdr );
928     return ret;
929 }
930 
931 /***********************************************************************
932 * MsiGetFeatureCostA   (MSI.@)
933 */
934 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
935                   MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
936 {
937     FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature),
938           iCostTree, iState, piCost);
939     if (piCost) *piCost = 0;
940     return ERROR_SUCCESS;
941 }
942 
943 /***********************************************************************
944 * MsiGetFeatureCostW   (MSI.@)
945 */
946 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
947                   MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
948 {
949     FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
950           iCostTree, iState, piCost);
951     if (piCost) *piCost = 0;
952     return ERROR_SUCCESS;
953 }
954 
955 /***********************************************************************
956  * MsiSetComponentStateA (MSI.@)
957  */
958 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
959                                   INSTALLSTATE iState)
960 {
961     UINT rc;
962     LPWSTR szwComponent = strdupAtoW(szComponent);
963 
964     rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
965 
966     msi_free(szwComponent);
967 
968     return rc;
969 }
970 
971 /***********************************************************************
972  * MsiGetComponentStateA (MSI.@)
973  */
974 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
975                   INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
976 {
977     LPWSTR szwComponent= NULL;
978     UINT rc;
979     
980     szwComponent= strdupAtoW(szComponent);
981 
982     rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
983 
984     msi_free( szwComponent);
985 
986     return rc;
987 }
988 
989 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
990                                    INSTALLSTATE iState)
991 {
992     MSICOMPONENT *comp;
993 
994     TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
995 
996     comp = get_loaded_component(package, szComponent);
997     if (!comp)
998         return ERROR_UNKNOWN_COMPONENT;
999 
1000     comp->Installed = iState;
1001 
1002     return ERROR_SUCCESS;
1003 }
1004 
1005 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
1006                   INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1007 {
1008     MSICOMPONENT *comp;
1009 
1010     TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
1011            piInstalled, piAction);
1012 
1013     comp = get_loaded_component(package,szComponent);
1014     if (!comp)
1015         return ERROR_UNKNOWN_COMPONENT;
1016 
1017     if (piInstalled)
1018         *piInstalled = comp->Installed;
1019 
1020     if (piAction)
1021         *piAction = comp->Action;
1022 
1023     TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
1024 
1025     return ERROR_SUCCESS;
1026 }
1027