Reactos
at master 208 lines 5.1 kB view raw
1/* 2 * Implementation of the Microsoft Installer (msi.dll) 3 * 4 * Copyright 2002-2005 Mike McCormack for CodeWeavers 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21#include <stdarg.h> 22 23#include "windef.h" 24#include "winbase.h" 25#include "winerror.h" 26#include "wine/debug.h" 27#include "msi.h" 28#include "msiquery.h" 29#include "objbase.h" 30#include "objidl.h" 31#include "msipriv.h" 32#include "winnls.h" 33 34#include "query.h" 35 36WINE_DEFAULT_DEBUG_CHANNEL(msidb); 37 38 39/* 40 * Code to delete rows from a table. 41 * 42 * We delete rows by blanking them out rather than trying to remove the row. 43 * This appears to be what the native MSI does (or tries to do). For the query: 44 * 45 * delete from Property 46 * 47 * some non-zero entries are left in the table by native MSI. I'm not sure if 48 * that's a bug in the way I'm running the query, or a just a bug. 49 */ 50 51struct delete_view 52{ 53 MSIVIEW view; 54 MSIDATABASE *db; 55 MSIVIEW *table; 56}; 57 58static UINT DELETE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val ) 59{ 60 struct delete_view *dv = (struct delete_view *)view; 61 62 TRACE("%p %d %d %p\n", dv, row, col, val ); 63 64 return ERROR_FUNCTION_FAILED; 65} 66 67static UINT DELETE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm) 68{ 69 struct delete_view *dv = (struct delete_view *)view; 70 71 TRACE("%p %d %d %p\n", dv, row, col, stm ); 72 73 return ERROR_FUNCTION_FAILED; 74} 75 76static UINT DELETE_execute( struct tagMSIVIEW *view, MSIRECORD *record ) 77{ 78 struct delete_view *dv = (struct delete_view *)view; 79 UINT r, i, rows = 0, cols = 0; 80 81 TRACE("%p %p\n", dv, record); 82 83 if( !dv->table ) 84 return ERROR_FUNCTION_FAILED; 85 86 r = dv->table->ops->execute( dv->table, record ); 87 if( r != ERROR_SUCCESS ) 88 return r; 89 90 r = dv->table->ops->get_dimensions( dv->table, &rows, &cols ); 91 if( r != ERROR_SUCCESS ) 92 return r; 93 94 TRACE("deleting %d rows\n", rows); 95 96 /* blank out all the rows that match */ 97 for ( i=0; i<rows; i++ ) 98 dv->table->ops->delete_row( dv->table, i ); 99 100 return ERROR_SUCCESS; 101} 102 103static UINT DELETE_close( struct tagMSIVIEW *view ) 104{ 105 struct delete_view *dv = (struct delete_view *)view; 106 107 TRACE("%p\n", dv ); 108 109 if( !dv->table ) 110 return ERROR_FUNCTION_FAILED; 111 112 return dv->table->ops->close( dv->table ); 113} 114 115static UINT DELETE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols ) 116{ 117 struct delete_view *dv = (struct delete_view *)view; 118 119 TRACE("%p %p %p\n", dv, rows, cols ); 120 121 if( !dv->table ) 122 return ERROR_FUNCTION_FAILED; 123 124 *rows = 0; 125 126 return dv->table->ops->get_dimensions( dv->table, NULL, cols ); 127} 128 129static UINT DELETE_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *name, 130 UINT *type, BOOL *temporary, LPCWSTR *table_name ) 131{ 132 struct delete_view *dv = (struct delete_view *)view; 133 134 TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, table_name ); 135 136 if( !dv->table ) 137 return ERROR_FUNCTION_FAILED; 138 139 return dv->table->ops->get_column_info( dv->table, n, name, 140 type, temporary, table_name); 141} 142 143static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, 144 MSIRECORD *rec, UINT row ) 145{ 146 struct delete_view *dv = (struct delete_view *)view; 147 148 TRACE("%p %d %p\n", dv, eModifyMode, rec ); 149 150 return ERROR_FUNCTION_FAILED; 151} 152 153static UINT DELETE_delete( struct tagMSIVIEW *view ) 154{ 155 struct delete_view *dv = (struct delete_view *)view; 156 157 TRACE("%p\n", dv ); 158 159 if( dv->table ) 160 dv->table->ops->delete( dv->table ); 161 162 free( dv ); 163 164 return ERROR_SUCCESS; 165} 166 167static const MSIVIEWOPS delete_ops = 168{ 169 DELETE_fetch_int, 170 DELETE_fetch_stream, 171 NULL, 172 NULL, 173 NULL, 174 NULL, 175 NULL, 176 NULL, 177 DELETE_execute, 178 DELETE_close, 179 DELETE_get_dimensions, 180 DELETE_get_column_info, 181 DELETE_modify, 182 DELETE_delete, 183 NULL, 184 NULL, 185 NULL, 186 NULL, 187 NULL, 188}; 189 190UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ) 191{ 192 struct delete_view *dv = NULL; 193 194 TRACE("%p\n", dv ); 195 196 dv = calloc( 1, sizeof *dv ); 197 if( !dv ) 198 return ERROR_FUNCTION_FAILED; 199 200 /* fill the structure */ 201 dv->view.ops = &delete_ops; 202 dv->db = db; 203 dv->table = table; 204 205 *view = &dv->view; 206 207 return ERROR_SUCCESS; 208}