static BOOL check_column_exists(MSIDATABASE *db, LPCWSTR table, LPCWSTR column) { MSIQUERY *view; MSIRECORD *rec; UINT r; static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', '`','_','C','o','l','u','m','n','s','`',' ','W','H','E','R','E',' ', '`','T','a','b','l','e','`','=','\'','%','s','\'',' ','A','N','D',' ', '`','N','a','m','e','`','=','\'','%','s','\'',0 }; r = MSI_OpenQuery(db, &view, query, table, column); if (r != ERROR_SUCCESS) return FALSE; r = MSI_ViewExecute(view, NULL); if (r != ERROR_SUCCESS) goto done; r = MSI_ViewFetch(view, &rec); if (r == ERROR_SUCCESS) msiobj_release(&rec->hdr); done: msiobj_release(&view->hdr); return (r == ERROR_SUCCESS); }
MSIRECORD *MSI_CloneRecord(MSIRECORD *rec) { MSIRECORD *clone; UINT r, i, count; count = MSI_RecordGetFieldCount(rec); clone = MSI_CreateRecord(count); if (!clone) return NULL; for (i = 0; i <= count; i++) { if (rec->fields[i].type == MSIFIELD_STREAM) { if (FAILED(IStream_Clone(rec->fields[i].u.stream, &clone->fields[i].u.stream))) { msiobj_release(&clone->hdr); return NULL; } clone->fields[i].type = MSIFIELD_STREAM; } else { r = MSI_RecordCopyField(rec, i, clone, i); if (r != ERROR_SUCCESS) { msiobj_release(&clone->hdr); return NULL; } } } return clone; }
UINT ACTION_FindRelatedProducts(MSIPACKAGE *package) { static const WCHAR Query[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M', ' ','`','U','p','g','r','a','d','e','`',0}; UINT rc = ERROR_SUCCESS; MSIQUERY *view; if (check_unique_action(package,szFindRelatedProducts)) { TRACE("Skipping FindRelatedProducts action: already done on client side\n"); return ERROR_SUCCESS; } else register_unique_action(package,szFindRelatedProducts); rc = MSI_DatabaseOpenViewW(package->db, Query, &view); if (rc != ERROR_SUCCESS) return ERROR_SUCCESS; rc = MSI_IterateRecords(view, NULL, ITERATE_FindRelatedProducts, package); msiobj_release(&view->hdr); return rc; }
UINT ACTION_FindRelatedProducts(MSIPACKAGE *package) { static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', '`','U','p','g','r','a','d','e','`',0}; MSIQUERY *view; UINT rc; if (msi_get_property_int(package->db, szInstalled, 0)) { TRACE("Skipping FindRelatedProducts action: product already installed\n"); return ERROR_SUCCESS; } if (msi_action_is_unique(package, szFindRelatedProducts)) { TRACE("Skipping FindRelatedProducts action: already done in UI sequence\n"); return ERROR_SUCCESS; } else msi_register_unique_action(package, szFindRelatedProducts); rc = MSI_DatabaseOpenViewW(package->db, query, &view); if (rc != ERROR_SUCCESS) return ERROR_SUCCESS; rc = MSI_IterateRecords(view, NULL, ITERATE_FindRelatedProducts, package); msiobj_release(&view->hdr); return rc; }
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; }
UINT ACTION_CCPSearch(MSIPACKAGE *package) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', 'f','r','o','m',' ', 'C','C','P','S','e','a','r','c','h',0}; MSIQUERY *view = NULL; UINT r; if (check_unique_action(package, szCCPSearch)) { TRACE("Skipping AppSearch action: already done in UI sequence\n"); return ERROR_SUCCESS; } else register_unique_action(package, szCCPSearch); r = MSI_OpenQuery(package->db, &view, query); if (r != ERROR_SUCCESS) return ERROR_SUCCESS; r = MSI_IterateRecords(view, NULL, ITERATE_CCPSearch, package); msiobj_release(&view->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 = 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 ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', 'f','r','o','m',' ', 'I','n','i','L','o','c','a','t','o','r',' ', 'w','h','e','r','e',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ','\'','%','s','\'',0}; MSIRECORD *row; LPWSTR fileName, section, key; int field, type; WCHAR buf[MAX_PATH]; TRACE("%s\n", debugstr_w(sig->Name)); *appValue = NULL; row = MSI_QueryGetRecord( package->db, query, sig->Name ); if (!row) { TRACE("failed to query IniLocator for %s\n", debugstr_w(sig->Name)); return ERROR_SUCCESS; } fileName = msi_dup_record_field(row, 2); section = msi_dup_record_field(row, 3); key = msi_dup_record_field(row, 4); field = MSI_RecordGetInteger(row, 5); type = MSI_RecordGetInteger(row, 6); if (field == MSI_NULL_INTEGER) field = 0; if (type == MSI_NULL_INTEGER) type = 0; GetPrivateProfileStringW(section, key, NULL, buf, MAX_PATH, fileName); if (buf[0]) { switch (type & 0x0f) { case msidbLocatorTypeDirectory: ACTION_SearchDirectory(package, sig, buf, 0, appValue); break; case msidbLocatorTypeFileName: *appValue = app_search_file(buf, sig); break; case msidbLocatorTypeRawValue: *appValue = get_ini_field(buf, field); break; } } msi_free(fileName); msi_free(section); msi_free(key); msiobj_release(&row->hdr); return ERROR_SUCCESS; }
static UINT CREATE_delete( struct tagMSIVIEW *view ) { MSICREATEVIEW *cv = (MSICREATEVIEW*)view; TRACE("%p\n", cv ); msiobj_release( &cv->db->hdr ); msi_free( cv ); return ERROR_SUCCESS; }
UINT WINAPI MsiEnableUIPreview( MSIHANDLE hdb, MSIHANDLE* phPreview ) { MSIDATABASE *db; MSIPREVIEW *preview; UINT r = ERROR_FUNCTION_FAILED; TRACE("%ld %p\n", hdb, phPreview); db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE ); if( !db ) { IWineMsiRemoteDatabase *remote_database; remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb ); if ( !remote_database ) return ERROR_INVALID_HANDLE; *phPreview = 0; IWineMsiRemoteDatabase_Release( remote_database ); WARN("MsiEnableUIPreview not allowed during a custom action!\n"); return ERROR_FUNCTION_FAILED; } preview = MSI_EnableUIPreview( db ); if( preview ) { *phPreview = alloc_msihandle( &preview->hdr ); msiobj_release( &preview->hdr ); r = ERROR_SUCCESS; if (! *phPreview) r = ERROR_NOT_ENOUGH_MEMORY; } msiobj_release( &db->hdr ); return r; }
UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, LPCWSTR szFolder, LPCWSTR szFilename) { MSIDATABASE *db; UINT r; TRACE("%lx %s %s\n",handle,debugstr_w(szFolder), debugstr_w(szFilename)); db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); if( !db ) return ERROR_INVALID_HANDLE; r = MSI_DatabaseImport( db, szFolder, szFilename ); msiobj_release( &db->hdr ); return r; }
MSIHANDLE WINAPI MsiCreateRecord( UINT cParams ) { MSIRECORD *rec; MSIHANDLE ret = 0; TRACE("%d\n", cParams); rec = MSI_CreateRecord( cParams ); if( rec ) { ret = alloc_msihandle( &rec->hdr ); msiobj_release( &rec->hdr ); } return ret; }
UINT ACTION_UnregisterFonts( MSIPACKAGE *package ) { static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','F','o','n','t','`',0}; MSIQUERY *view; UINT r; r = MSI_DatabaseOpenViewW( package->db, query, &view ); if (r != ERROR_SUCCESS) return ERROR_SUCCESS; r = MSI_IterateRecords( view, NULL, ITERATE_UnregisterFonts, package ); msiobj_release( &view->hdr ); return r; }
UINT WINAPI MsiRecordReadStream(MSIHANDLE handle, UINT iField, char *buf, LPDWORD sz) { MSIRECORD *rec; UINT ret; TRACE("%d %d %p %p\n", handle, iField, buf, sz); rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) return ERROR_INVALID_HANDLE; msiobj_lock( &rec->hdr ); ret = MSI_RecordReadStream( rec, iField, buf, sz ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); return ret; }
UINT WINAPI MsiRecordDataSize(MSIHANDLE handle, UINT iField) { MSIRECORD *rec; UINT ret; TRACE("%d %d\n", handle, iField); rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) return 0; msiobj_lock( &rec->hdr ); ret = MSI_RecordDataSize( rec, iField); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); return ret; }
UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, UINT iField, LPCSTR szValue ) { MSIRECORD *rec; UINT ret; TRACE("%d %d %s\n", handle, iField, debugstr_a(szValue)); rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) return ERROR_INVALID_HANDLE; msiobj_lock( &rec->hdr ); ret = MSI_RecordSetStringA( rec, iField, szValue ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); return ret; }
MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle ) { MSIDBSTATE ret = MSIDBSTATE_READ; MSIDATABASE *db; TRACE("%ld\n", handle); db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); if (!db) return MSIDBSTATE_ERROR; if (db->mode != MSIDBOPEN_READONLY ) ret = MSIDBSTATE_WRITE; msiobj_release( &db->hdr ); return ret; }
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB) { MSIDATABASE *db; UINT ret; TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB); ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db ); if( ret == ERROR_SUCCESS ) { *phDB = alloc_msihandle( &db->hdr ); msiobj_release( &db->hdr ); } return ret; }
/*********************************************************** * MsiCloseHandle [MSI.@] */ UINT WINAPI MsiCloseHandle(MSIHANDLE handle) { MSIOBJECTHDR *info = NULL; UINT ret = ERROR_INVALID_HANDLE; TRACE("%x\n",handle); if (!handle) return ERROR_SUCCESS; EnterCriticalSection( &MSI_handle_cs ); handle--; if (handle >= msihandletable_size) goto out; if (msihandletable[handle].remote) { IUnknown_Release( msihandletable[handle].u.unk ); } else { info = msihandletable[handle].u.obj; if( !info ) goto out; if( info->magic != MSIHANDLE_MAGIC ) { ERR("Invalid handle!\n"); goto out; } } msihandletable[handle].u.obj = NULL; msihandletable[handle].remote = 0; msihandletable[handle].dwThreadId = 0; ret = ERROR_SUCCESS; TRACE("handle %x destroyed\n", handle+1); out: LeaveCriticalSection( &MSI_handle_cs ); if( info ) msiobj_release( info ); return ret; }
UINT WINAPI MsiPreviewDialogW( MSIHANDLE hPreview, LPCWSTR szDialogName ) { MSIPREVIEW *preview; UINT r; TRACE("%ld %s\n", hPreview, debugstr_w(szDialogName)); preview = msihandle2msiinfo( hPreview, MSIHANDLETYPE_PREVIEW ); if( !preview ) return ERROR_INVALID_HANDLE; r = MSI_PreviewDialogW( preview, szDialogName ); msiobj_release( &preview->hdr ); return r; }
UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, UINT iField, int iVal ) { MSIRECORD *rec; UINT ret; TRACE("%d %u %d\n", handle, iField, iVal); rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) return ERROR_INVALID_HANDLE; msiobj_lock( &rec->hdr ); ret = MSI_RecordSetInteger( rec, iField, iVal ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); return ret; }
UINT WINAPI MsiRecordGetFieldCount( MSIHANDLE handle ) { MSIRECORD *rec; UINT ret; TRACE("%d\n", handle ); rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) return -1; msiobj_lock( &rec->hdr ); ret = MSI_RecordGetFieldCount( rec ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); return ret; }
int WINAPI MsiRecordGetInteger( MSIHANDLE handle, UINT iField) { MSIRECORD *rec; UINT ret; TRACE("%d %d\n", handle, iField ); rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) return MSI_NULL_INTEGER; msiobj_lock( &rec->hdr ); ret = MSI_RecordGetInteger( rec, iField ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); return ret; }
UINT ACTION_CCPSearch(MSIPACKAGE *package) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', 'f','r','o','m',' ', 'C','C','P','S','e','a','r','c','h',0}; MSIQUERY *view = NULL; UINT r; r = MSI_OpenQuery(package->db, &view, query); if (r != ERROR_SUCCESS) return ERROR_SUCCESS; r = MSI_IterateRecords(view, NULL, ITERATE_CCPSearch, package); msiobj_release(&view->hdr); return r; }
UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, UINT iField, LPWSTR szValue, LPDWORD pcchValue) { MSIRECORD *rec; UINT ret; TRACE("%d %d %p %p\n", handle, iField, szValue, pcchValue); rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) return ERROR_INVALID_HANDLE; msiobj_lock( &rec->hdr ); ret = MSI_RecordGetStringW( rec, iField, szValue, pcchValue ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); return ret; }
static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *action ) { MSIRECORD *uirow; LPWSTR uipath, p; /* the UI chunk */ uirow = MSI_CreateRecord( 9 ); MSI_RecordSetStringW( uirow, 1, f->FileName ); uipath = strdupW( f->TargetPath ); p = strrchrW(uipath,'\\'); if (p) p[1]=0; MSI_RecordSetStringW( uirow, 9, uipath); MSI_RecordSetInteger( uirow, 6, f->FileSize ); ui_actiondata( package, action, uirow); msiobj_release( &uirow->hdr ); msi_free( uipath ); ui_progress( package, 2, f->FileSize, 0, 0); }
MSIPREVIEW *MSI_EnableUIPreview( MSIDATABASE *db ) { MSIPREVIEW *preview = NULL; MSIPACKAGE *package; package = MSI_CreatePackage( db, NULL ); if( package ) { preview = alloc_msiobject( MSIHANDLETYPE_PREVIEW, sizeof (MSIPREVIEW), MSI_ClosePreview ); if( preview ) { preview->package = package; preview->dialog = 0; msiobj_addref( &package->hdr ); } msiobj_release( &package->hdr ); } return preview; }
UINT ACTION_RegisterFonts(MSIPACKAGE *package) { UINT rc; MSIQUERY * view; static const WCHAR ExecSeqQuery[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', '`','F','o','n','t','`',0}; rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view); if (rc != ERROR_SUCCESS) { TRACE("MSI_DatabaseOpenViewW failed: %d\n", rc); return ERROR_SUCCESS; } MSI_IterateRecords(view, NULL, ITERATE_RegisterFonts, package); msiobj_release(&view->hdr); return ERROR_SUCCESS; }
UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, UINT iField, LPCSTR szValue ) { WCHAR *valueW = NULL; MSIRECORD *rec; UINT ret; TRACE("%d %d %s\n", handle, iField, debugstr_a(szValue)); if (szValue && !(valueW = strdupAtoW( szValue ))) return ERROR_OUTOFMEMORY; rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD ); if( !rec ) { msi_free( valueW ); return ERROR_INVALID_HANDLE; } msiobj_lock( &rec->hdr ); ret = MSI_RecordSetStringW( rec, iField, valueW ); msiobj_unlock( &rec->hdr ); msiobj_release( &rec->hdr ); msi_free( valueW ); return ret; }