Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Implementation of the Microsoft Installer (msi.dll) |
| 3 | * |
Mike McCormack | 068b4ec | 2004-03-19 01:16:36 +0000 | [diff] [blame] | 4 | * Copyright 2002-2004 Mike McCormack for CodeWeavers |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 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 |
Jonathan Ernst | 360a3f9 | 2006-05-18 14:49:52 +0200 | [diff] [blame] | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 19 | */ |
| 20 | |
| 21 | #include <stdarg.h> |
| 22 | |
| 23 | #include "windef.h" |
| 24 | #include "winbase.h" |
| 25 | #include "winerror.h" |
| 26 | #include "wine/debug.h" |
Hans Leidekker | eaa57c5 | 2010-10-19 11:27:44 +0200 | [diff] [blame] | 27 | #include "wine/unicode.h" |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 28 | #include "msi.h" |
| 29 | #include "msiquery.h" |
| 30 | #include "objbase.h" |
| 31 | #include "objidl.h" |
| 32 | #include "msipriv.h" |
| 33 | #include "winnls.h" |
| 34 | |
| 35 | #include "query.h" |
| 36 | |
Mike McCormack | 50684c1 | 2005-11-02 14:24:21 +0000 | [diff] [blame] | 37 | WINE_DEFAULT_DEBUG_CHANNEL(msidb); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 38 | |
| 39 | |
| 40 | /* below is the query interface to a table */ |
| 41 | |
| 42 | typedef struct tagMSICREATEVIEW |
| 43 | { |
| 44 | MSIVIEW view; |
| 45 | MSIDATABASE *db; |
Hans Leidekker | 2018de0 | 2009-05-28 15:02:50 +0200 | [diff] [blame] | 46 | LPCWSTR name; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 47 | BOOL bIsTemp; |
James Hawkins | ea28915 | 2009-02-25 19:45:28 -0800 | [diff] [blame] | 48 | BOOL hold; |
Mike McCormack | d1a55eb | 2005-05-29 20:17:16 +0000 | [diff] [blame] | 49 | column_info *col_info; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 50 | } MSICREATEVIEW; |
| 51 | |
| 52 | static UINT CREATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val ) |
| 53 | { |
| 54 | MSICREATEVIEW *cv = (MSICREATEVIEW*)view; |
| 55 | |
| 56 | TRACE("%p %d %d %p\n", cv, row, col, val ); |
| 57 | |
| 58 | return ERROR_FUNCTION_FAILED; |
| 59 | } |
| 60 | |
Alexandre Julliard | a7a6f5f | 2004-07-09 22:25:34 +0000 | [diff] [blame] | 61 | static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record ) |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 62 | { |
| 63 | MSICREATEVIEW *cv = (MSICREATEVIEW*)view; |
James Hawkins | 74aa053 | 2009-02-25 19:45:15 -0800 | [diff] [blame] | 64 | BOOL persist = (cv->bIsTemp) ? MSICONDITION_FALSE : MSICONDITION_TRUE; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 65 | |
James Hawkins | ea28915 | 2009-02-25 19:45:28 -0800 | [diff] [blame] | 66 | TRACE("%p Table %s (%s)\n", cv, debugstr_w(cv->name), |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 67 | cv->bIsTemp?"temporary":"permanent"); |
| 68 | |
James Hawkins | ea28915 | 2009-02-25 19:45:28 -0800 | [diff] [blame] | 69 | if (cv->bIsTemp && !cv->hold) |
| 70 | return ERROR_SUCCESS; |
| 71 | |
Hans Leidekker | 80438ef | 2011-09-23 11:12:02 +0200 | [diff] [blame] | 72 | return msi_create_table( cv->db, cv->name, cv->col_info, persist ); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | static UINT CREATE_close( struct tagMSIVIEW *view ) |
| 76 | { |
| 77 | MSICREATEVIEW *cv = (MSICREATEVIEW*)view; |
| 78 | |
Mike McCormack | 068b4ec | 2004-03-19 01:16:36 +0000 | [diff] [blame] | 79 | TRACE("%p\n", cv); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 80 | |
| 81 | return ERROR_SUCCESS; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols ) |
| 85 | { |
| 86 | MSICREATEVIEW *cv = (MSICREATEVIEW*)view; |
| 87 | |
| 88 | TRACE("%p %p %p\n", cv, rows, cols ); |
| 89 | |
| 90 | return ERROR_FUNCTION_FAILED; |
| 91 | } |
| 92 | |
Hans Leidekker | d1b2058 | 2011-07-27 10:53:10 +0200 | [diff] [blame] | 93 | static UINT CREATE_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *name, |
| 94 | UINT *type, BOOL *temporary, LPCWSTR *table_name ) |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 95 | { |
| 96 | MSICREATEVIEW *cv = (MSICREATEVIEW*)view; |
| 97 | |
Nate Gallaher | cc366e1 | 2009-10-18 12:41:41 -0400 | [diff] [blame] | 98 | TRACE("%p %d %p %p %p %p\n", cv, n, name, type, temporary, table_name ); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 99 | |
| 100 | return ERROR_FUNCTION_FAILED; |
| 101 | } |
| 102 | |
Mike McCormack | ef1d367 | 2005-02-08 13:44:25 +0000 | [diff] [blame] | 103 | static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, |
James Hawkins | b830fb0 | 2007-07-26 17:40:38 -0700 | [diff] [blame] | 104 | MSIRECORD *rec, UINT row) |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 105 | { |
| 106 | MSICREATEVIEW *cv = (MSICREATEVIEW*)view; |
| 107 | |
Mike McCormack | ef1d367 | 2005-02-08 13:44:25 +0000 | [diff] [blame] | 108 | TRACE("%p %d %p\n", cv, eModifyMode, rec ); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 109 | |
| 110 | return ERROR_FUNCTION_FAILED; |
| 111 | } |
| 112 | |
| 113 | static UINT CREATE_delete( struct tagMSIVIEW *view ) |
| 114 | { |
| 115 | MSICREATEVIEW *cv = (MSICREATEVIEW*)view; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 116 | |
| 117 | TRACE("%p\n", cv ); |
| 118 | |
Aric Stewart | bc6ce2b | 2004-08-25 17:31:39 +0000 | [diff] [blame] | 119 | msiobj_release( &cv->db->hdr ); |
Mike McCormack | 8dc28d5 | 2005-09-20 11:57:19 +0000 | [diff] [blame] | 120 | msi_free( cv ); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 121 | |
| 122 | return ERROR_SUCCESS; |
| 123 | } |
| 124 | |
Alexandre Julliard | 9a59ee7 | 2006-06-10 12:02:39 +0200 | [diff] [blame] | 125 | static const MSIVIEWOPS create_ops = |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 126 | { |
| 127 | CREATE_fetch_int, |
Mike McCormack | 068b4ec | 2004-03-19 01:16:36 +0000 | [diff] [blame] | 128 | NULL, |
| 129 | NULL, |
Mike McCormack | 24e9a34 | 2004-07-06 18:56:12 +0000 | [diff] [blame] | 130 | NULL, |
James Hawkins | 9309f4d | 2007-06-18 13:49:31 -0700 | [diff] [blame] | 131 | NULL, |
James Hawkins | b830fb0 | 2007-07-26 17:40:38 -0700 | [diff] [blame] | 132 | NULL, |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 133 | CREATE_execute, |
| 134 | CREATE_close, |
| 135 | CREATE_get_dimensions, |
| 136 | CREATE_get_column_info, |
| 137 | CREATE_modify, |
James Hawkins | 3b1ab76 | 2007-07-18 18:21:00 -0700 | [diff] [blame] | 138 | CREATE_delete, |
| 139 | NULL, |
| 140 | NULL, |
James Hawkins | 0fd733b | 2007-07-20 14:01:13 -0700 | [diff] [blame] | 141 | NULL, |
James Hawkins | ccef56f | 2007-07-20 18:41:16 -0700 | [diff] [blame] | 142 | NULL, |
James Hawkins | fcc490d | 2007-11-06 05:18:24 -0600 | [diff] [blame] | 143 | NULL, |
James Hawkins | 91c205e | 2007-12-17 19:35:31 -0600 | [diff] [blame] | 144 | NULL, |
James Hawkins | 62c544c | 2008-10-02 15:56:54 -0500 | [diff] [blame] | 145 | NULL, |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 146 | }; |
| 147 | |
Hans Leidekker | 2018de0 | 2009-05-28 15:02:50 +0200 | [diff] [blame] | 148 | static UINT check_columns( const column_info *col_info ) |
Mike McCormack | 2924501 | 2006-08-31 17:04:40 +0900 | [diff] [blame] | 149 | { |
Hans Leidekker | 2018de0 | 2009-05-28 15:02:50 +0200 | [diff] [blame] | 150 | const column_info *c1, *c2; |
Mike McCormack | 2924501 | 2006-08-31 17:04:40 +0900 | [diff] [blame] | 151 | |
| 152 | /* check for two columns with the same name */ |
| 153 | for( c1 = col_info; c1; c1 = c1->next ) |
| 154 | for( c2 = c1->next; c2; c2 = c2->next ) |
Hans Leidekker | eaa57c5 | 2010-10-19 11:27:44 +0200 | [diff] [blame] | 155 | if (!strcmpW( c1->column, c2->column )) |
Mike McCormack | 2924501 | 2006-08-31 17:04:40 +0900 | [diff] [blame] | 156 | return ERROR_BAD_QUERY_SYNTAX; |
| 157 | |
| 158 | return ERROR_SUCCESS; |
| 159 | } |
| 160 | |
Hans Leidekker | 2018de0 | 2009-05-28 15:02:50 +0200 | [diff] [blame] | 161 | UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR table, |
Rob Shearman | 697d820 | 2007-04-23 08:26:44 +0100 | [diff] [blame] | 162 | column_info *col_info, BOOL hold ) |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 163 | { |
| 164 | MSICREATEVIEW *cv = NULL; |
Mike McCormack | 2924501 | 2006-08-31 17:04:40 +0900 | [diff] [blame] | 165 | UINT r; |
James Hawkins | 62c544c | 2008-10-02 15:56:54 -0500 | [diff] [blame] | 166 | column_info *col; |
Rob Shearman | 697d820 | 2007-04-23 08:26:44 +0100 | [diff] [blame] | 167 | BOOL temp = TRUE; |
James Hawkins | 241933e | 2009-02-25 19:45:22 -0800 | [diff] [blame] | 168 | BOOL tempprim = FALSE; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 169 | |
| 170 | TRACE("%p\n", cv ); |
| 171 | |
Mike McCormack | 2924501 | 2006-08-31 17:04:40 +0900 | [diff] [blame] | 172 | r = check_columns( col_info ); |
| 173 | if( r != ERROR_SUCCESS ) |
| 174 | return r; |
| 175 | |
Mike McCormack | 8dc28d5 | 2005-09-20 11:57:19 +0000 | [diff] [blame] | 176 | cv = msi_alloc_zero( sizeof *cv ); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 177 | if( !cv ) |
| 178 | return ERROR_FUNCTION_FAILED; |
Mike McCormack | 2924501 | 2006-08-31 17:04:40 +0900 | [diff] [blame] | 179 | |
Rob Shearman | 697d820 | 2007-04-23 08:26:44 +0100 | [diff] [blame] | 180 | for( col = col_info; col; col = col->next ) |
James Hawkins | 62c544c | 2008-10-02 15:56:54 -0500 | [diff] [blame] | 181 | { |
| 182 | if (!col->table) |
Hans Leidekker | 5922de4 | 2009-05-28 15:03:19 +0200 | [diff] [blame] | 183 | col->table = table; |
James Hawkins | 62c544c | 2008-10-02 15:56:54 -0500 | [diff] [blame] | 184 | |
Rob Shearman | 697d820 | 2007-04-23 08:26:44 +0100 | [diff] [blame] | 185 | if( !col->temporary ) |
Rob Shearman | 697d820 | 2007-04-23 08:26:44 +0100 | [diff] [blame] | 186 | temp = FALSE; |
James Hawkins | 241933e | 2009-02-25 19:45:22 -0800 | [diff] [blame] | 187 | else if ( col->type & MSITYPE_KEY ) |
| 188 | tempprim = TRUE; |
| 189 | } |
| 190 | |
| 191 | if ( !temp && tempprim ) |
| 192 | { |
| 193 | msi_free( cv ); |
| 194 | return ERROR_FUNCTION_FAILED; |
James Hawkins | 62c544c | 2008-10-02 15:56:54 -0500 | [diff] [blame] | 195 | } |
Rob Shearman | 697d820 | 2007-04-23 08:26:44 +0100 | [diff] [blame] | 196 | |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 197 | /* fill the structure */ |
| 198 | cv->view.ops = &create_ops; |
Alexandre Julliard | a7a6f5f | 2004-07-09 22:25:34 +0000 | [diff] [blame] | 199 | msiobj_addref( &db->hdr ); |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 200 | cv->db = db; |
Mike McCormack | 0093007 | 2005-05-23 12:08:17 +0000 | [diff] [blame] | 201 | cv->name = table; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 202 | cv->col_info = col_info; |
| 203 | cv->bIsTemp = temp; |
James Hawkins | ea28915 | 2009-02-25 19:45:28 -0800 | [diff] [blame] | 204 | cv->hold = hold; |
Mike McCormack | 14ec526 | 2004-03-16 19:18:22 +0000 | [diff] [blame] | 205 | *view = (MSIVIEW*) cv; |
| 206 | |
| 207 | return ERROR_SUCCESS; |
| 208 | } |