ReactOS  0.4.14-dev-599-g2d4d3f5
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 
43 typedef struct tabSTORAGE
44 {
47 } STORAGE;
48 
49 typedef 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(STORAGE *));
65  if (!sv->storages)
66  return FALSE;
67  }
68 
69  return TRUE;
70 }
71 
73 {
74  STORAGE *storage;
75 
76  storage = msi_alloc(sizeof(STORAGE));
77  if (!storage)
78  return NULL;
79 
81  storage->storage = stg;
82 
83  if (storage->storage)
84  IStorage_AddRef(storage->storage);
85 
86  return storage;
87 }
88 
90 {
92 
93  TRACE("(%p, %d, %d, %p)\n", view, row, col, val);
94 
95  if (col != 1)
97 
98  if (row >= sv->num_rows)
99  return ERROR_NO_MORE_ITEMS;
100 
101  *val = sv->storages[row]->str_index;
102 
103  return ERROR_SUCCESS;
104 }
105 
107 {
109 
110  TRACE("(%p, %d, %d, %p)\n", view, row, col, stm);
111 
112  if (row >= sv->num_rows)
113  return ERROR_FUNCTION_FAILED;
114 
115  return ERROR_INVALID_DATA;
116 }
117 
119 {
121 
122  FIXME("%p %d %p\n", sv, row, rec);
123 
125 }
126 
128 {
129  ILockBytes *lockbytes = NULL;
130  STATSTG stat;
131  LPVOID data;
132  HRESULT hr;
133  DWORD size, read;
135 
136  hr = IStream_Stat(stm, &stat, STATFLAG_NONAME);
137  if (FAILED(hr))
138  return hr;
139 
140  if (stat.cbSize.QuadPart >> 32)
141  {
142  ERR("Storage is too large\n");
143  return E_FAIL;
144  }
145 
146  size = stat.cbSize.QuadPart;
147  data = msi_alloc(size);
148  if (!data)
149  return E_OUTOFMEMORY;
150 
151  hr = IStream_Read(stm, data, size, &read);
152  if (FAILED(hr) || read != size)
153  goto done;
154 
155  hr = CreateILockBytesOnHGlobal(NULL, TRUE, &lockbytes);
156  if (FAILED(hr))
157  goto done;
158 
159  ZeroMemory(&offset, sizeof(ULARGE_INTEGER));
160  hr = ILockBytes_WriteAt(lockbytes, offset, data, size, &read);
161  if (FAILED(hr) || read != size)
162  goto done;
163 
164  hr = StgOpenStorageOnILockBytes(lockbytes, NULL,
166  NULL, 0, stg);
167  if (FAILED(hr))
168  goto done;
169 
170 done:
171  msi_free(data);
172  if (lockbytes) ILockBytes_Release(lockbytes);
173  return hr;
174 }
175 
177 {
179  IStorage *stg, *substg = NULL;
180  IStream *stm;
181  LPWSTR name = NULL;
182  HRESULT hr;
184 
185  TRACE("(%p, %p)\n", view, rec);
186 
187  if (row > sv->num_rows)
188  return ERROR_FUNCTION_FAILED;
189 
190  r = MSI_RecordGetIStream(rec, 2, &stm);
191  if (r != ERROR_SUCCESS)
192  return r;
193 
194  r = stream_to_storage(stm, &stg);
195  if (r != ERROR_SUCCESS)
196  {
197  IStream_Release(stm);
198  return r;
199  }
200 
201  name = strdupW(MSI_RecordGetString(rec, 1));
202  if (!name)
203  {
205  goto done;
206  }
207 
208  hr = IStorage_CreateStorage(sv->db->storage, name,
210  0, 0, &substg);
211  if (FAILED(hr))
212  {
214  goto done;
215  }
216 
217  hr = IStorage_CopyTo(stg, 0, NULL, NULL, substg);
218  if (FAILED(hr))
219  {
221  goto done;
222  }
223 
224  sv->storages[row] = create_storage(sv, name, stg);
225  if (!sv->storages[row])
227 
228 done:
229  msi_free(name);
230 
231  if (substg) IStorage_Release(substg);
232  IStorage_Release(stg);
233  IStream_Release(stm);
234 
235  return r;
236 }
237 
238 static UINT STORAGES_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary)
239 {
241 
242  if (!storages_set_table_size(sv, ++sv->num_rows))
243  return ERROR_FUNCTION_FAILED;
244 
245  if (row == -1)
246  row = sv->num_rows - 1;
247 
248  /* FIXME have to readjust rows */
249 
250  return STORAGES_set_row(view, row, rec, 0);
251 }
252 
254 {
255  FIXME("(%p %d): stub!\n", view, row);
256  return ERROR_SUCCESS;
257 }
258 
260 {
261  TRACE("(%p, %p)\n", view, record);
262  return ERROR_SUCCESS;
263 }
264 
266 {
267  TRACE("(%p)\n", view);
268  return ERROR_SUCCESS;
269 }
270 
271 static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
272 {
274 
275  TRACE("(%p, %p, %p)\n", view, rows, cols);
276 
277  if (cols) *cols = NUM_STORAGES_COLS;
278  if (rows) *rows = sv->num_rows;
279 
280  return ERROR_SUCCESS;
281 }
282 
284  UINT *type, BOOL *temporary, LPCWSTR *table_name )
285 {
286  TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary,
287  table_name);
288 
289  if (n == 0 || n > NUM_STORAGES_COLS)
291 
292  switch (n)
293  {
294  case 1:
295  if (name) *name = szName;
297  break;
298 
299  case 2:
300  if (name) *name = szData;
302  break;
303  }
304  if (table_name) *table_name = szStorages;
305  if (temporary) *temporary = FALSE;
306  return ERROR_SUCCESS;
307 }
308 
310 {
311  LPCWSTR str;
312  UINT r, i, id, data;
313 
314  str = MSI_RecordGetString(rec, 1);
315  r = msi_string2id(sv->db->strings, str, -1, &id);
316  if (r != ERROR_SUCCESS)
317  return r;
318 
319  for (i = 0; i < sv->num_rows; i++)
320  {
321  STORAGES_fetch_int(&sv->view, i, 1, &data);
322 
323  if (data == id)
324  {
325  *row = i;
326  return ERROR_SUCCESS;
327  }
328  }
329 
330  return ERROR_FUNCTION_FAILED;
331 }
332 
334 {
336  UINT r, row;
337 
338  r = storages_find_row(sv, rec, &row);
339  if (r != ERROR_SUCCESS)
340  return ERROR_FUNCTION_FAILED;
341 
342  return STORAGES_set_row(view, row, rec, 0);
343 }
344 
346 {
348  UINT r, row;
349 
350  r = storages_find_row(sv, rec, &row);
351  if (r == ERROR_SUCCESS)
352  return storages_modify_update(view, rec);
353 
354  return STORAGES_insert_row(view, rec, -1, FALSE);
355 }
356 
357 static UINT STORAGES_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
358 {
359  UINT r;
360 
361  TRACE("%p %d %p\n", view, eModifyMode, rec);
362 
363  switch (eModifyMode)
364  {
365  case MSIMODIFY_ASSIGN:
366  r = storages_modify_assign(view, rec);
367  break;
368 
369  case MSIMODIFY_INSERT:
370  r = STORAGES_insert_row(view, rec, -1, FALSE);
371  break;
372 
373  case MSIMODIFY_UPDATE:
374  r = storages_modify_update(view, rec);
375  break;
376 
379  case MSIMODIFY_REFRESH:
380  case MSIMODIFY_REPLACE:
381  case MSIMODIFY_MERGE:
382  case MSIMODIFY_DELETE:
383  case MSIMODIFY_VALIDATE:
386  FIXME("%p %d %p - mode not implemented\n", view, eModifyMode, rec );
388  break;
389 
390  default:
392  }
393 
394  return r;
395 }
396 
398 {
400  UINT i;
401 
402  TRACE("(%p)\n", view);
403 
404  for (i = 0; i < sv->num_rows; i++)
405  {
406  if (sv->storages[i]->storage)
407  IStorage_Release(sv->storages[i]->storage);
408  msi_free(sv->storages[i]);
409  }
410 
411  msi_free(sv->storages);
412  sv->storages = NULL;
413  msi_free(sv);
414 
415  return ERROR_SUCCESS;
416 }
417 
420 {
423 
424  TRACE("(%d, %d): %d\n", *row, col, val);
425 
426  if (col == 0 || col > NUM_STORAGES_COLS)
428 
429  while (index < sv->num_rows)
430  {
431  if (sv->storages[index]->str_index == val)
432  {
433  *row = index;
434  break;
435  }
436 
437  index++;
438  }
439 
440  *handle = UlongToPtr(++index);
441  if (index >= sv->num_rows)
442  return ERROR_NO_MORE_ITEMS;
443 
444  return ERROR_SUCCESS;
445 }
446 
447 static const MSIVIEWOPS storages_ops =
448 {
462  NULL,
463  NULL,
464  NULL,
465  NULL,
466  NULL,
467  NULL,
468 };
469 
471 {
472  STORAGE *storage = NULL;
473  IEnumSTATSTG *stgenum = NULL;
474  STATSTG stat;
475  HRESULT hr;
476  UINT count = 0, size;
477 
478  hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum);
479  if (FAILED(hr))
480  return -1;
481 
482  sv->max_storages = 1;
483  sv->storages = msi_alloc(sizeof(STORAGE *));
484  if (!sv->storages)
485  return -1;
486 
487  while (TRUE)
488  {
489  size = 0;
490  hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &size);
491  if (FAILED(hr) || !size)
492  break;
493 
494  if (stat.type != STGTY_STORAGE)
495  {
496  CoTaskMemFree(stat.pwcsName);
497  continue;
498  }
499 
500  TRACE("enumerated storage %s\n", debugstr_w(stat.pwcsName));
501 
502  storage = create_storage(sv, stat.pwcsName, NULL);
503  if (!storage)
504  {
505  count = -1;
506  CoTaskMemFree(stat.pwcsName);
507  break;
508  }
509 
510  IStorage_OpenStorage(sv->db->storage, stat.pwcsName, NULL,
512  &storage->storage);
513  CoTaskMemFree(stat.pwcsName);
514 
515  if (!storages_set_table_size(sv, ++count))
516  {
517  count = -1;
518  break;
519  }
520 
521  sv->storages[count - 1] = storage;
522  }
523 
524  IEnumSTATSTG_Release(stgenum);
525  return count;
526 }
527 
529 {
530  MSISTORAGESVIEW *sv;
531  INT rows;
532 
533  TRACE("(%p, %p)\n", db, view);
534 
535  sv = msi_alloc_zero( sizeof(MSISTORAGESVIEW) );
536  if (!sv)
537  return ERROR_FUNCTION_FAILED;
538 
539  sv->view.ops = &storages_ops;
540  sv->db = db;
541 
542  rows = add_storages_to_table(sv);
543  if (rows < 0)
544  {
545  msi_free( sv );
546  return ERROR_FUNCTION_FAILED;
547  }
548  sv->num_rows = rows;
549 
550  *view = (MSIVIEW *)sv;
551 
552  return ERROR_SUCCESS;
553 }
static UINT STORAGES_close(struct tagMSIVIEW *view)
Definition: storages.c:265
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define STGM_SHARE_DENY_NONE
Definition: objbase.h:919
struct tabSTORAGE STORAGE
#define TRUE
Definition: types.h:120
static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: storages.c:283
HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL global, BOOL delete_on_release, ILockBytes **ret)
Definition: memlockbytes.c:98
static UINT STORAGES_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
Definition: storages.c:106
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:922
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint GLuint GLsizei count
Definition: gl.h:1545
IStorage * storage
Definition: storages.c:46
static const WCHAR szData[]
Definition: msipriv.h:1195
GLintptr offset
Definition: glext.h:5920
static UINT STORAGES_get_row(struct tagMSIVIEW *view, UINT row, MSIRECORD **rec)
Definition: storages.c:118
UINT MSI_RecordGetIStream(MSIRECORD *, UINT, IStream **) DECLSPEC_HIDDEN
Definition: record.c:905
GLdouble n
Definition: glext.h:7729
struct tagMSISTORAGESVIEW MSISTORAGESVIEW
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ZeroMemory
Definition: winbase.h:1642
BOOL msi_add_string(string_table *st, const WCHAR *data, int len, enum StringPersistence persistence) DECLSPEC_HIDDEN
Definition: string.c:307
#define MSITYPE_STRING
Definition: msipriv.h:47
#define E_FAIL
Definition: ddrawi.h:102
int32_t INT
Definition: typedefs.h:56
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1216
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1210
static UINT STORAGES_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary)
Definition: storages.c:238
static UINT storages_modify_assign(struct tagMSIVIEW *view, MSIRECORD *rec)
Definition: storages.c:345
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
GLenum GLint GLuint mask
Definition: glext.h:6028
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
string_table * strings
Definition: msipriv.h:99
static UINT STORAGES_delete(struct tagMSIVIEW *view)
Definition: storages.c:397
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
#define NUM_STORAGES_COLS
Definition: storages.c:40
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
static STORAGE * create_storage(MSISTORAGESVIEW *sv, LPCWSTR name, IStorage *stg)
Definition: storages.c:72
#define STGM_WRITE
Definition: objbase.h:917
#define MSITYPE_NULLABLE
Definition: msipriv.h:48
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:482
GLuint index
Definition: glext.h:6031
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
GLuint GLfloat * val
Definition: glext.h:7180
UINT str_index
Definition: storages.c:45
#define STGM_READ
Definition: objbase.h:916
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
const MSIVIEWOPS * ops
Definition: msipriv.h:348
LONG HRESULT
Definition: typedefs.h:77
UINT msi_string2id(const string_table *st, const WCHAR *data, int len, UINT *id) DECLSPEC_HIDDEN
Definition: string.c:404
static const WCHAR szStorages[]
Definition: msipriv.h:1179
int JSAMPARRAY int int num_rows
Definition: jpegint.h:412
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT WINAPI StgOpenStorageOnILockBytes(ILockBytes *plkbyt, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8984
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static BOOL storages_set_table_size(MSISTORAGESVIEW *sv, UINT size)
Definition: storages.c:59
static UINT storages_find_row(MSISTORAGESVIEW *sv, MSIRECORD *rec, UINT *row)
Definition: storages.c:309
#define index(s, c)
Definition: various.h:29
static UINT STORAGES_find_matching_rows(struct tagMSIVIEW *view, UINT col, UINT val, UINT *row, MSIITERHANDLE *handle)
Definition: storages.c:418
static UINT storages_modify_update(struct tagMSIVIEW *view, MSIRECORD *rec)
Definition: storages.c:333
static HRESULT stream_to_storage(IStream *stm, IStorage **stg)
Definition: storages.c:127
Definition: stat.h:55
static UINT STORAGES_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
Definition: storages.c:357
#define STGM_READWRITE
Definition: objbase.h:918
static INT add_storages_to_table(MSISTORAGESVIEW *sv)
Definition: storages.c:470
MSIDATABASE * db
Definition: storages.c:52
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define ERR(fmt,...)
Definition: debug.h:109
static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: storages.c:271
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
static UINT STORAGES_delete_row(struct tagMSIVIEW *view, UINT row)
Definition: storages.c:253
static UINT STORAGES_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: storages.c:89
#define MAX_STORAGES_NAME_LEN
Definition: storages.c:41
enum tagMSIMODIFY MSIMODIFY
unsigned int UINT
Definition: ndis.h:50
#define MSITYPE_VALID
Definition: msipriv.h:45
static UINT STORAGES_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
Definition: storages.c:176
static UINT STORAGES_execute(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: storages.c:259
static BOOL msi_free(void *mem)
Definition: msipriv.h:1227
Definition: name.c:38
static const WCHAR szName[]
Definition: msipriv.h:1194
WINE_DEFAULT_DEBUG_CHANNEL(msidb)
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1204
GLenum GLuint id
Definition: glext.h:5579
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
static const MSIVIEWOPS storages_ops
Definition: storages.c:447
IStorage * storage
Definition: msipriv.h:98
UINT STORAGES_CreateView(MSIDATABASE *db, MSIVIEW **view)
Definition: storages.c:528
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
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
STORAGE ** storages
Definition: storages.c:53