Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
ab13c00f
Commit
ab13c00f
authored
Jun 07, 2011
by
Hans Leidekker
Committed by
Alexandre Julliard
Jun 07, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Add support for returning validation errors.
parent
c869192c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
95 additions
and
48 deletions
+95
-48
msipriv.h
dlls/msi/msipriv.h
+2
-0
msiquery.c
dlls/msi/msiquery.c
+29
-29
table.c
dlls/msi/table.c
+30
-19
db.c
dlls/msi/tests/db.c
+34
-0
No files found.
dlls/msi/msipriv.h
View file @
ab13c00f
...
...
@@ -325,6 +325,8 @@ struct tagMSIVIEW
{
MSIOBJECTHDR
hdr
;
const
MSIVIEWOPS
*
ops
;
MSIDBERROR
error
;
const
WCHAR
*
error_column
;
};
struct
msi_dialog_tag
;
...
...
dlls/msi/msiquery.c
View file @
ab13c00f
...
...
@@ -650,66 +650,66 @@ UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode,
return
r
;
}
MSIDBERROR
WINAPI
MsiViewGetErrorW
(
MSIHANDLE
handle
,
LPWSTR
szColumnNameBuffer
,
LPDWORD
pcchBuf
)
MSIDBERROR
WINAPI
MsiViewGetErrorW
(
MSIHANDLE
handle
,
LPWSTR
buffer
,
LPDWORD
buflen
)
{
MSIQUERY
*
query
=
NULL
;
static
const
WCHAR
szError
[]
=
{
0
}
;
MSIDBERROR
r
=
MSIDBERROR_NOERROR
;
MSIQUERY
*
query
;
const
WCHAR
*
column
;
MSIDBERROR
r
;
DWORD
len
;
FIXME
(
"%d %p %p - returns empty error string
\n
"
,
handle
,
szColumnNameBuffer
,
pcchBuf
);
TRACE
(
"%u %p %p
\n
"
,
handle
,
buffer
,
buflen
);
if
(
!
pcchBuf
)
if
(
!
buflen
)
return
MSIDBERROR_INVALIDARG
;
query
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_VIEW
);
if
(
!
query
)
return
MSIDBERROR_INVALIDARG
;
len
=
strlenW
(
szError
);
if
(
szColumnNameBuffer
)
if
((
r
=
query
->
view
->
error
))
column
=
query
->
view
->
error_column
;
else
column
=
szEmpty
;
len
=
strlenW
(
column
);
if
(
buffer
)
{
if
(
*
pcchBuf
>
len
)
lstrcpyW
(
szColumnNameBuffer
,
szError
);
if
(
*
buflen
>
len
)
strcpyW
(
buffer
,
column
);
else
r
=
MSIDBERROR_MOREDATA
;
}
*
pcchBuf
=
len
;
*
buflen
=
len
;
msiobj_release
(
&
query
->
hdr
);
return
r
;
}
MSIDBERROR
WINAPI
MsiViewGetErrorA
(
MSIHANDLE
handle
,
LPSTR
szColumnNameBuffer
,
LPDWORD
pcchBuf
)
MSIDBERROR
WINAPI
MsiViewGetErrorA
(
MSIHANDLE
handle
,
LPSTR
buffer
,
LPDWORD
buflen
)
{
static
const
CHAR
szError
[]
=
{
0
}
;
MSIQUERY
*
query
=
NULL
;
MSIDBERROR
r
=
MSIDBERROR_NOERROR
;
MSIQUERY
*
query
;
const
WCHAR
*
column
;
MSIDBERROR
r
;
DWORD
len
;
FIXME
(
"%d %p %p - returns empty error string
\n
"
,
handle
,
szColumnNameBuffer
,
pcchBuf
);
TRACE
(
"%u %p %p
\n
"
,
handle
,
buffer
,
buflen
);
if
(
!
pcchBuf
)
if
(
!
buflen
)
return
MSIDBERROR_INVALIDARG
;
query
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_VIEW
);
if
(
!
query
)
if
(
!
query
)
return
MSIDBERROR_INVALIDARG
;
len
=
strlen
(
szError
);
if
(
szColumnNameBuffer
)
if
((
r
=
query
->
view
->
error
))
column
=
query
->
view
->
error_column
;
else
column
=
szEmpty
;
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
column
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
buffer
)
{
if
(
*
pcchBuf
>
len
)
lstrcpyA
(
szColumnNameBuffer
,
szError
);
if
(
*
buflen
>=
len
)
WideCharToMultiByte
(
CP_ACP
,
0
,
column
,
-
1
,
buffer
,
*
buflen
,
NULL
,
NULL
);
else
r
=
MSIDBERROR_MOREDATA
;
}
*
pcchBuf
=
len
;
*
buflen
=
len
-
1
;
msiobj_release
(
&
query
->
hdr
);
return
r
;
}
...
...
dlls/msi/table.c
View file @
ab13c00f
...
...
@@ -1579,9 +1579,9 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
return
ERROR_SUCCESS
;
}
static
UINT
msi_table_find_row
(
MSITABLEVIEW
*
tv
,
MSIRECORD
*
rec
,
UINT
*
row
);
static
UINT
msi_table_find_row
(
MSITABLEVIEW
*
tv
,
MSIRECORD
*
rec
,
UINT
*
row
,
UINT
*
column
);
static
UINT
table_validate_new
(
MSITABLEVIEW
*
tv
,
MSIRECORD
*
rec
)
static
UINT
table_validate_new
(
MSITABLEVIEW
*
tv
,
MSIRECORD
*
rec
,
UINT
*
column
)
{
UINT
r
,
row
,
i
;
...
...
@@ -1599,7 +1599,10 @@ static UINT table_validate_new( MSITABLEVIEW *tv, MSIRECORD *rec )
str
=
MSI_RecordGetString
(
rec
,
i
+
1
);
if
(
str
==
NULL
||
str
[
0
]
==
0
)
{
if
(
column
)
*
column
=
i
;
return
ERROR_INVALID_DATA
;
}
}
else
{
...
...
@@ -1607,12 +1610,15 @@ static UINT table_validate_new( MSITABLEVIEW *tv, MSIRECORD *rec )
n
=
MSI_RecordGetInteger
(
rec
,
i
+
1
);
if
(
n
==
MSI_NULL_INTEGER
)
{
if
(
column
)
*
column
=
i
;
return
ERROR_INVALID_DATA
;
}
}
}
/* check there's no duplicate keys */
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
);
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
,
column
);
if
(
r
==
ERROR_SUCCESS
)
return
ERROR_FUNCTION_FAILED
;
...
...
@@ -1685,7 +1691,7 @@ static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec, UINT row,
TRACE
(
"%p %p %s
\n
"
,
tv
,
rec
,
temporary
?
"TRUE"
:
"FALSE"
);
/* check that the key is unique - can we find a matching row? */
r
=
table_validate_new
(
tv
,
rec
);
r
=
table_validate_new
(
tv
,
rec
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
return
ERROR_FUNCTION_FAILED
;
...
...
@@ -1760,7 +1766,7 @@ static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
if
(
!
tv
->
table
)
return
ERROR_INVALID_PARAMETER
;
r
=
msi_table_find_row
(
tv
,
rec
,
&
new_row
);
r
=
msi_table_find_row
(
tv
,
rec
,
&
new_row
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"can't find row to modify
\n
"
);
...
...
@@ -1785,7 +1791,7 @@ static UINT msi_table_assign(struct tagMSIVIEW *view, MSIRECORD *rec)
if
(
!
tv
->
table
)
return
ERROR_INVALID_PARAMETER
;
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
);
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
,
NULL
);
if
(
r
==
ERROR_SUCCESS
)
return
TABLE_set_row
(
view
,
row
,
rec
,
(
1
<<
tv
->
num_cols
)
-
1
);
else
...
...
@@ -1797,7 +1803,7 @@ static UINT modify_delete_row( struct tagMSIVIEW *view, MSIRECORD *rec )
MSITABLEVIEW
*
tv
=
(
MSITABLEVIEW
*
)
view
;
UINT
row
,
r
;
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
);
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
...
...
@@ -1828,7 +1834,7 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD
*
rec
,
UINT
row
)
{
MSITABLEVIEW
*
tv
=
(
MSITABLEVIEW
*
)
view
;
UINT
r
;
UINT
r
,
column
;
TRACE
(
"%p %d %p
\n
"
,
view
,
eModifyMode
,
rec
);
...
...
@@ -1838,18 +1844,24 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
r
=
modify_delete_row
(
view
,
rec
);
break
;
case
MSIMODIFY_VALIDATE_NEW
:
r
=
table_validate_new
(
tv
,
rec
);
r
=
table_validate_new
(
tv
,
rec
,
&
column
);
if
(
r
!=
ERROR_SUCCESS
)
{
tv
->
view
.
error
=
MSIDBERROR_DUPLICATEKEY
;
tv
->
view
.
error_column
=
tv
->
columns
[
column
].
colname
;
r
=
ERROR_INVALID_DATA
;
}
break
;
case
MSIMODIFY_INSERT
:
r
=
table_validate_new
(
tv
,
rec
);
r
=
table_validate_new
(
tv
,
rec
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
break
;
r
=
TABLE_insert_row
(
view
,
rec
,
-
1
,
FALSE
);
break
;
case
MSIMODIFY_INSERT_TEMPORARY
:
r
=
table_validate_new
(
tv
,
rec
);
r
=
table_validate_new
(
tv
,
rec
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
break
;
r
=
TABLE_insert_row
(
view
,
rec
,
-
1
,
TRUE
);
...
...
@@ -2017,7 +2029,7 @@ static UINT TABLE_remove_column(struct tagMSIVIEW *view, LPCWSTR table, UINT num
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
msi_table_find_row
((
MSITABLEVIEW
*
)
columns
,
rec
,
&
row
);
r
=
msi_table_find_row
((
MSITABLEVIEW
*
)
columns
,
rec
,
&
row
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
goto
done
;
...
...
@@ -2294,7 +2306,7 @@ static UINT TABLE_drop(struct tagMSIVIEW *view)
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
msi_table_find_row
((
MSITABLEVIEW
*
)
tables
,
rec
,
&
row
);
r
=
msi_table_find_row
((
MSITABLEVIEW
*
)
tables
,
rec
,
&
row
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
goto
done
;
...
...
@@ -2660,7 +2672,7 @@ static UINT* msi_record_to_row( const MSITABLEVIEW *tv, MSIRECORD *rec )
return
data
;
}
static
UINT
msi_row_matches
(
MSITABLEVIEW
*
tv
,
UINT
row
,
const
UINT
*
data
)
static
UINT
msi_row_matches
(
MSITABLEVIEW
*
tv
,
UINT
row
,
const
UINT
*
data
,
UINT
*
column
)
{
UINT
i
,
r
,
x
,
ret
=
ERROR_FUNCTION_FAILED
;
...
...
@@ -2683,14 +2695,13 @@ static UINT msi_row_matches( MSITABLEVIEW *tv, UINT row, const UINT *data )
ret
=
ERROR_FUNCTION_FAILED
;
break
;
}
if
(
column
)
*
column
=
i
;
ret
=
ERROR_SUCCESS
;
}
return
ret
;
}
static
UINT
msi_table_find_row
(
MSITABLEVIEW
*
tv
,
MSIRECORD
*
rec
,
UINT
*
row
)
static
UINT
msi_table_find_row
(
MSITABLEVIEW
*
tv
,
MSIRECORD
*
rec
,
UINT
*
row
,
UINT
*
column
)
{
UINT
i
,
r
=
ERROR_FUNCTION_FAILED
,
*
data
;
...
...
@@ -2699,7 +2710,7 @@ static UINT msi_table_find_row( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *row )
return
r
;
for
(
i
=
0
;
i
<
tv
->
table
->
row_count
;
i
++
)
{
r
=
msi_row_matches
(
tv
,
i
,
data
);
r
=
msi_row_matches
(
tv
,
i
,
data
,
column
);
if
(
r
==
ERROR_SUCCESS
)
{
*
row
=
i
;
...
...
@@ -2844,7 +2855,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
if
(
TRACE_ON
(
msidb
))
dump_record
(
rec
);
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
);
r
=
msi_table_find_row
(
tv
,
rec
,
&
row
,
NULL
);
if
(
r
==
ERROR_SUCCESS
)
{
if
(
!
mask
)
...
...
dlls/msi/tests/db.c
View file @
ab13c00f
...
...
@@ -754,6 +754,19 @@ static void test_viewmodify(void)
r
=
run_query
(
hdb
,
0
,
query
);
ok
(
r
==
ERROR_SUCCESS
,
"query failed
\n
"
);
query
=
"CREATE TABLE `_Validation` ( "
"`Table` CHAR(32) NOT NULL, `Column` CHAR(32) NOT NULL, "
"`Nullable` CHAR(4) NOT NULL, `MinValue` INT, `MaxValue` INT, "
"`KeyTable` CHAR(255), `KeyColumn` SHORT, `Category` CHAR(32), "
"`Set` CHAR(255), `Description` CHAR(255) PRIMARY KEY `Table`, `Column`)"
;
r
=
run_query
(
hdb
,
0
,
query
);
ok
(
r
==
ERROR_SUCCESS
,
"query failed
\n
"
);
query
=
"INSERT INTO `_Validation` ( `Table`, `Column`, `Nullable` ) "
"VALUES('phone', 'id', 'N')"
;
r
=
run_query
(
hdb
,
0
,
query
);
ok
(
r
==
ERROR_SUCCESS
,
"query failed
\n
"
);
/* check what the error function reports without doing anything */
sz
=
0
;
/* passing NULL as the 3rd param make function to crash on older platforms */
...
...
@@ -808,6 +821,13 @@ static void test_viewmodify(void)
r
=
MsiViewModify
(
hview
,
-
1
,
hrec
);
ok
(
r
==
ERROR_INVALID_DATA
,
"MsiViewModify failed
\n
"
);
sz
=
sizeof
buffer
;
buffer
[
0
]
=
'x'
;
err
=
MsiViewGetError
(
hview
,
buffer
,
&
sz
);
ok
(
err
==
MSIDBERROR_NOERROR
,
"MsiViewGetError return
\n
"
);
ok
(
buffer
[
0
]
==
0
,
"buffer not cleared
\n
"
);
ok
(
sz
==
0
,
"size not zero
\n
"
);
r
=
MsiCloseHandle
(
hrec
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to close record
\n
"
);
...
...
@@ -826,6 +846,20 @@ static void test_viewmodify(void)
r
=
MsiViewModify
(
hview
,
MSIMODIFY_INSERT_TEMPORARY
,
hrec
);
ok
(
r
==
ERROR_SUCCESS
,
"MsiViewModify failed
\n
"
);
/* validate it */
r
=
MsiViewExecute
(
hview
,
0
);
ok
(
r
==
ERROR_SUCCESS
,
"MsiViewExecute failed
\n
"
);
r
=
MsiViewModify
(
hview
,
MSIMODIFY_VALIDATE_NEW
,
hrec
);
ok
(
r
==
ERROR_INVALID_DATA
,
"MsiViewModify failed %u
\n
"
,
r
);
sz
=
sizeof
buffer
;
buffer
[
0
]
=
'x'
;
err
=
MsiViewGetError
(
hview
,
buffer
,
&
sz
);
ok
(
err
==
MSIDBERROR_DUPLICATEKEY
,
"MsiViewGetError returned %u
\n
"
,
err
);
ok
(
!
strcmp
(
buffer
,
"id"
),
"expected
\"
id
\"
c, got
\"
%s
\"\n
"
,
buffer
);
ok
(
sz
==
2
,
"size not 2
\n
"
);
/* insert the same thing again */
r
=
MsiViewExecute
(
hview
,
0
);
ok
(
r
==
ERROR_SUCCESS
,
"MsiViewExecute failed
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment