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
6950ac1d
Commit
6950ac1d
authored
Oct 29, 2012
by
Hans Leidekker
Committed by
Alexandre Julliard
Oct 29, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Add support for storing strings with embedded nulls in the string table.
parent
652863f4
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
66 additions
and
50 deletions
+66
-50
msipriv.h
dlls/msi/msipriv.h
+2
-2
msiquery.c
dlls/msi/msiquery.c
+1
-1
storages.c
dlls/msi/storages.c
+1
-1
streams.c
dlls/msi/streams.c
+1
-1
string.c
dlls/msi/string.c
+45
-28
table.c
dlls/msi/table.c
+14
-15
where.c
dlls/msi/where.c
+2
-2
No files found.
dlls/msi/msipriv.h
View file @
6950ac1d
...
...
@@ -754,9 +754,9 @@ enum StringPersistence
};
extern
BOOL
msi_addstringW
(
string_table
*
st
,
const
WCHAR
*
data
,
int
len
,
USHORT
refcount
,
enum
StringPersistence
persistence
)
DECLSPEC_HIDDEN
;
extern
UINT
msi_string2id
W
(
const
string_table
*
st
,
LPCWSTR
buffer
,
UINT
*
id
)
DECLSPEC_HIDDEN
;
extern
UINT
msi_string2id
(
const
string_table
*
st
,
const
WCHAR
*
data
,
int
len
,
UINT
*
id
)
DECLSPEC_HIDDEN
;
extern
VOID
msi_destroy_stringtable
(
string_table
*
st
)
DECLSPEC_HIDDEN
;
extern
const
WCHAR
*
msi_string_lookup
_id
(
const
string_table
*
st
,
UINT
id
)
DECLSPEC_HIDDEN
;
extern
const
WCHAR
*
msi_string_lookup
(
const
string_table
*
st
,
UINT
id
,
int
*
len
)
DECLSPEC_HIDDEN
;
extern
HRESULT
msi_init_string_table
(
IStorage
*
stg
)
DECLSPEC_HIDDEN
;
extern
string_table
*
msi_load_string_table
(
IStorage
*
stg
,
UINT
*
bytes_per_strref
)
DECLSPEC_HIDDEN
;
extern
UINT
msi_save_string_table
(
const
string_table
*
st
,
IStorage
*
storage
,
UINT
*
bytes_per_strref
)
DECLSPEC_HIDDEN
;
...
...
dlls/msi/msiquery.c
View file @
6950ac1d
...
...
@@ -347,7 +347,7 @@ UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
{
LPCWSTR
sval
;
sval
=
msi_string_lookup
_id
(
db
->
strings
,
ival
);
sval
=
msi_string_lookup
(
db
->
strings
,
ival
,
NULL
);
MSI_RecordSetStringW
(
*
rec
,
i
,
sval
);
}
else
...
...
dlls/msi/storages.c
View file @
6950ac1d
...
...
@@ -312,7 +312,7 @@ static UINT storages_find_row(MSISTORAGESVIEW *sv, MSIRECORD *rec, UINT *row)
UINT
r
,
i
,
id
,
data
;
str
=
MSI_RecordGetString
(
rec
,
1
);
r
=
msi_string2id
W
(
sv
->
db
->
strings
,
str
,
&
id
);
r
=
msi_string2id
(
sv
->
db
->
strings
,
str
,
-
1
,
&
id
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
...
...
dlls/msi/streams.c
View file @
6950ac1d
...
...
@@ -299,7 +299,7 @@ static UINT streams_find_row(MSISTREAMSVIEW *sv, MSIRECORD *rec, UINT *row)
UINT
r
,
i
,
id
,
data
;
str
=
MSI_RecordGetString
(
rec
,
1
);
r
=
msi_string2id
W
(
sv
->
db
->
strings
,
str
,
&
id
);
r
=
msi_string2id
(
sv
->
db
->
strings
,
str
,
-
1
,
&
id
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
...
...
dlls/msi/string.c
View file @
6950ac1d
...
...
@@ -45,7 +45,8 @@ struct msistring
{
USHORT
persistent_refcount
;
USHORT
nonpersistent_refcount
;
LPWSTR
str
;
WCHAR
*
data
;
int
len
;
};
struct
string_table
...
...
@@ -112,7 +113,7 @@ VOID msi_destroy_stringtable( string_table *st )
{
if
(
st
->
strings
[
i
].
persistent_refcount
||
st
->
strings
[
i
].
nonpersistent_refcount
)
msi_free
(
st
->
strings
[
i
].
str
);
msi_free
(
st
->
strings
[
i
].
data
);
}
msi_free
(
st
->
strings
);
msi_free
(
st
->
sorted
);
...
...
@@ -162,6 +163,19 @@ static int st_find_free_entry( string_table *st )
return
st
->
freeslot
;
}
static
inline
int
cmp_string
(
const
WCHAR
*
str1
,
int
len1
,
const
WCHAR
*
str2
,
int
len2
)
{
if
(
len1
<
len2
)
return
-
1
;
else
if
(
len1
>
len2
)
return
1
;
while
(
len1
)
{
if
(
*
str1
==
*
str2
)
{
str1
++
;
str2
++
;
}
else
return
*
str1
-
*
str2
;
len1
--
;
}
return
0
;
}
static
int
find_insert_index
(
const
string_table
*
st
,
UINT
string_id
)
{
int
i
,
c
,
low
=
0
,
high
=
st
->
sortcount
-
1
;
...
...
@@ -169,8 +183,8 @@ static int find_insert_index( const string_table *st, UINT string_id )
while
(
low
<=
high
)
{
i
=
(
low
+
high
)
/
2
;
c
=
strcmpW
(
st
->
strings
[
string_id
].
str
,
st
->
strings
[
st
->
sorted
[
i
]].
str
);
c
=
cmp_string
(
st
->
strings
[
string_id
].
data
,
st
->
strings
[
string_id
].
len
,
st
->
strings
[
st
->
sorted
[
i
]].
data
,
st
->
strings
[
st
->
sorted
[
i
]].
len
);
if
(
c
<
0
)
high
=
i
-
1
;
else
if
(
c
>
0
)
...
...
@@ -194,7 +208,8 @@ static void insert_string_sorted( string_table *st, UINT string_id )
st
->
sortcount
++
;
}
static
void
set_st_entry
(
string_table
*
st
,
UINT
n
,
LPWSTR
str
,
USHORT
refcount
,
enum
StringPersistence
persistence
)
static
void
set_st_entry
(
string_table
*
st
,
UINT
n
,
WCHAR
*
str
,
int
len
,
USHORT
refcount
,
enum
StringPersistence
persistence
)
{
if
(
persistence
==
StringPersistent
)
{
...
...
@@ -207,7 +222,8 @@ static void set_st_entry( string_table *st, UINT n, LPWSTR str, USHORT refcount,
st
->
strings
[
n
].
nonpersistent_refcount
=
refcount
;
}
st
->
strings
[
n
].
str
=
str
;
st
->
strings
[
n
].
data
=
str
;
st
->
strings
[
n
].
len
=
len
;
insert_string_sorted
(
st
,
n
);
...
...
@@ -237,9 +253,8 @@ static UINT msi_string2idA( const string_table *st, LPCSTR buffer, UINT *id )
return
ERROR_NOT_ENOUGH_MEMORY
;
MultiByteToWideChar
(
st
->
codepage
,
0
,
buffer
,
-
1
,
str
,
sz
);
r
=
msi_string2id
W
(
st
,
str
,
id
);
r
=
msi_string2id
(
st
,
str
,
sz
-
1
,
id
);
msi_free
(
str
);
return
r
;
}
...
...
@@ -289,7 +304,7 @@ static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, U
MultiByteToWideChar
(
st
->
codepage
,
0
,
data
,
len
,
str
,
sz
);
str
[
sz
]
=
0
;
set_st_entry
(
st
,
n
,
str
,
refcount
,
persistence
);
set_st_entry
(
st
,
n
,
str
,
sz
,
refcount
,
persistence
);
return
n
;
}
...
...
@@ -301,10 +316,10 @@ int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcoun
if
(
!
data
)
return
0
;
if
(
!
data
[
0
]
)
if
(
!
data
[
0
]
&&
!
len
)
return
0
;
if
(
msi_string2idW
(
st
,
data
,
&
n
)
==
ERROR_SUCCESS
)
if
(
msi_string2id
(
st
,
data
,
len
,
&
n
)
==
ERROR_SUCCESS
)
{
if
(
persistence
==
StringPersistent
)
st
->
strings
[
n
].
persistent_refcount
+=
refcount
;
...
...
@@ -320,7 +335,7 @@ int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcoun
/* allocate a new string */
if
(
len
<
0
)
len
=
strlenW
(
data
);
TRACE
(
"%s, n = %d len = %d
\n
"
,
debugstr_w
(
data
),
n
,
len
);
TRACE
(
"%s, n = %d len = %d
\n
"
,
debugstr_wn
(
data
,
len
),
n
,
len
);
str
=
msi_alloc
(
(
len
+
1
)
*
sizeof
(
WCHAR
)
);
if
(
!
str
)
...
...
@@ -328,13 +343,13 @@ int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcoun
memcpy
(
str
,
data
,
len
*
sizeof
(
WCHAR
)
);
str
[
len
]
=
0
;
set_st_entry
(
st
,
n
,
str
,
refcount
,
persistence
);
set_st_entry
(
st
,
n
,
str
,
len
,
refcount
,
persistence
);
return
n
;
}
/* find the string identified by an id - return null if there's none */
const
WCHAR
*
msi_string_lookup
_id
(
const
string_table
*
st
,
UINT
id
)
const
WCHAR
*
msi_string_lookup
(
const
string_table
*
st
,
UINT
id
,
int
*
len
)
{
if
(
id
==
0
)
return
szEmpty
;
...
...
@@ -345,7 +360,9 @@ const WCHAR *msi_string_lookup_id( const string_table *st, UINT id )
if
(
id
&&
!
st
->
strings
[
id
].
persistent_refcount
&&
!
st
->
strings
[
id
].
nonpersistent_refcount
)
return
NULL
;
return
st
->
strings
[
id
].
str
;
if
(
len
)
*
len
=
st
->
strings
[
id
].
len
;
return
st
->
strings
[
id
].
data
;
}
/*
...
...
@@ -361,16 +378,15 @@ const WCHAR *msi_string_lookup_id( const string_table *st, UINT id )
*/
static
UINT
msi_id2stringA
(
const
string_table
*
st
,
UINT
id
,
LPSTR
buffer
,
UINT
*
sz
)
{
UINT
len
,
lenW
;
int
len
,
lenW
;
const
WCHAR
*
str
;
TRACE
(
"Finding string %d of %d
\n
"
,
id
,
st
->
maxcount
);
str
=
msi_string_lookup
_id
(
st
,
id
);
str
=
msi_string_lookup
(
st
,
id
,
&
lenW
);
if
(
!
str
)
return
ERROR_FUNCTION_FAILED
;
lenW
=
strlenW
(
str
);
len
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
str
,
lenW
,
NULL
,
0
,
NULL
,
NULL
);
if
(
*
sz
<
len
)
{
...
...
@@ -382,20 +398,22 @@ static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT
}
/*
* msi_string2id
W
* msi_string2id
*
* [in] st - pointer to the string table
* [in] str - string to find in the string table
* [out] id - id of the string, if found
*/
UINT
msi_string2id
W
(
const
string_table
*
st
,
LPCWSTR
str
,
UINT
*
id
)
UINT
msi_string2id
(
const
string_table
*
st
,
const
WCHAR
*
str
,
int
len
,
UINT
*
id
)
{
int
i
,
c
,
low
=
0
,
high
=
st
->
sortcount
-
1
;
if
(
len
<
0
)
len
=
strlenW
(
str
);
while
(
low
<=
high
)
{
i
=
(
low
+
high
)
/
2
;
c
=
strcmpW
(
str
,
st
->
strings
[
st
->
sorted
[
i
]].
str
);
c
=
cmp_string
(
str
,
len
,
st
->
strings
[
st
->
sorted
[
i
]].
data
,
st
->
strings
[
st
->
sorted
[
i
]].
len
);
if
(
c
<
0
)
high
=
i
-
1
;
...
...
@@ -407,7 +425,6 @@ UINT msi_string2idW( const string_table *st, LPCWSTR str, UINT *id )
return
ERROR_SUCCESS
;
}
}
return
ERROR_INVALID_PARAMETER
;
}
...
...
@@ -415,7 +432,7 @@ static void string_totalsize( const string_table *st, UINT *datasize, UINT *pool
{
UINT
i
,
len
,
holesize
;
if
(
st
->
strings
[
0
].
str
||
st
->
strings
[
0
].
persistent_refcount
||
st
->
strings
[
0
].
nonpersistent_refcount
)
if
(
st
->
strings
[
0
].
data
||
st
->
strings
[
0
].
persistent_refcount
||
st
->
strings
[
0
].
nonpersistent_refcount
)
ERR
(
"oops. element 0 has a string
\n
"
);
*
poolsize
=
4
;
...
...
@@ -425,14 +442,14 @@ static void string_totalsize( const string_table *st, UINT *datasize, UINT *pool
{
if
(
!
st
->
strings
[
i
].
persistent_refcount
)
{
TRACE
(
"[%u] nonpersistent = %s
\n
"
,
i
,
debugstr_w
(
st
->
strings
[
i
].
str
));
TRACE
(
"[%u] nonpersistent = %s
\n
"
,
i
,
debugstr_w
n
(
st
->
strings
[
i
].
data
,
st
->
strings
[
i
].
len
));
(
*
poolsize
)
+=
4
;
}
else
if
(
st
->
strings
[
i
].
str
)
else
if
(
st
->
strings
[
i
].
data
)
{
TRACE
(
"[%u] = %s
\n
"
,
i
,
debugstr_w
(
st
->
strings
[
i
].
str
));
len
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
st
->
strings
[
i
].
str
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
TRACE
(
"[%u] = %s
\n
"
,
i
,
debugstr_w
n
(
st
->
strings
[
i
].
data
,
st
->
strings
[
i
].
len
));
len
=
WideCharToMultiByte
(
st
->
codepage
,
0
,
st
->
strings
[
i
].
data
,
st
->
strings
[
i
].
len
+
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
len
)
len
--
;
(
*
datasize
)
+=
len
;
...
...
dlls/msi/table.c
View file @
6950ac1d
...
...
@@ -660,7 +660,7 @@ static UINT get_tablecolumns( MSIDATABASE *db, LPCWSTR szTableName, MSICOLUMNINF
}
/* convert table and column names to IDs from the string table */
r
=
msi_string2id
W
(
db
->
strings
,
szTableName
,
&
table_id
);
r
=
msi_string2id
(
db
->
strings
,
szTableName
,
-
1
,
&
table_id
);
if
(
r
!=
ERROR_SUCCESS
)
{
WARN
(
"Couldn't find id for %s
\n
"
,
debugstr_w
(
szTableName
));
...
...
@@ -693,9 +693,9 @@ static UINT get_tablecolumns( MSIDATABASE *db, LPCWSTR szTableName, MSICOLUMNINF
ERR
(
"duplicate column %d
\n
"
,
col
);
continue
;
}
colinfo
[
col
-
1
].
tablename
=
msi_string_lookup
_id
(
db
->
strings
,
table_id
);
colinfo
[
col
-
1
].
tablename
=
msi_string_lookup
(
db
->
strings
,
table_id
,
NULL
);
colinfo
[
col
-
1
].
number
=
col
;
colinfo
[
col
-
1
].
colname
=
msi_string_lookup
_id
(
db
->
strings
,
id
);
colinfo
[
col
-
1
].
colname
=
msi_string_lookup
(
db
->
strings
,
id
,
NULL
);
colinfo
[
col
-
1
].
type
=
read_table_int
(
table
->
data
,
i
,
table
->
colinfo
[
3
].
offset
,
sizeof
(
USHORT
)
)
-
(
1
<<
15
);
colinfo
[
col
-
1
].
offset
=
0
;
...
...
@@ -763,9 +763,9 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info,
UINT
table_id
=
msi_addstringW
(
db
->
strings
,
col
->
table
,
-
1
,
1
,
string_persistence
);
UINT
col_id
=
msi_addstringW
(
db
->
strings
,
col
->
column
,
-
1
,
1
,
string_persistence
);
table
->
colinfo
[
i
].
tablename
=
msi_string_lookup
_id
(
db
->
strings
,
table_id
);
table
->
colinfo
[
i
].
tablename
=
msi_string_lookup
(
db
->
strings
,
table_id
,
NULL
);
table
->
colinfo
[
i
].
number
=
i
+
1
;
table
->
colinfo
[
i
].
colname
=
msi_string_lookup
_id
(
db
->
strings
,
col_id
);
table
->
colinfo
[
i
].
colname
=
msi_string_lookup
(
db
->
strings
,
col_id
,
NULL
);
table
->
colinfo
[
i
].
type
=
col
->
type
;
table
->
colinfo
[
i
].
offset
=
0
;
table
->
colinfo
[
i
].
ref_count
=
0
;
...
...
@@ -981,7 +981,7 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name )
!
strcmpW
(
name
,
szStreams
)
||
!
strcmpW
(
name
,
szStorages
)
)
return
TRUE
;
r
=
msi_string2id
W
(
db
->
strings
,
name
,
&
table_id
);
r
=
msi_string2id
(
db
->
strings
,
name
,
-
1
,
&
table_id
);
if
(
r
!=
ERROR_SUCCESS
)
{
TRACE
(
"Couldn't find id for %s
\n
"
,
debugstr_w
(
name
));
...
...
@@ -1087,7 +1087,7 @@ static UINT msi_stream_name( const MSITABLEVIEW *tv, UINT row, LPWSTR *pstname )
if
(
tv
->
columns
[
i
].
type
&
MSITYPE_STRING
)
{
sval
=
msi_string_lookup
_id
(
tv
->
db
->
strings
,
ival
);
sval
=
msi_string_lookup
(
tv
->
db
->
strings
,
ival
,
NULL
);
if
(
!
sval
)
{
r
=
ERROR_INVALID_PARAMETER
;
...
...
@@ -1276,7 +1276,7 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT
LPCWSTR
sval
=
MSI_RecordGetString
(
rec
,
iField
);
if
(
sval
)
{
r
=
msi_string2id
W
(
tv
->
db
->
strings
,
sval
,
pvalue
);
r
=
msi_string2id
(
tv
->
db
->
strings
,
sval
,
-
1
,
pvalue
);
if
(
r
!=
ERROR_SUCCESS
)
return
ERROR_NOT_FOUND
;
}
...
...
@@ -2343,7 +2343,7 @@ static MSIRECORD *msi_get_transform_record( const MSITABLEVIEW *tv, const string
LPCWSTR
sval
;
val
=
read_raw_int
(
rawdata
,
ofs
,
bytes_per_strref
);
sval
=
msi_string_lookup
_id
(
st
,
val
);
sval
=
msi_string_lookup
(
st
,
val
,
NULL
);
MSI_RecordSetStringW
(
rec
,
i
+
1
,
sval
);
TRACE
(
" field %d [%s]
\n
"
,
i
+
1
,
debugstr_w
(
sval
));
ofs
+=
bytes_per_strref
;
...
...
@@ -2395,13 +2395,12 @@ static void dump_record( MSIRECORD *rec )
static
void
dump_table
(
const
string_table
*
st
,
const
USHORT
*
rawdata
,
UINT
rawsize
)
{
LPCWSTR
sval
;
UINT
i
;
for
(
i
=
0
;
i
<
(
rawsize
/
2
);
i
++
)
for
(
i
=
0
;
i
<
rawsize
/
2
;
i
++
)
{
sval
=
msi_string_lookup_id
(
st
,
rawdata
[
i
]
);
MESSAGE
(
" %04x %s
\n
"
,
rawdata
[
i
],
debugstr_w
(
sval
)
);
int
len
;
const
WCHAR
*
sval
=
msi_string_lookup
(
st
,
rawdata
[
i
],
&
len
);
MESSAGE
(
" %04x %s
\n
"
,
rawdata
[
i
],
debugstr_wn
(
sval
,
len
)
);
}
}
...
...
@@ -2425,7 +2424,7 @@ static UINT* msi_record_to_row( const MSITABLEVIEW *tv, MSIRECORD *rec )
str
=
MSI_RecordGetString
(
rec
,
i
+
1
);
if
(
str
)
{
r
=
msi_string2id
W
(
tv
->
db
->
strings
,
str
,
&
data
[
i
]
);
r
=
msi_string2id
(
tv
->
db
->
strings
,
str
,
-
1
,
&
data
[
i
]
);
/* if there's no matching string in the string table,
these keys can't match any record, so fail now. */
...
...
dlls/msi/where.c
View file @
6950ac1d
...
...
@@ -494,7 +494,7 @@ static UINT STRING_evaluate( MSIWHEREVIEW *wv, const UINT rows[],
case
EXPR_COL_NUMBER_STRING
:
r
=
expr_fetch_value
(
&
expr
->
u
.
column
,
rows
,
&
val
);
if
(
r
==
ERROR_SUCCESS
)
*
str
=
msi_string_lookup
_id
(
wv
->
db
->
strings
,
val
);
*
str
=
msi_string_lookup
(
wv
->
db
->
strings
,
val
,
NULL
);
else
*
str
=
NULL
;
break
;
...
...
@@ -883,7 +883,7 @@ static UINT join_find_row( MSIWHEREVIEW *wv, MSIRECORD *rec, UINT *row )
UINT
r
,
i
,
id
,
data
;
str
=
MSI_RecordGetString
(
rec
,
1
);
r
=
msi_string2id
W
(
wv
->
db
->
strings
,
str
,
&
id
);
r
=
msi_string2id
(
wv
->
db
->
strings
,
str
,
-
1
,
&
id
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
...
...
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