ReactOS 0.4.15-dev-7842-g558ab78
storages.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2008 James Hawkins
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 "winuser.h"
28#include "winerror.h"
29#include "ole2.h"
30#include "msi.h"
31#include "msiquery.h"
32#include "objbase.h"
33#include "msipriv.h"
34#include "query.h"
35
36#include "wine/debug.h"
37
39
40#define NUM_STORAGES_COLS 2
41#define MAX_STORAGES_NAME_LEN 62
42
43typedef struct tabSTORAGE
44{
48
49typedef struct tagMSISTORAGESVIEW
50{
58
60{
61 if (size >= sv->max_storages)
62 {
63 sv->max_storages *= 2;
64 sv->storages = msi_realloc(sv->storages, sv->max_storages * sizeof(*sv->storages));
65 if (!sv->storages)
66 return FALSE;
67 }
68
69 return TRUE;
70}
71
73{
75
76 TRACE("(%p, %d, %d, %p)\n", view, row, col, val);
77
78 if (col != 1)
80
81 if (row >= sv->num_rows)
83
84 *val = sv->storages[row].str_index;
85
86 return ERROR_SUCCESS;
87}
88
90{
92
93 TRACE("(%p, %d, %d, %p)\n", view, row, col, stm);
94
95 if (row >= sv->num_rows)
97
98 return ERROR_INVALID_DATA;
99}
100
101static UINT STORAGES_set_string( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len )
102{
103 ERR("Cannot modify primary key.\n");
105}
106
108{
109 ILockBytes *lockbytes = NULL;
110 STATSTG stat;
111 LPVOID data;
112 HRESULT hr;
113 DWORD size, read;
115
116 hr = IStream_Stat(stm, &stat, STATFLAG_NONAME);
117 if (FAILED(hr))
118 return hr;
119
120 if (stat.cbSize.QuadPart >> 32)
121 {
122 ERR("Storage is too large\n");
123 return E_FAIL;
124 }
125
126 size = stat.cbSize.QuadPart;
128 if (!data)
129 return E_OUTOFMEMORY;
130
131 hr = IStream_Read(stm, data, size, &read);
132 if (FAILED(hr) || read != size)
133 goto done;
134
135 hr = CreateILockBytesOnHGlobal(NULL, TRUE, &lockbytes);
136 if (FAILED(hr))
137 goto done;
138
140 hr = ILockBytes_WriteAt(lockbytes, offset, data, size, &read);
141 if (FAILED(hr) || read != size)
142 goto done;
143
146 NULL, 0, stg);
147 if (FAILED(hr))
148 goto done;
149
150done:
151 msi_free(data);
152 if (lockbytes) ILockBytes_Release(lockbytes);
153 return hr;
154}
155
157{
159 IStorage *stg, *substg, *prev;
160 const WCHAR *name;
161 HRESULT hr;
162 UINT r;
163
164 TRACE("view %p, row %u, col %u, stream %p.\n", view, row, col, stream);
165
166 if ((r = stream_to_storage(stream, &stg)))
167 return r;
168
170
171 hr = IStorage_CreateStorage(sv->db->storage, name,
173 0, 0, &substg);
174 if (FAILED(hr))
175 {
176 IStorage_Release(stg);
178 }
179
180 hr = IStorage_CopyTo(stg, 0, NULL, NULL, substg);
181 if (FAILED(hr))
182 {
183 IStorage_Release(substg);
184 IStorage_Release(stg);
186 }
187 IStorage_Release(substg);
188
189 prev = sv->storages[row].storage;
190 sv->storages[row].storage = stg;
191 if (prev) IStorage_Release(prev);
192
193 return ERROR_SUCCESS;
194}
195
197{
199 IStorage *stg, *substg = NULL, *prev;
200 IStream *stm;
201 LPWSTR name = NULL;
202 HRESULT hr;
204
205 TRACE("(%p, %p)\n", view, rec);
206
207 if (row >= sv->num_rows)
209
210 r = MSI_RecordGetIStream(rec, 2, &stm);
211 if (r != ERROR_SUCCESS)
212 return r;
213
214 r = stream_to_storage(stm, &stg);
215 if (r != ERROR_SUCCESS)
216 {
217 IStream_Release(stm);
218 return r;
219 }
220
222 if (!name)
223 {
225 goto done;
226 }
227
228 hr = IStorage_CreateStorage(sv->db->storage, name,
230 0, 0, &substg);
231 if (FAILED(hr))
232 {
234 goto done;
235 }
236
237 hr = IStorage_CopyTo(stg, 0, NULL, NULL, substg);
238 if (FAILED(hr))
239 {
241 goto done;
242 }
243
244 prev = sv->storages[row].storage;
246 IStorage_AddRef(stg);
247 sv->storages[row].storage = stg;
248 if (prev) IStorage_Release(prev);
249
250done:
251 msi_free(name);
252
253 if (substg) IStorage_Release(substg);
254 IStorage_Release(stg);
255 IStream_Release(stm);
256
257 return r;
258}
259
260static UINT STORAGES_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary)
261{
263
264 if (!storages_set_table_size(sv, ++sv->num_rows))
266
267 if (row == -1)
268 row = sv->num_rows - 1;
269
270 memset(&sv->storages[row], 0, sizeof(sv->storages[row]));
271
272 /* FIXME have to readjust rows */
273
274 return STORAGES_set_row(view, row, rec, 0);
275}
276
278{
279 FIXME("(%p %d): stub!\n", view, row);
280 return ERROR_SUCCESS;
281}
282
284{
285 TRACE("(%p, %p)\n", view, record);
286 return ERROR_SUCCESS;
287}
288
290{
291 TRACE("(%p)\n", view);
292 return ERROR_SUCCESS;
293}
294
296{
298
299 TRACE("(%p, %p, %p)\n", view, rows, cols);
300
301 if (cols) *cols = NUM_STORAGES_COLS;
302 if (rows) *rows = sv->num_rows;
303
304 return ERROR_SUCCESS;
305}
306
308 UINT *type, BOOL *temporary, LPCWSTR *table_name )
309{
310 TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary,
311 table_name);
312
313 if (n == 0 || n > NUM_STORAGES_COLS)
315
316 switch (n)
317 {
318 case 1:
319 if (name) *name = L"Name";
321 break;
322
323 case 2:
324 if (name) *name = L"Data";
326 break;
327 }
328 if (table_name) *table_name = L"_Storages";
329 if (temporary) *temporary = FALSE;
330 return ERROR_SUCCESS;
331}
332
334{
335 LPCWSTR str;
336 UINT r, i, id, data;
337
338 str = MSI_RecordGetString(rec, 1);
339 r = msi_string2id(sv->db->strings, str, -1, &id);
340 if (r != ERROR_SUCCESS)
341 return r;
342
343 for (i = 0; i < sv->num_rows; i++)
344 {
345 STORAGES_fetch_int(&sv->view, i, 1, &data);
346
347 if (data == id)
348 {
349 *row = i;
350 return ERROR_SUCCESS;
351 }
352 }
353
355}
356
358{
360 UINT r, row;
361
362 r = storages_find_row(sv, rec, &row);
363 if (r != ERROR_SUCCESS)
365
366 return STORAGES_set_row(view, row, rec, 0);
367}
368
370{
372 UINT r, row;
373
374 r = storages_find_row(sv, rec, &row);
375 if (r == ERROR_SUCCESS)
376 return storages_modify_update(view, rec);
377
378 return STORAGES_insert_row(view, rec, -1, FALSE);
379}
380
381static UINT STORAGES_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
382{
383 UINT r;
384
385 TRACE("%p %d %p\n", view, eModifyMode, rec);
386
387 switch (eModifyMode)
388 {
389 case MSIMODIFY_ASSIGN:
391 break;
392
393 case MSIMODIFY_INSERT:
394 r = STORAGES_insert_row(view, rec, -1, FALSE);
395 break;
396
397 case MSIMODIFY_UPDATE:
399 break;
400
405 case MSIMODIFY_MERGE:
406 case MSIMODIFY_DELETE:
410 FIXME("%p %d %p - mode not implemented\n", view, eModifyMode, rec );
412 break;
413
414 default:
416 }
417
418 return r;
419}
420
422{
424 UINT i;
425
426 TRACE("(%p)\n", view);
427
428 for (i = 0; i < sv->num_rows; i++)
429 {
430 if (sv->storages[i].storage)
431 IStorage_Release(sv->storages[i].storage);
432 }
433
434 msi_free(sv->storages);
435 sv->storages = NULL;
436 msi_free(sv);
437
438 return ERROR_SUCCESS;
439}
440
442{
445 NULL,
457 NULL,
458 NULL,
459 NULL,
460 NULL,
461 NULL,
462};
463
465{
466 IEnumSTATSTG *stgenum = NULL;
467 STATSTG stat;
468 HRESULT hr;
469 UINT count = 0;
470 ULONG size;
471
472 hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum);
473 if (FAILED(hr))
474 return -1;
475
476 sv->max_storages = 1;
477 sv->storages = msi_alloc(sizeof(*sv->storages));
478 if (!sv->storages)
479 return -1;
480
481 while (TRUE)
482 {
483 size = 0;
484 hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &size);
485 if (FAILED(hr) || !size)
486 break;
487
488 if (stat.type != STGTY_STORAGE)
489 {
490 CoTaskMemFree(stat.pwcsName);
491 continue;
492 }
493
494 TRACE("enumerated storage %s\n", debugstr_w(stat.pwcsName));
495
496 if (!storages_set_table_size(sv, ++count))
497 {
498 count = -1;
499 break;
500 }
501
502 sv->storages[count - 1].str_index = msi_add_string(sv->db->strings, stat.pwcsName, -1, FALSE);
503 sv->storages[count - 1].storage = NULL;
504
505 IStorage_OpenStorage(sv->db->storage, stat.pwcsName, NULL,
507 &sv->storages[count - 1].storage);
508 CoTaskMemFree(stat.pwcsName);
509 }
510
511 IEnumSTATSTG_Release(stgenum);
512 return count;
513}
514
516{
517 MSISTORAGESVIEW *sv;
518 INT rows;
519
520 TRACE("(%p, %p)\n", db, view);
521
522 sv = msi_alloc_zero( sizeof(MSISTORAGESVIEW) );
523 if (!sv)
525
526 sv->view.ops = &storages_ops;
527 sv->db = db;
528
529 rows = add_storages_to_table(sv);
530 if (rows < 0)
531 {
532 msi_free( sv );
534 }
535 sv->num_rows = rows;
536
537 *view = (MSIVIEW *)sv;
538
539 return ERROR_SUCCESS;
540}
#define stat
Definition: acwin.h:99
#define read
Definition: acwin.h:96
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
HRESULT WINAPI StgOpenStorageOnILockBytes(ILockBytes *plkbyt, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8984
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
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLintptr offset
Definition: glext.h:5920
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
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_w
Definition: kernel32.h:32
HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL global, BOOL delete_on_release, ILockBytes **ret)
Definition: memlockbytes.c:98
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1154
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
UINT MSI_RecordGetIStream(MSIRECORD *, UINT, IStream **) DECLSPEC_HIDDEN
Definition: record.c:852
UINT msi_string2id(const string_table *st, const WCHAR *data, int len, UINT *id) DECLSPEC_HIDDEN
Definition: string.c:400
#define MSITYPE_VALID
Definition: msipriv.h:48
static void msi_free(void *mem)
Definition: msipriv.h:1159
BOOL msi_add_string(string_table *st, const WCHAR *data, int len, BOOL persistent) DECLSPEC_HIDDEN
Definition: string.c:303
#define MSITYPE_STRING
Definition: msipriv.h:50
const WCHAR * msi_string_lookup(const string_table *st, UINT id, int *len) DECLSPEC_HIDDEN
Definition: string.c:343
#define MSITYPE_NULLABLE
Definition: msipriv.h:51
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
@ MSIMODIFY_DELETE
Definition: msiquery.h:57
@ MSIMODIFY_REPLACE
Definition: msiquery.h:55
@ MSIMODIFY_MERGE
Definition: msiquery.h:56
@ MSIMODIFY_INSERT_TEMPORARY
Definition: msiquery.h:58
@ MSIMODIFY_UPDATE
Definition: msiquery.h:53
@ MSIMODIFY_VALIDATE_DELETE
Definition: msiquery.h:62
@ 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
@ MSIMODIFY_VALIDATE_FIELD
Definition: msiquery.h:61
@ MSIMODIFY_VALIDATE
Definition: msiquery.h:59
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#define STGM_SHARE_DENY_NONE
Definition: objbase.h:920
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
static UINT STORAGES_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
Definition: storages.c:89
static UINT STORAGES_execute(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: storages.c:283
static UINT STORAGES_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: storages.c:72
static UINT storages_modify_update(struct tagMSIVIEW *view, MSIRECORD *rec)
Definition: storages.c:357
static UINT STORAGES_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary)
Definition: storages.c:260
struct tabSTORAGE STORAGE
static UINT STORAGES_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
Definition: storages.c:196
static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: storages.c:307
UINT STORAGES_CreateView(MSIDATABASE *db, MSIVIEW **view)
Definition: storages.c:515
static UINT STORAGES_delete_row(struct tagMSIVIEW *view, UINT row)
Definition: storages.c:277
static UINT STORAGES_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
Definition: storages.c:381
static UINT STORAGES_close(struct tagMSIVIEW *view)
Definition: storages.c:289
#define NUM_STORAGES_COLS
Definition: storages.c:40
static INT add_storages_to_table(MSISTORAGESVIEW *sv)
Definition: storages.c:464
#define MAX_STORAGES_NAME_LEN
Definition: storages.c:41
static UINT STORAGES_delete(struct tagMSIVIEW *view)
Definition: storages.c:421
static HRESULT stream_to_storage(IStream *stm, IStorage **stg)
Definition: storages.c:107
static const MSIVIEWOPS storages_ops
Definition: storages.c:441
static UINT STORAGES_set_stream(MSIVIEW *view, UINT row, UINT col, IStream *stream)
Definition: storages.c:156
static BOOL storages_set_table_size(MSISTORAGESVIEW *sv, UINT size)
Definition: storages.c:59
static UINT storages_modify_assign(struct tagMSIVIEW *view, MSIRECORD *rec)
Definition: storages.c:369
static UINT storages_find_row(MSISTORAGESVIEW *sv, MSIRECORD *rec, UINT *row)
Definition: storages.c:333
static UINT STORAGES_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len)
Definition: storages.c:101
static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: storages.c:295
struct tagMSISTORAGESVIEW MSISTORAGESVIEW
Definition: name.c:39
Definition: stat.h:55
Definition: parse.h:23
UINT str_index
Definition: storages.c:45
IStorage * storage
Definition: storages.c:46
IStorage * storage
Definition: msipriv.h:109
string_table * strings
Definition: msipriv.h:110
STORAGE * storages
Definition: storages.c:53
MSIDATABASE * db
Definition: storages.c:52
const MSIVIEWOPS * ops
Definition: msipriv.h:355
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define ZeroMemory
Definition: winbase.h:1712
int MSIMODIFY
Definition: winemsi.idl:33
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define ERROR_INVALID_DATA
Definition: winerror.h:116
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185