#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"
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;
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);
{
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,'\\');
}
}
+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)
{
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;
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));
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 );
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]);
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()
*
continue;
strcatW(dir, str);
if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
- strcatW(dir, cszbs);
+ strcatW(dir, szBackSlash);
}
return dir;
}
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,'|');
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)
{
continue;
if (newstate == INSTALLSTATE_LOCAL)
- msi_component_set_state( component, INSTALLSTATE_LOCAL );
+ msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
else
{
ComponentList *clist;
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 )
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);
}
}
}
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++;
BOOL check_unique_action(const MSIPACKAGE *package, LPCWSTR action)
{
- INT i;
+ UINT i;
if (!package->script)
return FALSE;
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;
-}