static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
{
- WCHAR volume_name[MAX_PATH + 1];
- WCHAR root[MAX_PATH + 1];
+ WCHAR volume_name[MAX_PATH + 1], root[MAX_PATH + 1];
+ const WCHAR *p;
+ int len, len2;
strcpyW(root, source_root);
PathStripToRootW(root);
WARN("failed to get volume information for %s (%u)\n", debugstr_w(root), GetLastError());
return FALSE;
}
- return !strcmpiW( mi->volume_label, volume_name );
+
+ len = strlenW( volume_name );
+ len2 = strlenW( mi->volume_label );
+ if (len2 > len) return FALSE;
+ p = volume_name + len - len2;
+
+ return !strcmpiW( mi->volume_label, p );
}
static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
{
MSICABINETSTREAM *cab;
IStream *stream;
- WCHAR *encoded;
- HRESULT hr;
- cab = msi_get_cabinet_stream( package_disk.package, package_disk.id );
- if (!cab)
+ if (!(cab = msi_get_cabinet_stream( package_disk.package, package_disk.id )))
{
WARN("failed to get cabinet stream\n");
return -1;
}
- if (!cab->stream[0] || !(encoded = encode_streamname( FALSE, cab->stream + 1 )))
+ if (cab->storage == package_disk.package->db->storage)
{
- WARN("failed to encode stream name\n");
- return -1;
+ UINT r = msi_get_stream( package_disk.package->db, cab->stream + 1, &stream );
+ if (r != ERROR_SUCCESS)
+ {
+ WARN("failed to get stream %u\n", r);
+ return -1;
+ }
}
- if (msi_clone_open_stream( package_disk.package->db, cab->storage, encoded, &stream ) != ERROR_SUCCESS)
+ else /* patch storage */
{
+ HRESULT hr;
+ WCHAR *encoded;
+
+ if (!(encoded = encode_streamname( FALSE, cab->stream + 1 )))
+ {
+ WARN("failed to encode stream name\n");
+ return -1;
+ }
hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream );
+ msi_free( encoded );
if (FAILED(hr))
{
WARN("failed to open stream 0x%08x\n", hr);
- msi_free( encoded );
return -1;
}
}
- msi_free( encoded );
return (INT_PTR)stream;
}
mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
- if (!mi->first_volume)
- mi->first_volume = strdupW(mi->volume_label);
-
msiobj_release(&row->hdr);
return ERROR_SUCCESS;
}
{
TRACE("removing read-only attribute on %s\n", debugstr_w(path));
SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY );
- handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs2, NULL);
+ handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL);
if (handle != INVALID_HANDLE_VALUE) goto done;
err = GetLastError();
msi_free(mi->disk_prompt);
msi_free(mi->cabinet);
msi_free(mi->volume_label);
- msi_free(mi->first_volume);
msi_free(mi);
}
mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
msiobj_release(&row->hdr);
- if (!mi->first_volume)
- mi->first_volume = strdupW(mi->volume_label);
-
msi_set_sourcedir_props(package, FALSE);
source_dir = msi_dup_property(package->db, szSourceDir);
lstrcpyW(mi->sourcedir, source_dir);
}
}
/* check volume matches, change media if not */
- if (mi->volume_label && mi->disk_id > 1 && strcmpW( mi->first_volume, mi->volume_label ))
+ if (mi->volume_label && mi->disk_id > 1)
{
WCHAR *source = msi_dup_property( package->db, szSourceDir );
BOOL match = source_matches_volume( mi, source );