ReactOS 0.4.16-dev-122-g325d74c
select.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2002-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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22
23#define COBJMACROS
24
25#include "windef.h"
26#include "winbase.h"
27#include "winerror.h"
28#include "wine/debug.h"
29#include "msi.h"
30#include "msiquery.h"
31#include "objbase.h"
32#include "objidl.h"
33#include "msipriv.h"
34#include "winnls.h"
35
36#include "query.h"
37
39
40
41/* below is the query interface to a table */
42
44{
51};
52
54{
55 UINT r, col_count, i;
57
58 if ((r = sv->table->ops->get_dimensions( sv->table, NULL, &col_count )))
59 return r;
60
61 if (!(object = MSI_CreateRecord( col_count )))
62 return ERROR_OUTOFMEMORY;
63
64 for (i = 0; i < sv->num_cols; i++)
65 {
66 if ((r = MSI_RecordCopyField( in, i + 1, object, sv->cols[i] )))
67 {
68 msiobj_release( &object->hdr );
69 return r;
70 }
71 }
72
73 *out = object;
74 return ERROR_SUCCESS;
75}
76
78{
79 struct select_view *sv = (struct select_view *)view;
80
81 TRACE("%p %d %d %p\n", sv, row, col, val );
82
83 if( !sv->table )
85
86 if( !col || col > sv->num_cols )
88
89 col = sv->cols[ col - 1 ];
90 if( !col )
91 {
92 *val = 0;
93 return ERROR_SUCCESS;
94 }
95 return sv->table->ops->fetch_int( sv->table, row, col, val );
96}
97
99{
100 struct select_view *sv = (struct select_view *)view;
101
102 TRACE("%p %d %d %p\n", sv, row, col, stm );
103
104 if( !sv->table )
106
107 if( !col || col > sv->num_cols )
109
110 col = sv->cols[ col - 1 ];
111 if( !col )
112 {
113 *stm = NULL;
114 return ERROR_SUCCESS;
115 }
116 return sv->table->ops->fetch_stream( sv->table, row, col, stm );
117}
118
120{
121 struct select_view *sv = (struct select_view *)view;
122 UINT i, expanded_mask = 0, r = ERROR_SUCCESS, col_count = 0;
123 MSIRECORD *expanded;
124
125 TRACE("%p %d %p %08x\n", sv, row, rec, mask );
126
127 if ( !sv->table )
129
130 /* test if any of the mask bits are invalid */
131 if ( mask >= (1<<sv->num_cols) )
133
134 /* find the number of columns in the table below */
135 r = sv->table->ops->get_dimensions( sv->table, NULL, &col_count );
136 if( r )
137 return r;
138
139 /* expand the record to the right size for the underlying table */
140 expanded = MSI_CreateRecord( col_count );
141 if ( !expanded )
143
144 /* move the right fields across */
145 for ( i=0; i<sv->num_cols; i++ )
146 {
147 r = MSI_RecordCopyField( rec, i+1, expanded, sv->cols[ i ] );
148 if (r != ERROR_SUCCESS)
149 break;
150 expanded_mask |= (1<<(sv->cols[i]-1));
151 }
152
153 /* set the row in the underlying table */
154 if (r == ERROR_SUCCESS)
155 r = sv->table->ops->set_row( sv->table, row, expanded, expanded_mask );
156
157 msiobj_release( &expanded->hdr );
158 return r;
159}
160
162{
163 struct select_view *sv = (struct select_view *)view;
164 UINT table_cols, r;
165 MSIRECORD *outrec;
166
167 TRACE("%p %p\n", sv, record );
168
169 if ( !sv->table )
171
172 /* rearrange the record to suit the table */
173 r = sv->table->ops->get_dimensions( sv->table, NULL, &table_cols );
174 if (r != ERROR_SUCCESS)
175 return r;
176
177 if ((r = translate_record( sv, record, &outrec )))
178 return r;
179
180 r = sv->table->ops->insert_row( sv->table, outrec, row, temporary );
181
182 msiobj_release( &outrec->hdr );
183 return r;
184}
185
187{
188 struct select_view *sv = (struct select_view *)view;
189
190 TRACE("%p %p\n", sv, record);
191
192 if( !sv->table )
194
195 return sv->table->ops->execute( sv->table, record );
196}
197
199{
200 struct select_view *sv = (struct select_view *)view;
201
202 TRACE("%p\n", sv );
203
204 if( !sv->table )
206
207 return sv->table->ops->close( sv->table );
208}
209
211{
212 struct select_view *sv = (struct select_view *)view;
213
214 TRACE("%p %p %p\n", sv, rows, cols );
215
216 if( !sv->table )
218
219 if( cols )
220 *cols = sv->num_cols;
221
222 return sv->table->ops->get_dimensions( sv->table, rows, NULL );
223}
224
226 UINT *type, BOOL *temporary, LPCWSTR *table_name )
227{
228 struct select_view *sv = (struct select_view *)view;
229
230 TRACE("%p %d %p %p %p %p\n", sv, n, name, type, temporary, table_name );
231
232 if( !sv->table )
234
235 if( !n || n > sv->num_cols )
237
238 n = sv->cols[ n - 1 ];
239 if( !n )
240 {
241 if (name) *name = L"";
243 if (temporary) *temporary = FALSE;
244 if (table_name) *table_name = L"";
245 return ERROR_SUCCESS;
246 }
247 return sv->table->ops->get_column_info( sv->table, n, name,
248 type, temporary, table_name );
249}
250
252{
253 struct select_view *sv = (struct select_view *)view;
254 UINT r, i, col, type, val;
256 LPCWSTR str;
257
258 for (i = 0; i < sv->num_cols; i++)
259 {
260 col = sv->cols[i];
261
263 if (r != ERROR_SUCCESS)
264 {
265 ERR("Failed to get column information: %d\n", r);
266 return r;
267 }
268
270 {
271 if (MSI_RecordGetIStream(rec, i + 1, &stream))
273 r = sv->table->ops->set_stream(sv->table, row, col, stream);
274 IStream_Release(stream);
275 }
276 else if (type & MSITYPE_STRING)
277 {
278 int len;
279 str = msi_record_get_string(rec, i + 1, &len);
280 r = sv->table->ops->set_string(sv->table, row, col, str, len);
281 }
282 else
283 {
284 val = MSI_RecordGetInteger(rec, i + 1);
285 r = sv->table->ops->set_int(sv->table, row, col, val);
286 }
287
288 if (r != ERROR_SUCCESS)
289 {
290 ERR("Failed to modify record: %d\n", r);
291 return r;
292 }
293 }
294
295 return ERROR_SUCCESS;
296}
297
299 MSIRECORD *rec, UINT row )
300{
301 struct select_view *sv = (struct select_view *)view;
302 MSIRECORD *table_rec;
303 UINT r;
304
305 TRACE("view %p, mode %d, rec %p, row %u.\n", view, mode, rec, row);
306
307 if( !sv->table )
309
310 /* Tests demonstrate that UPDATE only affects the columns selected and that
311 * others are left unchanged; however, ASSIGN overwrites unselected columns
312 * to NULL. Similarly, MERGE matches all unselected columns as NULL rather
313 * than just ignoring them. */
314
315 switch (mode)
316 {
318 return msi_view_refresh_row(sv->db, view, row, rec);
319 case MSIMODIFY_UPDATE:
320 return msi_select_update(view, rec, row);
321 case MSIMODIFY_INSERT:
322 case MSIMODIFY_ASSIGN:
323 case MSIMODIFY_MERGE:
326 if ((r = translate_record( sv, rec, &table_rec )))
327 return r;
328
329 r = sv->table->ops->modify( sv->table, mode, table_rec, row );
330 msiobj_release( &table_rec->hdr );
331 return r;
332 case MSIMODIFY_DELETE:
333 return sv->table->ops->modify( sv->table, mode, rec, row );
334 default:
335 FIXME("unhandled mode %d\n", mode);
337 }
338}
339
341{
342 struct select_view *sv = (struct select_view *)view;
343
344 TRACE("%p\n", sv );
345
346 if( sv->table )
347 sv->table->ops->delete( sv->table );
348 sv->table = NULL;
349
350 free( sv );
351
352 return ERROR_SUCCESS;
353}
354
355static const MSIVIEWOPS select_ops =
356{
359 NULL,
360 NULL,
361 NULL,
364 NULL,
371 NULL,
372 NULL,
373 NULL,
374 NULL,
375 NULL,
376};
377
378static UINT SELECT_AddColumn( struct select_view *sv, const WCHAR *name, const WCHAR *table_name )
379{
380 UINT r, n;
381 MSIVIEW *table;
382
383 TRACE("%p adding %s.%s\n", sv, debugstr_w( table_name ),
384 debugstr_w( name ));
385
386 if( sv->view.ops != &select_ops )
388
389 table = sv->table;
390 if( !table )
392 if( !table->ops->get_dimensions )
394 if( !table->ops->get_column_info )
396
397 if( sv->num_cols >= sv->max_cols )
399
400 if ( !name[0] ) n = 0;
401 else
402 {
403 r = VIEW_find_column( table, name, table_name, &n );
404 if( r != ERROR_SUCCESS )
405 return r;
406 }
407
408 sv->cols[sv->num_cols] = n;
409 TRACE("Translating column %s from %d -> %d\n",
410 debugstr_w( name ), sv->num_cols, n);
411
412 sv->num_cols++;
413
414 return ERROR_SUCCESS;
415}
416
417static int select_count_columns( const column_info *col )
418{
419 int n;
420 for (n = 0; col; col = col->next)
421 n++;
422 return n;
423}
424
426 const column_info *columns )
427{
428 struct select_view *sv = NULL;
429 UINT count = 0, r = ERROR_SUCCESS;
430
431 TRACE("%p\n", sv );
432
433 count = select_count_columns( columns );
434
435 sv = calloc( 1, offsetof( struct select_view, cols[count] ) );
436 if( !sv )
438
439 /* fill the structure */
440 sv->view.ops = &select_ops;
441 sv->db = db;
442 sv->table = table;
443 sv->num_cols = 0;
444 sv->max_cols = count;
445
446 while( columns )
447 {
448 r = SELECT_AddColumn( sv, columns->column, columns->table );
449 if( r )
450 break;
451 columns = columns->next;
452 }
453
454 if( r == ERROR_SUCCESS )
455 *view = &sv->view;
456 else
457 free( sv );
458
459 return r;
460}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define free
Definition: debug_ros.c:5
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
static UINT SELECT_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: select.c:210
static UINT SELECT_close(struct tagMSIVIEW *view)
Definition: select.c:198
UINT msi_select_update(MSIVIEW *view, MSIRECORD *rec, UINT row)
Definition: select.c:251
static const MSIVIEWOPS select_ops
Definition: select.c:355
static UINT SELECT_execute(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: select.c:186
static UINT SELECT_AddColumn(struct select_view *sv, const WCHAR *name, const WCHAR *table_name)
Definition: select.c:378
static UINT SELECT_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: select.c:77
static UINT translate_record(struct select_view *sv, MSIRECORD *in, MSIRECORD **out)
Definition: select.c:53
static UINT SELECT_insert_row(struct tagMSIVIEW *view, MSIRECORD *record, UINT row, BOOL temporary)
Definition: select.c:161
static UINT SELECT_modify(struct tagMSIVIEW *view, MSIMODIFY mode, MSIRECORD *rec, UINT row)
Definition: select.c:298
UINT SELECT_CreateView(MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table, const column_info *columns)
Definition: select.c:425
static UINT SELECT_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
Definition: select.c:98
static UINT SELECT_get_column_info(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: select.c:225
static UINT SELECT_delete(struct tagMSIVIEW *view)
Definition: select.c:340
static UINT SELECT_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
Definition: select.c:119
static int select_count_columns(const column_info *col)
Definition: select.c:417
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum mode
Definition: glext.h:6217
GLuint in
Definition: glext.h:9616
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define debugstr_w
Definition: kernel32.h:32
int MSI_RecordGetInteger(MSIRECORD *, UINT)
Definition: record.c:213
UINT MSI_RecordGetIStream(MSIRECORD *, UINT, IStream **)
Definition: record.c:852
const WCHAR * msi_record_get_string(const MSIRECORD *, UINT, int *)
Definition: record.c:420
#define MSITYPE_VALID
Definition: msipriv.h:48
#define MSITYPE_IS_BINARY(type)
Definition: msipriv.h:62
#define MSITYPE_STRING
Definition: msipriv.h:50
#define MSITYPE_UNKNOWN
Definition: msipriv.h:54
UINT VIEW_find_column(MSIVIEW *, LPCWSTR, LPCWSTR, UINT *)
Definition: msiquery.c:59
UINT MSI_RecordCopyField(MSIRECORD *, UINT, MSIRECORD *, UINT)
Definition: record.c:166
MSIRECORD * MSI_CreateRecord(UINT)
Definition: record.c:76
UINT msi_view_refresh_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD *rec)
Definition: msiquery.c:287
@ MSIMODIFY_DELETE
Definition: msiquery.h:57
@ MSIMODIFY_MERGE
Definition: msiquery.h:56
@ MSIMODIFY_INSERT_TEMPORARY
Definition: msiquery.h:58
@ MSIMODIFY_UPDATE
Definition: msiquery.h:53
@ MSIMODIFY_ASSIGN
Definition: msiquery.h:54
@ MSIMODIFY_VALIDATE_NEW
Definition: msiquery.h:60
@ MSIMODIFY_INSERT
Definition: msiquery.h:52
@ MSIMODIFY_REFRESH
Definition: msiquery.h:51
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
static FILE * out
Definition: regtests2xml.c:44
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#define offsetof(TYPE, MEMBER)
#define TRACE(s)
Definition: solgame.cpp:4
Definition: name.c:39
MSIDATABASE * db
Definition: select.c:46
UINT max_cols
Definition: select.c:49
UINT cols[1]
Definition: select.c:50
MSIVIEW * table
Definition: select.c:47
MSIVIEW view
Definition: select.c:45
UINT num_cols
Definition: select.c:48
Definition: parse.h:23
MSIOBJECTHDR hdr
Definition: msipriv.h:151
UINT(* insert_row)(struct tagMSIVIEW *view, MSIRECORD *record, UINT row, BOOL temporary)
Definition: msipriv.h:283
UINT(* set_row)(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
Definition: msipriv.h:278
UINT(* set_stream)(struct tagMSIVIEW *view, UINT row, UINT col, IStream *stream)
Definition: msipriv.h:271
UINT(* fetch_int)(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: msipriv.h:242
UINT(* set_string)(struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len)
Definition: msipriv.h:264
UINT(* fetch_stream)(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
Definition: msipriv.h:250
UINT(* modify)(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *record, UINT row)
Definition: msipriv.h:319
UINT(* close)(struct tagMSIVIEW *view)
Definition: msipriv.h:298
UINT(* get_dimensions)(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: msipriv.h:306
UINT(* execute)(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: msipriv.h:293
UINT(* get_column_info)(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: msipriv.h:313
UINT(* set_int)(struct tagMSIVIEW *view, UINT row, UINT col, int val)
Definition: msipriv.h:257
UINT(* delete)(struct tagMSIVIEW *)
Definition: msipriv.h:324
const MSIVIEWOPS * ops
Definition: msipriv.h:355
int MSIMODIFY
Definition: winemsi.idl:33
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185