msi: Support setting streams in msi_select_update().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
226fd5cb23
commit
044c1dd23b
|
@ -221,6 +221,7 @@ static const MSIVIEWOPS alter_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALTER_execute,
|
||||
ALTER_close,
|
||||
ALTER_get_dimensions,
|
||||
|
|
|
@ -131,6 +131,7 @@ static const MSIVIEWOPS create_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
CREATE_execute,
|
||||
CREATE_close,
|
||||
CREATE_get_dimensions,
|
||||
|
|
|
@ -173,6 +173,7 @@ static const MSIVIEWOPS delete_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DELETE_execute,
|
||||
DELETE_close,
|
||||
DELETE_get_dimensions,
|
||||
|
|
|
@ -256,6 +256,7 @@ static const MSIVIEWOPS distinct_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DISTINCT_execute,
|
||||
DISTINCT_close,
|
||||
DISTINCT_get_dimensions,
|
||||
|
|
|
@ -101,6 +101,7 @@ static const MSIVIEWOPS drop_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DROP_execute,
|
||||
DROP_close,
|
||||
DROP_get_dimensions,
|
||||
|
|
|
@ -327,6 +327,7 @@ static const MSIVIEWOPS insert_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
INSERT_execute,
|
||||
INSERT_close,
|
||||
INSERT_get_dimensions,
|
||||
|
|
|
@ -256,6 +256,13 @@ typedef struct tagMSIVIEWOPS
|
|||
*/
|
||||
UINT (*set_string)( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len );
|
||||
|
||||
/*
|
||||
* set_stream - set the stream value at {row, col}
|
||||
* This function has undefined behaviour if the column does not contain
|
||||
* streams.
|
||||
*/
|
||||
UINT (*set_stream)( struct tagMSIVIEW *view, UINT row, UINT col, IStream *stream );
|
||||
|
||||
/*
|
||||
* set_row - sets values in a row as specified by mask
|
||||
*
|
||||
|
|
|
@ -234,6 +234,7 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
|
|||
{
|
||||
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
|
||||
UINT r, i, col, type, val;
|
||||
IStream *stream;
|
||||
LPCWSTR str;
|
||||
|
||||
for (i = 0; i < sv->num_cols; i++)
|
||||
|
@ -249,8 +250,9 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
|
|||
|
||||
if (MSITYPE_IS_BINARY(type))
|
||||
{
|
||||
ERR("Cannot modify binary data!\n");
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
if (MSI_RecordGetIStream(rec, i + 1, &stream))
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
r = sv->table->ops->set_stream(sv->table, row, col, stream);
|
||||
}
|
||||
else if (type & MSITYPE_STRING)
|
||||
{
|
||||
|
@ -311,6 +313,7 @@ static const MSIVIEWOPS select_ops =
|
|||
SELECT_fetch_stream,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
SELECT_set_row,
|
||||
SELECT_insert_row,
|
||||
NULL,
|
||||
|
|
|
@ -153,6 +153,46 @@ done:
|
|||
return hr;
|
||||
}
|
||||
|
||||
static UINT STORAGES_set_stream( MSIVIEW *view, UINT row, UINT col, IStream *stream )
|
||||
{
|
||||
MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view;
|
||||
IStorage *stg, *substg, *prev;
|
||||
const WCHAR *name;
|
||||
HRESULT hr;
|
||||
UINT r;
|
||||
|
||||
TRACE("view %p, row %u, col %u, stream %p.\n", view, row, col, stream);
|
||||
|
||||
if ((r = stream_to_storage(stream, &stg)))
|
||||
return r;
|
||||
|
||||
name = msi_string_lookup(sv->db->strings, sv->storages[row].str_index, NULL);
|
||||
|
||||
hr = IStorage_CreateStorage(sv->db->storage, name,
|
||||
STGM_WRITE | STGM_SHARE_EXCLUSIVE,
|
||||
0, 0, &substg);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IStorage_Release(stg);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
hr = IStorage_CopyTo(stg, 0, NULL, NULL, substg);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IStorage_Release(substg);
|
||||
IStorage_Release(stg);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
IStorage_Release(substg);
|
||||
|
||||
prev = sv->storages[row].storage;
|
||||
sv->storages[row].storage = stg;
|
||||
if (prev) IStorage_Release(prev);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT STORAGES_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
|
||||
{
|
||||
MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view;
|
||||
|
@ -404,6 +444,7 @@ static const MSIVIEWOPS storages_ops =
|
|||
STORAGES_fetch_stream,
|
||||
NULL,
|
||||
STORAGES_set_string,
|
||||
STORAGES_set_stream,
|
||||
STORAGES_set_row,
|
||||
STORAGES_insert_row,
|
||||
STORAGES_delete_row,
|
||||
|
|
|
@ -110,6 +110,19 @@ static UINT STREAMS_set_string( struct tagMSIVIEW *view, UINT row, UINT col, con
|
|||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
static UINT STREAMS_set_stream( MSIVIEW *view, UINT row, UINT col, IStream *stream )
|
||||
{
|
||||
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
|
||||
IStream *prev;
|
||||
|
||||
TRACE("view %p, row %u, col %u, stream %p.\n", view, row, col, stream);
|
||||
|
||||
prev = sv->db->streams[row].stream;
|
||||
IStream_AddRef(sv->db->streams[row].stream = stream);
|
||||
if (prev) IStream_Release(prev);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
|
||||
{
|
||||
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
|
||||
|
@ -340,6 +353,7 @@ static const MSIVIEWOPS streams_ops =
|
|||
STREAMS_fetch_stream,
|
||||
NULL,
|
||||
STREAMS_set_string,
|
||||
STREAMS_set_stream,
|
||||
STREAMS_set_row,
|
||||
STREAMS_insert_row,
|
||||
STREAMS_delete_row,
|
||||
|
|
|
@ -1357,6 +1357,22 @@ done:
|
|||
return r;
|
||||
}
|
||||
|
||||
static UINT TABLE_set_stream( MSIVIEW *view, UINT row, UINT col, IStream *stream )
|
||||
{
|
||||
MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
|
||||
WCHAR *name;
|
||||
UINT r;
|
||||
|
||||
TRACE("row %u, col %u, stream %p.\n", row, col, stream);
|
||||
|
||||
if ((r = get_stream_name( tv, row - 1, &name )))
|
||||
return r;
|
||||
|
||||
r = add_stream( tv->db, name, stream );
|
||||
msi_free( name );
|
||||
return r;
|
||||
}
|
||||
|
||||
static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT iField, UINT *pvalue )
|
||||
{
|
||||
MSICOLUMNINFO columninfo;
|
||||
|
@ -2126,6 +2142,7 @@ static const MSIVIEWOPS table_ops =
|
|||
TABLE_fetch_stream,
|
||||
TABLE_set_int,
|
||||
TABLE_set_string,
|
||||
TABLE_set_stream,
|
||||
TABLE_set_row,
|
||||
TABLE_insert_row,
|
||||
TABLE_delete_row,
|
||||
|
|
|
@ -204,6 +204,7 @@ static const MSIVIEWOPS update_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
UPDATE_execute,
|
||||
UPDATE_close,
|
||||
UPDATE_get_dimensions,
|
||||
|
|
|
@ -299,6 +299,26 @@ static UINT WHERE_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const
|
|||
return table->view->ops->set_string(table->view, rows[table->table_index], col, val, len);
|
||||
}
|
||||
|
||||
static UINT WHERE_set_stream(MSIVIEW *view, UINT row, UINT col, IStream *stream)
|
||||
{
|
||||
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
|
||||
JOINTABLE *table;
|
||||
UINT *rows;
|
||||
UINT r;
|
||||
|
||||
TRACE("view %p, row %u, col %u, stream %p.\n", wv, row, col, stream);
|
||||
|
||||
r = find_row(wv, row, &rows);
|
||||
if (r != ERROR_SUCCESS)
|
||||
return r;
|
||||
|
||||
table = find_table(wv, col, &col);
|
||||
if (!table)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
return table->view->ops->set_stream(table->view, rows[table->table_index], col, stream);
|
||||
}
|
||||
|
||||
static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
|
||||
{
|
||||
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
|
||||
|
@ -1098,6 +1118,7 @@ static const MSIVIEWOPS where_ops =
|
|||
WHERE_fetch_stream,
|
||||
WHERE_set_int,
|
||||
WHERE_set_string,
|
||||
WHERE_set_stream,
|
||||
WHERE_set_row,
|
||||
NULL,
|
||||
WHERE_delete_row,
|
||||
|
|
Loading…
Reference in New Issue