Commit 044c1dd2 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

msi: Support setting streams in msi_select_update().

parent 226fd5cb
...@@ -221,6 +221,7 @@ static const MSIVIEWOPS alter_ops = ...@@ -221,6 +221,7 @@ static const MSIVIEWOPS alter_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
ALTER_execute, ALTER_execute,
ALTER_close, ALTER_close,
ALTER_get_dimensions, ALTER_get_dimensions,
......
...@@ -131,6 +131,7 @@ static const MSIVIEWOPS create_ops = ...@@ -131,6 +131,7 @@ static const MSIVIEWOPS create_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
CREATE_execute, CREATE_execute,
CREATE_close, CREATE_close,
CREATE_get_dimensions, CREATE_get_dimensions,
......
...@@ -173,6 +173,7 @@ static const MSIVIEWOPS delete_ops = ...@@ -173,6 +173,7 @@ static const MSIVIEWOPS delete_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
DELETE_execute, DELETE_execute,
DELETE_close, DELETE_close,
DELETE_get_dimensions, DELETE_get_dimensions,
......
...@@ -256,6 +256,7 @@ static const MSIVIEWOPS distinct_ops = ...@@ -256,6 +256,7 @@ static const MSIVIEWOPS distinct_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
DISTINCT_execute, DISTINCT_execute,
DISTINCT_close, DISTINCT_close,
DISTINCT_get_dimensions, DISTINCT_get_dimensions,
......
...@@ -101,6 +101,7 @@ static const MSIVIEWOPS drop_ops = ...@@ -101,6 +101,7 @@ static const MSIVIEWOPS drop_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
DROP_execute, DROP_execute,
DROP_close, DROP_close,
DROP_get_dimensions, DROP_get_dimensions,
......
...@@ -327,6 +327,7 @@ static const MSIVIEWOPS insert_ops = ...@@ -327,6 +327,7 @@ static const MSIVIEWOPS insert_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
INSERT_execute, INSERT_execute,
INSERT_close, INSERT_close,
INSERT_get_dimensions, INSERT_get_dimensions,
......
...@@ -257,6 +257,13 @@ typedef struct tagMSIVIEWOPS ...@@ -257,6 +257,13 @@ typedef struct tagMSIVIEWOPS
UINT (*set_string)( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len ); 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 * set_row - sets values in a row as specified by mask
* *
* Similar semantics to fetch_int * Similar semantics to fetch_int
......
...@@ -234,6 +234,7 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) ...@@ -234,6 +234,7 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
{ {
MSISELECTVIEW *sv = (MSISELECTVIEW*)view; MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
UINT r, i, col, type, val; UINT r, i, col, type, val;
IStream *stream;
LPCWSTR str; LPCWSTR str;
for (i = 0; i < sv->num_cols; i++) for (i = 0; i < sv->num_cols; i++)
...@@ -249,8 +250,9 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) ...@@ -249,8 +250,9 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
if (MSITYPE_IS_BINARY(type)) if (MSITYPE_IS_BINARY(type))
{ {
ERR("Cannot modify binary data!\n"); if (MSI_RecordGetIStream(rec, i + 1, &stream))
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
r = sv->table->ops->set_stream(sv->table, row, col, stream);
} }
else if (type & MSITYPE_STRING) else if (type & MSITYPE_STRING)
{ {
...@@ -311,6 +313,7 @@ static const MSIVIEWOPS select_ops = ...@@ -311,6 +313,7 @@ static const MSIVIEWOPS select_ops =
SELECT_fetch_stream, SELECT_fetch_stream,
NULL, NULL,
NULL, NULL,
NULL,
SELECT_set_row, SELECT_set_row,
SELECT_insert_row, SELECT_insert_row,
NULL, NULL,
......
...@@ -153,6 +153,46 @@ done: ...@@ -153,6 +153,46 @@ done:
return hr; 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) static UINT STORAGES_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
{ {
MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view; MSISTORAGESVIEW *sv = (MSISTORAGESVIEW *)view;
...@@ -404,6 +444,7 @@ static const MSIVIEWOPS storages_ops = ...@@ -404,6 +444,7 @@ static const MSIVIEWOPS storages_ops =
STORAGES_fetch_stream, STORAGES_fetch_stream,
NULL, NULL,
STORAGES_set_string, STORAGES_set_string,
STORAGES_set_stream,
STORAGES_set_row, STORAGES_set_row,
STORAGES_insert_row, STORAGES_insert_row,
STORAGES_delete_row, STORAGES_delete_row,
......
...@@ -110,6 +110,19 @@ static UINT STREAMS_set_string( struct tagMSIVIEW *view, UINT row, UINT col, con ...@@ -110,6 +110,19 @@ static UINT STREAMS_set_string( struct tagMSIVIEW *view, UINT row, UINT col, con
return ERROR_FUNCTION_FAILED; 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) static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
{ {
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view; MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
...@@ -340,6 +353,7 @@ static const MSIVIEWOPS streams_ops = ...@@ -340,6 +353,7 @@ static const MSIVIEWOPS streams_ops =
STREAMS_fetch_stream, STREAMS_fetch_stream,
NULL, NULL,
STREAMS_set_string, STREAMS_set_string,
STREAMS_set_stream,
STREAMS_set_row, STREAMS_set_row,
STREAMS_insert_row, STREAMS_insert_row,
STREAMS_delete_row, STREAMS_delete_row,
......
...@@ -1357,6 +1357,22 @@ done: ...@@ -1357,6 +1357,22 @@ done:
return r; 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 ) static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT iField, UINT *pvalue )
{ {
MSICOLUMNINFO columninfo; MSICOLUMNINFO columninfo;
...@@ -2126,6 +2142,7 @@ static const MSIVIEWOPS table_ops = ...@@ -2126,6 +2142,7 @@ static const MSIVIEWOPS table_ops =
TABLE_fetch_stream, TABLE_fetch_stream,
TABLE_set_int, TABLE_set_int,
TABLE_set_string, TABLE_set_string,
TABLE_set_stream,
TABLE_set_row, TABLE_set_row,
TABLE_insert_row, TABLE_insert_row,
TABLE_delete_row, TABLE_delete_row,
......
...@@ -204,6 +204,7 @@ static const MSIVIEWOPS update_ops = ...@@ -204,6 +204,7 @@ static const MSIVIEWOPS update_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
UPDATE_execute, UPDATE_execute,
UPDATE_close, UPDATE_close,
UPDATE_get_dimensions, UPDATE_get_dimensions,
......
...@@ -299,6 +299,26 @@ static UINT WHERE_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const ...@@ -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); 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 ) static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{ {
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view; MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
...@@ -1098,6 +1118,7 @@ static const MSIVIEWOPS where_ops = ...@@ -1098,6 +1118,7 @@ static const MSIVIEWOPS where_ops =
WHERE_fetch_stream, WHERE_fetch_stream,
WHERE_set_int, WHERE_set_int,
WHERE_set_string, WHERE_set_string,
WHERE_set_stream,
WHERE_set_row, WHERE_set_row,
NULL, NULL,
WHERE_delete_row, WHERE_delete_row,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment