static UINT ITERATE_AppSearch(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; LPCWSTR propName, sigName; LPWSTR value = NULL; MSISIGNATURE sig; MSIRECORD *uirow; UINT r; /* get property and signature */ propName = MSI_RecordGetString(row, 1); sigName = MSI_RecordGetString(row, 2); TRACE("%s %s\n", debugstr_w(propName), debugstr_w(sigName)); r = search_sig_name( package, sigName, &sig, &value ); if (value) { r = msi_set_property( package->db, propName, value, -1 ); if (r == ERROR_SUCCESS && !strcmpW( propName, szSourceDir )) msi_reset_source_folders( package ); msi_free(value); } free_signature( &sig ); uirow = MSI_CreateRecord( 2 ); MSI_RecordSetStringW( uirow, 1, propName ); MSI_RecordSetStringW( uirow, 2, sigName ); MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, uirow); msiobj_release( &uirow->hdr ); return r; }
static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; LPCWSTR propName, sigName; LPWSTR value = NULL; MSISIGNATURE sig; MSIRECORD *uirow; UINT r; /* get property and signature */ propName = MSI_RecordGetString(row, 1); sigName = MSI_RecordGetString(row, 2); TRACE("%s %s\n", debugstr_w(propName), debugstr_w(sigName)); r = ACTION_AppSearchSigName(package, sigName, &sig, &value); if (value) { r = msi_set_property( package->db, propName, value ); if (r == ERROR_SUCCESS && !strcmpW( propName, cszSourceDir )) msi_reset_folders( package, TRUE ); msi_free(value); } ACTION_FreeSignature(&sig); uirow = MSI_CreateRecord( 2 ); MSI_RecordSetStringW( uirow, 1, propName ); MSI_RecordSetStringW( uirow, 2, sigName ); ui_actiondata( package, szAppSearch, uirow ); msiobj_release( &uirow->hdr ); return r; }
static UINT msi_media_get_disk_info( MSIPACKAGE *package, struct media_info *mi ) { MSIRECORD *row; LPWSTR ptr; static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', '`','D','i','s','k','I','d','`',' ','=',' ','%','i',0}; row = MSI_QueryGetRecord(package->db, query, mi->disk_id); if (!row) { TRACE("Unable to query row\n"); return ERROR_FUNCTION_FAILED; } mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3)); 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); ptr = strrchrW(mi->source, '\\') + 1; lstrcpyW(ptr, mi->cabinet); msiobj_release(&row->hdr); return ERROR_SUCCESS; }
static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; LPCWSTR signature; LPWSTR value = NULL; MSISIGNATURE sig; UINT r = ERROR_SUCCESS; static const WCHAR success[] = {'C','C','P','_','S','u','c','c','e','s','s',0}; signature = MSI_RecordGetString(row, 1); TRACE("%s\n", debugstr_w(signature)); ACTION_AppSearchSigName(package, signature, &sig, &value); if (value) { TRACE("Found signature %s\n", debugstr_w(signature)); msi_set_property(package->db, success, szOne); msi_free(value); r = ERROR_NO_MORE_ITEMS; } ACTION_FreeSignature(&sig); return r; }
static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', 'f','r','o','m',' ', 'D','r','L','o','c','a','t','o','r',' ', 'w','h','e','r','e',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0}; LPWSTR parent = NULL; LPCWSTR parentName; WCHAR path[MAX_PATH]; WCHAR expanded[MAX_PATH]; MSIRECORD *row; int depth; DWORD sz, attr; UINT rc; TRACE("%s\n", debugstr_w(sig->Name)); *appValue = NULL; row = MSI_QueryGetRecord( package->db, query, sig->Name ); if (!row) { TRACE("failed to query DrLocator for %s\n", debugstr_w(sig->Name)); return ERROR_SUCCESS; } /* check whether parent is set */ parentName = MSI_RecordGetString(row, 2); if (parentName) { MSISIGNATURE parentSig; rc = ACTION_AppSearchSigName(package, parentName, &parentSig, &parent); ACTION_FreeSignature(&parentSig); if (!parent) { msiobj_release(&row->hdr); return ERROR_SUCCESS; } } sz = MAX_PATH; MSI_RecordGetStringW(row, 3, path, &sz); if (MSI_RecordIsNull(row,4)) depth = 0; else depth = MSI_RecordGetInteger(row,4); if (sz) ACTION_ExpandAnyPath(package, path, expanded, MAX_PATH); else strcpyW(expanded, path); if (parent) { attr = GetFileAttributesW(parent); if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY)) { PathRemoveFileSpecW(parent); PathAddBackslashW(parent); } strcpyW(path, parent); strcatW(path, expanded); } else if (sz) strcpyW(path, expanded); PathAddBackslashW(path); rc = ACTION_SearchDirectory(package, sig, path, depth, appValue); msi_free(parent); msiobj_release(&row->hdr); TRACE("returning %d\n", rc); return rc; }
static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig) { static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', '`','C','o','m','p','L','o','c','a','t','o','r','`',' ', 'W','H','E','R','E',' ','`','S','i','g','n','a','t','u','r','e','_','`',' ','=',' ', '\'','%','s','\'',0}; static const WCHAR sigquery[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', '`','S','i','g','n','a','t','u','r','e','`',' ', 'W','H','E','R','E',' ','`','S','i','g','n','a','t','u','r','e','`',' ','=',' ', '\'','%','s','\'',0}; MSIRECORD *row, *rec; LPCWSTR signature, guid; BOOL sigpresent = TRUE; BOOL isdir; UINT type; WCHAR path[MAX_PATH]; DWORD size = MAX_PATH; LPWSTR ptr; DWORD attr; TRACE("%s\n", debugstr_w(sig->Name)); *appValue = NULL; row = MSI_QueryGetRecord(package->db, query, sig->Name); if (!row) { TRACE("failed to query CompLocator for %s\n", debugstr_w(sig->Name)); return ERROR_SUCCESS; } signature = MSI_RecordGetString(row, 1); guid = MSI_RecordGetString(row, 2); type = MSI_RecordGetInteger(row, 3); rec = MSI_QueryGetRecord(package->db, sigquery, signature); if (!rec) sigpresent = FALSE; *path = '\0'; MsiLocateComponentW(guid, path, &size); if (!*path) goto done; attr = GetFileAttributesW(path); if (attr == INVALID_FILE_ATTRIBUTES) goto done; isdir = (attr & FILE_ATTRIBUTE_DIRECTORY); if (type != msidbLocatorTypeDirectory && sigpresent && !isdir) { *appValue = app_search_file(path, sig); } else if (!sigpresent && (type != msidbLocatorTypeDirectory || isdir)) { if (type == msidbLocatorTypeFileName) { ptr = strrchrW(path, '\\'); *(ptr + 1) = '\0'; } else PathAddBackslashW(path); *appValue = strdupW(path); } else if (sigpresent) { PathAddBackslashW(path); lstrcatW(path, MSI_RecordGetString(rec, 2)); attr = GetFileAttributesW(path); if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY)) *appValue = strdupW(path); } done: if (rec) msiobj_release(&rec->hdr); msiobj_release(&row->hdr); return ERROR_SUCCESS; }
static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param ) { MSIPACKAGE *package = param; LPWSTR name; LPCWSTR filename; MSIFILE *file; MSICOMPONENT *comp; HKEY hkey1, hkey2; MSIRECORD *uirow; LPWSTR uipath, p; filename = MSI_RecordGetString( row, 1 ); file = msi_get_loaded_file( package, filename ); if (!file) { WARN("unable to find file %s\n", debugstr_w(filename)); return ERROR_SUCCESS; } comp = msi_get_loaded_component( package, file->Component->Component ); if (!comp) { WARN("unable to find component %s\n", debugstr_w(file->Component->Component)); return ERROR_SUCCESS; } comp->Action = msi_get_component_action( package, comp ); if (comp->Action != INSTALLSTATE_ABSENT) { TRACE("component not scheduled for removal %s\n", debugstr_w(comp->Component)); return ERROR_SUCCESS; } RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont1, &hkey1 ); RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 ); if (MSI_RecordIsNull( row, 2 )) name = font_name_from_file( file->TargetPath ); else name = msi_dup_record_field( row, 2 ); if (name) { RegDeleteValueW( hkey1, name ); RegDeleteValueW( hkey2, name ); } msi_free( name ); RegCloseKey( hkey1 ); RegCloseKey( hkey2 ); /* the UI chunk */ uirow = MSI_CreateRecord( 1 ); uipath = strdupW( file->TargetPath ); p = strrchrW( uipath,'\\' ); if (p) p++; else p = uipath; MSI_RecordSetStringW( uirow, 1, p ); msi_ui_actiondata( package, szUnregisterFonts, uirow ); msiobj_release( &uirow->hdr ); msi_free( uipath ); /* FIXME: call msi_ui_progress? */ return ERROR_SUCCESS; }
static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param) { MSIPACKAGE *package = param; WCHAR product[GUID_SIZE]; DWORD index = 0; DWORD attributes = 0; DWORD sz = GUID_SIZE; LPCWSTR upgrade_code; HKEY hkey = 0; UINT rc = ERROR_SUCCESS; MSIRECORD *uirow; upgrade_code = MSI_RecordGetString(rec,1); rc = MSIREG_OpenUpgradeCodesKey(upgrade_code, &hkey, FALSE); if (rc != ERROR_SUCCESS) return ERROR_SUCCESS; uirow = MSI_CreateRecord(1); attributes = MSI_RecordGetInteger(rec,5); while (rc == ERROR_SUCCESS) { rc = RegEnumValueW(hkey, index, product, &sz, NULL, NULL, NULL, NULL); if (rc == ERROR_SUCCESS) { WCHAR productid[GUID_SIZE]; LPCWSTR ver, language, action_property; DWORD check = 0, comp_ver, sz = 0x100; HKEY hukey; INT r; TRACE("Looking at index %u product %s\n", index, debugstr_w(product)); unsquash_guid(product, productid); if (MSIREG_OpenProductKey(productid, NULL, MSIINSTALLCONTEXT_USERMANAGED, &hukey, FALSE) && MSIREG_OpenProductKey(productid, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, &hukey, FALSE) && MSIREG_OpenProductKey(productid, NULL, MSIINSTALLCONTEXT_MACHINE, &hukey, FALSE)) { TRACE("product key not found\n"); rc = ERROR_SUCCESS; index ++; continue; } sz = sizeof(DWORD); RegQueryValueExW(hukey, INSTALLPROPERTY_VERSIONW, NULL, NULL, (LPBYTE)&check, &sz); /* check version minimum */ ver = MSI_RecordGetString(rec,2); if (ver) { comp_ver = msi_version_str_to_dword(ver); r = check - comp_ver; if (r < 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMinInclusive))) { TRACE("version below minimum\n"); RegCloseKey(hukey); index ++; continue; } } /* check version maximum */ ver = MSI_RecordGetString(rec,3); if (ver) { comp_ver = msi_version_str_to_dword(ver); r = check - comp_ver; if (r > 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMaxInclusive))) { RegCloseKey(hukey); index ++; continue; } TRACE("version above maximum\n"); } /* check language */ sz = sizeof(DWORD); RegQueryValueExW(hukey, INSTALLPROPERTY_LANGUAGEW, NULL, NULL, (LPBYTE)&check, &sz); RegCloseKey(hukey); language = MSI_RecordGetString(rec,4); if (!check_language(check, language, attributes)) { index ++; continue; TRACE("language doesn't match\n"); } TRACE("found related product\n"); action_property = MSI_RecordGetString(rec, 7); append_productcode(package, action_property, productid); MSI_RecordSetStringW(uirow, 1, productid); msi_ui_actiondata(package, szFindRelatedProducts, uirow); } index ++; } RegCloseKey(hkey); msiobj_release( &uirow->hdr); return ERROR_SUCCESS; }
static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; LPWSTR name; LPCWSTR filename; MSIFILE *file; HKEY hkey1, hkey2; MSIRECORD *uirow; LPWSTR uipath, p; filename = MSI_RecordGetString( row, 1 ); file = get_loaded_file( package, filename ); if (!file) { ERR("Unable to load file\n"); return ERROR_SUCCESS; } if (!file->Component->Enabled) { TRACE("component is disabled\n"); return ERROR_SUCCESS; } if (file->Component->ActionRequest != INSTALLSTATE_LOCAL) { TRACE("Component not scheduled for installation\n"); return ERROR_SUCCESS; } RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1); RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); if (MSI_RecordIsNull(row,2)) name = font_name_from_file( file->TargetPath ); else name = msi_dup_record_field(row,2); if (name) { msi_reg_set_val_str( hkey1, name, file->TargetPath); msi_reg_set_val_str( hkey2, name, file->TargetPath); } msi_free(name); RegCloseKey(hkey1); RegCloseKey(hkey2); /* the UI chunk */ uirow = MSI_CreateRecord( 1 ); uipath = strdupW( file->TargetPath ); p = strrchrW(uipath,'\\'); if (p) p++; else p = uipath; MSI_RecordSetStringW( uirow, 1, p ); ui_actiondata( package, szRegisterFonts, uirow); msiobj_release( &uirow->hdr ); msi_free( uipath ); /* FIXME: call ui_progress? */ return ERROR_SUCCESS; }
static UINT search_reg( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) { static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', 'R','e','g','L','o','c','a','t','o','r',' ','W','H','E','R','E',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0}; const WCHAR *keyPath, *valueName; WCHAR *deformatted = NULL, *ptr = NULL, *end; int root, type; REGSAM access = KEY_READ; HKEY rootKey, key = NULL; DWORD sz = 0, regType; LPBYTE value = NULL; MSIRECORD *row; UINT rc; TRACE("%s\n", debugstr_w(sig->Name)); *appValue = NULL; row = MSI_QueryGetRecord( package->db, query, sig->Name ); if (!row) { TRACE("failed to query RegLocator for %s\n", debugstr_w(sig->Name)); return ERROR_SUCCESS; } root = MSI_RecordGetInteger(row, 2); keyPath = MSI_RecordGetString(row, 3); valueName = MSI_RecordGetString(row, 4); type = MSI_RecordGetInteger(row, 5); deformat_string(package, keyPath, &deformatted); switch (root) { case msidbRegistryRootClassesRoot: rootKey = HKEY_CLASSES_ROOT; break; case msidbRegistryRootCurrentUser: rootKey = HKEY_CURRENT_USER; break; case msidbRegistryRootLocalMachine: rootKey = HKEY_LOCAL_MACHINE; if (type & msidbLocatorType64bit) access |= KEY_WOW64_64KEY; else access |= KEY_WOW64_32KEY; break; case msidbRegistryRootUsers: rootKey = HKEY_USERS; break; default: WARN("Unknown root key %d\n", root); goto end; } rc = RegOpenKeyExW( rootKey, deformatted, 0, access, &key ); if (rc) { TRACE("RegOpenKeyExW returned %d\n", rc); goto end; } msi_free(deformatted); deformat_string(package, valueName, &deformatted); rc = RegQueryValueExW(key, deformatted, NULL, NULL, NULL, &sz); if (rc) { TRACE("RegQueryValueExW returned %d\n", rc); goto end; } /* FIXME: sanity-check sz before allocating (is there an upper-limit * on the value of a property?) */ value = msi_alloc( sz ); rc = RegQueryValueExW(key, deformatted, NULL, ®Type, value, &sz); if (rc) { TRACE("RegQueryValueExW returned %d\n", rc); goto end; } /* bail out if the registry key is empty */ if (sz == 0) goto end; /* expand if needed */ if (regType == REG_EXPAND_SZ) { sz = ExpandEnvironmentStringsW((LPCWSTR)value, NULL, 0); if (sz) { LPWSTR buf = msi_alloc(sz * sizeof(WCHAR)); ExpandEnvironmentStringsW((LPCWSTR)value, buf, sz); msi_free(value); value = (LPBYTE)buf; } } if ((regType == REG_SZ || regType == REG_EXPAND_SZ) && (ptr = strchrW((LPWSTR)value, '"')) && (end = strchrW(++ptr, '"'))) *end = '\0'; else ptr = (LPWSTR)value; switch (type & 0x0f) { case msidbLocatorTypeDirectory: search_directory( package, sig, ptr, 0, appValue ); break; case msidbLocatorTypeFileName: *appValue = search_file( package, ptr, sig ); break; case msidbLocatorTypeRawValue: convert_reg_value( regType, value, sz, appValue ); break; default: FIXME("unimplemented for type %d (key path %s, value %s)\n", type, debugstr_w(keyPath), debugstr_w(valueName)); } end: msi_free( value ); RegCloseKey( key ); msi_free( deformatted ); msiobj_release(&row->hdr); 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; }
static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; LPWSTR name; LPCWSTR filename; MSIFILE *file; static const WCHAR regfont1[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s',' ','N','T','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'F','o','n','t','s',0}; static const WCHAR regfont2[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'F','o','n','t','s',0}; HKEY hkey1; HKEY hkey2; MSIRECORD *uirow; LPWSTR uipath, p; filename = MSI_RecordGetString( row, 1 ); file = get_loaded_file( package, filename ); if (!file) { ERR("Unable to load file\n"); return ERROR_SUCCESS; } /* check to make sure that component is installed */ if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL)) { TRACE("Skipping: Component not scheduled for install\n"); return ERROR_SUCCESS; } RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1); RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); if (MSI_RecordIsNull(row,2)) name = load_ttfname_from( file->TargetPath ); else name = msi_dup_record_field(row,2); if (name) { msi_reg_set_val_str( hkey1, name, file->TargetPath); msi_reg_set_val_str( hkey2, name, file->TargetPath); } msi_free(name); RegCloseKey(hkey1); RegCloseKey(hkey2); /* the UI chunk */ uirow = MSI_CreateRecord( 1 ); uipath = strdupW( file->TargetPath ); p = strrchrW(uipath,'\\'); if (p) p++; else p = uipath; MSI_RecordSetStringW( uirow, 1, p ); ui_actiondata( package, szRegisterFonts, uirow); msiobj_release( &uirow->hdr ); msi_free( uipath ); /* FIXME: call ui_progress? */ return ERROR_SUCCESS; }
static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param) { MSIPACKAGE *package = (MSIPACKAGE*)param; WCHAR product[GUID_SIZE]; DWORD index = 0; DWORD attributes = 0; DWORD sz = GUID_SIZE; LPCWSTR upgrade_code; HKEY hkey = 0; UINT rc = ERROR_SUCCESS; MSIRECORD *uirow; upgrade_code = MSI_RecordGetString(rec,1); rc = MSIREG_OpenUpgradeCodesKey(upgrade_code, &hkey, FALSE); if (rc != ERROR_SUCCESS) return ERROR_SUCCESS; uirow = MSI_CreateRecord(1); attributes = MSI_RecordGetInteger(rec,5); while (rc == ERROR_SUCCESS) { rc = RegEnumValueW(hkey, index, product, &sz, NULL, NULL, NULL, NULL); TRACE("Looking at (%li) %s\n",index,debugstr_w(product)); if (rc == ERROR_SUCCESS) { WCHAR productid[GUID_SIZE]; LPCWSTR ver; LPCWSTR language; LPCWSTR action_property; DWORD check = 0x00000000; DWORD comp_ver = 0x00000000; DWORD sz = 0x100; HKEY hukey; INT r; unsquash_guid(product,productid); rc = MSIREG_OpenUserProductsKey(productid, &hukey, FALSE); if (rc != ERROR_SUCCESS) { rc = ERROR_SUCCESS; index ++; continue; } sz = sizeof(DWORD); RegQueryValueExW(hukey, INSTALLPROPERTY_VERSIONW, NULL, NULL, (LPBYTE)&check, &sz); /* check min */ ver = MSI_RecordGetString(rec,2); comp_ver = msi_version_str_to_dword(ver); r = check - comp_ver; if (r < 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMinInclusive))) { RegCloseKey(hukey); index ++; continue; } /* check max */ ver = MSI_RecordGetString(rec,3); comp_ver = msi_version_str_to_dword(ver); r = check - comp_ver; if (r > 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMaxInclusive))) { RegCloseKey(hukey); index ++; continue; } /* check language*/ sz = sizeof(DWORD); RegQueryValueExW(hukey, INSTALLPROPERTY_LANGUAGEW, NULL, NULL, (LPBYTE)&check, &sz); RegCloseKey(hukey); language = MSI_RecordGetString(rec,4); TRACE("Checking languages 0x%lx and %s\n", check, debugstr_w(language)); if (!check_language(check, language, attributes)) { index ++; continue; } action_property = MSI_RecordGetString(rec,7); append_productcode(package,action_property,productid); ui_actiondata(package,szFindRelatedProducts,uirow); } index ++; } RegCloseKey(hkey); msiobj_release( &uirow->hdr); return ERROR_SUCCESS; }