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
5a0d459c
Commit
5a0d459c
authored
Feb 04, 2008
by
James Hawkins
Committed by
Alexandre Julliard
Feb 05, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Reimplement MsiFormatRecord.
parent
e618c6d1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
811 additions
and
584 deletions
+811
-584
format.c
dlls/msi/format.c
+668
-420
format.c
dlls/msi/tests/format.c
+143
-164
No files found.
dlls/msi/format.c
View file @
5a0d459c
...
...
@@ -19,10 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiformatrecord.asp
*/
#include <stdarg.h>
#include <stdio.h>
...
...
@@ -43,11 +39,288 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msifo
WINE_DEFAULT_DEBUG_CHANNEL
(
msi
);
/* types arranged by precedence */
#define FORMAT_NULL 0x0001
#define FORMAT_LITERAL 0x0002
#define FORMAT_NUMBER 0x0004
#define FORMAT_LBRACK 0x0010
#define FORMAT_LBRACE 0x0020
#define FORMAT_RBRACK 0x0011
#define FORMAT_RBRACE 0x0021
#define FORMAT_ESCAPE 0x0040
#define FORMAT_PROPNULL 0x0080
#define FORMAT_ERROR 0x1000
#define FORMAT_FAIL 0x2000
#define left_type(x) (x & 0xF0)
typedef
struct
_tagFORMAT
{
MSIPACKAGE
*
package
;
MSIRECORD
*
record
;
LPWSTR
deformatted
;
int
len
;
int
n
;
BOOL
propfailed
;
BOOL
groupfailed
;
int
groups
;
}
FORMAT
;
typedef
struct
_tagFORMSTR
{
struct
list
entry
;
int
n
;
int
len
;
int
type
;
BOOL
propfound
;
BOOL
nonprop
;
}
FORMSTR
;
typedef
struct
_tagSTACK
{
struct
list
items
;
}
STACK
;
static
DWORD
deformat_string_internal
(
MSIPACKAGE
*
package
,
LPCWSTR
ptr
,
WCHAR
**
data
,
DWORD
len
,
MSIRECORD
*
record
,
BOOL
*
in_group
);
static
STACK
*
create_stack
(
void
)
{
STACK
*
stack
=
msi_alloc
(
sizeof
(
STACK
));
list_init
(
&
stack
->
items
);
return
stack
;
}
static
void
free_stack
(
STACK
*
stack
)
{
while
(
!
list_empty
(
&
stack
->
items
))
{
FORMSTR
*
str
=
LIST_ENTRY
(
list_head
(
&
stack
->
items
),
FORMSTR
,
entry
);
list_remove
(
&
str
->
entry
);
msi_free
(
str
);
}
msi_free
(
stack
);
}
static
void
stack_push
(
STACK
*
stack
,
FORMSTR
*
str
)
{
list_add_head
(
&
stack
->
items
,
&
str
->
entry
);
}
static
FORMSTR
*
stack_pop
(
STACK
*
stack
)
{
FORMSTR
*
ret
;
if
(
list_empty
(
&
stack
->
items
))
return
NULL
;
ret
=
LIST_ENTRY
(
list_head
(
&
stack
->
items
),
FORMSTR
,
entry
);
list_remove
(
&
ret
->
entry
);
return
ret
;
}
static
FORMSTR
*
stack_find
(
STACK
*
stack
,
int
type
)
{
FORMSTR
*
str
;
LIST_FOR_EACH_ENTRY
(
str
,
&
stack
->
items
,
FORMSTR
,
entry
)
{
if
(
str
->
type
==
type
)
return
str
;
}
return
NULL
;
}
static
FORMSTR
*
stack_peek
(
STACK
*
stack
)
{
return
LIST_ENTRY
(
list_head
(
&
stack
->
items
),
FORMSTR
,
entry
);
}
static
LPCWSTR
get_formstr_data
(
FORMAT
*
format
,
FORMSTR
*
str
)
{
return
&
format
->
deformatted
[
str
->
n
];
}
static
LPWSTR
dup_formstr
(
FORMAT
*
format
,
FORMSTR
*
str
)
{
LPWSTR
val
;
LPCWSTR
data
;
if
(
str
->
len
==
0
)
return
NULL
;
val
=
msi_alloc
((
str
->
len
+
1
)
*
sizeof
(
WCHAR
));
data
=
get_formstr_data
(
format
,
str
);
lstrcpynW
(
val
,
data
,
str
->
len
+
1
);
return
val
;
}
static
LPWSTR
deformat_index
(
FORMAT
*
format
,
FORMSTR
*
str
)
{
LPWSTR
val
,
ret
;
val
=
msi_alloc
((
str
->
len
+
1
)
*
sizeof
(
WCHAR
));
lstrcpynW
(
val
,
get_formstr_data
(
format
,
str
),
str
->
len
+
1
);
ret
=
msi_dup_record_field
(
format
->
record
,
atoiW
(
val
));
msi_free
(
val
);
return
ret
;
}
static
LPWSTR
deformat_property
(
FORMAT
*
format
,
FORMSTR
*
str
)
{
LPWSTR
val
,
ret
;
val
=
msi_alloc
((
str
->
len
+
1
)
*
sizeof
(
WCHAR
));
lstrcpynW
(
val
,
get_formstr_data
(
format
,
str
),
str
->
len
+
1
);
ret
=
msi_dup_property
(
format
->
package
,
val
);
msi_free
(
val
);
return
ret
;
}
static
LPWSTR
deformat_component
(
FORMAT
*
format
,
FORMSTR
*
str
)
{
LPWSTR
key
,
ret
=
NULL
;
MSICOMPONENT
*
comp
;
BOOL
source
;
key
=
msi_alloc
((
str
->
len
+
1
)
*
sizeof
(
WCHAR
));
lstrcpynW
(
key
,
get_formstr_data
(
format
,
str
),
str
->
len
+
1
);
comp
=
get_loaded_component
(
format
->
package
,
key
);
if
(
!
comp
)
goto
done
;
source
=
(
comp
->
Action
==
INSTALLSTATE_SOURCE
)
?
TRUE
:
FALSE
;
ret
=
resolve_folder
(
format
->
package
,
comp
->
Directory
,
source
,
FALSE
,
TRUE
,
NULL
);
done:
msi_free
(
key
);
return
ret
;
}
static
LPWSTR
deformat_file
(
FORMAT
*
format
,
FORMSTR
*
str
,
BOOL
shortname
)
{
LPWSTR
key
,
ret
=
NULL
;
MSIFILE
*
file
;
DWORD
size
;
key
=
msi_alloc
((
str
->
len
+
1
)
*
sizeof
(
WCHAR
));
lstrcpynW
(
key
,
get_formstr_data
(
format
,
str
),
str
->
len
+
1
);
file
=
get_loaded_file
(
format
->
package
,
key
);
if
(
!
file
)
goto
done
;
if
(
!
shortname
)
{
ret
=
strdupW
(
file
->
TargetPath
);
goto
done
;
}
size
=
GetShortPathNameW
(
file
->
TargetPath
,
NULL
,
0
);
if
(
size
<=
0
)
{
ret
=
strdupW
(
file
->
TargetPath
);
goto
done
;
}
size
++
;
ret
=
msi_alloc
(
size
*
sizeof
(
WCHAR
));
GetShortPathNameW
(
file
->
TargetPath
,
ret
,
size
);
done:
msi_free
(
key
);
return
ret
;
}
static
LPWSTR
deformat_environment
(
FORMAT
*
format
,
FORMSTR
*
str
)
{
LPWSTR
key
,
ret
=
NULL
;
DWORD
sz
;
key
=
msi_alloc
((
str
->
len
+
1
)
*
sizeof
(
WCHAR
));
lstrcpynW
(
key
,
get_formstr_data
(
format
,
str
),
str
->
len
+
1
);
sz
=
GetEnvironmentVariableW
(
key
,
NULL
,
0
);
if
(
sz
<=
0
)
goto
done
;
sz
++
;
ret
=
msi_alloc
(
sz
*
sizeof
(
WCHAR
));
GetEnvironmentVariableW
(
key
,
ret
,
sz
);
done:
msi_free
(
key
);
return
ret
;
}
static
LPWSTR
deformat_literal
(
FORMAT
*
format
,
FORMSTR
*
str
,
BOOL
*
propfound
,
BOOL
*
nonprop
,
int
*
type
)
{
LPCWSTR
data
=
get_formstr_data
(
format
,
str
);
LPWSTR
replaced
=
NULL
;
char
ch
=
data
[
0
];
if
(
ch
==
'\\'
)
{
str
->
n
++
;
if
(
str
->
len
==
1
)
{
str
->
len
=
0
;
replaced
=
NULL
;
}
else
{
str
->
len
=
1
;
replaced
=
dup_formstr
(
format
,
str
);
}
}
else
if
(
ch
==
'~'
)
{
if
(
str
->
len
!=
1
)
replaced
=
NULL
;
else
{
replaced
=
msi_alloc
(
sizeof
(
WCHAR
));
*
replaced
=
'\0'
;
}
}
else
if
(
ch
==
'%'
||
ch
==
'#'
||
ch
==
'!'
||
ch
==
'$'
)
{
str
->
n
++
;
str
->
len
--
;
switch
(
ch
)
{
case
'%'
:
replaced
=
deformat_environment
(
format
,
str
);
break
;
case
'#'
:
replaced
=
deformat_file
(
format
,
str
,
FALSE
);
break
;
case
'!'
:
replaced
=
deformat_file
(
format
,
str
,
TRUE
);
break
;
case
'$'
:
replaced
=
deformat_component
(
format
,
str
);
break
;
}
*
type
=
FORMAT_LITERAL
;
}
else
{
replaced
=
deformat_property
(
format
,
str
);
*
type
=
FORMAT_LITERAL
;
if
(
replaced
)
*
propfound
=
TRUE
;
else
format
->
propfailed
=
TRUE
;
}
return
replaced
;
}
static
LPWSTR
build_default_format
(
const
MSIRECORD
*
record
)
{
...
...
@@ -70,7 +343,7 @@ static LPWSTR build_default_format(const MSIRECORD* record)
size
=
1
;
for
(
i
=
1
;
i
<=
count
;
i
++
)
{
sprintfW
(
index
,
fmt_index
,
i
);
sprintfW
(
index
,
fmt_index
,
i
);
str
=
MSI_RecordGetString
(
record
,
i
);
len
=
(
str
)
?
lstrlenW
(
str
)
:
0
;
len
+=
(
sizeof
(
fmt_null
)
-
3
)
+
lstrlenW
(
index
);
...
...
@@ -84,9 +357,9 @@ static LPWSTR build_default_format(const MSIRECORD* record)
}
if
(
str
)
sprintfW
(
buf
,
fmt
,
i
,
str
);
sprintfW
(
buf
,
fmt
,
i
,
str
);
else
sprintfW
(
buf
,
fmt_null
,
i
);
sprintfW
(
buf
,
fmt_null
,
i
);
if
(
!
rc
)
{
...
...
@@ -99,516 +372,493 @@ static LPWSTR build_default_format(const MSIRECORD* record)
lstrcatW
(
rc
,
buf
);
}
}
msi_free
(
buf
);
return
rc
;
}
static
const
WCHAR
*
scanW
(
LPCWSTR
buf
,
WCHAR
token
,
DWORD
len
)
static
BOOL
format_is_number
(
WCHAR
x
)
{
DWORD
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
if
(
buf
[
i
]
==
token
)
return
&
buf
[
i
];
return
NULL
;
return
((
x
>=
'0'
)
&&
(
x
<=
'9'
));
}
/* break out helper functions for deformating */
static
LPWSTR
deformat_component
(
MSIPACKAGE
*
package
,
LPCWSTR
key
,
DWORD
*
sz
)
static
BOOL
format_str_is_number
(
LPWSTR
str
)
{
LPWSTR
value
=
NULL
;
MSICOMPONENT
*
comp
;
BOOL
source
;
LPWSTR
ptr
;
*
sz
=
0
;
if
(
!
package
)
return
NULL
;
for
(
ptr
=
str
;
*
ptr
;
ptr
++
)
if
(
!
format_is_number
(
*
ptr
)
)
return
FALSE
;
comp
=
get_loaded_component
(
package
,
key
);
if
(
comp
)
{
source
=
(
comp
->
Action
==
INSTALLSTATE_SOURCE
)
?
TRUE
:
FALSE
;
value
=
resolve_folder
(
package
,
comp
->
Directory
,
source
,
FALSE
,
TRUE
,
NULL
);
*
sz
=
(
strlenW
(
value
))
*
sizeof
(
WCHAR
);
}
return
TRUE
;
}
return
value
;
static
BOOL
format_is_alpha
(
x
)
{
return
(
!
format_is_number
(
x
)
&&
x
!=
'\0'
&&
x
!=
'['
&&
x
!=
']'
&&
x
!=
'{'
&&
x
!=
'}'
);
}
static
LPWSTR
deformat_file
(
MSIPACKAGE
*
package
,
LPCWSTR
key
,
DWORD
*
sz
,
BOOL
shortname
)
static
BOOL
format_is_literal
(
x
)
{
LPWSTR
value
=
NULL
;
MSIFILE
*
file
;
return
(
format_is_alpha
(
x
)
||
format_is_number
(
x
))
;
}
*
sz
=
0
;
static
int
format_lex
(
FORMAT
*
format
,
FORMSTR
**
out
)
{
int
type
,
len
=
1
;
FORMSTR
*
str
;
LPCWSTR
data
;
WCHAR
ch
;
if
(
!
package
)
return
NULL
;
*
out
=
NULL
;
file
=
get_loaded_file
(
package
,
key
);
if
(
file
)
if
(
!
format
->
deformatted
)
return
FORMAT_NULL
;
*
out
=
msi_alloc_zero
(
sizeof
(
FORMSTR
));
if
(
!*
out
)
return
FORMAT_FAIL
;
str
=
*
out
;
str
->
n
=
format
->
n
;
str
->
len
=
1
;
data
=
get_formstr_data
(
format
,
str
);
ch
=
data
[
0
];
switch
(
ch
)
{
if
(
!
shortname
)
{
value
=
strdupW
(
file
->
TargetPath
);
*
sz
=
(
strlenW
(
value
))
*
sizeof
(
WCHAR
);
}
else
case
'{'
:
type
=
FORMAT_LBRACE
;
break
;
case
'}'
:
type
=
FORMAT_RBRACE
;
break
;
case
'['
:
type
=
FORMAT_LBRACK
;
break
;
case
']'
:
type
=
FORMAT_RBRACK
;
break
;
case
'~'
:
type
=
FORMAT_PROPNULL
;
break
;
case
'\0'
:
type
=
FORMAT_NULL
;
break
;
default:
type
=
0
;
}
if
(
type
)
{
str
->
type
=
type
;
format
->
n
++
;
return
type
;
}
if
(
ch
==
'\\'
)
{
while
(
data
[
len
]
&&
data
[
len
]
!=
']'
)
len
++
;
type
=
FORMAT_ESCAPE
;
}
else
if
(
format_is_alpha
(
ch
))
{
while
(
format_is_literal
(
data
[
len
]))
len
++
;
type
=
FORMAT_LITERAL
;
}
else
if
(
format_is_number
(
ch
))
{
while
(
format_is_number
(
data
[
len
]))
len
++
;
type
=
FORMAT_NUMBER
;
if
(
data
[
len
]
!=
']'
)
{
DWORD
size
=
0
;
size
=
GetShortPathNameW
(
file
->
TargetPath
,
NULL
,
0
)
;
while
(
format_is_literal
(
data
[
len
]))
len
++
;
if
(
size
>
0
)
{
*
sz
=
(
size
-
1
)
*
sizeof
(
WCHAR
);
size
++
;
value
=
msi_alloc
(
size
*
sizeof
(
WCHAR
));
GetShortPathNameW
(
file
->
TargetPath
,
value
,
size
);
}
else
{
value
=
strdupW
(
file
->
TargetPath
);
*
sz
=
(
lstrlenW
(
value
))
*
sizeof
(
WCHAR
);
}
type
=
FORMAT_LITERAL
;
}
}
else
{
ERR
(
"Got unknown character %c(%x)
\n
"
,
ch
,
ch
);
return
FORMAT_ERROR
;
}
format
->
n
+=
len
;
str
->
len
=
len
;
str
->
type
=
type
;
return
valu
e
;
return
typ
e
;
}
static
LPWSTR
deformat_environment
(
MSIPACKAGE
*
package
,
LPCWSTR
key
,
DWORD
*
chunk
)
static
FORMSTR
*
format_replace
(
FORMAT
*
format
,
BOOL
propfound
,
BOOL
nonprop
,
int
oldsize
,
int
type
,
LPWSTR
replace
)
{
LPWSTR
value
=
NULL
;
DWORD
sz
;
FORMSTR
*
ret
;
LPWSTR
str
,
ptr
;
DWORD
size
=
0
;
int
n
;
sz
=
GetEnvironmentVariableW
(
key
,
NULL
,
0
);
if
(
sz
>
0
)
if
(
replace
)
{
sz
++
;
value
=
msi_alloc
(
sz
*
sizeof
(
WCHAR
))
;
GetEnvironmentVariableW
(
key
,
value
,
sz
);
*
chunk
=
(
strlenW
(
value
))
*
sizeof
(
WCHAR
);
if
(
!*
replace
)
size
=
1
;
else
size
=
lstrlenW
(
replace
);
}
else
size
-=
oldsize
;
size
=
format
->
len
+
size
+
1
;
if
(
size
<=
1
)
{
WARN
(
"Unknown environment variable %s
\n
"
,
debugstr_w
(
key
));
*
chunk
=
0
;
value
=
NULL
;
msi_free
(
format
->
deformatted
);
format
->
deformatted
=
NULL
;
format
->
len
=
0
;
return
NULL
;
}
return
value
;
}
static
LPWSTR
deformat_NULL
(
DWORD
*
chunk
)
{
LPWSTR
value
;
str
=
msi_alloc
(
size
*
sizeof
(
WCHAR
));
if
(
!
str
)
return
NULL
;
value
=
msi_alloc
(
sizeof
(
WCHAR
)
*
2
);
value
[
0
]
=
0
;
*
chunk
=
sizeof
(
WCHAR
);
return
value
;
}
str
[
0
]
=
'\0'
;
memcpy
(
str
,
format
->
deformatted
,
format
->
n
*
sizeof
(
WCHAR
));
n
=
format
->
n
;
static
LPWSTR
deformat_escape
(
LPCWSTR
key
,
DWORD
*
chunk
)
{
LPWSTR
value
;
if
(
replace
)
{
if
(
!*
replace
)
{
str
[
n
]
=
'\0'
;
n
++
;
}
else
{
lstrcpyW
(
&
str
[
n
],
replace
);
n
+=
lstrlenW
(
replace
);
}
}
value
=
msi_alloc
(
sizeof
(
WCHAR
)
*
2
);
value
[
0
]
=
key
[
0
];
*
chunk
=
sizeof
(
WCHAR
);
ptr
=
&
format
->
deformatted
[
format
->
n
+
oldsize
];
memcpy
(
&
str
[
n
],
ptr
,
(
lstrlenW
(
ptr
)
+
1
)
*
sizeof
(
WCHAR
));
return
value
;
}
msi_free
(
format
->
deformatted
);
format
->
deformatted
=
str
;
format
->
len
=
size
-
1
;
if
(
!
replace
)
return
NULL
;
static
BOOL
is_key_number
(
LPCWSTR
key
)
{
INT
index
=
0
;
if
(
key
[
0
]
==
0
)
return
FALSE
;
ret
=
msi_alloc_zero
(
sizeof
(
FORMSTR
));
if
(
!
ret
)
return
NULL
;
while
(
isdigitW
(
key
[
index
]))
index
++
;
if
(
key
[
index
]
==
0
)
return
TRUE
;
else
return
FALSE
;
ret
->
len
=
lstrlenW
(
replace
);
ret
->
type
=
type
;
ret
->
n
=
format
->
n
;
ret
->
propfound
=
propfound
;
ret
->
nonprop
=
nonprop
;
return
ret
;
}
static
LPWSTR
deformat_index
(
MSIRECORD
*
record
,
LPCWSTR
key
,
DWORD
*
chunk
)
static
LPWSTR
replace_stack_group
(
FORMAT
*
format
,
STACK
*
values
,
BOOL
*
propfound
,
BOOL
*
nonprop
,
int
*
oldsize
,
int
*
type
)
{
INT
index
;
LPWSTR
value
;
LPWSTR
replaced
=
NULL
;
FORMSTR
*
content
;
FORMSTR
*
node
;
int
n
;
index
=
atoiW
(
key
);
TRACE
(
"record index %i
\n
"
,
index
);
value
=
msi_dup_record_field
(
record
,
index
);
if
(
value
)
*
chunk
=
strlenW
(
value
)
*
sizeof
(
WCHAR
);
else
*
nonprop
=
FALSE
;
*
propfound
=
FALSE
;
node
=
stack_pop
(
values
);
n
=
node
->
n
;
*
oldsize
=
node
->
len
;
msi_free
(
node
);
while
((
node
=
stack_pop
(
values
)))
{
value
=
NULL
;
*
chunk
=
0
;
*
oldsize
+=
node
->
len
;
if
(
node
->
nonprop
)
*
nonprop
=
TRUE
;
if
(
node
->
propfound
)
*
propfound
=
TRUE
;
msi_free
(
node
);
}
return
value
;
}
static
LPWSTR
deformat_property
(
MSIPACKAGE
*
package
,
LPCWSTR
key
,
DWORD
*
chunk
)
{
LPWSTR
value
;
content
=
msi_alloc_zero
(
sizeof
(
FORMSTR
));
content
->
n
=
n
;
content
->
len
=
*
oldsize
;
content
->
type
=
FORMAT_LITERAL
;
if
(
!
package
)
if
(
!
format
->
groupfailed
&&
(
*
oldsize
==
2
||
(
format
->
propfailed
&&
!*
nonprop
)))
{
msi_free
(
content
);
return
NULL
;
}
else
if
(
format
->
deformatted
[
content
->
n
+
1
]
==
'{'
&&
format
->
deformatted
[
content
->
n
+
content
->
len
-
2
]
==
'}'
)
{
format
->
groupfailed
=
FALSE
;
content
->
len
=
0
;
}
else
if
(
*
propfound
&&
!*
nonprop
&&
!
format
->
groupfailed
&&
format
->
groups
==
0
)
{
content
->
n
++
;
content
->
len
-=
2
;
}
else
{
if
(
format
->
groups
!=
0
)
format
->
groupfailed
=
TRUE
;
value
=
msi_dup_property
(
package
,
key
);
*
nonprop
=
TRUE
;
}
if
(
value
)
*
chunk
=
(
strlenW
(
value
))
*
sizeof
(
WCHAR
);
replaced
=
dup_formstr
(
format
,
content
);
*
type
=
content
->
type
;
msi_free
(
content
);
return
value
;
if
(
format
->
groups
==
0
)
format
->
propfailed
=
FALSE
;
return
replaced
;
}
/*
* Groups cannot be nested. They are just treated as from { to next }
*/
static
BOOL
find_next_group
(
LPCWSTR
source
,
DWORD
len_remaining
,
LPWSTR
*
group
,
LPCWSTR
*
mark
,
LPCWSTR
*
mark2
)
static
LPWSTR
replace_stack_prop
(
FORMAT
*
format
,
STACK
*
values
,
BOOL
*
propfound
,
BOOL
*
nonprop
,
int
*
oldsize
,
int
*
type
)
{
int
i
;
BOOL
found
=
FALSE
;
LPWSTR
replaced
=
NULL
;
FORMSTR
*
content
;
FORMSTR
*
node
;
int
n
;
*
mark
=
scanW
(
source
,
'{'
,
len_remaining
);
if
(
!*
mark
)
return
FALSE
;
*
propfound
=
FALSE
;
*
nonprop
=
FALSE
;
for
(
i
=
1
;
(
*
mark
-
source
)
+
i
<
len_remaining
;
i
++
)
node
=
stack_pop
(
values
);
n
=
node
->
n
;
*
oldsize
=
node
->
len
;
*
type
=
stack_peek
(
values
)
->
type
;
msi_free
(
node
);
while
((
node
=
stack_pop
(
values
)))
{
if
((
*
mark
)[
i
]
==
'}'
)
{
found
=
TRUE
;
break
;
}
*
oldsize
+=
node
->
len
;
if
(
*
type
!=
FORMAT_ESCAPE
&&
stack_peek
(
values
)
&&
node
->
type
!=
*
type
)
*
type
=
FORMAT_LITERAL
;
msi_free
(
node
);
}
if
(
!
found
)
return
FALSE
;
*
mark2
=
&
(
*
mark
)[
i
];
content
=
msi_alloc_zero
(
sizeof
(
FORMSTR
));
content
->
n
=
n
+
1
;
content
->
len
=
*
oldsize
-
2
;
content
->
type
=
*
type
;
i
=
*
mark2
-
*
mark
;
*
group
=
msi_alloc
(
i
*
sizeof
(
WCHAR
));
if
(
*
type
==
FORMAT_NUMBER
)
{
replaced
=
deformat_index
(
format
,
content
);
if
(
replaced
)
*
propfound
=
TRUE
;
else
format
->
propfailed
=
TRUE
;
i
-=
1
;
memcpy
(
*
group
,
&
(
*
mark
)[
1
],
i
*
sizeof
(
WCHAR
));
(
*
group
)[
i
]
=
0
;
if
(
replaced
)
*
type
=
format_str_is_number
(
replaced
)
?
FORMAT_NUMBER
:
FORMAT_LITERAL
;
}
else
if
(
format
->
package
)
{
replaced
=
deformat_literal
(
format
,
content
,
propfound
,
nonprop
,
type
);
}
else
{
*
nonprop
=
TRUE
;
content
->
n
--
;
content
->
len
+=
2
;
replaced
=
dup_formstr
(
format
,
content
);
}
TRACE
(
"Found group %s
\n
"
,
debugstr_w
(
*
group
)
);
return
TRUE
;
msi_free
(
content
);
return
replaced
;
}
static
BOOL
find_next_outermost_key
(
LPCWSTR
source
,
DWORD
len_remaining
,
LPWSTR
*
key
,
LPCWSTR
*
mark
,
LPCWSTR
*
mark2
,
BOOL
*
nested
)
static
UINT
replace_stack
(
FORMAT
*
format
,
STACK
*
stack
,
STACK
*
values
)
{
INT
count
=
0
;
INT
total_count
=
0
;
int
i
;
LPWSTR
replaced
=
NULL
;
FORMSTR
*
beg
;
FORMSTR
*
top
;
FORMSTR
*
node
;
BOOL
propfound
=
FALSE
;
BOOL
nonprop
=
FALSE
;
BOOL
group
=
FALSE
;
int
oldsize
=
0
;
int
type
,
n
;
node
=
stack_peek
(
values
);
type
=
node
->
type
;
n
=
node
->
n
;
if
(
type
==
FORMAT_LBRACK
)
replaced
=
replace_stack_prop
(
format
,
values
,
&
propfound
,
&
nonprop
,
&
oldsize
,
&
type
);
else
if
(
type
==
FORMAT_LBRACE
)
{
replaced
=
replace_stack_group
(
format
,
values
,
&
propfound
,
&
nonprop
,
&
oldsize
,
&
type
);
group
=
TRUE
;
}
*
nested
=
FALSE
;
*
mark
=
scanW
(
source
,
'['
,
len_remaining
);
if
(
!*
mark
)
return
FALSE
;
format
->
n
=
n
;
beg
=
format_replace
(
format
,
propfound
,
nonprop
,
oldsize
,
type
,
replaced
);
if
(
!
beg
)
return
ERROR_SUCCESS
;
msi_free
(
replaced
);
format
->
n
=
beg
->
n
+
beg
->
len
;
if
(
type
==
FORMAT_PROPNULL
)
format
->
n
++
;
count
=
1
;
total_count
=
1
;
for
(
i
=
1
;
(
*
mark
-
source
)
+
i
<
len_remaining
&&
count
>
0
;
i
++
)
top
=
stack_peek
(
stack
);
if
(
top
)
{
if
((
*
mark
)[
i
]
==
'['
&&
(
*
mark
)[
i
-
1
]
!=
'\\'
)
{
count
++
;
total_count
++
;
*
nested
=
TRUE
;
}
else
if
((
*
mark
)[
i
]
==
']'
&&
(
*
mark
)[
i
-
1
]
!=
'\\'
)
type
=
top
->
type
;
if
((
type
==
FORMAT_LITERAL
||
type
==
FORMAT_NUMBER
)
&&
type
==
beg
->
type
)
{
count
--
;
}
}
top
->
len
+=
beg
->
len
;
if
(
count
>
0
)
return
FALSE
;
if
(
group
)
top
->
nonprop
=
FALSE
;
*
mark2
=
&
(
*
mark
)[
i
-
1
];
if
(
type
==
FORMAT_LITERAL
)
top
->
nonprop
=
beg
->
nonprop
;
i
=
*
mark2
-
*
mark
;
*
key
=
msi_alloc
(
i
*
sizeof
(
WCHAR
));
/* do not have the [] in the key */
i
-=
1
;
memcpy
(
*
key
,
&
(
*
mark
)[
1
],
i
*
sizeof
(
WCHAR
));
(
*
key
)[
i
]
=
0
;
if
(
beg
->
propfound
)
top
->
propfound
=
TRUE
;
TRACE
(
"Found Key %s
\n
"
,
debugstr_w
(
*
key
));
return
TRUE
;
msi_free
(
beg
);
return
ERROR_SUCCESS
;
}
}
stack_push
(
stack
,
beg
);
return
ERROR_SUCCESS
;
}
static
LPWSTR
deformat_group
(
MSIPACKAGE
*
package
,
LPWSTR
group
,
DWORD
len
,
MSIRECORD
*
record
,
DWORD
*
size
)
static
BOOL
verify_format
(
LPWSTR
data
)
{
LPWSTR
value
=
NULL
;
LPCWSTR
mark
,
mark2
;
LPWSTR
key
;
BOOL
nested
;
INT
failcount
;
static
const
WCHAR
fmt
[]
=
{
'{'
,
'%'
,
's'
,
'}'
,
0
};
UINT
sz
;
int
count
=
0
;
if
(
!
group
||
group
[
0
]
==
0
)
while
(
*
data
)
{
*
size
=
0
;
return
NULL
;
if
(
*
data
==
'['
&&
*
(
data
-
1
)
!=
'\\'
)
count
++
;
else
if
(
*
data
==
']'
)
count
--
;
data
++
;
}
/* if no [] then group is returned as is */
if
(
!
find_next_outermost_key
(
group
,
len
,
&
key
,
&
mark
,
&
mark2
,
&
nested
))
{
*
size
=
(
len
+
2
)
*
sizeof
(
WCHAR
);
value
=
msi_alloc
(
*
size
);
sprintfW
(
value
,
fmt
,
group
);
/* do not return size of the null at the end */
*
size
=
(
len
+
1
)
*
sizeof
(
WCHAR
);
return
value
;
}
msi_free
(
key
);
failcount
=
0
;
sz
=
deformat_string_internal
(
package
,
group
,
&
value
,
strlenW
(
group
),
record
,
&
failcount
);
if
(
failcount
==
0
)
{
*
size
=
sz
*
sizeof
(
WCHAR
);
return
value
;
}
else
if
(
failcount
<
0
)
{
LPWSTR
v2
;
v2
=
msi_alloc
((
sz
+
2
)
*
sizeof
(
WCHAR
));
v2
[
0
]
=
'{'
;
memcpy
(
&
v2
[
1
],
value
,
sz
*
sizeof
(
WCHAR
));
v2
[
sz
+
1
]
=
'}'
;
msi_free
(
value
);
*
size
=
(
sz
+
2
)
*
sizeof
(
WCHAR
);
return
v2
;
}
else
{
msi_free
(
value
);
*
size
=
0
;
return
NULL
;
}
}
if
(
count
>
0
)
return
FALSE
;
return
TRUE
;
}
/*
* len is in WCHARs
* return is also in WCHARs
*/
static
DWORD
deformat_string_internal
(
MSIPACKAGE
*
package
,
LPCWSTR
ptr
,
WCHAR
**
data
,
DWORD
len
,
MSIRECORD
*
record
,
INT
*
failcount
)
{
LPCWSTR
mark
=
NULL
;
LPCWSTR
mark2
=
NULL
;
DWORD
size
=
0
;
DWORD
chunk
=
0
;
LPWSTR
key
;
LPWSTR
value
=
NULL
;
DWORD
sz
;
LPBYTE
newdata
=
NULL
;
const
WCHAR
*
progress
=
NULL
;
BOOL
nested
=
FALSE
;
WCHAR
**
data
,
DWORD
*
len
,
MSIRECORD
*
record
,
INT
*
failcount
)
{
FORMAT
format
;
FORMSTR
*
str
=
NULL
;
STACK
*
stack
,
*
temp
;
FORMSTR
*
node
;
int
type
;
if
(
ptr
==
NULL
)
if
(
!
ptr
)
{
TRACE
(
"Deformatting NULL string
\n
"
);
*
data
=
NULL
;
return
0
;
*
len
=
0
;
return
ERROR_SUCCESS
;
}
TRACE
(
"Starting with %s
\n
"
,
debugstr_wn
(
ptr
,
len
));
*
data
=
strdupW
(
ptr
);
*
len
=
lstrlenW
(
ptr
);
/* scan for special characters... fast exit */
if
((
!
scanW
(
ptr
,
'['
,
len
)
||
(
scanW
(
ptr
,
'['
,
len
)
&&
!
scanW
(
ptr
,
']'
,
len
)))
&&
(
scanW
(
ptr
,
'{'
,
len
)
&&
!
scanW
(
ptr
,
'}'
,
len
)))
{
/* not formatted */
*
data
=
msi_alloc
((
len
*
sizeof
(
WCHAR
)));
memcpy
(
*
data
,
ptr
,
len
*
sizeof
(
WCHAR
));
TRACE
(
"Returning %s
\n
"
,
debugstr_wn
(
*
data
,
len
));
return
len
;
}
progress
=
ptr
;
ZeroMemory
(
&
format
,
sizeof
(
FORMAT
));
format
.
package
=
package
;
format
.
record
=
record
;
format
.
deformatted
=
*
data
;
format
.
len
=
*
len
;
while
(
progress
-
ptr
<
len
)
{
/* seek out first group if existing */
if
(
find_next_group
(
progress
,
len
-
(
progress
-
ptr
),
&
key
,
&
mark
,
&
mark2
))
{
value
=
deformat_group
(
package
,
key
,
strlenW
(
key
)
+
1
,
record
,
&
chunk
);
msi_free
(
key
);
key
=
NULL
;
nested
=
FALSE
;
}
/* formatted string located */
else
if
(
!
find_next_outermost_key
(
progress
,
len
-
(
progress
-
ptr
),
&
key
,
&
mark
,
&
mark2
,
&
nested
))
{
LPBYTE
nd2
;
TRACE
(
"after value %s
\n
"
,
debugstr_wn
((
LPWSTR
)
newdata
,
size
/
sizeof
(
WCHAR
)));
chunk
=
(
len
-
(
progress
-
ptr
))
*
sizeof
(
WCHAR
);
TRACE
(
"after chunk is %i + %i
\n
"
,
size
,
chunk
);
if
(
size
)
nd2
=
msi_realloc
(
newdata
,(
size
+
chunk
));
else
nd2
=
msi_alloc
(
chunk
);
newdata
=
nd2
;
memcpy
(
&
newdata
[
size
],
progress
,
chunk
);
size
+=
chunk
;
break
;
}
stack
=
create_stack
();
temp
=
create_stack
();
if
(
mark
!=
progress
)
{
LPBYTE
tgt
;
DWORD
old_size
=
size
;
INT
cnt
=
(
mark
-
progress
);
TRACE
(
"%i (%i) characters before marker
\n
"
,
cnt
,(
mark
-
progress
));
size
+=
cnt
*
sizeof
(
WCHAR
);
if
(
!
old_size
)
tgt
=
msi_alloc
(
size
);
else
tgt
=
msi_realloc
(
newdata
,
size
);
newdata
=
tgt
;
memcpy
(
&
newdata
[
old_size
],
progress
,(
cnt
*
sizeof
(
WCHAR
)));
}
if
(
!
verify_format
(
*
data
))
return
ERROR_SUCCESS
;
progress
=
mark
;
if
(
nested
)
{
TRACE
(
"Nested key... %s
\n
"
,
debugstr_w
(
key
));
deformat_string_internal
(
package
,
key
,
&
value
,
strlenW
(
key
)
+
1
,
record
,
failcount
);
msi_free
(
key
);
key
=
value
;
}
TRACE
(
"Current %s .. %s
\n
"
,
debugstr_wn
((
LPWSTR
)
newdata
,
size
/
sizeof
(
WCHAR
)),
debugstr_w
(
key
));
if
(
!
package
)
while
((
type
=
format_lex
(
&
format
,
&
str
))
!=
FORMAT_NULL
)
{
if
(
type
==
FORMAT_LBRACK
||
type
==
FORMAT_LBRACE
||
type
==
FORMAT_LITERAL
||
type
==
FORMAT_NUMBER
||
type
==
FORMAT_ESCAPE
||
type
==
FORMAT_PROPNULL
)
{
/* only deformat number indexs */
if
(
key
&&
is_key_number
(
key
))
if
(
type
==
FORMAT_LBRACE
)
{
value
=
deformat_index
(
record
,
key
,
&
chunk
);
if
(
!
chunk
&&
failcount
&&
*
failcount
>=
0
)
(
*
failcount
)
++
;
format
.
propfailed
=
FALSE
;
format
.
groups
++
;
}
else
else
if
(
type
==
FORMAT_ESCAPE
&&
!
stack_find
(
stack
,
FORMAT_LBRACK
))
{
if
(
failcount
)
*
failcount
=
-
1
;
if
(
key
)
{
DWORD
keylen
=
strlenW
(
key
);
chunk
=
(
keylen
+
2
)
*
sizeof
(
WCHAR
);
value
=
msi_alloc
(
chunk
);
value
[
0
]
=
'['
;
memcpy
(
&
value
[
1
],
key
,
keylen
*
sizeof
(
WCHAR
));
value
[
1
+
keylen
]
=
']'
;
}
format
.
n
-=
str
->
len
-
1
;
str
->
len
=
1
;
}
stack_push
(
stack
,
str
);
}
else
else
if
(
type
==
FORMAT_RBRACK
||
type
==
FORMAT_RBRACE
)
{
sz
=
0
;
if
(
key
)
switch
(
key
[
0
])
{
case
'~'
:
value
=
deformat_NULL
(
&
chunk
);
break
;
case
'$'
:
value
=
deformat_component
(
package
,
&
key
[
1
],
&
chunk
);
break
;
case
'#'
:
value
=
deformat_file
(
package
,
&
key
[
1
],
&
chunk
,
FALSE
);
break
;
case
'!'
:
/* should be short path */
value
=
deformat_file
(
package
,
&
key
[
1
],
&
chunk
,
TRUE
);
break
;
case
'\\'
:
value
=
deformat_escape
(
&
key
[
1
],
&
chunk
);
break
;
case
'%'
:
value
=
deformat_environment
(
package
,
&
key
[
1
],
&
chunk
);
break
;
default:
/* index keys cannot be nested */
if
(
is_key_number
(
key
))
if
(
!
nested
)
value
=
deformat_index
(
record
,
key
,
&
chunk
);
else
{
static
const
WCHAR
fmt
[]
=
{
'['
,
'%'
,
's'
,
']'
,
0
};
value
=
msi_alloc
(
10
);
sprintfW
(
value
,
fmt
,
key
);
chunk
=
strlenW
(
value
)
*
sizeof
(
WCHAR
);
}
else
value
=
deformat_property
(
package
,
key
,
&
chunk
);
break
;
}
}
if
(
type
==
FORMAT_RBRACE
)
format
.
groups
--
;
msi_free
(
key
);
stack_push
(
stack
,
str
);
if
(
value
!=
NULL
)
{
LPBYTE
nd2
;
TRACE
(
"value %s, chunk %i size %i
\n
"
,
debugstr_w
(
value
),
chunk
,
size
);
if
(
size
)
nd2
=
msi_realloc
(
newdata
,(
size
+
chunk
));
else
nd2
=
msi_alloc
(
chunk
);
newdata
=
nd2
;
memcpy
(
&
newdata
[
size
],
value
,
chunk
);
size
+=
chunk
;
msi_free
(
value
);
}
else
if
(
failcount
&&
*
failcount
>=
0
)
(
*
failcount
)
++
;
if
(
stack_find
(
stack
,
left_type
(
type
)))
{
do
{
node
=
stack_pop
(
stack
);
stack_push
(
temp
,
node
);
}
while
(
node
->
type
!=
left_type
(
type
));
progress
=
mark2
+
1
;
replace_stack
(
&
format
,
stack
,
temp
);
}
}
}
TRACE
(
"after everything %s
\n
"
,
debugstr_wn
((
LPWSTR
)
newdata
,
size
/
sizeof
(
WCHAR
)))
;
*
data
=
format
.
deformatted
;
*
len
=
format
.
len
;
*
data
=
(
LPWSTR
)
newdata
;
return
size
/
sizeof
(
WCHAR
);
}
msi_free
(
str
)
;
free_stack
(
stack
);
free_stack
(
temp
);
return
ERROR_SUCCESS
;
}
UINT
MSI_FormatRecordW
(
MSIPACKAGE
*
package
,
MSIRECORD
*
record
,
LPWSTR
buffer
,
LPDWORD
size
)
...
...
@@ -626,9 +876,7 @@ UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer,
TRACE
(
"(%s)
\n
"
,
debugstr_w
(
rec
));
len
=
deformat_string_internal
(
package
,
rec
,
&
deformated
,
rec
?
strlenW
(
rec
)
:
0
,
record
,
NULL
);
deformat_string_internal
(
package
,
rec
,
&
deformated
,
&
len
,
record
,
NULL
);
if
(
buffer
)
{
if
(
*
size
>
len
)
...
...
@@ -770,8 +1018,8 @@ UINT WINAPI MsiFormatRecordA( MSIHANDLE hInstall, MSIHANDLE hRecord,
goto
done
;
save
=
len
+
1
;
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
value
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
WideCharToMultiByte
(
CP_ACP
,
0
,
value
,
-
1
,
szResult
,
*
sz
,
NULL
,
NULL
);
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
value
,
len
+
1
,
NULL
,
0
,
NULL
,
NULL
);
WideCharToMultiByte
(
CP_ACP
,
0
,
value
,
len
,
szResult
,
*
sz
,
NULL
,
NULL
);
if
(
szResult
&&
len
>
*
sz
)
{
...
...
dlls/msi/tests/format.c
View file @
5a0d459c
...
...
@@ -517,7 +517,6 @@ static void test_formatrecord(void)
ok
(
sz
==
7
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"boo hoo"
),
"wrong output
\n
"
);
/* empty string */
r
=
MsiRecordSetString
(
hrec
,
0
,
""
);
sz
=
sizeof
buffer
;
...
...
@@ -734,11 +733,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
16
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{{2hey}1[dummy]}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1][2]}[3]{[4][dummy]}}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"2"
);
...
...
@@ -750,10 +746,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
0
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1][2]}[3]} {[1][2]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"1"
);
...
...
@@ -765,10 +759,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
12
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{{12}3} {12}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[1][2]} {{[1][2]}[3]} {[1][2]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"1"
);
...
...
@@ -780,10 +772,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
15
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"12 {{12}3} {12}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"1"
);
...
...
@@ -795,11 +785,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
15
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"12 {{12}3} {12}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{blah} {[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"1"
);
...
...
@@ -811,10 +798,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
22
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{blah} 12 {{12}3} {12}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1]}[2]} {[4]}{[1][2]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"1"
);
...
...
@@ -826,10 +811,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
13
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{{1}2} {}{12}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1]}} {[4]}{[1][2]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"1"
);
...
...
@@ -841,10 +824,8 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
3
,
"size wrong,(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
" 12"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{{[1]}} {[4]}{[1][2]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"1"
);
...
...
@@ -1015,61 +996,54 @@ static void test_formatrecord(void)
ok
(
0
==
strcmp
(
buffer
,
"boo hoo"
),
"wrong output
\n
"
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1]}}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
0
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{ {[1]}}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
0
==
strcmp
(
buffer
,
" {hoo}"
),
"wrong output
\n
"
);
ok
(
sz
==
6
,
"size wrong
\n
"
);
todo_wine
{
ok
(
0
==
strcmp
(
buffer
,
" {hoo}"
),
"wrong output
\n
"
);
ok
(
sz
==
6
,
"size wrong
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1]} }"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
8
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{{hoo} }"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{ [1]}}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
0
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1] }}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
0
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{a}{b}{c }{ d}{any text}}"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
0
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{a} }"
);
...
...
@@ -1079,13 +1053,11 @@ static void test_formatrecord(void)
ok
(
0
==
strcmp
(
buffer
,
"{{a} }"
),
"wrong output
\n
"
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{a} {b}}"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
0
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
...
...
@@ -1097,13 +1069,11 @@ static void test_formatrecord(void)
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{a b}}"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
0
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{ }"
);
...
...
@@ -1113,13 +1083,11 @@ static void test_formatrecord(void)
ok
(
0
==
strcmp
(
buffer
,
"{ }"
),
"wrong output
\n
"
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
" {{a}}}"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
2
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
" }"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
...
...
@@ -1174,6 +1142,14 @@ static void test_formatrecord(void)
ok
(
0
==
strcmp
(
buffer
,
"[
\\
[]"
),
"wrong output
\n
"
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
MsiRecordSetString
(
hrec
,
0
,
"[
\\
[]"
);
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
(
buffer
);
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
sz
==
4
,
"Expected 4, got %d
\n
"
,
sz
);
ok
(
!
lstrcmpA
(
buffer
,
"[
\\
[]"
),
"Expected
\"
[
\\
[]
\"
, got
\"
%s
\"\n
"
,
buffer
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"[foo]"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
...
...
@@ -1198,44 +1174,36 @@ static void test_formatrecord(void)
ok
(
0
==
strcmp
(
buffer
,
"[%FOO]"
),
"wrong output
\n
"
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
6
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{{hoo}"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{ {[1]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
8
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{{ {hoo}"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{ {[1]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
8
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{{ {hoo}"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{ {{[1]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{{ {{hoo}"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"[1]}"
);
...
...
@@ -1264,24 +1232,33 @@ static void test_formatrecord(void)
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
19
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"01{2{3{4hoo56}7}8}9"
),
"wrong output
\n
"
);
todo_wine
{
ok
(
sz
==
19
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"01{2{3{4hoo56}7}8}9"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"0{1{2[1]3}4"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"01{2hoo34"
),
"wrong output
\n
"
);
todo_wine
{
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"01{2hoo34"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"0{1{2[1]3}4"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"01{2hoo34"
),
"wrong output
\n
"
);
todo_wine
{
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"01{2hoo34"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[1.} [1]"
);
...
...
@@ -1289,7 +1266,10 @@ static void test_formatrecord(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{[1.} hoo"
),
"wrong output
\n
"
);
todo_wine
{
ok
(
0
==
strcmp
(
buffer
,
"{[1.} hoo"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[{[1]}]}"
);
...
...
@@ -1297,8 +1277,11 @@ static void test_formatrecord(void)
r
=
MsiRecordSetString
(
hrec
,
2
,
"foo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{[{[1]}]}"
),
"wrong output
\n
"
);
todo_wine
{
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{[{[1]}]}"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[1][}"
);
...
...
@@ -1306,8 +1289,11 @@ static void test_formatrecord(void)
r
=
MsiRecordSetString
(
hrec
,
2
,
"foo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
2
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"2["
),
"wrong output
\n
"
);
todo_wine
{
ok
(
sz
==
2
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"2["
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"[1]"
);
...
...
@@ -1319,17 +1305,17 @@ static void test_formatrecord(void)
ok
(
0
==
strcmp
(
buffer
,
"[2]"
),
"wrong output
\n
"
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"[{{boo}}1]"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
ok
(
sz
==
3
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[1]"
),
"wrong output
\n
"
);
todo_wine
{
ok
(
0
==
strcmp
(
buffer
,
"[1]"
),
"wrong output: %s
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"[{{boo}}1]"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"[1{{boo}}]"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
...
...
@@ -1337,33 +1323,36 @@ static void test_formatrecord(void)
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
3
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[1]"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[1]{{boo} }}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
11
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"hoo{{boo }}"
),
"wrong output
\n
"
);
todo_wine
{
ok
(
sz
==
11
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"hoo{{boo }}"
),
"wrong output
\n
"
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[1{{boo}}]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
12
,
"size wrong: got %u, expected 12
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{[1{{boo}}]}"
),
"wrong output: got %s, expected [1]
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
12
,
"size wrong: got %u, expected 12
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{[1{{boo}}]}"
),
"wrong output: got %s, expected [1]
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
r
=
MsiRecordSetString
(
hrec
,
0
,
"{{[1]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
6
,
"size wrong: got %u, expected 3
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{{hoo}"
),
"wrong output: got %s, expected [1]
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[1{{bo}o}}]}"
);
...
...
@@ -1377,16 +1366,22 @@ static void test_formatrecord(void)
r
=
MsiRecordSetString
(
hrec
,
0
,
"{[1{{b{o}o}}]}"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
14
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{[1{{b{o}o}}]}"
),
"wrong output %s
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
14
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{[1{{b{o}o}}]}"
),
"wrong output %s
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"{ {[1]}"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"hoo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
5
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
" {hoo"
),
"wrong output %s
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
5
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
" {hoo"
),
"wrong output %s
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
/* {} inside a substitution does strange things... */
...
...
@@ -1394,24 +1389,33 @@ static void test_formatrecord(void)
r
=
MsiRecordSetString
(
hrec
,
1
,
"2"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
5
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[[1]]"
),
"wrong output %s
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
5
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[[1]]"
),
"wrong output %s
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"[[1]{}[1]]"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"2"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
6
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[[1]2]"
),
"wrong output %s
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
6
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[[1]2]"
),
"wrong output %s
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"[a[1]b[1]c{}d[1]e]"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"2"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
14
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[a[1]b[1]cd2e]"
),
"wrong output %s
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
14
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"[a[1]b[1]cd2e]"
),
"wrong output %s
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
r
=
MsiRecordSetString
(
hrec
,
0
,
"[a[1]b"
);
...
...
@@ -1489,8 +1493,11 @@ static void test_formatrecord(void)
r
=
MsiRecordSetString
(
hrec
,
1
,
"foo"
);
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
sz
==
12
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{foo[-1]foo}"
),
"wrong output %s
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
12
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"{foo[-1]foo}"
),
"wrong output %s
\n
"
,
buffer
);
}
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
/* nested braces */
...
...
@@ -1540,31 +1547,22 @@ static void test_formatrecord(void)
MsiRecordSetString
(
hrec
,
0
,
"{abc}{{def}hi{j[one]k}}"
);
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
5
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{abc}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
ok
(
sz
==
5
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{abc}"
),
"wrong output (%s)
\n
"
,
buffer
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{{def}hi{j[one]k}}"
);
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
}
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{{def}hi{jk}}"
);
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
}
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{{{def}}hi{jk}}"
);
...
...
@@ -1590,21 +1588,15 @@ static void test_formatrecord(void)
MsiRecordSetString
(
hrec
,
0
,
"{{def}{jk}}"
);
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
}
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{{def}}"
);
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
}
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{a{b}c}"
);
...
...
@@ -1652,11 +1644,8 @@ static void test_formatrecord(void)
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
sz
==
33
,
"Expected 33, got %d
\n
"
,
sz
);
todo_wine
{
ok
(
!
lstrcmpA
(
buffer
,
"one {[noprop] [twoprop]} {abcdef}"
),
"Expected
\"
one {[noprop] [twoprop]} {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
}
ok
(
!
lstrcmpA
(
buffer
,
"one {[noprop] [twoprop]} {abcdef}"
),
"Expected
\"
one {[noprop] [twoprop]} {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
sz
=
sizeof
(
buffer
);
MsiRecordSetString
(
hrec
,
0
,
"[1] {[noprop] [one]} {abcdef}"
);
...
...
@@ -1664,11 +1653,8 @@ static void test_formatrecord(void)
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
sz
==
29
,
"Expected 29, got %d
\n
"
,
sz
);
todo_wine
{
ok
(
!
lstrcmpA
(
buffer
,
"one {[noprop] [one]} {abcdef}"
),
"Expected
\"
one {[noprop] [one]} {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
}
ok
(
!
lstrcmpA
(
buffer
,
"one {[noprop] [one]} {abcdef}"
),
"Expected
\"
one {[noprop] [one]} {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
sz
=
sizeof
(
buffer
);
MsiRecordSetString
(
hrec
,
0
,
"[1] {[one]} {abcdef}"
);
...
...
@@ -1676,11 +1662,8 @@ static void test_formatrecord(void)
r
=
MsiFormatRecord
(
0
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
sz
==
20
,
"Expected 20, got %d
\n
"
,
sz
);
todo_wine
{
ok
(
!
lstrcmpA
(
buffer
,
"one {[one]} {abcdef}"
),
"Expected
\"
one {[one]} {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
}
ok
(
!
lstrcmpA
(
buffer
,
"one {[one]} {abcdef}"
),
"Expected
\"
one {[one]} {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
MsiCloseHandle
(
hrec
);
}
...
...
@@ -1742,7 +1725,9 @@ static void test_formatrecord_package(void)
todo_wine
{
ok
(
sz
==
66
,
"size wrong (%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"1: [2] 2: stuff 3: prop 4: val 5: 6: 7: 8: 9: 10: 11: 12: "
),
"wrong output(%s)
\n
"
,
buffer
);
ok
(
!
lstrcmpA
(
buffer
,
"1: [2] 2: stuff 3: prop 4: val 5: 6: 7: 8: 9: 10: 11: 12: "
),
"wrong output(%s)
\n
"
,
buffer
);
}
/* now put play games with escaping */
...
...
@@ -1904,8 +1889,10 @@ static void test_formatrecord_package(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
ok
(
sz
==
9
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"boo "
),
"wrong output
\n
"
);
ok
(
sz
==
9
,
"size wrong: %d
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"boo "
),
"wrong output: %s
\n
"
,
buffer
);
ok
(
!
lstrcmpA
(
&
buffer
[
5
],
" hoo"
),
"Expected
\"
hoo
\"
, got
\"
%s
\"\n
"
,
&
buffer
[
5
]);
MsiRecordSetString
(
hrec
,
0
,
"[1] [~abc] [2]"
);
MsiRecordSetString
(
hrec
,
1
,
"boo"
);
...
...
@@ -1913,12 +1900,8 @@ static void test_formatrecord_package(void)
sz
=
sizeof
(
buffer
);
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
todo_wine
{
ok
(
sz
==
8
,
"Expected 8, got %d
\n
"
,
sz
);
ok
(
!
lstrcmpA
(
buffer
,
"boo hoo"
),
"Expected
\"
boo hoo
\"
, got
\"
%s
\"\n
"
,
buffer
);
}
ok
(
sz
==
8
,
"Expected 8, got %d
\n
"
,
sz
);
ok
(
!
lstrcmpA
(
buffer
,
"boo hoo"
),
"Expected
\"
boo hoo
\"
, got
\"
%s
\"\n
"
,
buffer
);
/* properties */
r
=
MsiSetProperty
(
package
,
"dummy"
,
"Bork"
);
...
...
@@ -1943,7 +1926,6 @@ static void test_formatrecord_package(void)
ok
(
sz
==
8
,
"size wrong
\n
"
);
ok
(
0
==
strcmp
(
buffer
,
"boo hoo"
),
"wrong output
\n
"
);
/* nesting tests */
r
=
MsiSetProperty
(
package
,
"dummya"
,
"foo"
);
r
=
MsiSetProperty
(
package
,
"dummyb"
,
"baa"
);
...
...
@@ -1960,7 +1942,6 @@ static void test_formatrecord_package(void)
ok
(
sz
==
12
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"foo baa whoa"
),
"wrong output (%s)
\n
"
,
buffer
);
r
=
MsiSetProperty
(
package
,
"dummya"
,
"1"
);
r
=
MsiSetProperty
(
package
,
"dummyb"
,
"[2]"
);
ok
(
r
==
ERROR_SUCCESS
,
"set property failed
\n
"
);
...
...
@@ -1972,8 +1953,11 @@ static void test_formatrecord_package(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
ok
(
sz
==
9
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"1 [1] [2]"
),
"wrong output (%s)
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
9
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"1 [1] [2]"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiSetProperty
(
package
,
"dummya"
,
"1"
);
r
=
MsiSetProperty
(
package
,
"dummyb"
,
"a"
);
...
...
@@ -1999,8 +1983,11 @@ static void test_formatrecord_package(void)
sz
=
sizeof
buffer
;
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
ok
(
sz
==
11
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"boo hoo [3]"
),
"wrong output (%s)
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
11
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"boo hoo [3]"
),
"wrong output (%s)
\n
"
,
buffer
);
}
r
=
MsiRecordSetString
(
hrec
,
0
,
"[1] [2] [[3]]"
);
r
=
MsiRecordSetString
(
hrec
,
1
,
"boo"
);
...
...
@@ -2087,7 +2074,7 @@ static void test_formatrecord_package(void)
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{a[one]bc[two]de[one]f}"
);
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
: %d
\n
"
,
r
);
ok
(
sz
==
25
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"amercurybcvenusdemercuryf"
),
"wrong output (%s)
\n
"
,
buffer
);
...
...
@@ -2114,38 +2101,39 @@ static void test_formatrecord_package(void)
MsiRecordSetString
(
hrec
,
0
,
"{abc{d[one]ef}"
);
/* missing final brace */
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
ok
(
sz
==
14
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"abc{dmercuryef"
),
"wrong output (%s)
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
14
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"abc{dmercuryef"
),
"wrong output (%s)
\n
"
,
buffer
);
}
MsiSetProperty
(
package
,
"one"
,
"mercury"
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{abc{d[one]ef}}"
);
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
ok
(
sz
==
15
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"abc{dmercuryef}"
),
"wrong output (%s)
\n
"
,
buffer
);
todo_wine
{
ok
(
sz
==
15
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"abc{dmercuryef}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
MsiSetProperty
(
package
,
"one"
,
"mercury"
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{abc}{{def}hi{j[one]k}}"
);
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
5
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{abc}"
),
"wrong output (%s)
\n
"
,
buffer
);
}
ok
(
sz
==
5
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
"{abc}"
),
"wrong output (%s)
\n
"
,
buffer
);
MsiSetProperty
(
package
,
"one"
,
"mercury"
);
sz
=
sizeof
buffer
;
MsiRecordSetString
(
hrec
,
0
,
"{{def}hi{j[one]k}}"
);
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"format failed
\n
"
);
todo_wine
{
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
}
ok
(
sz
==
0
,
"size wrong(%i)
\n
"
,
sz
);
ok
(
0
==
strcmp
(
buffer
,
""
),
"wrong output (%s)
\n
"
,
buffer
);
sz
=
sizeof
(
buffer
);
MsiRecordSetString
(
hrec
,
0
,
"[1] {[noprop] [twoprop]} {abcdef}"
);
...
...
@@ -2153,11 +2141,8 @@ static void test_formatrecord_package(void)
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
sz
==
13
,
"Expected 13, got %d
\n
"
,
sz
);
todo_wine
{
ok
(
!
lstrcmpA
(
buffer
,
"one {abcdef}"
),
"Expected
\"
one {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
}
ok
(
!
lstrcmpA
(
buffer
,
"one {abcdef}"
),
"Expected
\"
one {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
sz
=
sizeof
(
buffer
);
MsiRecordSetString
(
hrec
,
0
,
"[1] {[noprop] [one]} {abcdef}"
);
...
...
@@ -2165,11 +2150,8 @@ static void test_formatrecord_package(void)
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
sz
==
13
,
"Expected 13, got %d
\n
"
,
sz
);
todo_wine
{
ok
(
!
lstrcmpA
(
buffer
,
"one {abcdef}"
),
"Expected
\"
one {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
}
ok
(
!
lstrcmpA
(
buffer
,
"one {abcdef}"
),
"Expected
\"
one {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
sz
=
sizeof
(
buffer
);
MsiRecordSetString
(
hrec
,
0
,
"[1] {[one]} {abcdef}"
);
...
...
@@ -2177,11 +2159,8 @@ static void test_formatrecord_package(void)
r
=
MsiFormatRecord
(
package
,
hrec
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
sz
==
20
,
"Expected 20, got %d
\n
"
,
sz
);
todo_wine
{
ok
(
!
lstrcmpA
(
buffer
,
"one mercury {abcdef}"
),
"Expected
\"
one mercury {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
}
ok
(
!
lstrcmpA
(
buffer
,
"one mercury {abcdef}"
),
"Expected
\"
one mercury {abcdef}
\"
, got
\"
%s
\"\n
"
,
buffer
);
MsiCloseHandle
(
hrec
);
...
...
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