https://git.reactos.org/?p=reactos.git;a=commitdiff;h=580d3e1be0bde532af3f4…
commit 580d3e1be0bde532af3f4f3a2192045945ce7bdc
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Sun Mar 13 00:16:38 2022 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Mar 20 19:28:10 2022 +0100
[WINESYNC] msi: Support setting streams in msi_select_update().
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
wine commit id 044c1dd23b307a0b7f2188855d5bf6e479cefd5e by Zebediah Figura
<z.figura12(a)gmail.com>
---
dll/win32/msi/alter.c | 1 +
dll/win32/msi/create.c | 1 +
dll/win32/msi/delete.c | 1 +
dll/win32/msi/distinct.c | 1 +
dll/win32/msi/drop.c | 1 +
dll/win32/msi/insert.c | 1 +
dll/win32/msi/msipriv.h | 7 +++++++
dll/win32/msi/select.c | 7 +++++--
dll/win32/msi/storages.c | 41 +++++++++++++++++++++++++++++++++++++++++
dll/win32/msi/streams.c | 14 ++++++++++++++
dll/win32/msi/table.c | 17 +++++++++++++++++
dll/win32/msi/update.c | 1 +
dll/win32/msi/where.c | 21 +++++++++++++++++++++
13 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/dll/win32/msi/alter.c b/dll/win32/msi/alter.c
index d1a481ebfc9..5c5893c8248 100644
--- a/dll/win32/msi/alter.c
+++ b/dll/win32/msi/alter.c
@@ -221,6 +221,7 @@ static const MSIVIEWOPS alter_ops =
NULL,
NULL,
NULL,
+ NULL,
ALTER_execute,
ALTER_close,
ALTER_get_dimensions,
diff --git a/dll/win32/msi/create.c b/dll/win32/msi/create.c
index 3c00b70c531..2777954aa7d 100644
--- a/dll/win32/msi/create.c
+++ b/dll/win32/msi/create.c
@@ -131,6 +131,7 @@ static const MSIVIEWOPS create_ops =
NULL,
NULL,
NULL,
+ NULL,
CREATE_execute,
CREATE_close,
CREATE_get_dimensions,
diff --git a/dll/win32/msi/delete.c b/dll/win32/msi/delete.c
index e2e0e34678b..81bd9d7db2f 100644
--- a/dll/win32/msi/delete.c
+++ b/dll/win32/msi/delete.c
@@ -173,6 +173,7 @@ static const MSIVIEWOPS delete_ops =
NULL,
NULL,
NULL,
+ NULL,
DELETE_execute,
DELETE_close,
DELETE_get_dimensions,
diff --git a/dll/win32/msi/distinct.c b/dll/win32/msi/distinct.c
index 5bd5bf8676d..e102adb3de2 100644
--- a/dll/win32/msi/distinct.c
+++ b/dll/win32/msi/distinct.c
@@ -256,6 +256,7 @@ static const MSIVIEWOPS distinct_ops =
NULL,
NULL,
NULL,
+ NULL,
DISTINCT_execute,
DISTINCT_close,
DISTINCT_get_dimensions,
diff --git a/dll/win32/msi/drop.c b/dll/win32/msi/drop.c
index 60a92021060..89fac9dfc7c 100644
--- a/dll/win32/msi/drop.c
+++ b/dll/win32/msi/drop.c
@@ -94,6 +94,7 @@ static UINT DROP_delete( struct tagMSIVIEW *view )
static const MSIVIEWOPS drop_ops =
{
+ NULL,
NULL,
NULL,
NULL,
diff --git a/dll/win32/msi/insert.c b/dll/win32/msi/insert.c
index ed913c034c1..f1185eebaeb 100644
--- a/dll/win32/msi/insert.c
+++ b/dll/win32/msi/insert.c
@@ -327,6 +327,7 @@ static const MSIVIEWOPS insert_ops =
NULL,
NULL,
NULL,
+ NULL,
INSERT_execute,
INSERT_close,
INSERT_get_dimensions,
diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h
index 8bf0385a440..2177aa6f10e 100644
--- a/dll/win32/msi/msipriv.h
+++ b/dll/win32/msi/msipriv.h
@@ -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
*
diff --git a/dll/win32/msi/select.c b/dll/win32/msi/select.c
index c6e7b209033..9d3d887f56b 100644
--- a/dll/win32/msi/select.c
+++ b/dll/win32/msi/select.c
@@ -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,
diff --git a/dll/win32/msi/storages.c b/dll/win32/msi/storages.c
index 76a0e2e03f8..521b6e89e83 100644
--- a/dll/win32/msi/storages.c
+++ b/dll/win32/msi/storages.c
@@ -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,
diff --git a/dll/win32/msi/streams.c b/dll/win32/msi/streams.c
index 150e9288682..6565b3d4c40 100644
--- a/dll/win32/msi/streams.c
+++ b/dll/win32/msi/streams.c
@@ -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;
@@ -364,6 +377,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,
diff --git a/dll/win32/msi/table.c b/dll/win32/msi/table.c
index f26ab9f5b45..a2b83e27de2 100644
--- a/dll/win32/msi/table.c
+++ b/dll/win32/msi/table.c
@@ -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,
diff --git a/dll/win32/msi/update.c b/dll/win32/msi/update.c
index af629d2236c..e61342d11e4 100644
--- a/dll/win32/msi/update.c
+++ b/dll/win32/msi/update.c
@@ -204,6 +204,7 @@ static const MSIVIEWOPS update_ops =
NULL,
NULL,
NULL,
+ NULL,
UPDATE_execute,
UPDATE_close,
UPDATE_get_dimensions,
diff --git a/dll/win32/msi/where.c b/dll/win32/msi/where.c
index eaadac4310c..66de85bec94 100644
--- a/dll/win32/msi/where.c
+++ b/dll/win32/msi/where.c
@@ -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,