Started implementing support for the SubSystemTib field in the TEB of
[wine] / dlls / msi / insert.c
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2004 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
36 WINE_DEFAULT_DEBUG_CHANNEL(msi);
37
38
39 /* below is the query interface to a table */
40
41 typedef struct tagMSIINSERTVIEW
42 {
43     MSIVIEW          view;
44     MSIDATABASE     *db;
45     LPWSTR           name;
46     BOOL             bIsTemp;
47     string_list     *cols;
48     value_list      *vals;
49 } MSIINSERTVIEW;
50
51 static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
52 {
53     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
54
55     TRACE("%p %d %d %p\n", iv, row, col, val );
56
57     return ERROR_FUNCTION_FAILED;
58 }
59
60 static UINT INSERT_execute( struct tagMSIVIEW *view, MSIHANDLE record )
61 {
62 #if 0
63     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
64     create_col_info *col;
65     UINT r, nField, row, table_val, column_val;
66     const WCHAR szTables[] =  { '_','T','a','b','l','e','s',0 };
67     const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
68     MSIVIEW *tv = NULL;
69
70     TRACE("%p Table %s (%s)\n", iv, debugstr_w(iv->name), 
71           iv->bIsTemp?"temporary":"permanent");
72
73     /* only add tables that don't exist already */
74     if( TABLE_Exists(iv->db, iv->name ) )
75         return ERROR_BAD_QUERY_SYNTAX;
76
77     /* add the name to the _Tables table */
78     table_val = msi_addstringW( iv->db->strings, 0, iv->name, -1, 1 );
79     TRACE("New string %s -> %d\n", debugstr_w( iv->name ), table_val );
80     if( table_val < 0 )
81         return ERROR_FUNCTION_FAILED;
82
83     r = TABLE_CreateView( iv->db, szTables, &tv );
84     TRACE("CreateView returned %x\n", r);
85     if( r )
86         return r;
87
88     r = tv->ops->execute( tv, 0 );
89     TRACE("tv execute returned %x\n", r);
90     if( r )
91         return r;
92
93     row = -1;
94     r = tv->ops->insert_row( tv, &row );
95     TRACE("insert_row returned %x\n", r);
96     if( r )
97         goto err;
98
99     r = tv->ops->set_int( tv, row, 1, table_val );
100     if( r )
101         goto err;
102     tv->ops->delete( tv );
103     tv = NULL;
104
105     /* add each column to the _Columns table */
106     r = TABLE_CreateView( iv->db, szColumns, &tv );
107     if( r )
108         return r;
109
110     r = tv->ops->execute( tv, 0 );
111     TRACE("tv execute returned %x\n", r);
112     if( r )
113         return r;
114
115     /*
116      * need to set the table, column number, col name and type
117      * for each column we enter in the table
118      */
119     nField = 1;
120     for( col = iv->col_info; col; col = col->next )
121     {
122         row = -1;
123         r = tv->ops->insert_row( tv, &row );
124         if( r )
125             goto err;
126
127         column_val = msi_addstringW( iv->db->strings, 0, col->colname, -1, 1 );
128         TRACE("New string %s -> %d\n", debugstr_w( col->colname ), column_val );
129         if( column_val < 0 )
130             break;
131
132         r = tv->ops->set_int( tv, row, 1, table_val );
133         if( r )
134             break;
135
136         r = tv->ops->set_int( tv, row, 2, 0x8000|nField );
137         if( r )
138             break;
139
140         r = tv->ops->set_int( tv, row, 3, column_val );
141         if( r )
142             break;
143
144         r = tv->ops->set_int( tv, row, 4, 0x8000|col->type );
145         if( r )
146             break;
147     }
148     if( !col )
149         r = ERROR_SUCCESS;
150
151 err:
152     /* FIXME: remove values from the string table on error */
153     if( tv )
154         tv->ops->delete( tv );
155     return r;
156 #else
157     return ERROR_FUNCTION_FAILED;
158 #endif
159 }
160
161 static UINT INSERT_close( struct tagMSIVIEW *view )
162 {
163     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
164
165     TRACE("%p\n", iv);
166
167     return ERROR_SUCCESS;
168 }
169
170 static UINT INSERT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
171 {
172     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
173
174     TRACE("%p %p %p\n", iv, rows, cols );
175
176     return ERROR_FUNCTION_FAILED;
177 }
178
179 static UINT INSERT_get_column_info( struct tagMSIVIEW *view,
180                 UINT n, LPWSTR *name, UINT *type )
181 {
182     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
183
184     TRACE("%p %d %p %p\n", iv, n, name, type );
185
186     return ERROR_FUNCTION_FAILED;
187 }
188
189 static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
190 {
191     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
192
193     TRACE("%p %d %ld\n", iv, eModifyMode, hrec );
194
195     return ERROR_FUNCTION_FAILED;
196 }
197
198 static UINT INSERT_delete( struct tagMSIVIEW *view )
199 {
200     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
201
202     TRACE("%p\n", iv );
203
204     delete_string_list( iv->cols ); 
205     delete_value_list( iv->vals );
206     HeapFree( GetProcessHeap(), 0, iv->name );
207     HeapFree( GetProcessHeap(), 0, iv );
208
209     return ERROR_SUCCESS;
210 }
211
212
213 MSIVIEWOPS insert_ops =
214 {
215     INSERT_fetch_int,
216     NULL,
217     NULL,
218     INSERT_execute,
219     INSERT_close,
220     INSERT_get_dimensions,
221     INSERT_get_column_info,
222     INSERT_modify,
223     INSERT_delete
224 };
225
226 UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
227                         string_list *columns, value_list *values, BOOL temp )
228 {
229     MSIINSERTVIEW *iv = NULL;
230
231     TRACE("%p\n", iv );
232
233     iv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *iv );
234     if( !iv )
235         return ERROR_FUNCTION_FAILED;
236     
237     /* fill the structure */
238     iv->view.ops = &insert_ops;
239     iv->db = db;
240     iv->name = table;  /* FIXME: strdupW it? */
241     iv->cols = columns;
242     iv->vals = values;
243     iv->bIsTemp = temp;
244     *view = (MSIVIEW*) iv;
245
246     return ERROR_SUCCESS;
247 }