Sync trunk.
[reactos.git] / dll / win32 / msi / helpers.c
index cffc09a..54d2199 100644 (file)
 #include <stdarg.h>
 
 #include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
 #include "wine/debug.h"
 #include "msipriv.h"
 #include "winuser.h"
-#include "winreg.h"
-#include "shlwapi.h"
 #include "wine/unicode.h"
 #include "msidefs.h"
 
@@ -41,11 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
 static const WCHAR cszTargetDir[] = {'T','A','R','G','E','T','D','I','R',0};
 static const WCHAR cszDatabase[]={'D','A','T','A','B','A','S','E',0};
 
-const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};
-const WCHAR cszSOURCEDIR[] = {'S','O','U','R','C','E','D','I','R',0};
-const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};
-const WCHAR cszbs[]={'\\',0};
-
 LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name )
 {
     LPWSTR SystemFolder, dest, FilePath;
@@ -56,7 +47,7 @@ LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name )
     static const WCHAR szFolder[] =
         {'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
 
-    SystemFolder = msi_dup_property( package, szFolder );
+    SystemFolder = msi_dup_property( package->db, szFolder );
 
     dest = build_directory_name(3, SystemFolder, szInstaller, package->ProductCode);
 
@@ -169,11 +160,11 @@ static LPWSTR get_source_root( MSIPACKAGE *package )
 {
     LPWSTR path, p;
 
-    path = msi_dup_property( package, cszSourceDir );
+    path = msi_dup_property( package->db, cszSourceDir );
     if (path)
         return path;
 
-    path = msi_dup_property( package, cszDatabase );
+    path = msi_dup_property( package->db, cszDatabase );
     if (path)
     {
         p = strrchrW(path,'\\');
@@ -222,6 +213,34 @@ static void clean_spaces_from_path( LPWSTR p )
     }
 }
 
+LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file)
+{
+    LPWSTR p, path;
+
+    TRACE("Working to resolve source of file %s\n", debugstr_w(file->File));
+
+    if (file->IsCompressed)
+        return NULL;
+
+    p = resolve_folder(package, file->Component->Directory,
+                       TRUE, FALSE, TRUE, NULL);
+    path = build_directory_name(2, p, file->ShortName);
+
+    if (file->LongName &&
+        GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
+    {
+        msi_free(path);
+        path = build_directory_name(2, p, file->LongName);
+    }
+
+    msi_free(p);
+
+    TRACE("file %s source resolves to %s\n", debugstr_w(file->File),
+          debugstr_w(path));
+
+    return path;
+}
+
 LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 
                       BOOL set_prop, BOOL load_prop, MSIFOLDER **folder)
 {
@@ -246,19 +265,19 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
         if (!f->ResolvedTarget && !f->Property)
         {
             LPWSTR check_path;
-            check_path = msi_dup_property( package, cszTargetDir );
+            check_path = msi_dup_property( package->db, cszTargetDir );
             if (!check_path)
             {
-                check_path = msi_dup_property( package, cszRootDrive );
+                check_path = msi_dup_property( package->db, cszRootDrive );
                 if (set_prop)
-                    MSI_SetPropertyW(package,cszTargetDir,check_path);
+                    msi_set_property( package->db, cszTargetDir, check_path );
             }
 
             /* correct misbuilt target dir */
             path = build_directory_name(2, check_path, NULL);
             clean_spaces_from_path( path );
             if (strcmpiW(path,check_path)!=0)
-                MSI_SetPropertyW(package,cszTargetDir,path);
+                msi_set_property( package->db, cszTargetDir, path );
             msi_free(check_path);
 
             f->ResolvedTarget = path;
@@ -291,11 +310,11 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
 
         TRACE("   internally set to %s\n",debugstr_w(path));
         if (set_prop)
-            MSI_SetPropertyW( package, name, path );
+            msi_set_property( package->db, name, path );
         return path;
     }
 
-    if (!source && load_prop && (path = msi_dup_property( package, name )))
+    if (!source && load_prop && (path = msi_dup_property( package->db, name )))
     {
         f->ResolvedTarget = strdupW( path );
         TRACE("   property set to %s\n", debugstr_w(path));
@@ -319,38 +338,18 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
         f->ResolvedTarget = strdupW( path );
         TRACE("target -> %s\n", debugstr_w(path));
         if (set_prop)
-            MSI_SetPropertyW(package,name,path);
+            msi_set_property( package->db, name, path );
     }
     else
     {
-        /* source may be in a few different places ... check each of them */
         path = NULL;
 
-        /* try the long path directory */
-        if (f->SourceLongPath)
-        {
-            path = build_directory_name( 3, p, f->SourceLongPath, NULL );
-            if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
-            {
-                msi_free( path );
-                path = NULL;
-            }
-        }
-
-        /* try the short path directory */
-        if (!path && f->SourceShortPath)
-        {
-            path = build_directory_name( 3, p, f->SourceShortPath, NULL );
-            if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
-            {
-                msi_free( path );
-                path = NULL;
-            }
-        }
-
-        /* try the root of the install */
-        if (!path)
+        if (package->WordCount & msidbSumInfoSourceTypeCompressed)
             path = get_source_root( package );
+        else if (package->WordCount & msidbSumInfoSourceTypeSFN)
+            path = build_directory_name( 3, p, f->SourceShortPath, NULL );
+        else
+            path = build_directory_name( 3, p, f->SourceLongPath, NULL );
 
         TRACE("source -> %s\n", debugstr_w(path));
         f->ResolvedSource = strdupW( path );
@@ -413,7 +412,7 @@ UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action)
 
 void msi_free_action_script(MSIPACKAGE *package, UINT script)
 {
-    int i;
+    UINT i;
     for (i = 0; i < package->script->ActionCount[script]; i++)
         msi_free(package->script->Actions[script][i]);
 
@@ -422,232 +421,6 @@ void msi_free_action_script(MSIPACKAGE *package, UINT script)
     package->script->ActionCount[script] = 0;
 }
 
-static void remove_tracked_tempfiles(MSIPACKAGE* package)
-{
-    struct list *item, *cursor;
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles )
-    {
-        MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry );
-
-        list_remove( &temp->entry );
-        TRACE("deleting temp file %s\n", debugstr_w( temp->Path ));
-        if (!DeleteFileW( temp->Path ))
-            ERR("failed to delete %s\n", debugstr_w( temp->Path ));
-        msi_free( temp->Path );
-        msi_free( temp );
-    }
-}
-
-static void free_feature( MSIFEATURE *feature )
-{
-    struct list *item, *cursor;
-
-    LIST_FOR_EACH_SAFE( item, cursor, &feature->Children )
-    {
-        FeatureList *fl = LIST_ENTRY( item, FeatureList, entry );
-        list_remove( &fl->entry );
-        msi_free( fl );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &feature->Components )
-    {
-        ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
-        list_remove( &cl->entry );
-        msi_free( cl );
-    }
-    msi_free( feature->Feature );
-    msi_free( feature->Feature_Parent );
-    msi_free( feature->Directory );
-    msi_free( feature->Description );
-    msi_free( feature->Title );
-    msi_free( feature );
-}
-
-static void free_extension( MSIEXTENSION *ext )
-{
-    struct list *item, *cursor;
-
-    LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs )
-    {
-        MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry );
-
-        list_remove( &verb->entry );
-        msi_free( verb->Verb );
-        msi_free( verb->Command );
-        msi_free( verb->Argument );
-        msi_free( verb );
-    }
-
-    msi_free( ext->Extension );
-    msi_free( ext->ProgIDText );
-    msi_free( ext );
-}
-
-/* Called when the package is being closed */
-void ACTION_free_package_structures( MSIPACKAGE* package)
-{
-    INT i;
-    struct list *item, *cursor;
-
-    TRACE("Freeing package action data\n");
-
-    remove_tracked_tempfiles(package);
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->features )
-    {
-        MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry );
-        list_remove( &feature->entry );
-        free_feature( feature );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->folders )
-    {
-        MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
-
-        list_remove( &folder->entry );
-        msi_free( folder->Parent );
-        msi_free( folder->Directory );
-        msi_free( folder->TargetDefault );
-        msi_free( folder->SourceLongPath );
-        msi_free( folder->SourceShortPath );
-        msi_free( folder->ResolvedTarget );
-        msi_free( folder->ResolvedSource );
-        msi_free( folder->Property );
-        msi_free( folder );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->components )
-    {
-        MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
-
-        list_remove( &comp->entry );
-        msi_free( comp->Component );
-        msi_free( comp->ComponentId );
-        msi_free( comp->Directory );
-        msi_free( comp->Condition );
-        msi_free( comp->KeyPath );
-        msi_free( comp->FullKeypath );
-        msi_free( comp );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->files )
-    {
-        MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );
-
-        list_remove( &file->entry );
-        msi_free( file->File );
-        msi_free( file->FileName );
-        msi_free( file->ShortName );
-        msi_free( file->LongName );
-        msi_free( file->Version );
-        msi_free( file->Language );
-        msi_free( file->SourcePath );
-        msi_free( file->TargetPath );
-        msi_free( file );
-    }
-
-    /* clean up extension, progid, class and verb structures */
-    LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
-    {
-        MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry );
-
-        list_remove( &cls->entry );
-        msi_free( cls->clsid );
-        msi_free( cls->Context );
-        msi_free( cls->Description );
-        msi_free( cls->FileTypeMask );
-        msi_free( cls->IconPath );
-        msi_free( cls->DefInprocHandler );
-        msi_free( cls->DefInprocHandler32 );
-        msi_free( cls->Argument );
-        msi_free( cls->ProgIDText );
-        msi_free( cls );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->extensions )
-    {
-        MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry );
-
-        list_remove( &ext->entry );
-        free_extension( ext );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->progids )
-    {
-        MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry );
-
-        list_remove( &progid->entry );
-        msi_free( progid->ProgID );
-        msi_free( progid->Description );
-        msi_free( progid->IconPath );
-        msi_free( progid );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->mimes )
-    {
-        MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry );
-
-        list_remove( &mt->entry );
-        msi_free( mt->clsid );
-        msi_free( mt->ContentType );
-        msi_free( mt );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->appids )
-    {
-        MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry );
-
-        list_remove( &appid->entry );
-        msi_free( appid->AppID );
-        msi_free( appid->RemoteServerName );
-        msi_free( appid->LocalServer );
-        msi_free( appid->ServiceParameters );
-        msi_free( appid->DllSurrogate );
-        msi_free( appid );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_info )
-    {
-        MSISOURCELISTINFO *info = LIST_ENTRY( item, MSISOURCELISTINFO, entry );
-
-        list_remove( &info->entry );
-        msi_free( info->value );
-       msi_free( info );
-    }
-
-    LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_media )
-    {
-        MSIMEDIADISK *info = LIST_ENTRY( item, MSIMEDIADISK, entry );
-
-        list_remove( &info->entry );
-        msi_free( info->volume_label );
-        msi_free( info->disk_prompt );
-       msi_free( info );
-    }
-
-    if (package->script)
-    {
-        for (i = 0; i < TOTAL_SCRIPTS; i++)
-            msi_free_action_script(package, i);
-
-        for (i = 0; i < package->script->UniqueActionsCount; i++)
-            msi_free(package->script->UniqueActions[i]);
-
-        msi_free(package->script->UniqueActions);
-        msi_free(package->script);
-    }
-
-    msi_free(package->BaseURL);
-    msi_free(package->PackagePath);
-    msi_free(package->ProductCode);
-    msi_free(package->ActionFormat);
-    msi_free(package->LastAction);
-
-    /* cleanup control event subscriptions */
-    ControlEvent_CleanupSubscriptions(package);
-}
-
 /*
  *  build_directory_name()
  *
@@ -694,7 +467,7 @@ LPWSTR build_directory_name(DWORD count, ...)
             continue;
         strcatW(dir, str);
         if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
-            strcatW(dir, cszbs);
+            strcatW(dir, szBackSlash);
     }
     return dir;
 }
@@ -812,31 +585,6 @@ void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
     msiobj_release(&row->hdr);
 }
 
-BOOL ACTION_VerifyComponentForAction( const MSICOMPONENT* comp, INSTALLSTATE check )
-{
-    if (!comp)
-        return FALSE;
-
-    if (comp->Installed == check)
-        return FALSE;
-
-    if (comp->ActionRequest == check)
-        return TRUE;
-    else
-        return FALSE;
-}
-
-BOOL ACTION_VerifyFeatureForAction( const MSIFEATURE* feature, INSTALLSTATE check )
-{
-    if (!feature)
-        return FALSE;
-
-    if (feature->ActionRequest == check)
-        return TRUE;
-    else
-        return FALSE;
-}
-
 void reduce_to_longfilename(WCHAR* filename)
 {
     LPWSTR p = strchrW(filename,'|');
@@ -844,13 +592,6 @@ void reduce_to_longfilename(WCHAR* filename)
         memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));
 }
 
-void reduce_to_shortfilename(WCHAR* filename)
-{
-    LPWSTR p = strchrW(filename,'|');
-    if (p)
-        *p = 0;
-}
-
 LPWSTR create_component_advertise_string(MSIPACKAGE* package, 
                 MSICOMPONENT* component, LPCWSTR feature)
 {
@@ -915,7 +656,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
             continue;
  
         if (newstate == INSTALLSTATE_LOCAL)
-            msi_component_set_state( component, INSTALLSTATE_LOCAL );
+            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
         else 
         {
             ComponentList *clist;
@@ -923,7 +664,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
 
             component->hasLocalFeature = FALSE;
 
-            msi_component_set_state( component, newstate );
+            msi_component_set_state(package, component, newstate);
 
             /*if any other feature wants is local we need to set it local*/
             LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
