ReactOS 0.4.15-dev-8348-gc1b9bb5
streams.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2007 James Hawkins
5 * Copyright 2015 Hans Leidekker for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23
24#define COBJMACROS
25
26#include "windef.h"
27#include "winbase.h"
28#include "winerror.h"
29#include "msi.h"
30#include "msiquery.h"
31#include "objbase.h"
32#include "msipriv.h"
33#include "query.h"
34
35#include "wine/debug.h"
36
38
39#define NUM_STREAMS_COLS 2
40
41typedef struct tagMSISTREAMSVIEW
42{
47
49{
50 if (!db->num_streams_allocated)
51 {
52 if (!(db->streams = msi_alloc_zero( size * sizeof(MSISTREAM) ))) return FALSE;
54 return TRUE;
55 }
56 while (size >= db->num_streams_allocated)
57 {
58 MSISTREAM *tmp;
59 UINT new_size = db->num_streams_allocated * 2;
60 if (!(tmp = msi_realloc( db->streams, new_size * sizeof(*tmp) ))) return FALSE;
61 memset( tmp + db->num_streams_allocated, 0, (new_size - db->num_streams_allocated) * sizeof(*tmp) );
62 db->streams = tmp;
63 db->num_streams_allocated = new_size;
64 }
65 return TRUE;
66}
67
69{
71
72 TRACE("(%p, %d, %d, %p)\n", view, row, col, val);
73
74 if (col != 1)
76
77 if (row >= sv->db->num_streams)
79
80 *val = sv->db->streams[row].str_index;
81
82 return ERROR_SUCCESS;
83}
84
86{
89 HRESULT hr;
90
91 TRACE("(%p, %d, %d, %p)\n", view, row, col, stm);
92
93 if (row >= sv->db->num_streams)
95
96 pos.QuadPart = 0;
97 hr = IStream_Seek( sv->db->streams[row].stream, pos, STREAM_SEEK_SET, NULL );
98 if (FAILED( hr ))
100
101 *stm = sv->db->streams[row].stream;
102 IStream_AddRef( *stm );
103
104 return ERROR_SUCCESS;
105}
106
107static UINT STREAMS_set_string( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len )
108{
109 ERR("Cannot modify primary key.\n");
111}
112
114{
116 IStream *prev;
117
118 TRACE("view %p, row %u, col %u, stream %p.\n", view, row, col, stream);
119
120 prev = sv->db->streams[row].stream;
121 IStream_AddRef(sv->db->streams[row].stream = stream);
122 if (prev) IStream_Release(prev);
123 return ERROR_SUCCESS;
124}
125
127{
129
130 TRACE("(%p, %d, %p, %08x)\n", view, row, rec, mask);
131
132 if (row > sv->db->num_streams || mask >= (1 << sv->num_cols))
134
135 if (mask & 1)
136 {
137 const WCHAR *name = MSI_RecordGetString( rec, 1 );
138
139 if (!name) return ERROR_INVALID_PARAMETER;
140 sv->db->streams[row].str_index = msi_add_string( sv->db->strings, name, -1, FALSE );
141 }
142 if (mask & 2)
143 {
144 IStream *old, *new;
145 HRESULT hr;
146 UINT r;
147
148 r = MSI_RecordGetIStream( rec, 2, &new );
149 if (r != ERROR_SUCCESS)
150 return r;
151
152 old = sv->db->streams[row].stream;
153 hr = IStream_QueryInterface( new, &IID_IStream, (void **)&sv->db->streams[row].stream );
154 IStream_Release( new );
155 if (FAILED( hr ))
156 {
158 }
159 if (old) IStream_Release( old );
160 }
161
162 return ERROR_SUCCESS;
163}
164
166{
167 const WCHAR *str;
168 UINT r, i, id, val;
169
170 str = MSI_RecordGetString( rec, 1 );
171 r = msi_string2id( sv->db->strings, str, -1, &id );
172 if (r != ERROR_SUCCESS)
173 return r;
174
175 for (i = 0; i < sv->db->num_streams; i++)
176 {
177 STREAMS_fetch_int( &sv->view, i, 1, &val );
178
179 if (val == id)
180 {
181 if (row) *row = i;
182 return ERROR_SUCCESS;
183 }
184 }
185
187}
188
189static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary)
190{
192 UINT i, r, num_rows = sv->db->num_streams + 1;
193
194 TRACE("(%p, %p, %d, %d)\n", view, rec, row, temporary);
195
196 r = streams_find_row( sv, rec, NULL );
197 if (r == ERROR_SUCCESS)
199
200 if (!streams_resize_table( sv->db, num_rows ))
202
203 if (row == -1)
204 row = num_rows - 1;
205
206 /* shift the rows to make room for the new row */
207 for (i = num_rows - 1; i > row; i--)
208 {
209 sv->db->streams[i] = sv->db->streams[i - 1];
210 }
211
212 r = STREAMS_set_row( view, row, rec, (1 << sv->num_cols) - 1 );
213 if (r == ERROR_SUCCESS)
214 sv->db->num_streams = num_rows;
215
216 return r;
217}
218
220{
221 MSIDATABASE *db = ((MSISTREAMSVIEW *)view)->db;
222 UINT i, num_rows = db->num_streams - 1;
223 const WCHAR *name;
224 WCHAR *encname;
225 HRESULT hr;
226
227 TRACE("(%p %d)\n", view, row);
228
229 if (!db->num_streams || row > num_rows)
231
233 if (!(encname = encode_streamname( FALSE, name ))) return ERROR_OUTOFMEMORY;
234 IStream_Release( db->streams[row].stream );
235
236 for (i = row; i < num_rows; i++)
237 db->streams[i] = db->streams[i + 1];
238 db->num_streams = num_rows;
239
240 hr = IStorage_DestroyElement( db->storage, encname );
241 msi_free( encname );
243}
244
246{
247 TRACE("(%p, %p)\n", view, record);
248 return ERROR_SUCCESS;
249}
250
252{
253 TRACE("(%p)\n", view);
254 return ERROR_SUCCESS;
255}
256
257static UINT STREAMS_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
258{
260
261 TRACE("(%p, %p, %p)\n", view, rows, cols);
262
263 if (cols) *cols = sv->num_cols;
264 if (rows) *rows = sv->db->num_streams;
265
266 return ERROR_SUCCESS;
267}
268
270 UINT *type, BOOL *temporary, LPCWSTR *table_name )
271{
273
274 TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary, table_name);
275
276 if (!n || n > sv->num_cols)
278
279 switch (n)
280 {
281 case 1:
282 if (name) *name = L"Name";
284 break;
285
286 case 2:
287 if (name) *name = L"Data";
289 break;
290 }
291 if (table_name) *table_name = L"_Streams";
292 if (temporary) *temporary = FALSE;
293 return ERROR_SUCCESS;
294}
295
297{
299 UINT r, row;
300
301 r = streams_find_row(sv, rec, &row);
302 if (r != ERROR_SUCCESS)
304
305 return STREAMS_set_row( view, row, rec, (1 << sv->num_cols) - 1 );
306}
307
309{
311 UINT r;
312
313 r = streams_find_row( sv, rec, NULL );
314 if (r == ERROR_SUCCESS)
315 return streams_modify_update(view, rec);
316
317 return STREAMS_insert_row(view, rec, -1, FALSE);
318}
319
320static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
321{
322 UINT r;
323
324 TRACE("%p %d %p\n", view, eModifyMode, rec);
325
326 switch (eModifyMode)
327 {
328 case MSIMODIFY_ASSIGN:
330 break;
331
332 case MSIMODIFY_INSERT:
333 r = STREAMS_insert_row(view, rec, -1, FALSE);
334 break;
335
336 case MSIMODIFY_UPDATE:
338 break;
339
340 case MSIMODIFY_DELETE:
342 break;
343
348 case MSIMODIFY_MERGE:
352 FIXME("%p %d %p - mode not implemented\n", view, eModifyMode, rec );
354 break;
355
356 default:
358 }
359
360 return r;
361}
362
364{
366
367 TRACE("(%p)\n", view);
368
369 msi_free(sv);
370 return ERROR_SUCCESS;
371}
372
374{
377 NULL,
389 NULL,
390 NULL,
391 NULL,
392 NULL,
393 NULL,
394};
395
397{
398 HRESULT hr;
399
400 hr = IStorage_OpenStream( db->storage, name, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, stream );
401 if (FAILED( hr ))
402 {
404
406 {
407 hr = IStorage_OpenStream( transform->stg, name, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, stream );
408 if (SUCCEEDED( hr ))
409 break;
410 }
411 }
412 return hr;
413}
414
416{
417 UINT r, id, i;
418
419 r = msi_string2id( db->strings, name, -1, &id );
420 if (r != ERROR_SUCCESS)
421 return NULL;
422
423 for (i = 0; i < db->num_streams; i++)
424 {
425 if (db->streams[i].str_index == id) return &db->streams[i];
426 }
427 return NULL;
428}
429
431{
432 UINT i = db->num_streams;
433
434 if (!streams_resize_table( db, db->num_streams + 1 ))
435 return ERROR_OUTOFMEMORY;
436
437 db->streams[i].str_index = msi_add_string( db->strings, name, -1, FALSE );
438 db->streams[i].stream = stream;
439 db->num_streams++;
440
441 TRACE("added %s\n", debugstr_w( name ));
442 return ERROR_SUCCESS;
443}
444
446{
447 WCHAR decoded[MAX_STREAM_NAME_LEN + 1];
448 IEnumSTATSTG *stgenum;
449 STATSTG stat;
450 HRESULT hr;
451 ULONG count;
454
455 hr = IStorage_EnumElements( db->storage, 0, NULL, 0, &stgenum );
456 if (FAILED( hr ))
458
459 for (;;)
460 {
461 count = 0;
462 hr = IEnumSTATSTG_Next( stgenum, 1, &stat, &count );
463 if (FAILED( hr ) || !count)
464 break;
465
466 /* table streams are not in the _Streams table */
467 if (stat.type != STGTY_STREAM || *stat.pwcsName == 0x4840)
468 {
469 CoTaskMemFree( stat.pwcsName );
470 continue;
471 }
472 decode_streamname( stat.pwcsName, decoded );
473 if (find_stream( db, decoded ))
474 {
475 CoTaskMemFree( stat.pwcsName );
476 continue;
477 }
478 TRACE("found new stream %s\n", debugstr_w( decoded ));
479
480 hr = open_stream( db, stat.pwcsName, &stream );
481 CoTaskMemFree( stat.pwcsName );
482 if (FAILED( hr ))
483 {
484 ERR( "unable to open stream %#lx\n", hr );
486 break;
487 }
488
489 r = append_stream( db, decoded, stream );
490 if (r != ERROR_SUCCESS)
491 break;
492 }
493
494 TRACE("loaded %u streams\n", db->num_streams);
495 IEnumSTATSTG_Release( stgenum );
496 return r;
497}
498
500{
502 WCHAR *encname;
503 HRESULT hr;
504 UINT r;
505
506 if ((stream = find_stream( db, name )))
507 {
509
510 pos.QuadPart = 0;
511 hr = IStream_Seek( stream->stream, pos, STREAM_SEEK_SET, NULL );
512 if (FAILED( hr ))
514
515 *ret = stream->stream;
516 IStream_AddRef( *ret );
517 return ERROR_SUCCESS;
518 }
519
520 if (!(encname = encode_streamname( FALSE, name )))
521 return ERROR_OUTOFMEMORY;
522
523 hr = open_stream( db, encname, ret );
524 msi_free( encname );
525 if (FAILED( hr ))
527
528 r = append_stream( db, name, *ret );
529 if (r != ERROR_SUCCESS)
530 {
531 IStream_Release( *ret );
532 return r;
533 }
534
535 IStream_AddRef( *ret );
536 return ERROR_SUCCESS;
537}
538
540{
541 MSISTREAMSVIEW *sv;
542 UINT r;
543
544 TRACE("(%p, %p)\n", db, view);
545
546 r = load_streams( db );
547 if (r != ERROR_SUCCESS)
548 return r;
549
550 if (!(sv = msi_alloc_zero( sizeof(MSISTREAMSVIEW) )))
551 return ERROR_OUTOFMEMORY;
552
553 sv->view.ops = &streams_ops;
555 sv->db = db;
556
557 *view = (MSIVIEW *)sv;
558
559 return ERROR_SUCCESS;
560}
561
563{
564 HRESULT hr;
565 char buf[4096];
566 STATSTG stat;
568 ULONG count;
569 UINT size;
570
571 hr = IStream_Stat( src, &stat, STATFLAG_NONAME );
572 if (FAILED( hr )) return hr;
573
574 hr = IStream_SetSize( dst, stat.cbSize );
575 if (FAILED( hr )) return hr;
576
577 pos.QuadPart = 0;
578 hr = IStream_Seek( dst, pos, STREAM_SEEK_SET, NULL );
579 if (FAILED( hr )) return hr;
580
581 for (;;)
582 {
583 size = min( sizeof(buf), stat.cbSize.QuadPart );
584 hr = IStream_Read( src, buf, size, &count );
585 if (FAILED( hr ) || count != size)
586 {
587 WARN( "failed to read stream: %#lx\n", hr );
588 return E_INVALIDARG;
589 }
590 stat.cbSize.QuadPart -= count;
591 if (count)
592 {
593 size = count;
594 hr = IStream_Write( dst, buf, size, &count );
595 if (FAILED( hr ) || count != size)
596 {
597 WARN( "failed to write stream: %#lx\n", hr );
598 return E_INVALIDARG;
599 }
600 }
601 if (!stat.cbSize.QuadPart) break;
602 }
603
604 return S_OK;
605}
606
608{
609 UINT i;
610 const WCHAR *name;
611 WCHAR *encname;
613 HRESULT hr;
614
615 TRACE("got %u streams\n", db->num_streams);
616
617 for (i = 0; i < db->num_streams; i++)
618 {
620 if (!wcscmp( name, L"\5SummaryInformation" )) continue;
621
622 if (!(encname = encode_streamname( FALSE, name ))) return ERROR_OUTOFMEMORY;
623 TRACE("saving stream %s as %s\n", debugstr_w(name), debugstr_w(encname));
624
625 hr = IStorage_CreateStream( db->storage, encname, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stream );
626 if (SUCCEEDED( hr ))
627 {
629 if (FAILED( hr ))
630 {
631 ERR( "failed to write stream %s (hr = %#lx)\n", debugstr_w(encname), hr );
632 msi_free( encname );
633 IStream_Release( stream );
635 }
636 hr = IStream_Commit( stream, 0 );
637 IStream_Release( stream );
638 if (FAILED( hr ))
639 {
640 ERR( "failed to commit stream %s (hr = %#lx)\n", debugstr_w(encname), hr );
641 msi_free( encname );
643 }
644 }
645 else if (hr != STG_E_FILEALREADYEXISTS)
646 {
647 ERR( "failed to create stream %s (hr = %#lx)\n", debugstr_w(encname), hr );
648 msi_free( encname );
650 }
651 msi_free( encname );
652 }
653
654 return ERROR_SUCCESS;
655}
#define stat
Definition: acwin.h:99
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define E_INVALIDARG
Definition: ddrawi.h:101
#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
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
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint GLenum GLenum transform
Definition: glext.h:9407
GLenum src
Definition: glext.h:6340
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
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 S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define open_stream
Definition: intsym.h:251
uint32_t entry
Definition: isohybrid.c:63
int JSAMPARRAY int int num_rows
Definition: jpegint.h:421
#define debugstr_w
Definition: kernel32.h:32
#define min(a, b)
Definition: monoChain.cc:55
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
LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) DECLSPEC_HIDDEN
Definition: table.c:119
#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
#define MAX_STREAM_NAME_LEN
Definition: msipriv.h:56
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
BOOL decode_streamname(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN
Definition: table.c:178
@ 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_EXCLUSIVE
Definition: objbase.h:923
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
struct tagMSISTREAMSVIEW MSISTREAMSVIEW
UINT STREAMS_CreateView(MSIDATABASE *db, MSIVIEW **view)
Definition: streams.c:539
static const MSIVIEWOPS streams_ops
Definition: streams.c:373
static UINT STREAMS_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: streams.c:68
static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
Definition: streams.c:320
static UINT load_streams(MSIDATABASE *db)
Definition: streams.c:445
static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
Definition: streams.c:126
static UINT append_stream(MSIDATABASE *db, const WCHAR *name, IStream *stream)
Definition: streams.c:430
static UINT streams_find_row(MSISTREAMSVIEW *sv, MSIRECORD *rec, UINT *row)
Definition: streams.c:165
static UINT STREAMS_delete_row(struct tagMSIVIEW *view, UINT row)
Definition: streams.c:219
static UINT STREAMS_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
Definition: streams.c:85
static UINT STREAMS_close(struct tagMSIVIEW *view)
Definition: streams.c:251
UINT msi_commit_streams(MSIDATABASE *db)
Definition: streams.c:607
static UINT STREAMS_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len)
Definition: streams.c:107
static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary)
Definition: streams.c:189
static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: streams.c:269
static HRESULT write_stream(IStream *dst, IStream *src)
Definition: streams.c:562
static UINT STREAMS_set_stream(MSIVIEW *view, UINT row, UINT col, IStream *stream)
Definition: streams.c:113
static UINT STREAMS_delete(struct tagMSIVIEW *view)
Definition: streams.c:363
#define NUM_STREAMS_COLS
Definition: streams.c:39
static UINT streams_modify_update(struct tagMSIVIEW *view, MSIRECORD *rec)
Definition: streams.c:296
static UINT STREAMS_execute(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: streams.c:245
static UINT STREAMS_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: streams.c:257
static MSISTREAM * find_stream(MSIDATABASE *db, const WCHAR *name)
Definition: streams.c:415
static BOOL streams_resize_table(MSIDATABASE *db, UINT size)
Definition: streams.c:48
static UINT streams_modify_assign(struct tagMSIVIEW *view, MSIRECORD *rec)
Definition: streams.c:308
UINT msi_get_stream(MSIDATABASE *db, const WCHAR *name, IStream **ret)
Definition: streams.c:499
Definition: name.c:39
Definition: stat.h:55
Definition: parse.h:23
UINT num_streams_allocated
Definition: msipriv.h:122
MSISTREAM * streams
Definition: msipriv.h:120
UINT num_streams
Definition: msipriv.h:121
struct list transforms
Definition: msipriv.h:119
IStorage * storage
Definition: msipriv.h:109
string_table * strings
Definition: msipriv.h:110
MSIVIEW view
Definition: streams.c:43
MSIDATABASE * db
Definition: streams.c:44
UINT str_index
Definition: msipriv.h:88
IStream * stream
Definition: msipriv.h:89
const MSIVIEWOPS * ops
Definition: msipriv.h:355
uint32_t ULONG
Definition: typedefs.h:59
int ret
int MSIMODIFY
Definition: winemsi.idl:33
#define STG_E_FILEALREADYEXISTS
Definition: winerror.h:2579
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define ERROR_INVALID_DATA
Definition: winerror.h:116
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185