Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenalter.c
Go to the documentation of this file.
00001 /* 00002 * Implementation of the Microsoft Installer (msi.dll) 00003 * 00004 * Copyright 2006 Mike McCormack 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include <stdarg.h> 00022 00023 #include "windef.h" 00024 #include "winbase.h" 00025 #include "winerror.h" 00026 #include "wine/debug.h" 00027 #include "msi.h" 00028 #include "msiquery.h" 00029 #include "objbase.h" 00030 #include "objidl.h" 00031 #include "msipriv.h" 00032 00033 #include "query.h" 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(msidb); 00036 00037 typedef struct tagMSIALTERVIEW 00038 { 00039 MSIVIEW view; 00040 MSIDATABASE *db; 00041 MSIVIEW *table; 00042 column_info *colinfo; 00043 INT hold; 00044 } MSIALTERVIEW; 00045 00046 static UINT ALTER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val ) 00047 { 00048 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00049 00050 TRACE("%p %d %d %p\n", av, row, col, val ); 00051 00052 return ERROR_FUNCTION_FAILED; 00053 } 00054 00055 static UINT ALTER_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm) 00056 { 00057 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00058 00059 TRACE("%p %d %d %p\n", av, row, col, stm ); 00060 00061 return ERROR_FUNCTION_FAILED; 00062 } 00063 00064 static UINT ALTER_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec ) 00065 { 00066 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00067 00068 TRACE("%p %d %p\n", av, row, rec ); 00069 00070 return av->table->ops->get_row(av->table, row, rec); 00071 } 00072 00073 static UINT ITERATE_columns(MSIRECORD *row, LPVOID param) 00074 { 00075 (*(UINT *)param)++; 00076 return ERROR_SUCCESS; 00077 } 00078 00079 static BOOL check_column_exists(MSIDATABASE *db, LPCWSTR table, LPCWSTR column) 00080 { 00081 MSIQUERY *view; 00082 MSIRECORD *rec; 00083 UINT r; 00084 00085 static const WCHAR query[] = { 00086 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', 00087 '`','_','C','o','l','u','m','n','s','`',' ','W','H','E','R','E',' ', 00088 '`','T','a','b','l','e','`','=','\'','%','s','\'',' ','A','N','D',' ', 00089 '`','N','a','m','e','`','=','\'','%','s','\'',0 00090 }; 00091 00092 r = MSI_OpenQuery(db, &view, query, table, column); 00093 if (r != ERROR_SUCCESS) 00094 return FALSE; 00095 00096 r = MSI_ViewExecute(view, NULL); 00097 if (r != ERROR_SUCCESS) 00098 goto done; 00099 00100 r = MSI_ViewFetch(view, &rec); 00101 if (r == ERROR_SUCCESS) 00102 msiobj_release(&rec->hdr); 00103 00104 done: 00105 msiobj_release(&view->hdr); 00106 return (r == ERROR_SUCCESS); 00107 } 00108 00109 static UINT alter_add_column(MSIALTERVIEW *av) 00110 { 00111 UINT r, colnum = 1; 00112 MSIQUERY *view; 00113 MSIVIEW *columns; 00114 00115 static const WCHAR szColumns[] = {'_','C','o','l','u','m','n','s',0}; 00116 static const WCHAR query[] = { 00117 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', 00118 '`','_','C','o','l','u','m','n','s','`',' ','W','H','E','R','E',' ', 00119 '`','T','a','b','l','e','`','=','\'','%','s','\'',' ','O','R','D','E','R',' ', 00120 'B','Y',' ','`','N','u','m','b','e','r','`',0 00121 }; 00122 00123 r = TABLE_CreateView(av->db, szColumns, &columns); 00124 if (r != ERROR_SUCCESS) 00125 return r; 00126 00127 if (check_column_exists(av->db, av->colinfo->table, av->colinfo->column)) 00128 { 00129 columns->ops->delete(columns); 00130 return ERROR_BAD_QUERY_SYNTAX; 00131 } 00132 00133 r = MSI_OpenQuery(av->db, &view, query, av->colinfo->table, av->colinfo->column); 00134 if (r == ERROR_SUCCESS) 00135 { 00136 r = MSI_IterateRecords(view, NULL, ITERATE_columns, &colnum); 00137 msiobj_release(&view->hdr); 00138 if (r != ERROR_SUCCESS) 00139 { 00140 columns->ops->delete(columns); 00141 return r; 00142 } 00143 } 00144 r = columns->ops->add_column(columns, av->colinfo->table, 00145 colnum, av->colinfo->column, 00146 av->colinfo->type, (av->hold == 1)); 00147 00148 columns->ops->delete(columns); 00149 return r; 00150 } 00151 00152 static UINT ALTER_execute( struct tagMSIVIEW *view, MSIRECORD *record ) 00153 { 00154 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00155 UINT ref; 00156 00157 TRACE("%p %p\n", av, record); 00158 00159 if (av->hold == 1) 00160 av->table->ops->add_ref(av->table); 00161 else if (av->hold == -1) 00162 { 00163 ref = av->table->ops->release(av->table); 00164 if (ref == 0) 00165 av->table = NULL; 00166 } 00167 00168 if (av->colinfo) 00169 return alter_add_column(av); 00170 00171 return ERROR_SUCCESS; 00172 } 00173 00174 static UINT ALTER_close( struct tagMSIVIEW *view ) 00175 { 00176 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00177 00178 TRACE("%p\n", av ); 00179 00180 return ERROR_SUCCESS; 00181 } 00182 00183 static UINT ALTER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols ) 00184 { 00185 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00186 00187 TRACE("%p %p %p\n", av, rows, cols ); 00188 00189 return ERROR_FUNCTION_FAILED; 00190 } 00191 00192 static UINT ALTER_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *name, 00193 UINT *type, BOOL *temporary, LPCWSTR *table_name ) 00194 { 00195 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00196 00197 TRACE("%p %d %p %p %p %p\n", av, n, name, type, temporary, table_name ); 00198 00199 return ERROR_FUNCTION_FAILED; 00200 } 00201 00202 static UINT ALTER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, 00203 MSIRECORD *rec, UINT row ) 00204 { 00205 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00206 00207 TRACE("%p %d %p\n", av, eModifyMode, rec ); 00208 00209 return ERROR_FUNCTION_FAILED; 00210 } 00211 00212 static UINT ALTER_delete( struct tagMSIVIEW *view ) 00213 { 00214 MSIALTERVIEW *av = (MSIALTERVIEW*)view; 00215 00216 TRACE("%p\n", av ); 00217 if (av->table) 00218 av->table->ops->delete( av->table ); 00219 msi_free( av ); 00220 00221 return ERROR_SUCCESS; 00222 } 00223 00224 static UINT ALTER_find_matching_rows( struct tagMSIVIEW *view, UINT col, 00225 UINT val, UINT *row, MSIITERHANDLE *handle ) 00226 { 00227 TRACE("%p, %d, %u, %p\n", view, col, val, *handle); 00228 00229 return ERROR_FUNCTION_FAILED; 00230 } 00231 00232 static const MSIVIEWOPS alter_ops = 00233 { 00234 ALTER_fetch_int, 00235 ALTER_fetch_stream, 00236 ALTER_get_row, 00237 NULL, 00238 NULL, 00239 NULL, 00240 ALTER_execute, 00241 ALTER_close, 00242 ALTER_get_dimensions, 00243 ALTER_get_column_info, 00244 ALTER_modify, 00245 ALTER_delete, 00246 ALTER_find_matching_rows, 00247 NULL, 00248 NULL, 00249 NULL, 00250 NULL, 00251 NULL, 00252 NULL, 00253 }; 00254 00255 UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, column_info *colinfo, int hold ) 00256 { 00257 MSIALTERVIEW *av; 00258 UINT r; 00259 00260 TRACE("%p %p %s %d\n", view, colinfo, debugstr_w(name), hold ); 00261 00262 av = msi_alloc_zero( sizeof *av ); 00263 if( !av ) 00264 return ERROR_FUNCTION_FAILED; 00265 00266 r = TABLE_CreateView( db, name, &av->table ); 00267 if (r != ERROR_SUCCESS) 00268 { 00269 msi_free( av ); 00270 return r; 00271 } 00272 00273 if (colinfo) 00274 colinfo->table = name; 00275 00276 /* fill the structure */ 00277 av->view.ops = &alter_ops; 00278 av->db = db; 00279 av->hold = hold; 00280 av->colinfo = colinfo; 00281 00282 *view = &av->view; 00283 00284 return ERROR_SUCCESS; 00285 } Generated on Sat May 26 2012 04:23:46 for ReactOS by
1.7.6.1
|