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
b040e4bc
Commit
b040e4bc
authored
Mar 18, 2004
by
Mike McCormack
Committed by
Alexandre Julliard
Mar 18, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
When loading table data, split it up into rows.
parent
8d02010f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
370 additions
and
57 deletions
+370
-57
msi.c
dlls/msi/msi.c
+2
-2
msipriv.h
dlls/msi/msipriv.h
+7
-1
msiquery.c
dlls/msi/msiquery.c
+16
-3
string.c
dlls/msi/string.c
+56
-3
table.c
dlls/msi/table.c
+289
-48
No files found.
dlls/msi/msi.c
View file @
b040e4bc
...
...
@@ -500,13 +500,13 @@ UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, BOOL fAppend)
INSTALLSTATE
WINAPI
MsiQueryProductStateA
(
LPCSTR
szProduct
)
{
FIXME
(
"%s
\n
"
,
debugstr_a
(
szProduct
));
return
0
;
return
INSTALLSTATE_UNKNOWN
;
}
INSTALLSTATE
WINAPI
MsiQueryProductStateW
(
LPCWSTR
szProduct
)
{
FIXME
(
"%s
\n
"
,
debugstr_w
(
szProduct
));
return
0
;
return
INSTALLSTATE_UNKNOWN
;
}
INSTALLUILEVEL
WINAPI
MsiSetInternalUI
(
INSTALLUILEVEL
dwUILevel
,
HWND
*
phWnd
)
...
...
dlls/msi/msipriv.h
View file @
b040e4bc
...
...
@@ -153,14 +153,20 @@ extern void free_cached_tables( MSIDATABASE *db );
extern
UINT
find_cached_table
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSITABLE
**
table
);
extern
UINT
get_table
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSITABLE
**
table
);
extern
UINT
load_string_table
(
MSIDATABASE
*
db
);
extern
UINT
MSI_CommitTables
(
MSIDATABASE
*
db
);
/* string table functions */
extern
BOOL
msi_addstring
(
string_table
*
st
,
UINT
string_no
,
CHAR
*
data
,
UINT
len
,
UINT
refcount
);
extern
UINT
msi_id2string
(
string_table
*
st
,
UINT
string_no
,
LPWSTR
buffer
,
UINT
*
sz
);
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
string_table
*
msi_init_stringtable
(
int
entries
);
extern
VOID
msi_destroy_stringtable
(
string_table
*
st
);
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
);
UINT
VIEW_find_column
(
MSIVIEW
*
view
,
LPWSTR
name
,
UINT
*
n
);
...
...
dlls/msi/msiquery.c
View file @
b040e4bc
...
...
@@ -361,8 +361,22 @@ UINT WINAPI MsiDatabaseGenerateTransformW( MSIHANDLE hdb, MSIHANDLE hdbref,
UINT
WINAPI
MsiDatabaseCommit
(
MSIHANDLE
hdb
)
{
FIXME
(
"%ld
\n
"
,
hdb
);
return
ERROR_SUCCESS
;
MSIDATABASE
*
db
;
UINT
r
;
TRACE
(
"%ld
\n
"
,
hdb
);
db
=
msihandle2msiinfo
(
hdb
,
MSIHANDLETYPE_DATABASE
);
if
(
!
db
)
return
ERROR_INVALID_HANDLE
;
/* FIXME: lock the database */
r
=
MSI_CommitTables
(
db
);
/* FIXME: unlock the database */
return
r
;
}
UINT
WINAPI
MsiDatabaseGetPrimaryKeysA
(
MSIHANDLE
hdb
,
...
...
@@ -406,4 +420,3 @@ UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szFeature,
FIXME
(
"%ld %s %p %p
\n
"
,
hInstall
,
debugstr_w
(
szFeature
),
piInstalled
,
piAction
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
dlls/msi/string.c
View file @
b040e4bc
...
...
@@ -123,7 +123,7 @@ int msi_addstring( string_table *st, UINT string_no, CHAR *data, UINT len, UINT
{
int
n
;
TRACE
(
"[%2d] = %s
\n
"
,
string_no
,
debugstr_an
(
data
,
len
)
);
/* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */
n
=
st_find_free_entry
(
st
);
if
(
n
<
0
)
...
...
@@ -145,7 +145,35 @@ int msi_addstring( string_table *st, UINT string_no, CHAR *data, UINT len, UINT
return
n
;
}
UINT
msi_id2string
(
string_table
*
st
,
UINT
string_no
,
LPWSTR
buffer
,
UINT
*
sz
)
UINT
msi_id2stringW
(
string_table
*
st
,
UINT
string_no
,
LPWSTR
buffer
,
UINT
*
sz
)
{
UINT
len
;
LPSTR
str
;
TRACE
(
"Finding string %d of %d
\n
"
,
string_no
,
st
->
count
);
if
(
string_no
>=
st
->
count
)
return
ERROR_FUNCTION_FAILED
;
if
(
!
st
->
strings
[
string_no
].
refcount
)
return
ERROR_FUNCTION_FAILED
;
str
=
st
->
strings
[
string_no
].
str
;
len
=
strlen
(
str
);
if
(
!
buffer
)
{
*
sz
=
MultiByteToWideChar
(
CP_ACP
,
0
,
str
,
len
,
NULL
,
0
);
return
ERROR_SUCCESS
;
}
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
str
,
len
+
1
,
buffer
,
*
sz
);
if
(
!
len
)
buffer
[
*
sz
-
1
]
=
0
;
else
*
sz
=
len
;
return
ERROR_SUCCESS
;
}
UINT
msi_id2stringA
(
string_table
*
st
,
UINT
string_no
,
LPSTR
buffer
,
UINT
*
sz
)
{
UINT
len
;
LPSTR
str
;
...
...
@@ -166,7 +194,8 @@ UINT msi_id2string( string_table *st, UINT string_no, LPWSTR buffer, UINT *sz )
return
ERROR_SUCCESS
;
}
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
str
,
len
,
buffer
,
*
sz
-
1
);
if
(
len
>=
*
sz
)
len
=
*
sz
-
1
;
memcpy
(
buffer
,
str
,
len
);
buffer
[
len
]
=
0
;
*
sz
=
len
+
1
;
...
...
@@ -207,3 +236,27 @@ UINT msi_string2id( string_table *st, LPCWSTR buffer, UINT *id )
return
r
;
}
UINT
msi_string_count
(
string_table
*
st
)
{
return
st
->
count
;
}
UINT
msi_id_refcount
(
string_table
*
st
,
UINT
i
)
{
if
(
i
>=
st
->
count
)
return
0
;
return
st
->
strings
[
i
].
refcount
;
}
UINT
msi_string_totalsize
(
string_table
*
st
)
{
UINT
size
=
0
,
i
;
for
(
i
=
0
;
i
<
st
->
count
;
i
++
)
{
if
(
st
->
strings
[
i
].
str
)
size
+=
strlen
(
st
->
strings
[
i
].
str
);
}
return
size
;
}
dlls/msi/table.c
View file @
b040e4bc
...
...
@@ -46,16 +46,30 @@ typedef struct tagMSICOLUMNINFO
struct
tagMSITABLE
{
USHORT
*
data
;
UINT
size
;
USHORT
**
data
;
UINT
ref_count
;
UINT
row_count
;
struct
tagMSITABLE
*
next
;
struct
tagMSITABLE
*
prev
;
WCHAR
name
[
1
];
}
;
};
#define MAX_STREAM_NAME 0x1f
static
UINT
table_get_column_info
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSICOLUMNINFO
**
pcols
,
UINT
*
pcount
);
static
UINT
get_tablecolumns
(
MSIDATABASE
*
db
,
LPCWSTR
szTableName
,
MSICOLUMNINFO
*
colinfo
,
UINT
*
sz
);
static
inline
UINT
bytes_per_column
(
MSICOLUMNINFO
*
col
)
{
if
(
col
->
type
&
MSITYPE_STRING
)
return
2
;
if
(
(
col
->
type
&
0xff
)
>
4
)
ERR
(
"Invalid column size!
\n
"
);
return
col
->
type
&
0xff
;
}
static
int
utf2mime
(
int
x
)
{
if
(
(
x
>=
'0'
)
&&
(
x
<=
'9'
)
)
...
...
@@ -150,7 +164,7 @@ static BOOL decode_streamname(LPWSTR in, LPWSTR out)
}
#endif
static
BOOL
read_stream_data
(
IStorage
*
stg
,
LP
WSTR
stname
,
static
UINT
read_stream_data
(
IStorage
*
stg
,
LPC
WSTR
stname
,
USHORT
**
pdata
,
UINT
*
psz
)
{
HRESULT
r
;
...
...
@@ -159,8 +173,13 @@ static BOOL read_stream_data( IStorage *stg, LPWSTR stname,
ULONG
sz
,
count
;
IStream
*
stm
=
NULL
;
STATSTG
stat
;
WCHAR
encname
[
0x20
];
encode_streamname
(
TRUE
,
stname
,
encname
);
TRACE
(
"%s -> %s
\n
"
,
debugstr_w
(
stname
),
debugstr_w
(
encname
));
r
=
IStorage_OpenStream
(
stg
,
st
name
,
NULL
,
r
=
IStorage_OpenStream
(
stg
,
enc
name
,
NULL
,
STGM_READ
|
STGM_SHARE_EXCLUSIVE
,
0
,
&
stm
);
if
(
FAILED
(
r
)
)
{
...
...
@@ -208,12 +227,63 @@ end:
return
ret
;
}
UINT
read_table_from_storage
(
IStorage
*
stg
,
LPCWSTR
name
,
MSITABLE
**
ptable
)
static
UINT
write_stream_data
(
IStorage
*
stg
,
LPCWSTR
stname
,
LPVOID
data
,
UINT
sz
)
{
HRESULT
r
;
UINT
ret
=
ERROR_FUNCTION_FAILED
;
ULONG
count
;
IStream
*
stm
=
NULL
;
ULARGE_INTEGER
size
;
LARGE_INTEGER
pos
;
r
=
IStorage_OpenStream
(
stg
,
stname
,
NULL
,
STGM_WRITE
|
STGM_SHARE_EXCLUSIVE
,
0
,
&
stm
);
if
(
FAILED
(
r
)
)
{
WARN
(
"open stream failed r = %08lx - empty table?
\n
"
,
r
);
return
ret
;
}
size
.
QuadPart
=
sz
;
r
=
IStream_SetSize
(
stm
,
size
);
if
(
FAILED
(
r
)
||
(
count
!=
sz
)
)
{
ERR
(
"Failed to SetSize
\n
"
);
goto
end
;
}
pos
.
QuadPart
=
0
;
r
=
IStream_Seek
(
stm
,
pos
,
STREAM_SEEK_SET
,
NULL
);
if
(
FAILED
(
r
)
||
(
count
!=
sz
)
)
{
ERR
(
"Failed to Seek
\n
"
);
goto
end
;
}
r
=
IStream_Write
(
stm
,
data
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
(
count
!=
sz
)
)
{
ERR
(
"Failed to Write
\n
"
);
goto
end
;
}
ret
=
ERROR_SUCCESS
;
end:
IStream_Release
(
stm
);
return
ret
;
}
UINT
read_table_from_storage
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSITABLE
**
ptable
)
{
WCHAR
buffer
[
0x20
];
MSITABLE
*
t
;
USHORT
*
rawdata
=
NULL
;
UINT
rawsize
=
0
,
r
,
i
,
j
,
row_size
=
0
,
num_cols
=
0
;
MSICOLUMNINFO
*
cols
,
*
last_col
;
TRACE
(
"%s
-> %s
\n
"
,
debugstr_w
(
name
),
debugstr_w
(
buffer
));
TRACE
(
"%s
\n
"
,
debugstr_w
(
name
));
/* non-existing tables should be interpretted as empty tables */
t
=
HeapAlloc
(
GetProcessHeap
(),
0
,
...
...
@@ -221,15 +291,69 @@ UINT read_table_from_storage(IStorage *stg, LPCWSTR name, MSITABLE **ptable)
if
(
!
t
)
return
ERROR_NOT_ENOUGH_MEMORY
;
t
->
size
=
0
;
r
=
table_get_column_info
(
db
,
name
,
&
cols
,
&
num_cols
);
if
(
r
!=
ERROR_SUCCESS
)
{
HeapFree
(
GetProcessHeap
(),
0
,
t
);
return
r
;
}
last_col
=
&
cols
[
num_cols
-
1
];
row_size
=
last_col
->
offset
+
bytes_per_column
(
last_col
);
t
->
data
=
NULL
;
lstrcpyW
(
t
->
name
,
name
);
t
->
ref_count
=
1
;
*
ptable
=
t
;
/* if we can't read the table, just assume that it's empty */
encode_streamname
(
TRUE
,
name
,
buffer
);
read_stream_data
(
stg
,
buffer
,
&
t
->
data
,
&
t
->
size
);
read_stream_data
(
db
->
storage
,
name
,
&
rawdata
,
&
rawsize
);
if
(
!
rawdata
)
return
ERROR_SUCCESS
;
TRACE
(
"Read %d bytes
\n
"
,
rawsize
);
if
(
rawsize
%
row_size
)
{
ERR
(
"Table size is invalid %d/%d
\n
"
,
rawsize
,
row_size
);
return
ERROR_FUNCTION_FAILED
;
}
t
->
row_count
=
rawsize
/
row_size
;
t
->
data
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
t
->
row_count
*
sizeof
(
USHORT
*
)
);
if
(
!
t
->
data
)
return
ERROR_NOT_ENOUGH_MEMORY
;
/* FIXME: memory leak */
/* transpose all the data */
TRACE
(
"Transposing data from %d columns
\n
"
,
t
->
row_count
);
for
(
i
=
0
;
i
<
t
->
row_count
;
i
++
)
{
t
->
data
[
i
]
=
HeapAlloc
(
GetProcessHeap
(),
0
,
row_size
);
if
(
!
t
->
data
[
i
]
)
return
ERROR_NOT_ENOUGH_MEMORY
;
/* FIXME: memory leak */
for
(
j
=
0
;
j
<
num_cols
;
j
++
)
{
UINT
ofs
=
cols
[
j
].
offset
/
2
;
UINT
n
=
bytes_per_column
(
&
cols
[
j
]
);
switch
(
n
)
{
case
2
:
t
->
data
[
i
][
ofs
]
=
rawdata
[
ofs
*
t
->
row_count
+
i
];
break
;
case
4
:
t
->
data
[
i
][
ofs
]
=
rawdata
[
ofs
*
t
->
row_count
+
i
];
t
->
data
[
i
][
ofs
+
1
]
=
rawdata
[
ofs
*
t
->
row_count
+
i
+
1
];
break
;
default:
ERR
(
"oops - unknown column width %d
\n
"
,
n
);
return
ERROR_FUNCTION_FAILED
;
}
}
}
HeapFree
(
GetProcessHeap
(),
0
,
cols
);
HeapFree
(
GetProcessHeap
(),
0
,
rawdata
);
return
ERROR_SUCCESS
;
}
...
...
@@ -305,6 +429,40 @@ UINT find_cached_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
table_get_column_info
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSICOLUMNINFO
**
pcols
,
UINT
*
pcount
)
{
UINT
r
,
column_count
;
MSICOLUMNINFO
*
columns
;
/* get the number of columns in this table */
column_count
=
0
;
r
=
get_tablecolumns
(
db
,
name
,
NULL
,
&
column_count
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
/* if there's no columns, there's no table */
if
(
column_count
==
0
)
return
ERROR_INVALID_PARAMETER
;
TRACE
(
"Table %s found
\n
"
,
debugstr_w
(
name
)
);
columns
=
HeapAlloc
(
GetProcessHeap
(),
0
,
column_count
*
sizeof
(
MSICOLUMNINFO
));
if
(
!
columns
)
return
ERROR_FUNCTION_FAILED
;
r
=
get_tablecolumns
(
db
,
name
,
columns
,
&
column_count
);
if
(
r
!=
ERROR_SUCCESS
)
{
HeapFree
(
GetProcessHeap
(),
0
,
columns
);
return
ERROR_FUNCTION_FAILED
;
}
*
pcols
=
columns
;
*
pcount
=
column_count
;
return
r
;
}
UINT
get_table
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSITABLE
**
ptable
)
{
UINT
r
;
...
...
@@ -319,7 +477,7 @@ UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
return
r
;
}
r
=
read_table_from_storage
(
db
->
storage
,
name
,
ptable
);
r
=
read_table_from_storage
(
db
,
name
,
ptable
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
...
...
@@ -330,10 +488,17 @@ UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
return
ERROR_SUCCESS
;
}
UINT
save_table
(
MSIDATABASE
*
db
,
MSITABLE
*
ptable
)
{
return
ERROR_SUCCESS
;
}
UINT
load_string_table
(
MSIDATABASE
*
db
)
{
MSITABLE
*
pool
=
NULL
,
*
info
=
NULL
;
UINT
r
,
ret
=
ERROR_FUNCTION_FAILED
;
CHAR
*
data
;
USHORT
*
pool
;
UINT
r
,
ret
=
ERROR_FUNCTION_FAILED
,
datasize
=
0
,
poolsize
=
0
;
DWORD
i
,
count
,
offset
,
len
;
const
WCHAR
szStringData
[]
=
{
'_'
,
'S'
,
't'
,
'r'
,
'i'
,
'n'
,
'g'
,
'D'
,
'a'
,
't'
,
'a'
,
0
};
...
...
@@ -346,21 +511,21 @@ UINT load_string_table( MSIDATABASE *db )
db
->
strings
=
NULL
;
}
r
=
get_table
(
db
,
szStringPool
,
&
pool
);
r
=
read_stream_data
(
db
->
storage
,
szStringPool
,
&
pool
,
&
poolsize
);
if
(
r
!=
ERROR_SUCCESS
)
goto
end
;
r
=
get_table
(
db
,
szStringData
,
&
info
);
r
=
read_stream_data
(
db
->
storage
,
szStringData
,
(
USHORT
**
)
&
data
,
&
datasize
);
if
(
r
!=
ERROR_SUCCESS
)
goto
end
;
count
=
pool
->
size
/
4
;
count
=
poolsize
/
4
;
db
->
strings
=
msi_init_stringtable
(
count
);
offset
=
0
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
len
=
pool
->
data
[
i
*
2
];
msi_addstring
(
db
->
strings
,
i
,
(
LPSTR
)
info
->
data
+
offset
,
len
,
pool
->
data
[
i
*
2
+
1
]
);
len
=
pool
[
i
*
2
];
msi_addstring
(
db
->
strings
,
i
,
data
+
offset
,
len
,
pool
[
i
*
2
+
1
]
);
offset
+=
len
;
}
...
...
@@ -369,10 +534,75 @@ UINT load_string_table( MSIDATABASE *db )
ret
=
ERROR_SUCCESS
;
end:
if
(
info
)
release_table
(
db
,
info
);
if
(
pool
)
release_table
(
db
,
pool
);
HeapFree
(
GetProcessHeap
(),
0
,
pool
);
if
(
data
)
HeapFree
(
GetProcessHeap
(),
0
,
data
);
return
ret
;
}
UINT
save_string_table
(
MSIDATABASE
*
db
)
{
UINT
i
,
count
,
datasize
,
poolsize
,
sz
,
remaining
,
r
;
UINT
ret
=
ERROR_FUNCTION_FAILED
;
const
WCHAR
szStringData
[]
=
{
'_'
,
'S'
,
't'
,
'r'
,
'i'
,
'n'
,
'g'
,
'D'
,
'a'
,
't'
,
'a'
,
0
};
const
WCHAR
szStringPool
[]
=
{
'_'
,
'S'
,
't'
,
'r'
,
'i'
,
'n'
,
'g'
,
'P'
,
'o'
,
'o'
,
'l'
,
0
};
CHAR
*
data
=
NULL
;
USHORT
*
pool
=
NULL
;
/* construct the new table in memory first */
count
=
msi_string_count
(
db
->
strings
);
poolsize
=
count
*
2
*
sizeof
(
USHORT
);
datasize
=
msi_string_totalsize
(
db
->
strings
);
pool
=
HeapAlloc
(
GetProcessHeap
(),
0
,
poolsize
);
if
(
!
pool
)
goto
err
;
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
datasize
);
if
(
!
data
)
goto
err
;
remaining
=
datasize
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
sz
=
remaining
;
r
=
msi_id2stringA
(
db
->
strings
,
i
,
data
+
remaining
,
&
sz
);
if
(
r
!=
ERROR_SUCCESS
)
goto
err
;
pool
[
i
*
2
]
=
sz
;
pool
[
i
*
2
+
1
]
=
msi_id_refcount
(
db
->
strings
,
i
);
remaining
-=
sz
;
if
(
remaining
<
0
)
{
ERR
(
"oops remaining %d < 0
\n
"
,
remaining
);
goto
err
;
}
}
if
(
remaining
!=
0
)
{
ERR
(
"oops remaining %d != 0
\n
"
,
remaining
);
goto
err
;
}
/* write the streams */
r
=
write_stream_data
(
db
->
storage
,
szStringData
,
data
,
datasize
);
if
(
r
)
goto
err
;
r
=
write_stream_data
(
db
->
storage
,
szStringPool
,
pool
,
poolsize
);
if
(
r
)
goto
err
;
ret
=
ERROR_SUCCESS
;
err:
if
(
data
)
HeapFree
(
GetProcessHeap
(),
0
,
data
);
if
(
pool
)
HeapFree
(
GetProcessHeap
(),
0
,
pool
);
return
ret
;
}
...
...
@@ -386,15 +616,6 @@ static LPWSTR strdupW( LPCWSTR str )
return
ret
;
}
static
inline
UINT
bytes_per_column
(
MSICOLUMNINFO
*
col
)
{
if
(
col
->
type
&
MSITYPE_STRING
)
return
2
;
if
(
(
col
->
type
&
0xff
)
>
4
)
ERR
(
"Invalid column size!
\n
"
);
return
col
->
type
&
0xff
;
}
/* information for default tables */
const
WCHAR
szTables
[]
=
{
'_'
,
'T'
,
'a'
,
'b'
,
'l'
,
'e'
,
's'
,
0
};
const
WCHAR
szTable
[]
=
{
'T'
,
'a'
,
'b'
,
'l'
,
'e'
,
0
};
...
...
@@ -456,21 +677,21 @@ LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid)
UINT
sz
=
0
,
r
;
LPWSTR
str
;
r
=
msi_id2string
(
db
->
strings
,
stringid
,
NULL
,
&
sz
);
r
=
msi_id2string
W
(
db
->
strings
,
stringid
,
NULL
,
&
sz
);
if
(
r
!=
ERROR_SUCCESS
)
return
NULL
;
sz
++
;
/* space for NUL char */
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
*
sizeof
(
WCHAR
));
if
(
!
str
)
return
str
;
r
=
msi_id2string
(
db
->
strings
,
stringid
,
str
,
&
sz
);
r
=
msi_id2string
W
(
db
->
strings
,
stringid
,
str
,
&
sz
);
if
(
r
==
ERROR_SUCCESS
)
return
str
;
HeapFree
(
GetProcessHeap
(),
0
,
str
);
return
NULL
;
}
UINT
get_tablecolumns
(
MSIDATABASE
*
db
,
static
UINT
get_tablecolumns
(
MSIDATABASE
*
db
,
LPCWSTR
szTableName
,
MSICOLUMNINFO
*
colinfo
,
UINT
*
sz
)
{
UINT
r
,
i
,
n
=
0
,
table_id
,
count
,
maxcount
=
*
sz
;
...
...
@@ -500,18 +721,18 @@ UINT get_tablecolumns( MSIDATABASE *db,
TRACE
(
"Table id is %d
\n
"
,
table_id
);
count
=
table
->
size
/
8
;
count
=
table
->
row_count
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
table
->
data
[
i
]
!=
table_id
)
if
(
table
->
data
[
i
]
[
0
]
!=
table_id
)
continue
;
if
(
colinfo
)
{
UINT
id
=
table
->
data
[
i
+
count
*
2
];
UINT
id
=
table
->
data
[
i
]
[
2
];
colinfo
[
n
].
tablename
=
MSI_makestring
(
db
,
table_id
);
colinfo
[
n
].
number
=
table
->
data
[
i
+
count
]
-
(
1
<<
15
);
colinfo
[
n
].
number
=
table
->
data
[
i
][
1
]
-
(
1
<<
15
);
colinfo
[
n
].
colname
=
MSI_makestring
(
db
,
id
);
colinfo
[
n
].
type
=
table
->
data
[
i
+
count
*
3
];
colinfo
[
n
].
type
=
table
->
data
[
i
]
[
3
];
/* this assumes that columns are in order in the table */
if
(
n
)
colinfo
[
n
].
offset
=
colinfo
[
n
-
1
].
offset
...
...
@@ -567,9 +788,10 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name )
return
FALSE
;
}
count
=
table
->
size
/
2
;
/* count = table->size/2; */
count
=
table
->
row_count
;
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
table
->
data
[
i
]
==
table_id
)
if
(
table
->
data
[
i
]
[
0
]
==
table_id
)
break
;
release_table
(
db
,
table
);
...
...
@@ -593,7 +815,6 @@ typedef struct tagMSITABLEVIEW
WCHAR
name
[
1
];
}
MSITABLEVIEW
;
static
UINT
TABLE_fetch_int
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
UINT
*
val
)
{
MSITABLEVIEW
*
tv
=
(
MSITABLEVIEW
*
)
view
;
...
...
@@ -606,7 +827,7 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
return
ERROR_INVALID_PARAMETER
;
/* how many rows are there ? */
num_rows
=
tv
->
table
->
size
/
tv
->
row_size
;
num_rows
=
tv
->
table
->
row_count
;
if
(
row
>=
num_rows
)
return
ERROR_NO_MORE_ITEMS
;
...
...
@@ -622,12 +843,12 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
switch
(
n
)
{
case
4
:
offset
=
row
*
2
+
(
tv
->
columns
[
col
-
1
].
offset
/
2
)
*
num_rows
;
*
val
=
tv
->
table
->
data
[
offset
]
+
(
tv
->
table
->
data
[
offset
+
1
]
<<
16
);
offset
=
tv
->
columns
[
col
-
1
].
offset
/
2
;
*
val
=
tv
->
table
->
data
[
row
][
offset
]
+
(
tv
->
table
->
data
[
row
]
[
offset
+
1
]
<<
16
);
break
;
case
2
:
offset
=
row
+
(
tv
->
columns
[
col
-
1
].
offset
/
2
)
*
num_rows
;
*
val
=
tv
->
table
->
data
[
offset
];
offset
=
tv
->
columns
[
col
-
1
].
offset
/
2
;
*
val
=
tv
->
table
->
data
[
row
][
offset
];
break
;
default:
ERR
(
"oops! what is %d bytes per column?
\n
"
,
n
);
...
...
@@ -683,7 +904,7 @@ static UINT TABLE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
{
if
(
!
tv
->
table
)
return
ERROR_INVALID_PARAMETER
;
*
rows
=
tv
->
table
->
size
/
tv
->
row_size
;
*
rows
=
tv
->
table
->
row_count
;
}
return
ERROR_SUCCESS
;
...
...
@@ -815,3 +1036,23 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPWSTR name, MSIVIEW **view )
return
ERROR_SUCCESS
;
}
UINT
MSI_CommitTables
(
MSIDATABASE
*
db
)
{
UINT
r
;
MSITABLE
*
table
=
NULL
;
save_string_table
(
db
);
for
(
table
=
db
->
first_table
;
table
;
table
=
table
->
next
)
{
r
=
save_table
(
db
,
table
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
}
/* force everything to reload next time */
free_cached_tables
(
db
);
return
ERROR_SUCCESS
;
}
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