@@ -946,14 +687,14 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
                         if (component->Attributes & msidbComponentAttributesOptional)
                         {
                             if (f->Attributes & msidbFeatureAttributesFavorSource)
-                                msi_component_set_state( component, INSTALLSTATE_SOURCE );
+                                msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
                             else
-                                msi_component_set_state( component, INSTALLSTATE_LOCAL );
+                                msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
                         }
                         else if (component->Attributes & msidbComponentAttributesSourceOnly)
-                            msi_component_set_state( component, INSTALLSTATE_SOURCE );
+                            msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
                         else
-                            msi_component_set_state( component, INSTALLSTATE_LOCAL );
+                            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
                     }
                 }
             }
@@ -972,7 +713,7 @@ UINT register_unique_action(MSIPACKAGE *package, LPCWSTR action)
     if (!package->script)
         return FALSE;
 
-    TRACE("Registering Action %s as having fun\n",debugstr_w(action));
+    TRACE("Registering %s as unique action\n", debugstr_w(action));
     
     count = package->script->UniqueActionsCount;
     package->script->UniqueActionsCount++;
@@ -990,7 +731,7 @@ UINT register_unique_action(MSIPACKAGE *package, LPCWSTR action)
 
 BOOL check_unique_action(const MSIPACKAGE *package, LPCWSTR action)
 {
-    INT i;
+    UINT i;
 
     if (!package->script)
         return FALSE;
@@ -1044,147 +785,3 @@ WCHAR* generate_error_string(MSIPACKAGE *package, UINT error, DWORD count, ... )
     msiobj_release( &rec->hdr );
     return data;
 }
