https://git.reactos.org/?p=reactos.git;a=commitdiff;h=97918c366e8fe3f75bb34…
commit 97918c366e8fe3f75bb34dd125b21d36ab740627
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Sun Mar 13 00:16:33 2022 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Mar 20 19:28:10 2022 +0100
[WINESYNC] msi: Set table values directly in msi_select_update().
In order to avoid the need to create a temporary record and copy values back
and forth.
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 f45a7b04a6caca4eed1d08f4e69884b119f3aa17 by Zebediah Figura
<z.figura12(a)gmail.com>
---
dll/win32/msi/alter.c | 2 ++
dll/win32/msi/create.c | 2 ++
dll/win32/msi/delete.c | 2 ++
dll/win32/msi/distinct.c | 2 ++
dll/win32/msi/drop.c | 2 ++
dll/win32/msi/insert.c | 2 ++
dll/win32/msi/msipriv.h | 14 ++++++++++
dll/win32/msi/select.c | 26 ++++++------------
dll/win32/msi/storages.c | 8 ++++++
dll/win32/msi/streams.c | 8 ++++++
dll/win32/msi/table.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++--
dll/win32/msi/update.c | 2 ++
dll/win32/msi/where.c | 42 ++++++++++++++++++++++++++++
13 files changed, 164 insertions(+), 19 deletions(-)
diff --git a/dll/win32/msi/alter.c b/dll/win32/msi/alter.c
index 011a2dcfb81..96ff284a3df 100644
--- a/dll/win32/msi/alter.c
+++ b/dll/win32/msi/alter.c
@@ -229,6 +229,8 @@ static const MSIVIEWOPS alter_ops =
NULL,
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 dd4739df12f..2777954aa7d 100644
--- a/dll/win32/msi/create.c
+++ b/dll/win32/msi/create.c
@@ -130,6 +130,8 @@ static const MSIVIEWOPS create_ops =
NULL,
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 468115186b6..81bd9d7db2f 100644
--- a/dll/win32/msi/delete.c
+++ b/dll/win32/msi/delete.c
@@ -172,6 +172,8 @@ static const MSIVIEWOPS delete_ops =
NULL,
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 b1945a15465..e102adb3de2 100644
--- a/dll/win32/msi/distinct.c
+++ b/dll/win32/msi/distinct.c
@@ -255,6 +255,8 @@ static const MSIVIEWOPS distinct_ops =
NULL,
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 3179f14219e..89fac9dfc7c 100644
--- a/dll/win32/msi/drop.c
+++ b/dll/win32/msi/drop.c
@@ -94,6 +94,8 @@ static UINT DROP_delete( struct tagMSIVIEW *view )
static const MSIVIEWOPS drop_ops =
{
+ NULL,
+ NULL,
NULL,
NULL,
NULL,
diff --git a/dll/win32/msi/insert.c b/dll/win32/msi/insert.c
index a5333c9cdc6..f1185eebaeb 100644
--- a/dll/win32/msi/insert.c
+++ b/dll/win32/msi/insert.c
@@ -326,6 +326,8 @@ static const MSIVIEWOPS insert_ops =
NULL,
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 16b02ae86eb..9677d046452 100644
--- a/dll/win32/msi/msipriv.h
+++ b/dll/win32/msi/msipriv.h
@@ -248,6 +248,20 @@ typedef struct tagMSIVIEWOPS
*/
UINT (*get_row)( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec );
+ /*
+ * set_int - set the integer value at {row, col}
+ * This function has undefined behaviour if the column does not contain
+ * integers.
+ */
+ UINT (*set_int)( struct tagMSIVIEW *view, UINT row, UINT col, int val );
+
+ /*
+ * set_string - set the string value at {row, col}
+ * This function has undefined behaviour if the column does not contain
+ * strings.
+ */
+ UINT (*set_string)( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val,
int len );
+
/*
* 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 e17cbbbdf25..91765c8ec3b 100644
--- a/dll/win32/msi/select.c
+++ b/dll/win32/msi/select.c
@@ -247,16 +247,11 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD
*rec, UINT row)
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
UINT r, i, num_columns, col, type, val;
LPCWSTR str;
- MSIRECORD *mod;
r = SELECT_get_dimensions(view, NULL, &num_columns);
if (r != ERROR_SUCCESS)
return r;
- r = sv->table->ops->get_row(sv->table, row, &mod);
- if (r != ERROR_SUCCESS)
- return r;
-
for (i = 0; i < num_columns; i++)
{
col = sv->cols[i];
@@ -265,39 +260,34 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD
*rec, UINT row)
if (r != ERROR_SUCCESS)
{
ERR("Failed to get column information: %d\n", r);
- goto done;
+ return r;
}
if (MSITYPE_IS_BINARY(type))
{
ERR("Cannot modify binary data!\n");
- r = ERROR_FUNCTION_FAILED;
- goto done;
+ return ERROR_FUNCTION_FAILED;
}
else if (type & MSITYPE_STRING)
{
int len;
- str = msi_record_get_string( rec, i + 1, &len );
- r = msi_record_set_string( mod, col, str, len );
+ str = msi_record_get_string(rec, i + 1, &len);
+ r = sv->table->ops->set_string(sv->table, row, col, str, len);
}
else
{
val = MSI_RecordGetInteger(rec, i + 1);
- r = MSI_RecordSetInteger(mod, col, val);
+ r = sv->table->ops->set_int(sv->table, row, col, val);
}
if (r != ERROR_SUCCESS)
{
ERR("Failed to modify record: %d\n", r);
- goto done;
+ return r;
}
}
- r = sv->table->ops->modify(sv->table, MSIMODIFY_UPDATE, mod, row);
-
-done:
- msiobj_release(&mod->hdr);
- return r;
+ return ERROR_SUCCESS;
}
static UINT SELECT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
@@ -336,6 +326,8 @@ static const MSIVIEWOPS select_ops =
SELECT_fetch_int,
SELECT_fetch_stream,
SELECT_get_row,
+ NULL,
+ NULL,
SELECT_set_row,
SELECT_insert_row,
NULL,
diff --git a/dll/win32/msi/storages.c b/dll/win32/msi/storages.c
index 4379ae268b2..ad020dec55e 100644
--- a/dll/win32/msi/storages.c
+++ b/dll/win32/msi/storages.c
@@ -124,6 +124,12 @@ static UINT STORAGES_get_row( struct tagMSIVIEW *view, UINT row,
MSIRECORD **rec
return ERROR_CALL_NOT_IMPLEMENTED;
}
+static UINT STORAGES_set_string( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR
*val, int len )
+{
+ ERR("Cannot modify primary key.\n");
+ return ERROR_FUNCTION_FAILED;
+}
+
static HRESULT stream_to_storage(IStream *stm, IStorage **stg)
{
ILockBytes *lockbytes = NULL;
@@ -420,6 +426,8 @@ static const MSIVIEWOPS storages_ops =
STORAGES_fetch_int,
STORAGES_fetch_stream,
STORAGES_get_row,
+ NULL,
+ STORAGES_set_string,
STORAGES_set_row,
STORAGES_insert_row,
STORAGES_delete_row,
diff --git a/dll/win32/msi/streams.c b/dll/win32/msi/streams.c
index 845c3f2608e..ec34e34a85e 100644
--- a/dll/win32/msi/streams.c
+++ b/dll/win32/msi/streams.c
@@ -104,6 +104,12 @@ static UINT STREAMS_fetch_stream(struct tagMSIVIEW *view, UINT row,
UINT col, IS
return ERROR_SUCCESS;
}
+static UINT STREAMS_set_string( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR
*val, int len )
+{
+ ERR("Cannot modify primary key.\n");
+ return ERROR_FUNCTION_FAILED;
+}
+
static UINT STREAMS_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
@@ -366,6 +372,8 @@ static const MSIVIEWOPS streams_ops =
STREAMS_fetch_int,
STREAMS_fetch_stream,
STREAMS_get_row,
+ NULL,
+ STREAMS_set_string,
STREAMS_set_row,
STREAMS_insert_row,
STREAMS_delete_row,
diff --git a/dll/win32/msi/table.c b/dll/win32/msi/table.c
index e4f6b56f18a..a5de8ccf59c 100644
--- a/dll/win32/msi/table.c
+++ b/dll/win32/msi/table.c
@@ -1164,7 +1164,8 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row,
UINT col, ISt
return r;
}
-static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val )
+/* Set a table value, i.e. preadjusted integer or string ID. */
+static UINT table_set_bytes( MSITABLEVIEW *tv, UINT row, UINT col, UINT val )
{
UINT offset, n, i;
@@ -1221,6 +1222,70 @@ static UINT int_to_table_storage( const MSITABLEVIEW *tv, UINT col,
int val, UIN
return ERROR_SUCCESS;
}
+static UINT TABLE_set_int( MSIVIEW *view, UINT row, UINT col, int val )
+{
+ MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
+ UINT r, table_int;
+
+ TRACE("row %u, col %u, val %d.\n", row, col, val);
+
+ if ((r = int_to_table_storage( tv, col, val, &table_int )))
+ return r;
+
+ if (tv->columns[col-1].type & MSITYPE_KEY)
+ {
+ UINT key;
+
+ if ((r = TABLE_fetch_int( view, row, col, &key )))
+ return r;
+ if (key != table_int)
+ {
+ ERR("Cannot modify primary key %s.%s.\n",
+ debugstr_w(tv->table->name),
debugstr_w(tv->columns[col-1].colname));
+ return ERROR_FUNCTION_FAILED;
+ }
+ }
+
+ return table_set_bytes( tv, row, col, table_int );
+}
+
+static UINT TABLE_set_string( MSIVIEW *view, UINT row, UINT col, const WCHAR *val, int
len )
+{
+ MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
+ BOOL persistent;
+ UINT id, r;
+
+ TRACE("row %u, col %u, val %s.\n", row, col, debugstr_wn(val, len));
+
+ persistent = (tv->table->persistent != MSICONDITION_FALSE)
+ && tv->table->data_persistent[row];
+
+ if (val)
+ {
+ r = msi_string2id( tv->db->strings, val, len, &id );
+ if (r != ERROR_SUCCESS)
+ id = msi_add_string( tv->db->strings, val, len, persistent );
+ }
+ else
+ id = 0;
+
+ if (tv->columns[col-1].type & MSITYPE_KEY)
+ {
+ UINT key;
+
+ if ((r = TABLE_fetch_int( view, row, col, &key )))
+ return r;
+ if (key != id)
+ {
+ ERR("Cannot modify primary key %s.%s.\n",
+ debugstr_w(tv->table->name),
debugstr_w(tv->columns[col-1].colname));
+ return ERROR_FUNCTION_FAILED;
+ }
+ }
+
+ return table_set_bytes( tv, row, col, id );
+}
+
static UINT TABLE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
@@ -1402,7 +1467,7 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row,
MSIRECORD *rec, UI
}
}
- r = TABLE_set_int( tv, row, i+1, val );
+ r = table_set_bytes( tv, row, i+1, val );
if ( r != ERROR_SUCCESS )
break;
}
@@ -2060,6 +2125,8 @@ static const MSIVIEWOPS table_ops =
TABLE_fetch_int,
TABLE_fetch_stream,
TABLE_get_row,
+ TABLE_set_int,
+ TABLE_set_string,
TABLE_set_row,
TABLE_insert_row,
TABLE_delete_row,
diff --git a/dll/win32/msi/update.c b/dll/win32/msi/update.c
index ff4e1abf5f5..e61342d11e4 100644
--- a/dll/win32/msi/update.c
+++ b/dll/win32/msi/update.c
@@ -203,6 +203,8 @@ static const MSIVIEWOPS update_ops =
NULL,
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 234ba5e0084..6a10a049a63 100644
--- a/dll/win32/msi/where.c
+++ b/dll/win32/msi/where.c
@@ -271,6 +271,46 @@ static UINT WHERE_get_row( struct tagMSIVIEW *view, UINT row,
MSIRECORD **rec )
return msi_view_get_row( wv->db, view, row, rec );
}
+static UINT WHERE_set_int(struct tagMSIVIEW *view, UINT row, UINT col, int val)
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+ JOINTABLE *table;
+ UINT *rows;
+ UINT r;
+
+ TRACE("view %p, row %u, col %u, val %d.\n", wv, row, col, val );
+
+ 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_int(table->view,
rows[table->table_index], col, val);
+}
+
+static UINT WHERE_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR
*val, int len)
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+ JOINTABLE *table;
+ UINT *rows;
+ UINT r;
+
+ TRACE("view %p, row %u, col %u, val %s.\n", wv, row, col, debugstr_wn(val,
len));
+
+ 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_string(table->view,
rows[table->table_index], col, val, len);
+}
+
static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask
)
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
@@ -1069,6 +1109,8 @@ static const MSIVIEWOPS where_ops =
WHERE_fetch_int,
WHERE_fetch_stream,
WHERE_get_row,
+ WHERE_set_int,
+ WHERE_set_string,
WHERE_set_row,
NULL,
WHERE_delete_row,