static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform ) { MSISUMMARYINFO *si = MSI_GetSummaryInformationW( transform, 0 ); UINT valid_flags = 0, wanted_flags = 0; if (si) wanted_flags = msi_suminfo_get_int32( si, PID_CHARCOUNT ); TRACE("validation flags %x\n", wanted_flags); if (wanted_flags & ~(MSITRANSFORM_VALIDATE_PRODUCT|MSITRANSFORM_VALIDATE_LANGUAGE)) FIXME("unsupported validation flags %x\n", wanted_flags); if (wanted_flags & MSITRANSFORM_VALIDATE_PRODUCT) { WCHAR *package_product = msi_dup_property( package->db, szProductCode ); WCHAR *transform_product = msi_get_suminfo_product( transform ); TRACE("package = %s transform = %s\n", debugstr_w(package_product), debugstr_w(transform_product)); if (!transform_product || strstrW( transform_product, package_product )) { valid_flags |= MSITRANSFORM_VALIDATE_PRODUCT; } msi_free( transform_product ); msi_free( package_product ); } if (wanted_flags & MSITRANSFORM_VALIDATE_LANGUAGE) { WCHAR *template;
static UINT msi_change_media( MSIPACKAGE *package, struct media_info *mi ) { LPSTR msg; LPWSTR error, error_dialog; LPWSTR source_dir; UINT r = ERROR_SUCCESS; static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0}; static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0}; if ( (msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE && !gUIHandlerA ) return ERROR_SUCCESS; error = generate_error_string( package, 1302, 1, mi->disk_prompt ); error_dialog = msi_dup_property( package, error_prop ); source_dir = msi_dup_property( package, cszSourceDir ); PathStripToRootW(source_dir); while ( r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir) ) { r = msi_spawn_error_dialog( package, error_dialog, error ); if (gUIHandlerA) { msg = strdupWtoA( error ); gUIHandlerA( gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg ); msi_free(msg); } } msi_free( error ); msi_free( error_dialog ); msi_free( source_dir ); return r; }
static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, LPCWSTR productid) { LPWSTR prop; LPWSTR newprop; DWORD len; UINT r; prop = msi_dup_property(package->db, action_property ); if (prop) len = strlenW(prop); else len = 0; /*separator*/ len ++; len += strlenW(productid); /*null*/ len++; newprop = msi_alloc( len*sizeof(WCHAR) ); if (prop) { strcpyW(newprop,prop); strcatW(newprop,szSemiColon); } else newprop[0] = 0; strcatW(newprop,productid); r = msi_set_property( package->db, action_property, newprop ); if (r == ERROR_SUCCESS && !strcmpW( action_property, szSourceDir )) msi_reset_folders( package, TRUE ); TRACE("Found Related Product... %s now %s\n", debugstr_w(action_property), debugstr_w(newprop)); msi_free( prop ); msi_free( newprop ); }
static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, LPCWSTR productid) { LPWSTR prop; LPWSTR newprop; DWORD len; static const WCHAR separator[] = {';',0}; prop = msi_dup_property(package, action_property ); if (prop) len = strlenW(prop); else len = 0; /*separator*/ len ++; len += strlenW(productid); /*null*/ len++; newprop = msi_alloc( len*sizeof(WCHAR) ); if (prop) { strcpyW(newprop,prop); strcatW(newprop,separator); } else newprop[0] = 0; strcatW(newprop,productid); MSI_SetPropertyW(package, action_property, newprop); TRACE("Found Related Product... %s now %s\n",debugstr_w(action_property), debugstr_w(newprop)); msi_free( prop ); msi_free( newprop ); }
UINT i; if (!package->num_langids || !langid) return TRUE; for (i = 0; i < package->num_langids; i++) { if (package->langids[i] == langid) return TRUE; } return FALSE; } static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *patch ) { LPWSTR prod_code, patch_product, template = NULL; UINT ret = ERROR_FUNCTION_FAILED; prod_code = msi_dup_property( package->db, szProductCode ); patch_product = msi_get_suminfo_product( patch ); TRACE("db = %s patch = %s\n", debugstr_w(prod_code), debugstr_w(patch_product)); if (strstrW( patch_product, prod_code )) { MSISUMMARYINFO *si; const WCHAR *p; si = MSI_GetSummaryInformationW( patch, 0 ); if (!si) { ERR("no summary information!\n"); goto end; }
static UINT ready_media(MSIPACKAGE *package, MSIFILE *file, struct media_info *mi) { UINT rc = ERROR_SUCCESS; /* media info for continuous cabinet is already loaded */ if (mi->is_continuous) return ERROR_SUCCESS; rc = load_media_info(package, file, mi); if (rc != ERROR_SUCCESS) { ERR("Unable to load media info\n"); return ERROR_FUNCTION_FAILED; } /* cabinet is internal, no checks needed */ if (!mi->cabinet || mi->cabinet[0] == '#') return ERROR_SUCCESS; /* package should be downloaded */ if (file->IsCompressed && GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES && package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL)) { WCHAR temppath[MAX_PATH]; msi_download_file(mi->source, temppath); lstrcpyW(mi->source, temppath); return ERROR_SUCCESS; } /* check volume matches, change media if not */ if (mi->volume_label && mi->disk_id > 1 && lstrcmpW(mi->first_volume, mi->volume_label)) { LPWSTR source = msi_dup_property(package, cszSourceDir); BOOL matches; matches = source_matches_volume(mi, source); msi_free(source); if ((mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) && !matches) { rc = msi_change_media(package, mi); if (rc != ERROR_SUCCESS) return rc; } } if (file->IsCompressed && GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) { /* FIXME: this might be done earlier in the install process */ rc = find_published_source(package, mi); if (rc != ERROR_SUCCESS) { ERR("Cabinet not found: %s\n", debugstr_w(mi->source)); return ERROR_INSTALL_FAILURE; } } return ERROR_SUCCESS; }
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; }