-
-void msi_ui_error( DWORD msg_id, DWORD type )
-{
-    WCHAR text[2048];
-
-    static const WCHAR title[] = {
-        'W','i','n','d','o','w','s',' ','I','n','s','t','a','l','l','e','r',0
-    };
-
-    if (!MsiLoadStringW( -1, msg_id, text, sizeof(text) / sizeof(text[0]),
-                         MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) ))
-        return;
-
-    MessageBoxW( NULL, text, title, type );
-}
-
-typedef struct
-{
-    MSIPACKAGE *package;
-    MSIMEDIAINFO *mi;
-    MSIFILE *file;
-    LPWSTR destination;
-} CabData;
-
-static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
-{
-    TRACE("(%d)\n", fdint);
-
-    switch (fdint)
-    {
-    case fdintNEXT_CABINET:
-    {
-        ERR("continuous cabinets not handled\n");
-        return 0;
-    }
-
-    case fdintCOPY_FILE:
-    {
-        CabData *data = (CabData*) pfdin->pv;
-        LPWSTR file, path;
-        DWORD attrs, size;
-        HANDLE handle;
-        MSIFILE *f;
-
-        file = strdupAtoW(pfdin->psz1);
-        f = get_loaded_file(data->package, file);
-        msi_free(file);
-
-        if (!f)
-        {
-            WARN("unknown file in cabinet (%s)\n",debugstr_a(pfdin->psz1));
-            return 0;
-        }
-
-        if (lstrcmpW(f->File, data->file->File))
-            return 0;
-
-        size = lstrlenW(data->destination) + lstrlenW(data->file->FileName) + 2;
-        path = msi_alloc(size * sizeof(WCHAR));
-        lstrcpyW(path, data->destination);
-        PathAddBackslashW(path);
-        lstrcatW(path, data->file->FileName);
-
-        TRACE("extracting %s\n", debugstr_w(path));
-
-        attrs = f->Attributes & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
-        if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
-
-        handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0,
-                             NULL, CREATE_ALWAYS, attrs, NULL);
-        if (handle == INVALID_HANDLE_VALUE)
-        {
-            if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
-                ERR("failed to create %s (error %d)\n",
-                    debugstr_w(path), GetLastError());
-
-            msi_free(path);
-            return 0;
-        }
-
-        msi_free(path);
-        return (INT_PTR)handle;
-    }
-
-    case fdintCLOSE_FILE_INFO:
-    {
-        FILETIME ft;
-        FILETIME ftLocal;
-        HANDLE handle = (HANDLE)pfdin->hf;
-
-        if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
-            return -1;
-        if (!LocalFileTimeToFileTime(&ft, &ftLocal))
-            return -1;
-        if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
-            return -1;
-        CloseHandle(handle);
-        return 1;
-    }
-
-    default:
-        return 0;
-    }
-}
-
-UINT msi_extract_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR destdir)
-{
-    MSIMEDIAINFO *mi;
-    CabData data;
-    UINT r;
-
-    mi = msi_alloc_zero(sizeof(MSIMEDIAINFO));
-    if (!mi)
-        return ERROR_OUTOFMEMORY;
-
-    r = msi_load_media_info(package, file, mi);
-    if (r != ERROR_SUCCESS)
-        goto done;
-
-    if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
-    {
-        r = find_published_source(package, mi);
-        if (r != ERROR_SUCCESS)
-        {
-            ERR("Cabinet not found: %s\n", debugstr_w(mi->source));
-            return ERROR_INSTALL_FAILURE;
-        }
-    }
-
-    data.package = package;
-    data.mi = mi;
-    data.file = file;
-    data.destination = destdir;
-
-    if (!msi_cabextract(package, mi, cabinet_notify, &data))
-    {
-        ERR("Failed to extract cabinet file\n");
-        r = ERROR_FUNCTION_FAILED;
-    }
-
-done:
-    msi_free_media_info(mi);
-    return r;
-}