static UINT load_media_info(MSIPACKAGE *package, MSIFILE *file, struct media_info *mi) { MSIRECORD *row; LPWSTR source_dir; LPWSTR source; DWORD options; UINT r; static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=', ' ','%','i',' ','A','N','D',' ','`','D','i','s','k','I','d','`',' ','>','=', ' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ', '`','D','i','s','k','I','d','`',0 }; row = MSI_QueryGetRecord(package->db, query, file->Sequence, mi->disk_id); if (!row) { TRACE("Unable to query row\n"); return ERROR_FUNCTION_FAILED; } mi->is_extracted = FALSE; mi->disk_id = MSI_RecordGetInteger(row, 1); mi->last_sequence = MSI_RecordGetInteger(row, 2); msi_free(mi->disk_prompt); mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3)); msi_free(mi->cabinet); mi->cabinet = strdupW(MSI_RecordGetString(row, 4)); msi_free(mi->volume_label); mi->volume_label = strdupW(MSI_RecordGetString(row, 5)); msiobj_release(&row->hdr); if (!mi->first_volume) mi->first_volume = strdupW(mi->volume_label); source_dir = msi_dup_property(package, cszSourceDir); lstrcpyW(mi->source, source_dir); PathStripToRootW(source_dir); mi->type = GetDriveTypeW(source_dir); if (file->IsCompressed && mi->cabinet) { if (mi->cabinet[0] == '#') { r = writeout_cabinet_stream(package, &mi->cabinet[1], mi->source); if (r != ERROR_SUCCESS) { ERR("Failed to extract cabinet stream\n"); return ERROR_FUNCTION_FAILED; } } else lstrcatW(mi->source, mi->cabinet); } options = MSICODE_PRODUCT; if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) { source = source_dir; options |= MSISOURCETYPE_MEDIA; } else if (package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL)) { source = package->BaseURL; options |= MSISOURCETYPE_URL; } else { source = mi->source; options |= MSISOURCETYPE_NETWORK; } if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) msi_package_add_media_disk(package, package->Context, MSICODE_PRODUCT, mi->disk_id, mi->volume_label, mi->disk_prompt); msi_package_add_info(package, package->Context, options, INSTALLPROPERTY_LASTUSEDSOURCEW, source); msi_free(source_dir); return ERROR_SUCCESS; }
static UINT ready_media_for_file( MSIPACKAGE *package, struct media_info *mi, MSIFILE *file ) { UINT rc = ERROR_SUCCESS; MSIRECORD * row = 0; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=', ' ','%', 'i',' ','O','R','D','E','R',' ','B','Y',' ', '`','L','a','s','t','S','e','q','u','e','n','c','e','`',0}; LPCWSTR cab, volume; DWORD sz; INT seq; LPCWSTR prompt; MSICOMPONENT *comp = file->Component; if (file->Sequence <= mi->last_sequence) { set_file_source(package,file,comp,mi->last_path); TRACE("Media already ready (%u, %u)\n",file->Sequence,mi->last_sequence); return ERROR_SUCCESS; } mi->count ++; row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence); if (!row) { TRACE("Unable to query row\n"); return ERROR_FUNCTION_FAILED; } seq = MSI_RecordGetInteger(row,2); mi->last_sequence = seq; volume = MSI_RecordGetString(row, 5); prompt = MSI_RecordGetString(row, 3); msi_free(mi->last_path); mi->last_path = NULL; if (!file->IsCompressed) { mi->last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL); set_file_source(package,file,comp,mi->last_path); MsiSourceListAddMediaDiskW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume, prompt); MsiSourceListSetInfoW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT|MSISOURCETYPE_MEDIA, INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path); msiobj_release(&row->hdr); return rc; } cab = MSI_RecordGetString(row,4); if (cab) { TRACE("Source is CAB %s\n",debugstr_w(cab)); /* the stream does not contain the # character */ if (cab[0]=='#') { LPWSTR path; writeout_cabinet_stream(package,&cab[1],mi->source); mi->last_path = strdupW(mi->source); *(strrchrW(mi->last_path,'\\')+1)=0; path = msi_dup_property( package, cszSourceDir ); MsiSourceListAddMediaDiskW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume, prompt); MsiSourceListSetInfoW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT|MSISOURCETYPE_NETWORK, INSTALLPROPERTY_LASTUSEDSOURCEW, path); msi_free(path); } else { sz = MAX_PATH; mi->last_path = msi_alloc(MAX_PATH*sizeof(WCHAR)); if (MSI_GetPropertyW(package, cszSourceDir, mi->source, &sz)) { ERR("No Source dir defined\n"); rc = ERROR_FUNCTION_FAILED; } else { strcpyW(mi->last_path,mi->source); strcatW(mi->source,cab); MsiSourceListSetInfoW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT|MSISOURCETYPE_MEDIA, INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path); /* extract the cab file into a folder in the temp folder */ sz = MAX_PATH; if (MSI_GetPropertyW(package, cszTempFolder,mi->last_path, &sz) != ERROR_SUCCESS) GetTempPathW(MAX_PATH,mi->last_path); } } /* only download the remote cabinet file if a local copy does not exist */ if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES && UrlIsW(package->PackagePath, URLIS_URL)) { rc = msi_extract_remote_cabinet(package, mi); } else { rc = !extract_cabinet_file(package, mi->source, mi->last_path); } } else { sz = MAX_PATH; mi->last_path = msi_alloc(MAX_PATH*sizeof(WCHAR)); MSI_GetPropertyW(package,cszSourceDir,mi->source,&sz); strcpyW(mi->last_path,mi->source); MsiSourceListSetInfoW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT|MSISOURCETYPE_MEDIA, INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path); } set_file_source(package, file, comp, mi->last_path); MsiSourceListAddMediaDiskW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume, prompt); msiobj_release(&row->hdr); return rc; }