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
8e74308a
Commit
8e74308a
authored
Sep 28, 2005
by
Mike McCormack
Committed by
Alexandre Julliard
Sep 28, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix and test MsiViewGetColumnInfo and binary fields.
parent
3c37734f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
271 additions
and
13 deletions
+271
-13
msipriv.h
dlls/msi/msipriv.h
+2
-1
msiquery.c
dlls/msi/msiquery.c
+34
-3
sql.y
dlls/msi/sql.y
+4
-5
table.c
dlls/msi/table.c
+4
-4
db.c
dlls/msi/tests/db.c
+227
-0
No files found.
dlls/msi/msipriv.h
View file @
8e74308a
...
...
@@ -34,11 +34,12 @@
#define MSI_DATASIZEMASK 0x00ff
#define MSITYPE_VALID 0x0100
#define MSITYPE_LOCALIZABLE 0x200
#define MSITYPE_STRING 0x0800
#define MSITYPE_NULLABLE 0x1000
#define MSITYPE_KEY 0x2000
#define MSITYPE_
BINARY 0x8900
#define MSITYPE_
IS_BINARY(type) (((type) & ~MSITYPE_NULLABLE) == (MSITYPE_STRING|MSITYPE_VALID))
struct
tagMSITABLE
;
typedef
struct
tagMSITABLE
MSITABLE
;
...
...
dlls/msi/msiquery.c
View file @
8e74308a
...
...
@@ -294,8 +294,7 @@ UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
ERR
(
"Error getting column type for %d
\n
"
,
i
);
continue
;
}
if
((
type
!=
MSITYPE_BINARY
)
&&
(
type
!=
(
MSITYPE_BINARY
|
MSITYPE_NULLABLE
)))
if
(
!
MSITYPE_IS_BINARY
(
type
))
{
ret
=
view
->
ops
->
fetch_int
(
view
,
query
->
row
,
i
,
&
ival
);
if
(
ret
)
...
...
@@ -449,6 +448,29 @@ out:
return
ret
;
}
static
UINT
msi_set_record_type_string
(
MSIRECORD
*
rec
,
UINT
field
,
UINT
type
)
{
static
const
WCHAR
fmt
[]
=
{
'%'
,
'd'
,
0
};
WCHAR
szType
[
0x10
];
if
(
MSITYPE_IS_BINARY
(
type
))
szType
[
0
]
=
'v'
;
else
if
(
type
&
MSITYPE_LOCALIZABLE
)
szType
[
0
]
=
'l'
;
else
if
(
type
&
MSITYPE_STRING
)
szType
[
0
]
=
's'
;
else
szType
[
0
]
=
'i'
;
if
(
type
&
MSITYPE_NULLABLE
)
szType
[
0
]
&=
~
0x20
;
sprintfW
(
&
szType
[
1
],
fmt
,
(
type
&
0xff
)
);
TRACE
(
"type %04x -> %s
\n
"
,
type
,
debugstr_w
(
szType
)
);
return
MSI_RecordSetStringW
(
rec
,
field
,
szType
);
}
UINT
WINAPI
MsiViewGetColumnInfo
(
MSIHANDLE
hView
,
MSICOLINFO
info
,
MSIHANDLE
*
hRec
)
{
MSIVIEW
*
view
=
NULL
;
...
...
@@ -459,6 +481,12 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR
TRACE
(
"%ld %d %p
\n
"
,
hView
,
info
,
hRec
);
if
(
!
hRec
)
return
ERROR_INVALID_PARAMETER
;
if
(
info
!=
MSICOLINFO_NAMES
&&
info
!=
MSICOLINFO_TYPES
)
return
ERROR_INVALID_PARAMETER
;
query
=
msihandle2msiinfo
(
hView
,
MSIHANDLETYPE_VIEW
);
if
(
!
query
)
return
ERROR_INVALID_HANDLE
;
...
...
@@ -492,7 +520,10 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR
r
=
view
->
ops
->
get_column_info
(
view
,
i
+
1
,
&
name
,
&
type
);
if
(
r
!=
ERROR_SUCCESS
)
continue
;
MSI_RecordSetStringW
(
rec
,
i
+
1
,
name
);
if
(
info
==
MSICOLINFO_NAMES
)
MSI_RecordSetStringW
(
rec
,
i
+
1
,
name
);
else
msi_set_record_type_string
(
rec
,
i
+
1
,
type
);
msi_free
(
name
);
}
...
...
dlls/msi/sql.y
View file @
8e74308a
...
...
@@ -258,19 +258,18 @@ column_and_type:
column column_type
{
$$ = $1;
$$->type = $2;
$$->type = $2
| MSITYPE_VALID
;
}
;
column_type:
data_type_l
{
$$ = $1
| MSITYPE_VALID
;
$$ = $1;
}
| data_type_l TK_LOCALIZABLE
{
FIXME("LOCALIZABLE ignored\n");
$$ = $1 | MSITYPE_VALID;
$$ = $1 | MSITYPE_LOCALIZABLE;
}
;
...
...
@@ -312,7 +311,7 @@ data_type:
}
| TK_OBJECT
{
$$ =
0
;
$$ =
MSITYPE_STRING | MSITYPE_VALID
;
}
;
...
...
dlls/msi/table.c
View file @
8e74308a
...
...
@@ -817,13 +817,13 @@ static const WCHAR szNumber[] = { 'N','u','m','b','e','r',0 };
static
const
WCHAR
szType
[]
=
{
'T'
,
'y'
,
'p'
,
'e'
,
0
};
static
const
MSICOLUMNINFO
_Columns_cols
[
4
]
=
{
{
szColumns
,
1
,
szTable
,
MSITYPE_VALID
|
MSITYPE_STRING
|
32
,
0
},
{
szColumns
,
1
,
szTable
,
MSITYPE_VALID
|
MSITYPE_STRING
|
64
,
0
},
{
szColumns
,
2
,
szNumber
,
MSITYPE_VALID
|
2
,
2
},
{
szColumns
,
3
,
szName
,
MSITYPE_VALID
|
MSITYPE_STRING
|
32
,
4
},
{
szColumns
,
3
,
szName
,
MSITYPE_VALID
|
MSITYPE_STRING
|
64
,
4
},
{
szColumns
,
4
,
szType
,
MSITYPE_VALID
|
2
,
6
},
};
static
const
MSICOLUMNINFO
_Tables_cols
[
1
]
=
{
{
szTables
,
1
,
szName
,
MSITYPE_VALID
|
MSITYPE_STRING
|
32
,
0
},
{
szTables
,
1
,
szName
,
MSITYPE_VALID
|
MSITYPE_STRING
|
64
,
0
},
};
static
UINT
get_defaulttablecolumns
(
LPCWSTR
name
,
MSICOLUMNINFO
*
colinfo
,
UINT
*
sz
)
...
...
@@ -930,7 +930,7 @@ static UINT get_tablecolumns( MSIDATABASE *db,
colinfo
[
n
].
tablename
=
MSI_makestring
(
db
,
table_id
);
colinfo
[
n
].
number
=
table
->
data
[
i
][
1
]
-
(
1
<<
15
);
colinfo
[
n
].
colname
=
MSI_makestring
(
db
,
id
);
colinfo
[
n
].
type
=
table
->
data
[
i
]
[
3
];
colinfo
[
n
].
type
=
table
->
data
[
i
]
[
3
]
^
0x8000
;
/* this assumes that columns are in order in the table */
if
(
n
)
colinfo
[
n
].
offset
=
colinfo
[
n
-
1
].
offset
...
...
dlls/msi/tests/db.c
View file @
8e74308a
...
...
@@ -480,6 +480,231 @@ static void test_viewmodify(void)
ok
(
r
==
ERROR_SUCCESS
,
"MsiOpenDatabase close failed
\n
"
);
}
static
MSIHANDLE
create_db
(
void
)
{
MSIHANDLE
hdb
=
0
;
UINT
res
;
DeleteFile
(
msifile
);
/* create an empty database */
res
=
MsiOpenDatabase
(
msifile
,
MSIDBOPEN_CREATE
,
&
hdb
);
ok
(
res
==
ERROR_SUCCESS
,
"Failed to create database
\n
"
);
if
(
res
!=
ERROR_SUCCESS
)
return
hdb
;
res
=
MsiDatabaseCommit
(
hdb
);
ok
(
res
==
ERROR_SUCCESS
,
"Failed to commit database
\n
"
);
return
hdb
;
}
static
void
test_getcolinfo
(
void
)
{
MSIHANDLE
hdb
,
hview
=
0
,
rec
=
0
;
UINT
r
;
DWORD
sz
;
char
buffer
[
0x20
];
/* create an empty db */
hdb
=
create_db
();
ok
(
hdb
,
"failed to create db
\n
"
);
/* tables should be present */
r
=
MsiDatabaseOpenView
(
hdb
,
"select * from _Tables"
,
&
hview
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to open query
\n
"
);
r
=
MsiViewExecute
(
hview
,
0
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to execute query
\n
"
);
/* check that NAMES works */
rec
=
0
;
r
=
MsiViewGetColumnInfo
(
hview
,
MSICOLINFO_NAMES
,
&
rec
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to get names
\n
"
);
sz
=
sizeof
buffer
;
r
=
MsiRecordGetString
(
rec
,
1
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to get string
\n
"
);
ok
(
!
strcmp
(
buffer
,
"Name"
),
"_Tables has wrong column name
\n
"
);
r
=
MsiCloseHandle
(
rec
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to close record handle
\n
"
);
/* check that TYPES works */
rec
=
0
;
r
=
MsiViewGetColumnInfo
(
hview
,
MSICOLINFO_TYPES
,
&
rec
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to get names
\n
"
);
sz
=
sizeof
buffer
;
r
=
MsiRecordGetString
(
rec
,
1
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to get string
\n
"
);
ok
(
!
strcmp
(
buffer
,
"s64"
),
"_Tables has wrong column type
\n
"
);
r
=
MsiCloseHandle
(
rec
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to close record handle
\n
"
);
/* check that invalid values fail */
rec
=
0
;
r
=
MsiViewGetColumnInfo
(
hview
,
100
,
&
rec
);
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"wrong error code
\n
"
);
ok
(
rec
==
0
,
"returned a record
\n
"
);
r
=
MsiViewGetColumnInfo
(
hview
,
MSICOLINFO_TYPES
,
NULL
);
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"wrong error code
\n
"
);
r
=
MsiViewGetColumnInfo
(
0
,
MSICOLINFO_TYPES
,
&
rec
);
ok
(
r
==
ERROR_INVALID_HANDLE
,
"wrong error code
\n
"
);
r
=
MsiViewClose
(
hview
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to close view
\n
"
);
r
=
MsiCloseHandle
(
hview
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to close view handle
\n
"
);
r
=
MsiCloseHandle
(
hdb
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to close database
\n
"
);
}
static
MSIHANDLE
get_column_info
(
MSIHANDLE
hdb
,
const
char
*
query
,
MSICOLINFO
type
)
{
MSIHANDLE
hview
=
0
,
rec
=
0
;
UINT
r
;
r
=
MsiDatabaseOpenView
(
hdb
,
query
,
&
hview
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
MsiViewExecute
(
hview
,
0
);
if
(
r
==
ERROR_SUCCESS
)
{
MsiViewGetColumnInfo
(
hview
,
type
,
&
rec
);
MsiViewClose
(
hview
);
}
MsiCloseHandle
(
hview
);
return
rec
;
}
static
UINT
get_columns_table_type
(
MSIHANDLE
hdb
,
const
char
*
table
,
UINT
field
)
{
MSIHANDLE
hview
=
0
,
rec
=
0
;
UINT
r
,
type
=
0
;
char
query
[
0x100
];
sprintf
(
query
,
"select * from `_Columns` where `Table` = '%s'"
,
table
);
r
=
MsiDatabaseOpenView
(
hdb
,
query
,
&
hview
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
MsiViewExecute
(
hview
,
0
);
if
(
r
==
ERROR_SUCCESS
)
{
while
(
1
)
{
r
=
MsiViewFetch
(
hview
,
&
rec
);
if
(
r
!=
ERROR_SUCCESS
)
break
;
r
=
MsiRecordGetInteger
(
rec
,
2
);
if
(
r
==
field
)
type
=
MsiRecordGetInteger
(
rec
,
4
);
MsiCloseHandle
(
rec
);
}
MsiViewClose
(
hview
);
}
MsiCloseHandle
(
hview
);
return
type
;
}
static
BOOL
check_record
(
MSIHANDLE
rec
,
UINT
field
,
LPSTR
val
)
{
CHAR
buffer
[
0x20
];
UINT
r
;
DWORD
sz
;
sz
=
sizeof
buffer
;
r
=
MsiRecordGetString
(
rec
,
field
,
buffer
,
&
sz
);
return
(
r
==
ERROR_SUCCESS
)
&&
!
strcmp
(
val
,
buffer
);
}
static
void
test_viewgetcolumninfo
(
void
)
{
MSIHANDLE
hdb
=
0
,
rec
;
UINT
r
;
hdb
=
create_db
();
ok
(
hdb
,
"failed to create db
\n
"
);
r
=
run_query
(
hdb
,
"CREATE TABLE `Properties` "
"( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)"
);
ok
(
r
==
ERROR_SUCCESS
,
"Failed to create table
\n
"
);
/* check the column types */
rec
=
get_column_info
(
hdb
,
"select * from `Properties`"
,
MSICOLINFO_TYPES
);
ok
(
rec
,
"failed to get column info record
\n
"
);
ok
(
check_record
(
rec
,
1
,
"S255"
),
"wrong record type
\n
"
);
ok
(
check_record
(
rec
,
2
,
"S1"
),
"wrong record type
\n
"
);
MsiCloseHandle
(
rec
);
/* check the type in _Columns */
ok
(
0x3dff
==
get_columns_table_type
(
hdb
,
"Properties"
,
1
),
"_columns table wrong
\n
"
);
ok
(
0x1d01
==
get_columns_table_type
(
hdb
,
"Properties"
,
2
),
"_columns table wrong
\n
"
);
/* now try the names */
rec
=
get_column_info
(
hdb
,
"select * from `Properties`"
,
MSICOLINFO_NAMES
);
ok
(
rec
,
"failed to get column info record
\n
"
);
ok
(
check_record
(
rec
,
1
,
"Property"
),
"wrong record type
\n
"
);
ok
(
check_record
(
rec
,
2
,
"Value"
),
"wrong record type
\n
"
);
MsiCloseHandle
(
rec
);
r
=
run_query
(
hdb
,
"CREATE TABLE `Binary` "
"( `Name` CHAR(255), `Data` OBJECT PRIMARY KEY `Name`)"
);
ok
(
r
==
ERROR_SUCCESS
,
"Failed to create table
\n
"
);
/* check the column types */
rec
=
get_column_info
(
hdb
,
"select * from `Binary`"
,
MSICOLINFO_TYPES
);
ok
(
rec
,
"failed to get column info record
\n
"
);
ok
(
check_record
(
rec
,
1
,
"S255"
),
"wrong record type
\n
"
);
ok
(
check_record
(
rec
,
2
,
"V0"
),
"wrong record type
\n
"
);
MsiCloseHandle
(
rec
);
/* check the type in _Columns */
ok
(
0x3dff
==
get_columns_table_type
(
hdb
,
"Binary"
,
1
),
"_columns table wrong
\n
"
);
ok
(
0x1900
==
get_columns_table_type
(
hdb
,
"Binary"
,
2
),
"_columns table wrong
\n
"
);
/* now try the names */
rec
=
get_column_info
(
hdb
,
"select * from `Binary`"
,
MSICOLINFO_NAMES
);
ok
(
rec
,
"failed to get column info record
\n
"
);
ok
(
check_record
(
rec
,
1
,
"Name"
),
"wrong record type
\n
"
);
ok
(
check_record
(
rec
,
2
,
"Data"
),
"wrong record type
\n
"
);
MsiCloseHandle
(
rec
);
r
=
run_query
(
hdb
,
"CREATE TABLE `UIText` "
"( `Key` CHAR(72) NOT NULL, `Text` CHAR(255) LOCALIZABLE PRIMARY KEY `Key`)"
);
ok
(
r
==
ERROR_SUCCESS
,
"Failed to create table
\n
"
);
ok
(
0x2d48
==
get_columns_table_type
(
hdb
,
"UIText"
,
1
),
"_columns table wrong
\n
"
);
ok
(
0x1fff
==
get_columns_table_type
(
hdb
,
"UIText"
,
2
),
"_columns table wrong
\n
"
);
rec
=
get_column_info
(
hdb
,
"select * from `UIText`"
,
MSICOLINFO_NAMES
);
ok
(
rec
,
"failed to get column info record
\n
"
);
ok
(
check_record
(
rec
,
1
,
"Key"
),
"wrong record type
\n
"
);
ok
(
check_record
(
rec
,
2
,
"Text"
),
"wrong record type
\n
"
);
MsiCloseHandle
(
rec
);
rec
=
get_column_info
(
hdb
,
"select * from `UIText`"
,
MSICOLINFO_TYPES
);
ok
(
rec
,
"failed to get column info record
\n
"
);
ok
(
check_record
(
rec
,
1
,
"s72"
),
"wrong record type
\n
"
);
ok
(
check_record
(
rec
,
2
,
"L255"
),
"wrong record type
\n
"
);
MsiCloseHandle
(
rec
);
MsiCloseHandle
(
hdb
);
}
START_TEST
(
db
)
{
test_msidatabase
();
...
...
@@ -487,4 +712,6 @@ START_TEST(db)
test_msidecomposedesc
();
test_msibadqueries
();
test_viewmodify
();
test_viewgetcolumninfo
();
test_getcolinfo
();
}
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