msi: Clean up handling of temporary files.
This commit is contained in:
parent
20ef12a762
commit
17b05316a5
|
@ -2107,18 +2107,38 @@ BOOL msi_file_hash_matches( MSIFILE *file )
|
||||||
return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) );
|
return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static WCHAR *get_temp_dir( void )
|
static WCHAR *create_temp_dir( MSIDATABASE *db )
|
||||||
{
|
{
|
||||||
static UINT id;
|
static UINT id;
|
||||||
WCHAR tmp[MAX_PATH], dir[MAX_PATH];
|
WCHAR *ret;
|
||||||
|
|
||||||
GetTempPathW( MAX_PATH, tmp );
|
if (!db->tempfolder)
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
if (!GetTempFileNameW( tmp, szMsi, ++id, dir )) return NULL;
|
WCHAR tmp[MAX_PATH];
|
||||||
if (CreateDirectoryW( dir, NULL )) break;
|
UINT len = sizeof(tmp)/sizeof(tmp[0]);
|
||||||
|
|
||||||
|
if (msi_get_property( db, szTempFolder, tmp, &len ) ||
|
||||||
|
GetFileAttributesW( tmp ) != FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
GetTempPathW( MAX_PATH, tmp );
|
||||||
|
}
|
||||||
|
if (!(db->tempfolder = strdupW( tmp ))) return NULL;
|
||||||
}
|
}
|
||||||
return strdupW( dir );
|
|
||||||
|
if ((ret = msi_alloc( (strlenW( db->tempfolder ) + 20) * sizeof(WCHAR) )))
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (!GetTempFileNameW( db->tempfolder, szMsi, ++id, ret ))
|
||||||
|
{
|
||||||
|
msi_free( ret );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (CreateDirectoryW( ret, NULL )) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2181,9 +2201,8 @@ static void set_target_path( MSIPACKAGE *package, MSIFILE *file )
|
||||||
{
|
{
|
||||||
MSIASSEMBLY *assembly = file->Component->assembly;
|
MSIASSEMBLY *assembly = file->Component->assembly;
|
||||||
|
|
||||||
if (!assembly->tempdir) assembly->tempdir = get_temp_dir();
|
if (!assembly->tempdir) assembly->tempdir = create_temp_dir( package->db );
|
||||||
file->TargetPath = msi_build_directory_name( 2, assembly->tempdir, file->FileName );
|
file->TargetPath = msi_build_directory_name( 2, assembly->tempdir, file->FileName );
|
||||||
msi_track_tempfile( package, file->TargetPath );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -201,6 +201,35 @@ static void set_deferred_action_props( MSIPACKAGE *package, const WCHAR *deferre
|
||||||
msi_set_property( package->db, szProductCode, beg, end - beg );
|
msi_set_property( package->db, szProductCode, beg, end - beg );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WCHAR *msi_create_temp_file( MSIDATABASE *db )
|
||||||
|
{
|
||||||
|
WCHAR *ret;
|
||||||
|
|
||||||
|
if (!db->tempfolder)
|
||||||
|
{
|
||||||
|
WCHAR tmp[MAX_PATH];
|
||||||
|
UINT len = sizeof(tmp)/sizeof(tmp[0]);
|
||||||
|
|
||||||
|
if (msi_get_property( db, szTempFolder, tmp, &len ) ||
|
||||||
|
GetFileAttributesW( tmp ) != FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
GetTempPathW( MAX_PATH, tmp );
|
||||||
|
}
|
||||||
|
if (!(db->tempfolder = strdupW( tmp ))) return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = msi_alloc( (strlenW( db->tempfolder ) + 20) * sizeof(WCHAR) )))
|
||||||
|
{
|
||||||
|
if (!GetTempFileNameW( db->tempfolder, szMsi, 0, ret ))
|
||||||
|
{
|
||||||
|
msi_free( ret );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
|
static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
|
||||||
{
|
{
|
||||||
static const WCHAR query[] = {
|
static const WCHAR query[] = {
|
||||||
|
@ -208,38 +237,21 @@ static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL
|
||||||
'`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E',' ',
|
'`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E',' ',
|
||||||
'`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0};
|
'`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0};
|
||||||
MSIRECORD *row;
|
MSIRECORD *row;
|
||||||
MSIBINARY *binary;
|
MSIBINARY *binary = NULL;
|
||||||
HANDLE file;
|
HANDLE file;
|
||||||
CHAR buffer[1024];
|
CHAR buffer[1024];
|
||||||
WCHAR fmt[MAX_PATH], tmpfile[MAX_PATH];
|
WCHAR *tmpfile;
|
||||||
DWORD sz = MAX_PATH, write;
|
DWORD sz, write;
|
||||||
UINT r;
|
UINT r;
|
||||||
|
|
||||||
if (msi_get_property(package->db, szTempFolder, fmt, &sz) != ERROR_SUCCESS ||
|
if (!(tmpfile = msi_create_temp_file( package->db ))) return NULL;
|
||||||
GetFileAttributesW(fmt) == INVALID_FILE_ATTRIBUTES) GetTempPathW(MAX_PATH, fmt);
|
|
||||||
|
|
||||||
if (!GetTempFileNameW( fmt, szMsi, 0, tmpfile ))
|
if (!(row = MSI_QueryGetRecord( package->db, query, source ))) goto error;
|
||||||
{
|
if (!(binary = msi_alloc_zero( sizeof(MSIBINARY) ))) goto error;
|
||||||
TRACE("unable to create temp file %s (%u)\n", debugstr_w(tmpfile), GetLastError());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
row = MSI_QueryGetRecord(package->db, query, source);
|
file = CreateFileW( tmpfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||||
if (!row)
|
if (file == INVALID_HANDLE_VALUE) goto error;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!(binary = msi_alloc_zero( sizeof(MSIBINARY) )))
|
|
||||||
{
|
|
||||||
msiobj_release( &row->hdr );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
file = CreateFileW( tmpfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
|
||||||
if (file == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
msiobj_release( &row->hdr );
|
|
||||||
msi_free( binary );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
sz = sizeof(buffer);
|
sz = sizeof(buffer);
|
||||||
|
@ -253,13 +265,7 @@ static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL
|
||||||
} while (sz == sizeof buffer);
|
} while (sz == sizeof buffer);
|
||||||
|
|
||||||
CloseHandle( file );
|
CloseHandle( file );
|
||||||
msiobj_release( &row->hdr );
|
if (r != ERROR_SUCCESS) goto error;
|
||||||
if (r != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
DeleteFileW( tmpfile );
|
|
||||||
msi_free( binary );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* keep a reference to prevent the dll from being unloaded */
|
/* keep a reference to prevent the dll from being unloaded */
|
||||||
if (dll && !(binary->module = LoadLibraryW( tmpfile )))
|
if (dll && !(binary->module = LoadLibraryW( tmpfile )))
|
||||||
|
@ -267,9 +273,18 @@ static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL
|
||||||
WARN( "failed to load dll %s (%u)\n", debugstr_w( tmpfile ), GetLastError() );
|
WARN( "failed to load dll %s (%u)\n", debugstr_w( tmpfile ), GetLastError() );
|
||||||
}
|
}
|
||||||
binary->source = strdupW( source );
|
binary->source = strdupW( source );
|
||||||
binary->tmpfile = strdupW( tmpfile );
|
binary->tmpfile = tmpfile;
|
||||||
list_add_tail( &package->binaries, &binary->entry );
|
list_add_tail( &package->binaries, &binary->entry );
|
||||||
|
|
||||||
|
msiobj_release( &row->hdr );
|
||||||
return binary;
|
return binary;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (row) msiobj_release( &row->hdr );
|
||||||
|
DeleteFileW( tmpfile );
|
||||||
|
msi_free( tmpfile );
|
||||||
|
msi_free( binary );
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MSIBINARY *get_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
|
static MSIBINARY *get_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
|
||||||
|
|
|
@ -99,6 +99,7 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
||||||
DeleteFileW( db->deletefile );
|
DeleteFileW( db->deletefile );
|
||||||
msi_free( db->deletefile );
|
msi_free( db->deletefile );
|
||||||
}
|
}
|
||||||
|
msi_free( db->tempfolder );
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT db_initialize( IStorage *stg, const GUID *clsid )
|
static HRESULT db_initialize( IStorage *stg, const GUID *clsid )
|
||||||
|
|
|
@ -495,42 +495,17 @@ static MSIRECORD *msi_get_binary_record( MSIDATABASE *db, LPCWSTR name )
|
||||||
return MSI_QueryGetRecord( db, query, name );
|
return MSI_QueryGetRecord( db, query, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
static LPWSTR msi_create_tmp_path(void)
|
|
||||||
{
|
|
||||||
WCHAR tmp[MAX_PATH];
|
|
||||||
LPWSTR path = NULL;
|
|
||||||
DWORD len, r;
|
|
||||||
|
|
||||||
r = GetTempPathW( MAX_PATH, tmp );
|
|
||||||
if( !r )
|
|
||||||
return path;
|
|
||||||
len = lstrlenW( tmp ) + 20;
|
|
||||||
path = msi_alloc( len * sizeof (WCHAR) );
|
|
||||||
if( path )
|
|
||||||
{
|
|
||||||
r = GetTempFileNameW( tmp, szMsi, 0, path );
|
|
||||||
if (!r)
|
|
||||||
{
|
|
||||||
msi_free( path );
|
|
||||||
path = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HANDLE msi_load_image( MSIDATABASE *db, LPCWSTR name, UINT type,
|
static HANDLE msi_load_image( MSIDATABASE *db, LPCWSTR name, UINT type,
|
||||||
UINT cx, UINT cy, UINT flags )
|
UINT cx, UINT cy, UINT flags )
|
||||||
{
|
{
|
||||||
MSIRECORD *rec = NULL;
|
MSIRECORD *rec;
|
||||||
HANDLE himage = NULL;
|
HANDLE himage = NULL;
|
||||||
LPWSTR tmp;
|
LPWSTR tmp;
|
||||||
UINT r;
|
UINT r;
|
||||||
|
|
||||||
TRACE("%p %s %u %u %08x\n", db, debugstr_w(name), cx, cy, flags);
|
TRACE("%p %s %u %u %08x\n", db, debugstr_w(name), cx, cy, flags);
|
||||||
|
|
||||||
tmp = msi_create_tmp_path();
|
if (!(tmp = msi_create_temp_file( db ))) return NULL;
|
||||||
if( !tmp )
|
|
||||||
return himage;
|
|
||||||
|
|
||||||
rec = msi_get_binary_record( db, name );
|
rec = msi_get_binary_record( db, name );
|
||||||
if( rec )
|
if( rec )
|
||||||
|
|
|
@ -275,33 +275,33 @@ static MSIFILE *find_file( MSIPACKAGE *package, UINT disk_id, const WCHAR *filen
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR filename, DWORD action,
|
||||||
LPWSTR *path, DWORD *attrs, PVOID user)
|
LPWSTR *path, DWORD *attrs, PVOID user)
|
||||||
{
|
{
|
||||||
static MSIFILE *f = NULL;
|
static MSIFILE *file = NULL;
|
||||||
UINT_PTR disk_id = (UINT_PTR)user;
|
UINT_PTR disk_id = (UINT_PTR)user;
|
||||||
|
|
||||||
if (action == MSICABEXTRACT_BEGINEXTRACT)
|
if (action == MSICABEXTRACT_BEGINEXTRACT)
|
||||||
{
|
{
|
||||||
if (!(f = find_file( package, disk_id, file )))
|
if (!(file = find_file( package, disk_id, filename )))
|
||||||
{
|
{
|
||||||
TRACE("unknown file in cabinet (%s)\n", debugstr_w(file));
|
TRACE("unknown file in cabinet (%s)\n", debugstr_w(filename));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (f->disk_id != disk_id || (f->state != msifs_missing && f->state != msifs_overwrite))
|
if (file->state != msifs_missing && file->state != msifs_overwrite)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!msi_is_global_assembly( f->Component ))
|
if (!msi_is_global_assembly( file->Component ))
|
||||||
{
|
{
|
||||||
msi_create_directory(package, f->Component->Directory);
|
msi_create_directory( package, file->Component->Directory );
|
||||||
}
|
}
|
||||||
*path = strdupW(f->TargetPath);
|
*path = strdupW( file->TargetPath );
|
||||||
*attrs = f->Attributes;
|
*attrs = file->Attributes;
|
||||||
}
|
}
|
||||||
else if (action == MSICABEXTRACT_FILEEXTRACTED)
|
else if (action == MSICABEXTRACT_FILEEXTRACTED)
|
||||||
{
|
{
|
||||||
if (!msi_is_global_assembly( f->Component )) f->state = msifs_installed;
|
if (!msi_is_global_assembly( file->Component )) file->state = msifs_installed;
|
||||||
f = NULL;
|
file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -378,8 +378,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||||
data.cb = installfiles_cb;
|
data.cb = installfiles_cb;
|
||||||
data.user = (PVOID)(UINT_PTR)mi->disk_id;
|
data.user = (PVOID)(UINT_PTR)mi->disk_id;
|
||||||
|
|
||||||
if (file->IsCompressed &&
|
if (file->IsCompressed && !msi_cabextract(package, mi, &data))
|
||||||
!msi_cabextract(package, mi, &data))
|
|
||||||
{
|
{
|
||||||
ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
|
ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
|
||||||
rc = ERROR_INSTALL_FAILURE;
|
rc = ERROR_INSTALL_FAILURE;
|
||||||
|
@ -419,8 +418,8 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
||||||
{
|
{
|
||||||
MSICOMPONENT *comp = file->Component;
|
MSICOMPONENT *comp = file->Component;
|
||||||
|
|
||||||
if (!msi_is_global_assembly( comp ) || (file->state != msifs_missing && file->state != msifs_overwrite))
|
if (!msi_is_global_assembly( comp ) || comp->assembly->installed ||
|
||||||
continue;
|
(file->state != msifs_missing && file->state != msifs_overwrite)) continue;
|
||||||
|
|
||||||
rc = msi_install_assembly( package, comp );
|
rc = msi_install_assembly( package, comp );
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
|
@ -453,22 +452,18 @@ static BOOL patchfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
||||||
LPWSTR *path, DWORD *attrs, PVOID user)
|
LPWSTR *path, DWORD *attrs, PVOID user)
|
||||||
{
|
{
|
||||||
static MSIFILEPATCH *patch;
|
static MSIFILEPATCH *patch;
|
||||||
static WCHAR tmpfile[MAX_PATH], tmpdir[MAX_PATH];
|
|
||||||
UINT_PTR disk_id = (UINT_PTR)user;
|
UINT_PTR disk_id = (UINT_PTR)user;
|
||||||
|
|
||||||
if (!tmpdir[0]) GetTempPathW( MAX_PATH, tmpdir );
|
|
||||||
|
|
||||||
if (action == MSICABEXTRACT_BEGINEXTRACT)
|
if (action == MSICABEXTRACT_BEGINEXTRACT)
|
||||||
{
|
{
|
||||||
if (!(patch = find_filepatch( package, disk_id, file ))) return FALSE;
|
if (!(patch = find_filepatch( package, disk_id, file ))) return FALSE;
|
||||||
|
|
||||||
GetTempFileNameW( tmpdir, NULL, 0, tmpfile );
|
patch->path = msi_create_temp_file( package->db );
|
||||||
*path = strdupW( tmpfile );
|
*path = strdupW( patch->path );
|
||||||
*attrs = patch->File->Attributes;
|
*attrs = patch->File->Attributes;
|
||||||
}
|
}
|
||||||
else if (action == MSICABEXTRACT_FILEEXTRACTED)
|
else if (action == MSICABEXTRACT_FILEEXTRACTED)
|
||||||
{
|
{
|
||||||
patch->path = strdupW( tmpfile );
|
|
||||||
patch->extracted = TRUE;
|
patch->extracted = TRUE;
|
||||||
patch = NULL;
|
patch = NULL;
|
||||||
}
|
}
|
||||||
|
@ -531,14 +526,16 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
|
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
|
||||||
{
|
{
|
||||||
WCHAR tmpdir[MAX_PATH], tmpfile[MAX_PATH];
|
WCHAR *tmpfile;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
if (!patch->path) continue;
|
if (!patch->path) continue;
|
||||||
|
|
||||||
GetTempPathW( MAX_PATH, tmpdir );
|
if (!(tmpfile = msi_create_temp_file( package->db )))
|
||||||
GetTempFileNameW( tmpdir, NULL, 0, tmpfile );
|
{
|
||||||
|
rc = ERROR_INSTALL_FAILURE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
ret = ApplyPatchToFileW( patch->path, patch->File->TargetPath, tmpfile, 0 );
|
ret = ApplyPatchToFileW( patch->path, patch->File->TargetPath, tmpfile, 0 );
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
@ -550,7 +547,7 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
|
||||||
|
|
||||||
DeleteFileW( patch->path );
|
DeleteFileW( patch->path );
|
||||||
DeleteFileW( tmpfile );
|
DeleteFileW( tmpfile );
|
||||||
RemoveDirectoryW( tmpdir );
|
msi_free( tmpfile );
|
||||||
|
|
||||||
if (!ret && !(patch->Attributes & msidbPatchAttributesNonVital))
|
if (!ret && !(patch->Attributes & msidbPatchAttributesNonVital))
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,6 +100,7 @@ typedef struct tagMSIDATABASE
|
||||||
UINT bytes_per_strref;
|
UINT bytes_per_strref;
|
||||||
LPWSTR path;
|
LPWSTR path;
|
||||||
LPWSTR deletefile;
|
LPWSTR deletefile;
|
||||||
|
LPWSTR tempfolder;
|
||||||
LPCWSTR mode;
|
LPCWSTR mode;
|
||||||
UINT media_transform_offset;
|
UINT media_transform_offset;
|
||||||
UINT media_transform_disk_id;
|
UINT media_transform_disk_id;
|
||||||
|
@ -580,12 +581,6 @@ typedef struct tagMSIFILE
|
||||||
UINT disk_id;
|
UINT disk_id;
|
||||||
} MSIFILE;
|
} MSIFILE;
|
||||||
|
|
||||||
typedef struct tagMSITEMPFILE
|
|
||||||
{
|
|
||||||
struct list entry;
|
|
||||||
LPWSTR Path;
|
|
||||||
} MSITEMPFILE;
|
|
||||||
|
|
||||||
typedef struct tagMSIFILEPATCH
|
typedef struct tagMSIFILEPATCH
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
@ -1025,7 +1020,7 @@ extern MSICOMPONENT *msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *
|
||||||
extern MSIFEATURE *msi_get_loaded_feature(MSIPACKAGE *package, const WCHAR *Feature) DECLSPEC_HIDDEN;
|
extern MSIFEATURE *msi_get_loaded_feature(MSIPACKAGE *package, const WCHAR *Feature) DECLSPEC_HIDDEN;
|
||||||
extern MSIFILE *msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *file) DECLSPEC_HIDDEN;
|
extern MSIFILE *msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *file) DECLSPEC_HIDDEN;
|
||||||
extern MSIFOLDER *msi_get_loaded_folder(MSIPACKAGE *package, const WCHAR *dir) DECLSPEC_HIDDEN;
|
extern MSIFOLDER *msi_get_loaded_folder(MSIPACKAGE *package, const WCHAR *dir) DECLSPEC_HIDDEN;
|
||||||
extern int msi_track_tempfile(MSIPACKAGE *package, const WCHAR *path) DECLSPEC_HIDDEN;
|
extern WCHAR *msi_create_temp_file(MSIDATABASE *db) DECLSPEC_HIDDEN;
|
||||||
extern void msi_free_action_script(MSIPACKAGE *package, UINT script) DECLSPEC_HIDDEN;
|
extern void msi_free_action_script(MSIPACKAGE *package, UINT script) DECLSPEC_HIDDEN;
|
||||||
extern WCHAR *msi_build_icon_path(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN;
|
extern WCHAR *msi_build_icon_path(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN;
|
||||||
extern WCHAR *msi_build_directory_name(DWORD , ...) DECLSPEC_HIDDEN;
|
extern WCHAR *msi_build_directory_name(DWORD , ...) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -49,22 +49,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||||
|
|
||||||
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 ));
|
|
||||||
DeleteFileW( temp->Path );
|
|
||||||
msi_free( temp->Path );
|
|
||||||
msi_free( temp );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_feature( MSIFEATURE *feature )
|
static void free_feature( MSIFEATURE *feature )
|
||||||
{
|
{
|
||||||
struct list *item, *cursor;
|
struct list *item, *cursor;
|
||||||
|
@ -170,6 +154,22 @@ static void free_package_structures( MSIPACKAGE *package )
|
||||||
free_folder( folder );
|
free_folder( folder );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
if (msi_is_global_assembly( file->Component )) DeleteFileW( file->TargetPath );
|
||||||
|
msi_free( file->TargetPath );
|
||||||
|
msi_free( file );
|
||||||
|
}
|
||||||
|
|
||||||
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
|
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
|
||||||
{
|
{
|
||||||
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
|
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
|
||||||
|
@ -185,21 +185,6 @@ static void free_package_structures( MSIPACKAGE *package )
|
||||||
msi_free( comp );
|
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->TargetPath );
|
|
||||||
msi_free( file );
|
|
||||||
}
|
|
||||||
|
|
||||||
LIST_FOR_EACH_SAFE( item, cursor, &package->filepatches )
|
LIST_FOR_EACH_SAFE( item, cursor, &package->filepatches )
|
||||||
{
|
{
|
||||||
MSIFILEPATCH *patch = LIST_ENTRY( item, MSIFILEPATCH, entry );
|
MSIFILEPATCH *patch = LIST_ENTRY( item, MSIFILEPATCH, entry );
|
||||||
|
@ -347,8 +332,6 @@ static void free_package_structures( MSIPACKAGE *package )
|
||||||
msi_free( package->LastAction );
|
msi_free( package->LastAction );
|
||||||
msi_free( package->langids );
|
msi_free( package->langids );
|
||||||
|
|
||||||
remove_tracked_tempfiles(package);
|
|
||||||
|
|
||||||
/* cleanup control event subscriptions */
|
/* cleanup control event subscriptions */
|
||||||
msi_event_cleanup_all_subscriptions( package );
|
msi_event_cleanup_all_subscriptions( package );
|
||||||
}
|
}
|
||||||
|
@ -1329,22 +1312,6 @@ static UINT validate_package( MSIPACKAGE *package )
|
||||||
return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
|
return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int msi_track_tempfile( MSIPACKAGE *package, const WCHAR *path )
|
|
||||||
{
|
|
||||||
MSITEMPFILE *temp;
|
|
||||||
|
|
||||||
TRACE("%s\n", debugstr_w(path));
|
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
|
|
||||||
{
|
|
||||||
if (!strcmpW( path, temp->Path )) return 0;
|
|
||||||
}
|
|
||||||
if (!(temp = msi_alloc_zero( sizeof (MSITEMPFILE) ))) return -1;
|
|
||||||
list_add_head( &package->tempfiles, &temp->entry );
|
|
||||||
temp->Path = strdupW( path );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static WCHAR *get_product_code( MSIDATABASE *db )
|
static WCHAR *get_product_code( MSIDATABASE *db )
|
||||||
{
|
{
|
||||||
static const WCHAR query[] = {
|
static const WCHAR query[] = {
|
||||||
|
|
Loading…
Reference in New Issue