msi: Don't apply file patches in the cabinet extraction callback.
This commit is contained in:
parent
0762dd68f8
commit
006801366e
@ -1377,7 +1377,6 @@ static UINT load_patch(MSIRECORD *row, LPVOID param)
|
|||||||
patch->Sequence = MSI_RecordGetInteger( row, 2 );
|
patch->Sequence = MSI_RecordGetInteger( row, 2 );
|
||||||
patch->PatchSize = MSI_RecordGetInteger( row, 3 );
|
patch->PatchSize = MSI_RecordGetInteger( row, 3 );
|
||||||
patch->Attributes = MSI_RecordGetInteger( row, 4 );
|
patch->Attributes = MSI_RecordGetInteger( row, 4 );
|
||||||
patch->IsApplied = FALSE;
|
|
||||||
|
|
||||||
/* FIXME:
|
/* FIXME:
|
||||||
* Header field - for patch validation.
|
* Header field - for patch validation.
|
||||||
|
@ -436,13 +436,14 @@ done:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MSIFILEPATCH *get_next_filepatch( MSIPACKAGE *package, const WCHAR *key )
|
static MSIFILEPATCH *find_filepatch( MSIPACKAGE *package, UINT disk_id, const WCHAR *key )
|
||||||
{
|
{
|
||||||
MSIFILEPATCH *patch;
|
MSIFILEPATCH *patch;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
|
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
|
||||||
{
|
{
|
||||||
if (!patch->IsApplied && !strcmpW( key, patch->File->File )) return patch;
|
if (!patch->extracted && patch->disk_id == disk_id && !strcmpW( key, patch->File->File ))
|
||||||
|
return patch;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -450,45 +451,25 @@ static MSIFILEPATCH *get_next_filepatch( MSIPACKAGE *package, const WCHAR *key )
|
|||||||
static BOOL patchfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
static BOOL patchfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
|
||||||
LPWSTR *path, DWORD *attrs, PVOID user)
|
LPWSTR *path, DWORD *attrs, PVOID user)
|
||||||
{
|
{
|
||||||
static MSIFILEPATCH *p = NULL;
|
static MSIFILEPATCH *patch;
|
||||||
static WCHAR patch_path[MAX_PATH] = {0};
|
static WCHAR tmpfile[MAX_PATH], tmpdir[MAX_PATH];
|
||||||
static WCHAR temp_folder[MAX_PATH] = {0};
|
UINT_PTR disk_id = (UINT_PTR)user;
|
||||||
|
|
||||||
|
if (!tmpdir[0]) GetTempPathW( MAX_PATH, tmpdir );
|
||||||
|
|
||||||
if (action == MSICABEXTRACT_BEGINEXTRACT)
|
if (action == MSICABEXTRACT_BEGINEXTRACT)
|
||||||
{
|
{
|
||||||
if (temp_folder[0] == '\0')
|
if (!(patch = find_filepatch( package, disk_id, file ))) return FALSE;
|
||||||
GetTempPathW(MAX_PATH, temp_folder);
|
|
||||||
|
|
||||||
if (!(p = get_next_filepatch(package, file)) || !p->File->Component->Enabled)
|
GetTempFileNameW( tmpdir, NULL, 0, tmpfile );
|
||||||
return FALSE;
|
*path = strdupW( tmpfile );
|
||||||
|
*attrs = patch->File->Attributes;
|
||||||
GetTempFileNameW(temp_folder, NULL, 0, patch_path);
|
|
||||||
|
|
||||||
*path = strdupW(patch_path);
|
|
||||||
*attrs = p->File->Attributes;
|
|
||||||
}
|
}
|
||||||
else if (action == MSICABEXTRACT_FILEEXTRACTED)
|
else if (action == MSICABEXTRACT_FILEEXTRACTED)
|
||||||
{
|
{
|
||||||
WCHAR patched_file[MAX_PATH];
|
patch->path = strdupW( tmpfile );
|
||||||
BOOL br;
|
patch->extracted = TRUE;
|
||||||
|
patch = NULL;
|
||||||
GetTempFileNameW(temp_folder, NULL, 0, patched_file);
|
|
||||||
|
|
||||||
br = ApplyPatchToFileW(patch_path, p->File->TargetPath, patched_file, 0);
|
|
||||||
if (br)
|
|
||||||
{
|
|
||||||
/* FIXME: baseline cache */
|
|
||||||
|
|
||||||
DeleteFileW( p->File->TargetPath );
|
|
||||||
MoveFileW( patched_file, p->File->TargetPath );
|
|
||||||
|
|
||||||
p->IsApplied = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ERR("Failed patch %s: %d.\n", debugstr_w(p->File->TargetPath), GetLastError());
|
|
||||||
|
|
||||||
DeleteFileW(patch_path);
|
|
||||||
p = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -504,6 +485,8 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
|
|||||||
|
|
||||||
mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) );
|
mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) );
|
||||||
|
|
||||||
|
TRACE("extracting files\n");
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
|
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
|
||||||
{
|
{
|
||||||
MSIFILE *file = patch->File;
|
MSIFILE *file = patch->File;
|
||||||
@ -519,7 +502,7 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
|
|||||||
comp->Action = msi_get_component_action( package, comp );
|
comp->Action = msi_get_component_action( package, comp );
|
||||||
if (!comp->Enabled || comp->Action != INSTALLSTATE_LOCAL) continue;
|
if (!comp->Enabled || comp->Action != INSTALLSTATE_LOCAL) continue;
|
||||||
|
|
||||||
if (!patch->IsApplied)
|
if (!patch->extracted)
|
||||||
{
|
{
|
||||||
MSICABDATA data;
|
MSICABDATA data;
|
||||||
|
|
||||||
@ -529,23 +512,48 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
|
|||||||
ERR("Failed to ready media for %s\n", debugstr_w(file->File));
|
ERR("Failed to ready media for %s\n", debugstr_w(file->File));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
data.mi = mi;
|
||||||
data.mi = mi;
|
|
||||||
data.package = package;
|
data.package = package;
|
||||||
data.cb = patchfiles_cb;
|
data.cb = patchfiles_cb;
|
||||||
data.user = (PVOID)(UINT_PTR)mi->disk_id;
|
data.user = (PVOID)(UINT_PTR)mi->disk_id;
|
||||||
|
|
||||||
if (!msi_cabextract(package, mi, &data))
|
if (!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;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!patch->IsApplied && !(patch->Attributes & msidbPatchAttributesNonVital))
|
TRACE("applying patches\n");
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
|
||||||
|
{
|
||||||
|
WCHAR tmpdir[MAX_PATH], tmpfile[MAX_PATH];
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
if (!patch->path) continue;
|
||||||
|
|
||||||
|
GetTempPathW( MAX_PATH, tmpdir );
|
||||||
|
GetTempFileNameW( tmpdir, NULL, 0, tmpfile );
|
||||||
|
|
||||||
|
ret = ApplyPatchToFileW( patch->path, patch->File->TargetPath, tmpfile, 0 );
|
||||||
|
if (ret)
|
||||||
{
|
{
|
||||||
ERR("Failed to apply patch to file: %s\n", debugstr_w(file->File));
|
DeleteFileW( patch->File->TargetPath );
|
||||||
|
MoveFileW( tmpfile, patch->File->TargetPath );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WARN("failed to patch %s: %08x\n", debugstr_w(patch->File->TargetPath), GetLastError());
|
||||||
|
|
||||||
|
DeleteFileW( patch->path );
|
||||||
|
DeleteFileW( tmpfile );
|
||||||
|
RemoveDirectoryW( tmpdir );
|
||||||
|
|
||||||
|
if (!ret && !(patch->Attributes & msidbPatchAttributesNonVital))
|
||||||
|
{
|
||||||
|
ERR("Failed to apply patch to file: %s\n", debugstr_w(patch->File->File));
|
||||||
rc = ERROR_INSTALL_FAILURE;
|
rc = ERROR_INSTALL_FAILURE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -593,8 +593,9 @@ typedef struct tagMSIFILEPATCH
|
|||||||
INT Sequence;
|
INT Sequence;
|
||||||
INT PatchSize;
|
INT PatchSize;
|
||||||
INT Attributes;
|
INT Attributes;
|
||||||
BOOL IsApplied;
|
BOOL extracted;
|
||||||
UINT disk_id;
|
UINT disk_id;
|
||||||
|
WCHAR *path;
|
||||||
} MSIFILEPATCH;
|
} MSIFILEPATCH;
|
||||||
|
|
||||||
typedef struct tagMSIAPPID
|
typedef struct tagMSIAPPID
|
||||||
|
@ -200,6 +200,15 @@ static void free_package_structures( MSIPACKAGE *package )
|
|||||||
msi_free( file );
|
msi_free( file );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIST_FOR_EACH_SAFE( item, cursor, &package->filepatches )
|
||||||
|
{
|
||||||
|
MSIFILEPATCH *patch = LIST_ENTRY( item, MSIFILEPATCH, entry );
|
||||||
|
|
||||||
|
list_remove( &patch->entry );
|
||||||
|
msi_free( patch->path );
|
||||||
|
msi_free( patch );
|
||||||
|
}
|
||||||
|
|
||||||
/* clean up extension, progid, class and verb structures */
|
/* clean up extension, progid, class and verb structures */
|
||||||
LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
|
LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user