Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
ab519f2a
Commit
ab519f2a
authored
Jun 30, 2004
by
Mike McCormack
Committed by
Alexandre Julliard
Jun 30, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make the SQL insert query work.
parent
0e42073c
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
292 additions
and
268 deletions
+292
-268
insert.c
dlls/msi/insert.c
+70
-85
msipriv.h
dlls/msi/msipriv.h
+9
-5
query.h
dlls/msi/query.h
+3
-2
record.c
dlls/msi/record.c
+21
-47
select.c
dlls/msi/select.c
+79
-35
sql.y
dlls/msi/sql.y
+20
-17
string.c
dlls/msi/string.c
+56
-42
table.c
dlls/msi/table.c
+2
-2
tokenize.c
dlls/msi/tokenize.c
+4
-0
where.c
dlls/msi/where.c
+28
-33
No files found.
dlls/msi/insert.c
View file @
ab519f2a
...
...
@@ -42,10 +42,9 @@ typedef struct tagMSIINSERTVIEW
{
MSIVIEW
view
;
MSIDATABASE
*
db
;
LPWSTR
name
;
BOOL
bIsTemp
;
string_list
*
cols
;
value_list
*
vals
;
MSIVIEW
*
sv
;
value_list
*
vals
;
/* looks like these may be ignored... */
}
MSIINSERTVIEW
;
static
UINT
INSERT_fetch_int
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
UINT
*
val
)
...
...
@@ -59,131 +58,102 @@ static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
static
UINT
INSERT_execute
(
struct
tagMSIVIEW
*
view
,
MSIHANDLE
record
)
{
#if 0
MSIINSERTVIEW
*
iv
=
(
MSIINSERTVIEW
*
)
view
;
create_col_info *col;
UINT r, nField, row, table_val, column_val;
static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
MSIVIEW *tv = NULL;
TRACE("%p Table %s (%s)\n", iv, debugstr_w(iv->name),
iv->bIsTemp?"temporary":"permanent");
/* only add tables that don't exist already */
if( TABLE_Exists(iv->db, iv->name ) )
return ERROR_BAD_QUERY_SYNTAX;
/* add the name to the _Tables table */
table_val = msi_addstringW( iv->db->strings, 0, iv->name, -1, 1 );
TRACE("New string %s -> %d\n", debugstr_w( iv->name ), table_val );
if( table_val < 0 )
return ERROR_FUNCTION_FAILED;
UINT
n
,
type
,
val
,
r
,
row
,
col_count
=
0
;
MSIVIEW
*
sv
;
r = TABLE_CreateView( iv->db, szTables, &tv );
TRACE("CreateView returned %x\n", r);
if( r )
return r;
TRACE
(
"%p %ld
\n
"
,
iv
,
record
);
r = tv->ops->execute( tv, 0 );
sv
=
iv
->
sv
;
if
(
!
sv
)
return
ERROR_FUNCTION_FAILED
;
r
=
sv
->
ops
->
execute
(
sv
,
0
);
TRACE
(
"tv execute returned %x
\n
"
,
r
);
if
(
r
)
return
r
;
row = -1;
r = tv->ops->insert_row( tv, &row );
TRACE("insert_row returned %x\n", r);
r
=
sv
->
ops
->
get_dimensions
(
sv
,
NULL
,
&
col_count
);
if
(
r
)
goto
err
;
r = tv->ops->set_int( tv, row, 1, table_val );
if( r )
n
=
MsiRecordGetFieldCount
(
record
);
if
(
n
!=
col_count
)
{
ERR
(
"Number of fields do not match
\n
"
);
goto
err
;
tv->ops->delete( tv );
tv = NULL;
/* add each column to the _Columns table */
r = TABLE_CreateView( iv->db, szColumns, &tv );
if( r )
return r;
}
r = tv->ops->execute( tv, 0 );
TRACE("tv execute returned %x\n", r);
row
=
-
1
;
r
=
sv
->
ops
->
insert_row
(
sv
,
&
row
);
TRACE
(
"insert_row returned %x
\n
"
,
r
);
if
(
r
)
return
r;
goto
er
r
;
/*
* need to set the table, column number, col name and type
* for each column we enter in the table
*/
nField = 1;
for( col = iv->col_info; col; col = col->next )
for
(
n
=
1
;
n
<=
col_count
;
n
++
)
{
row = -1;
r = tv->ops->insert_row( tv, &row );
if( r )
goto err;
column_val = msi_addstringW( iv->db->strings, 0, col->colname, -1, 1 );
TRACE("New string %s -> %d\n", debugstr_w( col->colname ), column_val );
if( column_val < 0 )
break;
r = tv->ops->set_int( tv, row, 1, table_val );
if( r )
break;
r = tv->ops->set_int( tv, row, 2, 0x8000|nField );
if( r )
break;
r = tv->ops->set_int( tv, row, 3, column_val );
r
=
sv
->
ops
->
get_column_info
(
sv
,
n
,
NULL
,
&
type
);
if
(
r
)
break
;
r = tv->ops->set_int( tv, row, 4, 0x8000|col->type );
if
(
type
&
MSITYPE_STRING
)
{
const
WCHAR
*
str
=
MSI_RecordGetString
(
record
,
n
);
val
=
msi_addstringW
(
iv
->
db
->
strings
,
0
,
str
,
-
1
,
1
);
}
else
val
=
MsiRecordGetInteger
(
record
,
n
++
);
r
=
sv
->
ops
->
set_int
(
sv
,
row
,
1
,
val
);
if
(
r
)
break
;
}
if( !col )
r = ERROR_SUCCESS;
err:
/* FIXME: remove values from the string table on error */
if( tv )
tv->ops->delete( tv );
return r;
#else
return
ERROR_FUNCTION_FAILED
;
#endif
return
ERROR_SUCCESS
;
}
static
UINT
INSERT_close
(
struct
tagMSIVIEW
*
view
)
{
MSIINSERTVIEW
*
iv
=
(
MSIINSERTVIEW
*
)
view
;
MSIVIEW
*
sv
;
TRACE
(
"%p
\n
"
,
iv
);
return
ERROR_SUCCESS
;
sv
=
iv
->
sv
;
if
(
!
sv
)
return
ERROR_FUNCTION_FAILED
;
return
sv
->
ops
->
close
(
sv
);
}
static
UINT
INSERT_get_dimensions
(
struct
tagMSIVIEW
*
view
,
UINT
*
rows
,
UINT
*
cols
)
{
MSIINSERTVIEW
*
iv
=
(
MSIINSERTVIEW
*
)
view
;
MSIVIEW
*
sv
;
TRACE
(
"%p %p %p
\n
"
,
iv
,
rows
,
cols
);
return
ERROR_FUNCTION_FAILED
;
sv
=
iv
->
sv
;
if
(
!
sv
)
return
ERROR_FUNCTION_FAILED
;
return
sv
->
ops
->
get_dimensions
(
sv
,
rows
,
cols
);
}
static
UINT
INSERT_get_column_info
(
struct
tagMSIVIEW
*
view
,
UINT
n
,
LPWSTR
*
name
,
UINT
*
type
)
{
MSIINSERTVIEW
*
iv
=
(
MSIINSERTVIEW
*
)
view
;
MSIVIEW
*
sv
;
TRACE
(
"%p %d %p %p
\n
"
,
iv
,
n
,
name
,
type
);
return
ERROR_FUNCTION_FAILED
;
sv
=
iv
->
sv
;
if
(
!
sv
)
return
ERROR_FUNCTION_FAILED
;
return
sv
->
ops
->
get_column_info
(
sv
,
n
,
name
,
type
);
}
static
UINT
INSERT_modify
(
struct
tagMSIVIEW
*
view
,
MSIMODIFY
eModifyMode
,
MSIHANDLE
hrec
)
...
...
@@ -198,12 +168,14 @@ static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHA
static
UINT
INSERT_delete
(
struct
tagMSIVIEW
*
view
)
{
MSIINSERTVIEW
*
iv
=
(
MSIINSERTVIEW
*
)
view
;
MSIVIEW
*
sv
;
TRACE
(
"%p
\n
"
,
iv
);
delete_string_list
(
iv
->
cols
);
sv
=
iv
->
sv
;
if
(
sv
)
sv
->
ops
->
delete
(
sv
);
delete_value_list
(
iv
->
vals
);
HeapFree
(
GetProcessHeap
(),
0
,
iv
->
name
);
HeapFree
(
GetProcessHeap
(),
0
,
iv
);
return
ERROR_SUCCESS
;
...
...
@@ -227,20 +199,33 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
string_list
*
columns
,
value_list
*
values
,
BOOL
temp
)
{
MSIINSERTVIEW
*
iv
=
NULL
;
UINT
r
;
MSIVIEW
*
tv
=
NULL
,
*
sv
=
NULL
;
TRACE
(
"%p
\n
"
,
iv
);
r
=
TABLE_CreateView
(
db
,
table
,
&
tv
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
SELECT_CreateView
(
db
,
&
sv
,
tv
,
columns
);
if
(
r
!=
ERROR_SUCCESS
)
{
if
(
tv
)
tv
->
ops
->
delete
(
tv
);
return
r
;
}
iv
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
*
iv
);
if
(
!
iv
)
return
ERROR_FUNCTION_FAILED
;
/* fill the structure */
iv
->
view
.
ops
=
&
insert_ops
;
iv
->
db
=
db
;
iv
->
name
=
table
;
/* FIXME: strdupW it? */
iv
->
cols
=
columns
;
iv
->
vals
=
values
;
iv
->
bIsTemp
=
temp
;
iv
->
sv
=
sv
;
*
view
=
(
MSIVIEW
*
)
iv
;
return
ERROR_SUCCESS
;
...
...
dlls/msi/msipriv.h
View file @
ab519f2a
...
...
@@ -182,13 +182,13 @@ extern HRESULT init_string_table( IStorage *stg );
/* string table functions */
extern
BOOL
msi_addstring
(
string_table
*
st
,
UINT
string_no
,
const
CHAR
*
data
,
UINT
len
,
UINT
refcount
);
extern
BOOL
msi_addstringW
(
string_table
*
st
,
UINT
string_no
,
const
WCHAR
*
data
,
UINT
len
,
UINT
refcount
);
extern
BOOL
msi_addstring
(
string_table
*
st
,
UINT
string_no
,
const
CHAR
*
data
,
int
len
,
UINT
refcount
);
extern
BOOL
msi_addstringW
(
string_table
*
st
,
UINT
string_no
,
const
WCHAR
*
data
,
int
len
,
UINT
refcount
);
extern
UINT
msi_id2stringW
(
string_table
*
st
,
UINT
string_no
,
LPWSTR
buffer
,
UINT
*
sz
);
extern
UINT
msi_id2stringA
(
string_table
*
st
,
UINT
string_no
,
LPSTR
buffer
,
UINT
*
sz
);
extern
LPWSTR
MSI_makestring
(
MSIDATABASE
*
db
,
UINT
stringid
);
extern
UINT
msi_string2id
(
string_table
*
st
,
LPCWSTR
buffer
,
UINT
*
id
);
extern
UINT
msi_string2id
W
(
string_table
*
st
,
LPCWSTR
buffer
,
UINT
*
id
);
extern
UINT
msi_string2idA
(
string_table
*
st
,
LPCSTR
str
,
UINT
*
id
);
extern
string_table
*
msi_init_stringtable
(
int
entries
,
UINT
codepage
);
extern
VOID
msi_destroy_stringtable
(
string_table
*
st
);
...
...
@@ -196,7 +196,7 @@ extern UINT msi_string_count( string_table *st );
extern
UINT
msi_id_refcount
(
string_table
*
st
,
UINT
i
);
extern
UINT
msi_string_totalsize
(
string_table
*
st
);
extern
UINT
msi_strcmp
(
string_table
*
st
,
UINT
lval
,
UINT
rval
,
UINT
*
res
);
extern
const
char
*
msi_string_lookup_id
(
string_table
*
st
,
UINT
id
);
extern
const
WCHAR
*
msi_string_lookup_id
(
string_table
*
st
,
UINT
id
);
UINT
VIEW_find_column
(
MSIVIEW
*
view
,
LPWSTR
name
,
UINT
*
n
);
...
...
@@ -208,11 +208,15 @@ UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
UINT
ACTION_DoTopLevelINSTALL
(
MSIHANDLE
hPackage
,
LPCWSTR
szPackagePath
,
LPCWSTR
szCommandLine
);
/* record internals */
extern
UINT
WINAPI
MSI_RecordSetIStream
(
MSIHANDLE
handle
,
unsigned
int
iField
,
IStream
*
stm
);
extern
const
WCHAR
*
MSI_RecordGetString
(
MSIHANDLE
handle
,
unsigned
int
iField
);
/* stream internals */
extern
UINT
get_raw_stream
(
MSIHANDLE
hdb
,
LPCWSTR
stname
,
IStream
**
stm
);
extern
UINT
db_get_raw_stream
(
MSIDATABASE
*
db
,
LPCWSTR
stname
,
IStream
**
stm
);
extern
void
enum_stream_names
(
IStorage
*
stg
);
#endif
/* __WINE_MSI_PRIVATE__ */
dlls/msi/query.h
View file @
ab519f2a
...
...
@@ -50,6 +50,7 @@
#define EXPR_UVAL 6
#define EXPR_STRCMP 7
#define EXPR_UTF8 8
#define EXPR_WILDCARD 9
struct
sql_str
{
LPCWSTR
data
;
...
...
@@ -101,8 +102,8 @@ UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phView);
UINT
TABLE_CreateView
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSIVIEW
**
view
);
UINT
SELECT_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
);
UINT
SELECT_AddColumn
(
MSIVIEW
*
select
,
LPWSTR
name
);
UINT
SELECT_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
,
string_list
*
columns
);
UINT
DISTINCT_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
);
...
...
dlls/msi/record.c
View file @
ab519f2a
...
...
@@ -48,7 +48,6 @@ typedef struct tagMSIFIELD
union
{
INT
iVal
;
LPSTR
szVal
;
LPWSTR
szwVal
;
IStream
*
stream
;
}
u
;
...
...
@@ -67,9 +66,6 @@ void MSI_FreeField( MSIFIELD *field )
case
MSIFIELD_NULL
:
case
MSIFIELD_INT
:
break
;
case
MSIFIELD_STR
:
HeapFree
(
GetProcessHeap
(),
0
,
field
->
u
.
szVal
);
break
;
case
MSIFIELD_WSTR
:
HeapFree
(
GetProcessHeap
(),
0
,
field
->
u
.
szwVal
);
break
;
...
...
@@ -125,29 +121,6 @@ unsigned int WINAPI MsiRecordGetFieldCount( MSIHANDLE handle )
return
rec
->
count
;
}
static
BOOL
string2intA
(
LPCSTR
str
,
int
*
out
)
{
int
x
=
0
;
LPCSTR
p
=
str
;
if
(
*
p
==
'-'
)
/* skip the minus sign */
p
++
;
while
(
*
p
)
{
if
(
(
*
p
<
'0'
)
||
(
*
p
>
'9'
)
)
return
FALSE
;
x
*=
10
;
x
+=
(
*
p
-
'0'
);
p
++
;
}
if
(
str
[
0
]
==
'-'
)
/* check if it's negative */
x
=
-
x
;
*
out
=
x
;
return
TRUE
;
}
static
BOOL
string2intW
(
LPCWSTR
str
,
int
*
out
)
{
int
x
=
0
;
...
...
@@ -189,10 +162,6 @@ int WINAPI MsiRecordGetInteger( MSIHANDLE handle, unsigned int iField)
{
case
MSIFIELD_INT
:
return
rec
->
fields
[
iField
].
u
.
iVal
;
case
MSIFIELD_STR
:
if
(
string2intA
(
rec
->
fields
[
iField
].
u
.
szVal
,
&
ret
)
)
return
ret
;
return
MSI_NULL_INTEGER
;
case
MSIFIELD_WSTR
:
if
(
string2intW
(
rec
->
fields
[
iField
].
u
.
szwVal
,
&
ret
)
)
return
ret
;
...
...
@@ -286,10 +255,6 @@ UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField,
len
=
lstrlenA
(
buffer
);
lstrcpynA
(
szValue
,
buffer
,
*
pcchValue
);
break
;
case
MSIFIELD_STR
:
len
=
lstrlenA
(
rec
->
fields
[
iField
].
u
.
szVal
);
lstrcpynA
(
szValue
,
rec
->
fields
[
iField
].
u
.
szVal
,
*
pcchValue
);
break
;
case
MSIFIELD_WSTR
:
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
rec
->
fields
[
iField
].
u
.
szwVal
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
...
...
@@ -308,6 +273,20 @@ UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField,
return
ret
;
}
const
WCHAR
*
MSI_RecordGetString
(
MSIHANDLE
handle
,
unsigned
int
iField
)
{
MSIRECORD
*
rec
;
rec
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_RECORD
);
if
(
!
rec
)
return
NULL
;
if
(
iField
>
rec
->
count
)
return
NULL
;
return
rec
->
fields
[
iField
].
u
.
szwVal
;
}
UINT
WINAPI
MsiRecordGetStringW
(
MSIHANDLE
handle
,
unsigned
int
iField
,
LPWSTR
szValue
,
DWORD
*
pcchValue
)
{
...
...
@@ -337,12 +316,6 @@ UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, unsigned int iField,
len
=
lstrlenW
(
rec
->
fields
[
iField
].
u
.
szwVal
);
lstrcpynW
(
szValue
,
rec
->
fields
[
iField
].
u
.
szwVal
,
*
pcchValue
);
break
;
case
MSIFIELD_STR
:
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
rec
->
fields
[
iField
].
u
.
szVal
,
-
1
,
NULL
,
0
);
MultiByteToWideChar
(
CP_ACP
,
0
,
rec
->
fields
[
iField
].
u
.
szVal
,
-
1
,
szValue
,
*
pcchValue
);
break
;
default:
break
;
}
...
...
@@ -363,7 +336,8 @@ UINT WINAPI MsiRecordDataSize(MSIHANDLE hRecord, unsigned int iField)
UINT
WINAPI
MsiRecordSetStringA
(
MSIHANDLE
handle
,
unsigned
int
iField
,
LPCSTR
szValue
)
{
MSIRECORD
*
rec
;
LPSTR
str
;
LPWSTR
str
;
UINT
len
;
TRACE
(
"%ld %d %s
\n
"
,
handle
,
iField
,
debugstr_a
(
szValue
));
...
...
@@ -374,12 +348,12 @@ UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, unsigned int iField, LPCSTR s
if
(
iField
>
rec
->
count
)
return
ERROR_INVALID_FIELD
;
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
lstrlenA
(
szValue
)
+
1
)
*
sizeof
str
[
0
]
);
lstrcpyA
(
str
,
szValue
);
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
szValue
,
-
1
,
NULL
,
0
);
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
MultiByteToWideChar
(
CP_ACP
,
0
,
szValue
,
-
1
,
str
,
len
);
MSI_FreeField
(
&
rec
->
fields
[
iField
]
);
rec
->
fields
[
iField
].
type
=
MSIFIELD_STR
;
rec
->
fields
[
iField
].
u
.
szVal
=
str
;
rec
->
fields
[
iField
].
type
=
MSIFIELD_
W
STR
;
rec
->
fields
[
iField
].
u
.
sz
w
Val
=
str
;
return
0
;
}
...
...
dlls/msi/select.c
View file @
ab519f2a
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2002 Mike McCormack for CodeWeavers
* Copyright 2002
-2004
Mike McCormack for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -65,6 +65,35 @@ static UINT SELECT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
return
sv
->
table
->
ops
->
fetch_int
(
sv
->
table
,
row
,
col
,
val
);
}
static
UINT
SELECT_set_int
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
UINT
val
)
{
MSISELECTVIEW
*
sv
=
(
MSISELECTVIEW
*
)
view
;
TRACE
(
"%p %d %d %04x
\n
"
,
sv
,
row
,
col
,
val
);
if
(
!
sv
->
table
)
return
ERROR_FUNCTION_FAILED
;
if
(
(
col
==
0
)
||
(
col
>
sv
->
num_cols
)
)
return
ERROR_FUNCTION_FAILED
;
col
=
sv
->
cols
[
col
-
1
];
return
sv
->
table
->
ops
->
set_int
(
sv
->
table
,
row
,
col
,
val
);
}
static
UINT
SELECT_insert_row
(
struct
tagMSIVIEW
*
view
,
UINT
*
num
)
{
MSISELECTVIEW
*
sv
=
(
MSISELECTVIEW
*
)
view
;
TRACE
(
"%p %p
\n
"
,
sv
,
num
);
if
(
!
sv
->
table
)
return
ERROR_FUNCTION_FAILED
;
return
sv
->
table
->
ops
->
insert_row
(
sv
->
table
,
num
);
}
static
UINT
SELECT_execute
(
struct
tagMSIVIEW
*
view
,
MSIHANDLE
record
)
{
MSISELECTVIEW
*
sv
=
(
MSISELECTVIEW
*
)
view
;
...
...
@@ -152,8 +181,8 @@ static UINT SELECT_delete( struct tagMSIVIEW *view )
MSIVIEWOPS
select_ops
=
{
SELECT_fetch_int
,
NULL
,
NULL
,
SELECT_set_int
,
SELECT_insert_row
,
SELECT_execute
,
SELECT_close
,
SELECT_get_dimensions
,
...
...
@@ -162,39 +191,8 @@ MSIVIEWOPS select_ops =
SELECT_delete
};
UINT
SELECT_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
tabl
e
)
static
UINT
SELECT_AddColumn
(
MSISELECTVIEW
*
sv
,
LPWSTR
nam
e
)
{
MSISELECTVIEW
*
sv
=
NULL
;
UINT
count
=
0
,
r
;
TRACE
(
"%p
\n
"
,
sv
);
r
=
table
->
ops
->
get_dimensions
(
table
,
NULL
,
&
count
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"can't get table dimensions
\n
"
);
return
r
;
}
sv
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
*
sv
+
count
*
sizeof
(
UINT
)
);
if
(
!
sv
)
return
ERROR_FUNCTION_FAILED
;
/* fill the structure */
sv
->
view
.
ops
=
&
select_ops
;
sv
->
db
=
db
;
sv
->
table
=
table
;
sv
->
num_cols
=
0
;
sv
->
max_cols
=
count
;
*
view
=
(
MSIVIEW
*
)
sv
;
return
ERROR_SUCCESS
;
}
UINT
SELECT_AddColumn
(
MSIVIEW
*
view
,
LPWSTR
name
)
{
MSISELECTVIEW
*
sv
=
(
MSISELECTVIEW
*
)
view
;
UINT
r
,
n
=
0
;
MSIVIEW
*
table
;
...
...
@@ -226,3 +224,49 @@ UINT SELECT_AddColumn( MSIVIEW *view, LPWSTR name )
return
ERROR_SUCCESS
;
}
UINT
SELECT_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
,
string_list
*
columns
)
{
MSISELECTVIEW
*
sv
=
NULL
;
UINT
count
=
0
,
r
;
TRACE
(
"%p
\n
"
,
sv
);
r
=
table
->
ops
->
get_dimensions
(
table
,
NULL
,
&
count
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"can't get table dimensions
\n
"
);
return
r
;
}
sv
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
*
sv
+
count
*
sizeof
(
UINT
)
);
if
(
!
sv
)
return
ERROR_FUNCTION_FAILED
;
/* fill the structure */
sv
->
view
.
ops
=
&
select_ops
;
sv
->
db
=
db
;
sv
->
table
=
table
;
sv
->
num_cols
=
0
;
sv
->
max_cols
=
count
;
while
(
columns
)
{
r
=
SELECT_AddColumn
(
sv
,
columns
->
string
);
if
(
r
)
break
;
columns
=
columns
->
next
;
}
if
(
r
!=
ERROR_SUCCESS
)
{
sv
->
view
.
ops
->
delete
(
&
sv
->
view
);
sv
=
NULL
;
}
*
view
=
&
sv
->
view
;
return
r
;
}
dlls/msi/sql.y
View file @
ab519f2a
...
...
@@ -64,6 +64,7 @@ static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
static struct expr * EXPR_column( LPWSTR );
static struct expr * EXPR_ival( struct sql_str *);
static struct expr * EXPR_sval( struct sql_str *);
static struct expr * EXPR_wildcard();
%}
...
...
@@ -114,7 +115,7 @@ static struct expr * EXPR_sval( struct sql_str *);
%token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE
%token TK_UPDATE TK_UPLUS TK_USING
%token TK_VACUUM TK_VALUES TK_VIEW
%token TK_WHEN TK_WHERE
%token TK_WHEN TK_WHERE
TK_WILDCARD
/*
* These are extra tokens used by the lexer but never seen by the
...
...
@@ -460,7 +461,11 @@ expr:
val:
column_val
| const_val
;
| TK_WILDCARD
{
$$ = EXPR_wildcard();
}
;
constlist:
const_val
...
...
@@ -603,21 +608,9 @@ static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in,
{
MSIVIEW *view = NULL;
SELECT_CreateView( db, &view, in );
if( view )
{
string_list *x = columns;
while( x )
{
string_list *t = x->next;
SELECT_AddColumn( view, x->string );
HeapFree( GetProcessHeap(), 0, x->string );
HeapFree( GetProcessHeap(), 0, x );
x = t;
}
}
else
SELECT_CreateView( db, &view, in, columns );
delete_string_list( columns );
if( !view )
ERR("Error creating select query\n");
return view;
}
...
...
@@ -641,6 +634,16 @@ static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in,
return view;
}
static struct expr * EXPR_wildcard()
{
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
if( e )
{
e->type = EXPR_WILDCARD;
}
return e;
}
static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r )
{
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
...
...
dlls/msi/string.c
View file @
ab519f2a
...
...
@@ -25,6 +25,7 @@
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
...
...
@@ -40,7 +41,7 @@ typedef struct _msistring
{
UINT
hash
;
UINT
refcount
;
LPSTR
str
;
LP
W
STR
str
;
}
msistring
;
struct
string_table
...
...
@@ -51,7 +52,7 @@ struct string_table
msistring
*
strings
;
/* an array of strings (in the tree) */
};
static
int
msistring_makehash
(
const
char
*
str
)
static
int
msistring_makehash
(
const
WCHAR
*
str
)
{
int
hash
=
0
;
...
...
@@ -103,6 +104,8 @@ static int st_find_free_entry( string_table *st )
int
i
,
sz
;
msistring
*
p
;
TRACE
(
"%p
\n
"
,
st
);
for
(
i
=
st
->
freeslot
;
i
<
st
->
count
;
i
++
)
if
(
!
st
->
strings
[
i
].
refcount
)
return
i
;
...
...
@@ -131,8 +134,10 @@ static void st_mark_entry_used( string_table *st, int n )
st
->
freeslot
=
n
+
1
;
}
int
msi_addstring
(
string_table
*
st
,
UINT
n
,
const
CHAR
*
data
,
UINT
len
,
UINT
refcount
)
int
msi_addstring
(
string_table
*
st
,
UINT
n
,
const
CHAR
*
data
,
int
len
,
UINT
refcount
)
{
int
sz
;
if
(
!
data
[
0
]
)
return
0
;
if
(
n
>
0
)
...
...
@@ -154,12 +159,13 @@ int msi_addstring( string_table *st, UINT n, const CHAR *data, UINT len, UINT re
/* allocate a new string */
if
(
len
<
0
)
len
=
strlen
(
data
);
st
->
strings
[
n
].
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
+
1
);
len
=
strlen
(
data
);
sz
=
MultiByteToWideChar
(
st
->
codepage
,
0
,
data
,
len
,
NULL
,
0
);
st
->
strings
[
n
].
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
sz
+
1
)
*
sizeof
(
WCHAR
)
);
if
(
!
st
->
strings
[
n
].
str
)
return
-
1
;
memcpy
(
st
->
strings
[
n
].
str
,
data
,
len
);
st
->
strings
[
n
].
str
[
len
]
=
0
;
MultiByteToWideChar
(
st
->
codepage
,
0
,
data
,
len
,
st
->
strings
[
n
].
str
,
sz
);
st
->
strings
[
n
].
str
[
sz
]
=
0
;
st
->
strings
[
n
].
refcount
=
1
;
st
->
strings
[
n
].
hash
=
msistring_makehash
(
st
->
strings
[
n
].
str
);
...
...
@@ -168,10 +174,8 @@ int msi_addstring( string_table *st, UINT n, const CHAR *data, UINT len, UINT re
return
n
;
}
int
msi_addstringW
(
string_table
*
st
,
UINT
n
,
const
WCHAR
*
data
,
UINT
len
,
UINT
refcount
)
int
msi_addstringW
(
string_table
*
st
,
UINT
n
,
const
WCHAR
*
data
,
int
len
,
UINT
refcount
)
{
int
sz
;
/* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */
if
(
!
data
[
0
]
)
...
...
@@ -183,7 +187,7 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, UINT len, UINT
}
else
{
if
(
ERROR_SUCCESS
==
msi_string2id
(
st
,
data
,
&
n
)
)
if
(
ERROR_SUCCESS
==
msi_string2id
W
(
st
,
data
,
&
n
)
)
{
st
->
strings
[
n
].
refcount
++
;
return
n
;
...
...
@@ -194,13 +198,16 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, UINT len, UINT
}
/* allocate a new string */
sz
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
data
,
len
,
NULL
,
0
,
NULL
,
NULL
);
st
->
strings
[
n
].
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
+
1
);
if
(
len
<
0
)
len
=
strlenW
(
data
);
TRACE
(
"%s, n = %d len = %d
\n
"
,
debugstr_w
(
data
),
n
,
len
);
st
->
strings
[
n
].
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
len
+
1
)
*
sizeof
(
WCHAR
)
);
if
(
!
st
->
strings
[
n
].
str
)
return
-
1
;
WideCharToMultiByte
(
st
->
codepage
,
0
,
data
,
len
,
st
->
strings
[
n
].
str
,
sz
,
NULL
,
NULL
);
st
->
strings
[
n
].
str
[
sz
]
=
0
;
TRACE
(
"%d
\n
"
,
__LINE__
);
memcpy
(
st
->
strings
[
n
].
str
,
data
,
len
*
sizeof
(
WCHAR
)
);
st
->
strings
[
n
].
str
[
len
]
=
0
;
st
->
strings
[
n
].
refcount
=
1
;
st
->
strings
[
n
].
hash
=
msistring_makehash
(
st
->
strings
[
n
].
str
);
...
...
@@ -210,10 +217,11 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, UINT len, UINT
}
/* find the string identified by an id - return null if there's none */
const
char
*
msi_string_lookup_id
(
string_table
*
st
,
UINT
id
)
const
WCHAR
*
msi_string_lookup_id
(
string_table
*
st
,
UINT
id
)
{
static
const
WCHAR
zero
[]
=
{
0
};
if
(
id
==
0
)
return
""
;
return
zero
;
if
(
id
>=
st
->
count
)
return
NULL
;
...
...
@@ -239,7 +247,7 @@ const char *msi_string_lookup_id( string_table *st, UINT id )
UINT
msi_id2stringW
(
string_table
*
st
,
UINT
id
,
LPWSTR
buffer
,
UINT
*
sz
)
{
UINT
len
;
const
char
*
str
;
const
WCHAR
*
str
;
TRACE
(
"Finding string %d of %d
\n
"
,
id
,
st
->
count
);
...
...
@@ -247,7 +255,7 @@ UINT msi_id2stringW( string_table *st, UINT id, LPWSTR buffer, UINT *sz )
if
(
!
str
)
return
ERROR_FUNCTION_FAILED
;
len
=
MultiByteToWideChar
(
st
->
codepage
,
0
,
str
,
-
1
,
NULL
,
0
);
len
=
strlenW
(
str
)
+
1
;
if
(
!
buffer
)
{
...
...
@@ -255,7 +263,10 @@ UINT msi_id2stringW( string_table *st, UINT id, LPWSTR buffer, UINT *sz )
return
ERROR_SUCCESS
;
}
*
sz
=
MultiByteToWideChar
(
st
->
codepage
,
0
,
str
,
-
1
,
buffer
,
*
sz
);
if
(
*
sz
<
len
)
*
sz
=
len
;
memcpy
(
buffer
,
str
,
(
*
sz
)
*
sizeof
(
WCHAR
)
);
*
sz
=
len
;
return
ERROR_SUCCESS
;
}
...
...
@@ -275,7 +286,7 @@ UINT msi_id2stringW( string_table *st, UINT id, LPWSTR buffer, UINT *sz )
UINT
msi_id2stringA
(
string_table
*
st
,
UINT
id
,
LPSTR
buffer
,
UINT
*
sz
)
{
UINT
len
;
const
char
*
str
;
const
WCHAR
*
str
;
TRACE
(
"Finding string %d of %d
\n
"
,
id
,
st
->
count
);
...
...
@@ -283,7 +294,7 @@ UINT msi_id2stringA( string_table *st, UINT id, LPSTR buffer, UINT *sz )
if
(
!
str
)
return
ERROR_FUNCTION_FAILED
;
len
=
strlen
(
str
)
+
1
;
len
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
str
,
-
1
,
NULL
,
0
,
NULL
,
NULL
)
;
if
(
!
buffer
)
{
...
...
@@ -291,22 +302,19 @@ UINT msi_id2stringA( string_table *st, UINT id, LPSTR buffer, UINT *sz )
return
ERROR_SUCCESS
;
}
if
(
*
sz
<
len
)
*
sz
=
len
;
memcpy
(
buffer
,
str
,
*
sz
);
*
sz
=
len
;
*
sz
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
str
,
-
1
,
buffer
,
*
sz
,
NULL
,
NULL
);
return
ERROR_SUCCESS
;
}
/*
* msi_string2id
A
* msi_string2id
W
*
* [in] st - pointer to the string table
* [in] str -
UTF8
string to find in the string table
* [in] str - string to find in the string table
* [out] id - id of the string, if found
*/
UINT
msi_string2id
A
(
string_table
*
st
,
LPC
STR
str
,
UINT
*
id
)
UINT
msi_string2id
W
(
string_table
*
st
,
LPCW
STR
str
,
UINT
*
id
)
{
int
hash
;
UINT
i
,
r
=
ERROR_INVALID_PARAMETER
;
...
...
@@ -315,7 +323,7 @@ UINT msi_string2idA( string_table *st, LPCSTR str, UINT *id )
for
(
i
=
0
;
i
<
st
->
count
;
i
++
)
{
if
(
(
st
->
strings
[
i
].
hash
==
hash
)
&&
!
strcmp
(
st
->
strings
[
i
].
str
,
str
)
)
!
strcmp
W
(
st
->
strings
[
i
].
str
,
str
)
)
{
r
=
ERROR_SUCCESS
;
*
id
=
i
;
...
...
@@ -326,13 +334,13 @@ UINT msi_string2idA( string_table *st, LPCSTR str, UINT *id )
return
r
;
}
UINT
msi_string2id
(
string_table
*
st
,
LPCW
STR
buffer
,
UINT
*
id
)
UINT
msi_string2id
A
(
string_table
*
st
,
LPC
STR
buffer
,
UINT
*
id
)
{
DWORD
sz
;
UINT
r
=
ERROR_INVALID_PARAMETER
;
LPSTR
str
;
LP
W
STR
str
;
TRACE
(
"Finding string %s in string table
\n
"
,
debugstr_
w
(
buffer
)
);
TRACE
(
"Finding string %s in string table
\n
"
,
debugstr_
a
(
buffer
)
);
if
(
buffer
[
0
]
==
0
)
{
...
...
@@ -340,15 +348,15 @@ UINT msi_string2id( string_table *st, LPCWSTR buffer, UINT *id )
return
ERROR_SUCCESS
;
}
sz
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
buffer
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
sz
=
MultiByteToWideChar
(
st
->
codepage
,
0
,
buffer
,
-
1
,
NULL
,
0
);
if
(
sz
<=
0
)
return
r
;
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
);
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
*
sizeof
(
WCHAR
)
);
if
(
!
str
)
return
ERROR_NOT_ENOUGH_MEMORY
;
WideCharToMultiByte
(
st
->
codepage
,
0
,
buffer
,
-
1
,
str
,
sz
,
NULL
,
NULL
);
MultiByteToWideChar
(
st
->
codepage
,
0
,
buffer
,
-
1
,
str
,
sz
);
r
=
msi_string2id
A
(
st
,
str
,
id
);
r
=
msi_string2id
W
(
st
,
str
,
id
);
if
(
str
)
HeapFree
(
GetProcessHeap
(),
0
,
str
);
...
...
@@ -357,7 +365,7 @@ UINT msi_string2id( string_table *st, LPCWSTR buffer, UINT *id )
UINT
msi_strcmp
(
string_table
*
st
,
UINT
lval
,
UINT
rval
,
UINT
*
res
)
{
const
char
*
l_str
,
*
r_str
;
/* utf8 */
const
WCHAR
*
l_str
,
*
r_str
;
l_str
=
msi_string_lookup_id
(
st
,
lval
);
if
(
!
l_str
)
...
...
@@ -368,7 +376,7 @@ UINT msi_strcmp( string_table *st, UINT lval, UINT rval, UINT *res )
return
ERROR_INVALID_PARAMETER
;
/* does this do the right thing for all UTF-8 strings? */
*
res
=
strcmp
(
l_str
,
r_str
);
*
res
=
strcmp
W
(
l_str
,
r_str
);
return
ERROR_SUCCESS
;
}
...
...
@@ -387,12 +395,18 @@ UINT msi_id_refcount( string_table *st, UINT i )
UINT
msi_string_totalsize
(
string_table
*
st
)
{
UINT
size
=
0
,
i
;
UINT
size
=
0
,
i
,
len
;
for
(
i
=
0
;
i
<
st
->
count
;
i
++
)
{
if
(
st
->
strings
[
i
].
str
)
size
+=
strlen
(
st
->
strings
[
i
].
str
);
{
len
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
st
->
strings
[
i
].
str
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
len
)
len
--
;
size
+=
len
;
}
}
return
size
;
}
dlls/msi/table.c
View file @
ab519f2a
...
...
@@ -935,7 +935,7 @@ static UINT get_tablecolumns( MSIDATABASE *db,
}
/* convert table and column names to IDs from the string table */
r
=
msi_string2id
(
db
->
strings
,
szTableName
,
&
table_id
);
r
=
msi_string2id
W
(
db
->
strings
,
szTableName
,
&
table_id
);
if
(
r
!=
ERROR_SUCCESS
)
{
release_table
(
db
,
table
);
...
...
@@ -998,7 +998,7 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name )
if
(
!
lstrcmpW
(
name
,
szColumns
)
)
return
TRUE
;
r
=
msi_string2id
(
db
->
strings
,
name
,
&
table_id
);
r
=
msi_string2id
W
(
db
->
strings
,
name
,
&
table_id
);
if
(
r
!=
ERROR_SUCCESS
)
{
TRACE
(
"Couldn't find id for %s
\n
"
,
debugstr_w
(
name
));
...
...
dlls/msi/tokenize.c
View file @
ab519f2a
...
...
@@ -318,6 +318,10 @@ int sqliteGetToken(const WCHAR *z, int *tokenType){
return
2
;
}
}
case
'?'
:
{
*
tokenType
=
TK_WILDCARD
;
return
1
;
}
case
','
:
{
*
tokenType
=
TK_COMMA
;
return
1
;
...
...
dlls/msi/where.c
View file @
ab519f2a
...
...
@@ -24,6 +24,7 @@
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
...
...
@@ -95,8 +96,8 @@ static UINT INT_evaluate( UINT lval, UINT op, UINT rval )
return
0
;
}
static
const
char
*
STRING_evaluate
(
string_table
*
st
,
MSIVIEW
*
table
,
UINT
row
,
struct
expr
*
expr
)
static
const
WCHAR
*
STRING_evaluate
(
string_table
*
st
,
MSIVIEW
*
table
,
UINT
row
,
struct
expr
*
expr
,
MSIHANDLE
record
)
{
UINT
val
=
0
,
r
;
...
...
@@ -108,8 +109,11 @@ static const char *STRING_evaluate( string_table *st,
return
NULL
;
return
msi_string_lookup_id
(
st
,
val
);
case
EXPR_UTF8
:
return
expr
->
u
.
utf8
;
case
EXPR_SVAL
:
return
expr
->
u
.
sval
;
case
EXPR_WILDCARD
:
return
MSI_RecordGetString
(
record
,
1
);
default:
ERR
(
"Invalid expression type
\n
"
);
...
...
@@ -119,13 +123,13 @@ static const char *STRING_evaluate( string_table *st,
}
static
UINT
STRCMP_Evaluate
(
string_table
*
st
,
MSIVIEW
*
table
,
UINT
row
,
struct
expr
*
cond
,
UINT
*
val
)
struct
expr
*
cond
,
UINT
*
val
,
MSIHANDLE
record
)
{
int
sr
;
const
char
*
l_str
,
*
r_str
;
const
WCHAR
*
l_str
,
*
r_str
;
l_str
=
STRING_evaluate
(
st
,
table
,
row
,
cond
->
u
.
expr
.
left
);
r_str
=
STRING_evaluate
(
st
,
table
,
row
,
cond
->
u
.
expr
.
right
);
l_str
=
STRING_evaluate
(
st
,
table
,
row
,
cond
->
u
.
expr
.
left
,
record
);
r_str
=
STRING_evaluate
(
st
,
table
,
row
,
cond
->
u
.
expr
.
right
,
record
);
if
(
l_str
==
r_str
)
sr
=
0
;
else
if
(
l_str
&&
!
r_str
)
...
...
@@ -133,7 +137,7 @@ static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row,
else
if
(
r_str
&&
!
l_str
)
sr
=
-
1
;
else
sr
=
strcmp
(
l_str
,
r_str
);
sr
=
strcmp
W
(
l_str
,
r_str
);
*
val
=
(
cond
->
u
.
expr
.
op
==
OP_EQ
&&
(
sr
==
0
)
)
||
(
cond
->
u
.
expr
.
op
==
OP_LT
&&
(
sr
<
0
)
)
||
...
...
@@ -143,7 +147,7 @@ static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row,
}
static
UINT
WHERE_evaluate
(
MSIDATABASE
*
db
,
MSIVIEW
*
table
,
UINT
row
,
struct
expr
*
cond
,
UINT
*
val
)
struct
expr
*
cond
,
UINT
*
val
,
MSIHANDLE
record
)
{
UINT
r
,
lval
,
rval
;
...
...
@@ -155,26 +159,26 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
case
EXPR_COL_NUMBER
:
return
table
->
ops
->
fetch_int
(
table
,
row
,
cond
->
u
.
col_number
,
val
);
/* case EXPR_IVAL:
*val = cond->u.ival;
return ERROR_SUCCESS; */
case
EXPR_UVAL
:
*
val
=
cond
->
u
.
uval
;
return
ERROR_SUCCESS
;
case
EXPR_COMPLEX
:
r
=
WHERE_evaluate
(
db
,
table
,
row
,
cond
->
u
.
expr
.
left
,
&
lval
);
r
=
WHERE_evaluate
(
db
,
table
,
row
,
cond
->
u
.
expr
.
left
,
&
lval
,
record
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
WHERE_evaluate
(
db
,
table
,
row
,
cond
->
u
.
expr
.
right
,
&
rval
);
r
=
WHERE_evaluate
(
db
,
table
,
row
,
cond
->
u
.
expr
.
right
,
&
rval
,
record
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
*
val
=
INT_evaluate
(
lval
,
cond
->
u
.
expr
.
op
,
rval
);
return
ERROR_SUCCESS
;
case
EXPR_STRCMP
:
return
STRCMP_Evaluate
(
db
->
strings
,
table
,
row
,
cond
,
val
);
return
STRCMP_Evaluate
(
db
->
strings
,
table
,
row
,
cond
,
val
,
record
);
case
EXPR_WILDCARD
:
*
val
=
MsiRecordGetInteger
(
record
,
1
);
return
ERROR_SUCCESS
;
default:
ERR
(
"Invalid expression type
\n
"
);
...
...
@@ -211,7 +215,7 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIHANDLE record )
for
(
i
=
0
;
i
<
count
;
i
++
)
{
val
=
0
;
r
=
WHERE_evaluate
(
wv
->
db
,
table
,
i
,
wv
->
cond
,
&
val
);
r
=
WHERE_evaluate
(
wv
->
db
,
table
,
i
,
wv
->
cond
,
&
val
,
record
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
val
)
...
...
@@ -350,8 +354,7 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
static
UINT
WHERE_VerifyCondition
(
MSIDATABASE
*
db
,
MSIVIEW
*
table
,
struct
expr
*
cond
,
UINT
*
valid
)
{
UINT
r
,
val
=
0
,
len
;
char
*
str
;
UINT
r
,
val
=
0
;
switch
(
cond
->
type
)
{
...
...
@@ -380,8 +383,8 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
return
r
;
/* check the type of the comparison */
if
(
(
cond
->
u
.
expr
.
left
->
type
==
EXPR_
UTF8
)
||
(
cond
->
u
.
expr
.
right
->
type
==
EXPR_
UTF8
)
)
if
(
(
cond
->
u
.
expr
.
left
->
type
==
EXPR_
SVAL
)
||
(
cond
->
u
.
expr
.
right
->
type
==
EXPR_
SVAL
)
)
{
switch
(
cond
->
u
.
expr
.
op
)
{
...
...
@@ -405,18 +408,10 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
cond
->
type
=
EXPR_UVAL
;
cond
->
u
.
uval
=
cond
->
u
.
ival
+
(
1
<<
15
);
break
;
case
EXPR_WILDCARD
:
*
valid
=
1
;
break
;
case
EXPR_SVAL
:
/* convert to UTF8 so we have the same format as the DB */
len
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
cond
->
u
.
sval
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
if
(
!
str
)
return
ERROR_OUTOFMEMORY
;
WideCharToMultiByte
(
CP_UTF8
,
0
,
cond
->
u
.
sval
,
-
1
,
str
,
len
,
NULL
,
NULL
);
HeapFree
(
GetProcessHeap
(),
0
,
cond
->
u
.
sval
);
cond
->
type
=
EXPR_UTF8
;
cond
->
u
.
utf8
=
str
;
*
valid
=
1
;
break
;
default:
...
...
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