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
896b4f05
Commit
896b4f05
authored
Apr 01, 2024
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
widl: Always use new-style format strings in interpreted mode.
parent
7cd0f395
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
24 additions
and
39 deletions
+24
-39
client.c
tools/widl/client.c
+4
-5
proxy.c
tools/widl/proxy.c
+11
-12
server.c
tools/widl/server.c
+2
-2
typegen.c
tools/widl/typegen.c
+0
-0
widl.c
tools/widl/widl.c
+6
-13
widl.h
tools/widl/widl.h
+1
-7
No files found.
tools/widl/client.c
View file @
896b4f05
...
@@ -285,7 +285,6 @@ static void write_function_stub( const type_t *iface, const var_t *func,
...
@@ -285,7 +285,6 @@ static void write_function_stub( const type_t *iface, const var_t *func,
static
void
write_serialize_function
(
FILE
*
file
,
const
type_t
*
type
,
const
type_t
*
iface
,
static
void
write_serialize_function
(
FILE
*
file
,
const
type_t
*
type
,
const
type_t
*
iface
,
const
char
*
func_name
,
const
char
*
ret_type
)
const
char
*
func_name
,
const
char
*
ret_type
)
{
{
enum
stub_mode
mode
=
get_stub_mode
();
static
int
emitted_pickling_info
;
static
int
emitted_pickling_info
;
if
(
iface
&&
!
type
->
typestring_offset
)
if
(
iface
&&
!
type
->
typestring_offset
)
...
@@ -296,7 +295,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
...
@@ -296,7 +295,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
return
;
return
;
}
}
if
(
!
emitted_pickling_info
&&
iface
&&
mode
!=
MODE_Os
)
if
(
!
emitted_pickling_info
&&
iface
&&
interpreted_mode
)
{
{
fprintf
(
file
,
"static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =
\n
"
);
fprintf
(
file
,
"static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =
\n
"
);
fprintf
(
file
,
"{
\n
"
);
fprintf
(
file
,
"{
\n
"
);
...
@@ -318,9 +317,9 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
...
@@ -318,9 +317,9 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
fprintf
(
file
,
"{
\n
"
);
fprintf
(
file
,
"{
\n
"
);
fprintf
(
file
,
" %sNdrMesType%s%s(
\n
"
,
ret_type
?
"return "
:
""
,
func_name
,
fprintf
(
file
,
" %sNdrMesType%s%s(
\n
"
,
ret_type
?
"return "
:
""
,
func_name
,
mode
!=
MODE_Os
?
"2"
:
""
);
interpreted_mode
?
"2"
:
""
);
fprintf
(
file
,
" IDL_handle,
\n
"
);
fprintf
(
file
,
" IDL_handle,
\n
"
);
if
(
mode
!=
MODE_Os
)
if
(
interpreted_mode
)
fprintf
(
file
,
" (MIDL_TYPE_PICKLING_INFO*)&__MIDL_TypePicklingInfo,
\n
"
);
fprintf
(
file
,
" (MIDL_TYPE_PICKLING_INFO*)&__MIDL_TypePicklingInfo,
\n
"
);
fprintf
(
file
,
" &%s_StubDesc,
\n
"
,
iface
->
name
);
fprintf
(
file
,
" &%s_StubDesc,
\n
"
,
iface
->
name
);
fprintf
(
file
,
" (PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],
\n
"
,
fprintf
(
file
,
" (PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],
\n
"
,
...
@@ -418,7 +417,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
...
@@ -418,7 +417,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
print_client
(
"0,
\n
"
);
print_client
(
"0,
\n
"
);
print_client
(
"__MIDL_TypeFormatString.Format,
\n
"
);
print_client
(
"__MIDL_TypeFormatString.Format,
\n
"
);
print_client
(
"1, /* -error bounds_check flag */
\n
"
);
print_client
(
"1, /* -error bounds_check flag */
\n
"
);
print_client
(
"0x%x, /* Ndr library version */
\n
"
,
get_stub_mode
()
==
MODE_Oif
?
0x50002
:
0x10001
);
print_client
(
"0x%x, /* Ndr library version */
\n
"
,
interpreted_mode
?
0x50002
:
0x10001
);
print_client
(
"0,
\n
"
);
print_client
(
"0,
\n
"
);
print_client
(
"0x50200ca, /* MIDL Version 5.2.202 */
\n
"
);
print_client
(
"0x50200ca, /* MIDL Version 5.2.202 */
\n
"
);
print_client
(
"0,
\n
"
);
print_client
(
"0,
\n
"
);
...
...
tools/widl/proxy.c
View file @
896b4f05
...
@@ -61,7 +61,7 @@ static void write_stubdesc(int expr_eval_routines)
...
@@ -61,7 +61,7 @@ static void write_stubdesc(int expr_eval_routines)
print_proxy
(
"{0}, 0, 0, %s, 0,
\n
"
,
expr_eval_routines
?
"ExprEvalRoutines"
:
"0"
);
print_proxy
(
"{0}, 0, 0, %s, 0,
\n
"
,
expr_eval_routines
?
"ExprEvalRoutines"
:
"0"
);
print_proxy
(
"__MIDL_TypeFormatString.Format,
\n
"
);
print_proxy
(
"__MIDL_TypeFormatString.Format,
\n
"
);
print_proxy
(
"1, /* -error bounds_check flag */
\n
"
);
print_proxy
(
"1, /* -error bounds_check flag */
\n
"
);
print_proxy
(
"0x%x, /* Ndr library version */
\n
"
,
get_stub_mode
()
==
MODE_Oif
?
0x50002
:
0x10001
);
print_proxy
(
"0x%x, /* Ndr library version */
\n
"
,
interpreted_mode
?
0x50002
:
0x10001
);
print_proxy
(
"0,
\n
"
);
print_proxy
(
"0,
\n
"
);
print_proxy
(
"0x50200ca, /* MIDL Version 5.2.202 */
\n
"
);
print_proxy
(
"0x50200ca, /* MIDL Version 5.2.202 */
\n
"
);
print_proxy
(
"0,
\n
"
);
print_proxy
(
"0,
\n
"
);
...
@@ -193,7 +193,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
...
@@ -193,7 +193,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
indent
=
0
;
indent
=
0
;
if
(
is_interpreted_func
(
iface
,
func
))
if
(
is_interpreted_func
(
iface
,
func
))
{
{
if
(
get_stub_mode
()
==
MODE_Oif
&&
!
is_callas
(
func
->
attrs
))
return
;
if
(
!
is_callas
(
func
->
attrs
))
return
;
write_type_decl_left
(
proxy
,
&
retval
->
declspec
);
write_type_decl_left
(
proxy
,
&
retval
->
declspec
);
print_proxy
(
" %s %s_%s_Proxy(
\n
"
,
callconv
,
iface
->
name
,
get_name
(
func
));
print_proxy
(
" %s %s_%s_Proxy(
\n
"
,
callconv
,
iface
->
name
,
get_name
(
func
));
write_args
(
proxy
,
args
,
iface
->
name
,
1
,
TRUE
,
NAME_DEFAULT
);
write_args
(
proxy
,
args
,
iface
->
name
,
1
,
TRUE
,
NAME_DEFAULT
);
...
@@ -519,7 +519,6 @@ static int write_proxy_methods(type_t *iface, int skip)
...
@@ -519,7 +519,6 @@ static int write_proxy_methods(type_t *iface, int skip)
if
(
skip
||
(
is_local
(
func
->
attrs
)
&&
!
get_callas_source
(
iface
,
func
)))
if
(
skip
||
(
is_local
(
func
->
attrs
)
&&
!
get_callas_source
(
iface
,
func
)))
print_proxy
(
"0, /* %s::%s */
\n
"
,
iface
->
name
,
get_name
(
func
));
print_proxy
(
"0, /* %s::%s */
\n
"
,
iface
->
name
,
get_name
(
func
));
else
if
(
is_interpreted_func
(
iface
,
func
)
&&
else
if
(
is_interpreted_func
(
iface
,
func
)
&&
get_stub_mode
()
==
MODE_Oif
&&
!
is_local
(
func
->
attrs
)
&&
!
is_local
(
func
->
attrs
)
&&
type_iface_get_inherit
(
iface
))
type_iface_get_inherit
(
iface
))
print_proxy
(
"(void *)-1, /* %s::%s */
\n
"
,
iface
->
name
,
get_name
(
func
));
print_proxy
(
"(void *)-1, /* %s::%s */
\n
"
,
iface
->
name
,
get_name
(
func
));
...
@@ -556,7 +555,7 @@ static int write_stub_methods(type_t *iface, int skip)
...
@@ -556,7 +555,7 @@ static int write_stub_methods(type_t *iface, int skip)
if
(
i
)
fprintf
(
proxy
,
",
\n
"
);
if
(
i
)
fprintf
(
proxy
,
",
\n
"
);
if
(
skip
||
missing
)
print_proxy
(
"STUB_FORWARDING_FUNCTION"
);
if
(
skip
||
missing
)
print_proxy
(
"STUB_FORWARDING_FUNCTION"
);
else
if
(
is_interpreted_func
(
iface
,
func
))
else
if
(
is_interpreted_func
(
iface
,
func
))
print_proxy
(
"(PRPC_STUB_FUNCTION)%s"
,
get_stub_mode
()
==
MODE_Oif
?
"NdrStubCall2"
:
"NdrStubCall"
);
print_proxy
(
"(PRPC_STUB_FUNCTION)%s"
,
interpreted_mode
?
"NdrStubCall2"
:
"NdrStubCall"
);
else
print_proxy
(
"%s_%s_Stub"
,
iface
->
name
,
fname
);
else
print_proxy
(
"%s_%s_Stub"
,
iface
->
name
,
fname
);
i
++
;
i
++
;
}
}
...
@@ -641,7 +640,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
...
@@ -641,7 +640,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
print_proxy
(
"};
\n\n
"
);
print_proxy
(
"};
\n\n
"
);
/* proxy info */
/* proxy info */
if
(
get_stub_mode
()
==
MODE_Oif
)
if
(
interpreted_mode
)
{
{
print_proxy
(
"static const MIDL_STUBLESS_PROXY_INFO %s_ProxyInfo =
\n
"
,
iface
->
name
);
print_proxy
(
"static const MIDL_STUBLESS_PROXY_INFO %s_ProxyInfo =
\n
"
,
iface
->
name
);
print_proxy
(
"{
\n
"
);
print_proxy
(
"{
\n
"
);
...
@@ -658,13 +657,13 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
...
@@ -658,13 +657,13 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
/* proxy vtable */
/* proxy vtable */
print_proxy
(
"static %sCINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =
\n
"
,
print_proxy
(
"static %sCINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =
\n
"
,
(
get_stub_mode
()
!=
MODE_Os
||
need_delegation_indirect
(
iface
))
?
""
:
"const "
,
(
interpreted_mode
||
need_delegation_indirect
(
iface
))
?
""
:
"const "
,
count
,
iface
->
name
);
count
,
iface
->
name
);
print_proxy
(
"{
\n
"
);
print_proxy
(
"{
\n
"
);
indent
++
;
indent
++
;
print_proxy
(
"{
\n
"
);
print_proxy
(
"{
\n
"
);
indent
++
;
indent
++
;
if
(
get_stub_mode
()
==
MODE_Oif
)
print_proxy
(
"&%s_ProxyInfo,
\n
"
,
iface
->
name
);
if
(
interpreted_mode
)
print_proxy
(
"&%s_ProxyInfo,
\n
"
,
iface
->
name
);
print_proxy
(
"&IID_%s,
\n
"
,
iface
->
name
);
print_proxy
(
"&IID_%s,
\n
"
,
iface
->
name
);
indent
--
;
indent
--
;
print_proxy
(
"},
\n
"
);
print_proxy
(
"},
\n
"
);
...
@@ -785,7 +784,7 @@ int need_inline_stubs(const type_t *iface)
...
@@ -785,7 +784,7 @@ int need_inline_stubs(const type_t *iface)
{
{
const
statement_t
*
stmt
;
const
statement_t
*
stmt
;
if
(
get_stub_mode
()
==
MODE_Os
)
return
1
;
if
(
!
interpreted_mode
)
return
1
;
STATEMENTS_FOR_EACH_FUNC
(
stmt
,
type_iface_get_stmts
(
iface
)
)
STATEMENTS_FOR_EACH_FUNC
(
stmt
,
type_iface_get_stmts
(
iface
)
)
{
{
...
@@ -801,7 +800,7 @@ static int need_proxy_and_inline_stubs(const type_t *iface)
...
@@ -801,7 +800,7 @@ static int need_proxy_and_inline_stubs(const type_t *iface)
const
statement_t
*
stmt
;
const
statement_t
*
stmt
;
if
(
!
need_proxy
(
iface
))
return
0
;
if
(
!
need_proxy
(
iface
))
return
0
;
if
(
get_stub_mode
()
==
MODE_Os
)
return
1
;
if
(
!
interpreted_mode
)
return
1
;
STATEMENTS_FOR_EACH_FUNC
(
stmt
,
type_iface_get_stmts
(
iface
)
)
STATEMENTS_FOR_EACH_FUNC
(
stmt
,
type_iface_get_stmts
(
iface
)
)
{
{
...
@@ -895,10 +894,10 @@ static void write_proxy_routines(const statement_list_t *stmts)
...
@@ -895,10 +894,10 @@ static void write_proxy_routines(const statement_list_t *stmts)
const
type_t
*
delegate_to
;
const
type_t
*
delegate_to
;
print_proxy
(
"#ifndef __REDQ_RPCPROXY_H_VERSION__
\n
"
);
print_proxy
(
"#ifndef __REDQ_RPCPROXY_H_VERSION__
\n
"
);
print_proxy
(
"#define __REQUIRED_RPCPROXY_H_VERSION__ %u
\n
"
,
get_stub_mode
()
==
MODE_Oif
?
475
:
440
);
print_proxy
(
"#define __REQUIRED_RPCPROXY_H_VERSION__ %u
\n
"
,
interpreted_mode
?
475
:
440
);
print_proxy
(
"#endif
\n
"
);
print_proxy
(
"#endif
\n
"
);
print_proxy
(
"
\n
"
);
print_proxy
(
"
\n
"
);
if
(
get_stub_mode
()
==
MODE_Oif
)
print_proxy
(
"#define USE_STUBLESS_PROXY
\n
"
);
if
(
interpreted_mode
)
print_proxy
(
"#define USE_STUBLESS_PROXY
\n
"
);
print_proxy
(
"#include
\"
rpcproxy.h
\"\n
"
);
print_proxy
(
"#include
\"
rpcproxy.h
\"\n
"
);
print_proxy
(
"#ifndef __RPCPROXY_H_VERSION__
\n
"
);
print_proxy
(
"#ifndef __RPCPROXY_H_VERSION__
\n
"
);
print_proxy
(
"#error This code needs a newer version of rpcproxy.h
\n
"
);
print_proxy
(
"#error This code needs a newer version of rpcproxy.h
\n
"
);
...
@@ -1002,7 +1001,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
...
@@ -1002,7 +1001,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
fprintf
(
proxy
,
"}
\n
"
);
fprintf
(
proxy
,
"}
\n
"
);
fprintf
(
proxy
,
"
\n
"
);
fprintf
(
proxy
,
"
\n
"
);
table_version
=
get_stub_mode
()
==
MODE_Oif
?
2
:
1
;
table_version
=
interpreted_mode
?
2
:
1
;
for
(
i
=
0
;
i
<
count
;
i
++
)
for
(
i
=
0
;
i
<
count
;
i
++
)
{
{
if
(
type_iface_get_async_iface
(
interfaces
[
i
])
!=
interfaces
[
i
])
continue
;
if
(
type_iface_get_async_iface
(
interfaces
[
i
])
!=
interfaces
[
i
])
continue
;
...
...
tools/widl/server.c
View file @
896b4f05
...
@@ -273,7 +273,7 @@ static void write_dispatchtable(type_t *iface)
...
@@ -273,7 +273,7 @@ static void write_dispatchtable(type_t *iface)
{
{
var_t
*
func
=
stmt
->
u
.
var
;
var_t
*
func
=
stmt
->
u
.
var
;
if
(
is_interpreted_func
(
iface
,
func
))
if
(
is_interpreted_func
(
iface
,
func
))
print_server
(
"
%s,
\n
"
,
get_stub_mode
()
==
MODE_Oif
?
"NdrServerCall2"
:
"NdrServerCall
"
);
print_server
(
"
NdrServerCall2,
\n
"
);
else
else
print_server
(
"%s_%s,
\n
"
,
iface
->
name
,
get_name
(
func
));
print_server
(
"%s_%s,
\n
"
,
iface
->
name
,
get_name
(
func
));
method_count
++
;
method_count
++
;
...
@@ -380,7 +380,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
...
@@ -380,7 +380,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
print_server
(
"0,
\n
"
);
print_server
(
"0,
\n
"
);
print_server
(
"__MIDL_TypeFormatString.Format,
\n
"
);
print_server
(
"__MIDL_TypeFormatString.Format,
\n
"
);
print_server
(
"1, /* -error bounds_check flag */
\n
"
);
print_server
(
"1, /* -error bounds_check flag */
\n
"
);
print_server
(
"0x%x, /* Ndr library version */
\n
"
,
get_stub_mode
()
==
MODE_Oif
?
0x50002
:
0x10001
);
print_server
(
"0x%x, /* Ndr library version */
\n
"
,
interpreted_mode
?
0x50002
:
0x10001
);
print_server
(
"0,
\n
"
);
print_server
(
"0,
\n
"
);
print_server
(
"0x50200ca, /* MIDL Version 5.2.202 */
\n
"
);
print_server
(
"0x50200ca, /* MIDL Version 5.2.202 */
\n
"
);
print_server
(
"0,
\n
"
);
print_server
(
"0,
\n
"
);
...
...
tools/widl/typegen.c
View file @
896b4f05
This diff is collapsed.
Click to expand it.
tools/widl/widl.c
View file @
896b4f05
...
@@ -109,9 +109,9 @@ int do_dlldata = 0;
...
@@ -109,9 +109,9 @@ int do_dlldata = 0;
static
int
no_preprocess
=
0
;
static
int
no_preprocess
=
0
;
int
old_names
=
0
;
int
old_names
=
0
;
int
winrt_mode
=
0
;
int
winrt_mode
=
0
;
int
interpreted_mode
=
0
;
int
use_abi_namespace
=
0
;
int
use_abi_namespace
=
0
;
static
int
stdinc
=
1
;
static
int
stdinc
=
1
;
static
enum
stub_mode
stub_mode
=
MODE_Os
;
char
*
input_name
;
char
*
input_name
;
char
*
idl_name
;
char
*
idl_name
;
...
@@ -199,13 +199,6 @@ static const struct long_option long_options[] = {
...
@@ -199,13 +199,6 @@ static const struct long_option long_options[] = {
static
void
rm_tempfile
(
void
);
static
void
rm_tempfile
(
void
);
enum
stub_mode
get_stub_mode
(
void
)
{
/* old-style interpreted stubs are not supported on 64-bit */
if
(
stub_mode
==
MODE_Oi
&&
pointer_size
==
8
)
return
MODE_Oif
;
return
stub_mode
;
}
static
char
*
make_token
(
const
char
*
name
)
static
char
*
make_token
(
const
char
*
name
)
{
{
char
*
token
;
char
*
token
;
...
@@ -595,11 +588,11 @@ static void option_callback( int optc, char *optarg )
...
@@ -595,11 +588,11 @@ static void option_callback( int optc, char *optarg )
output_name
=
xstrdup
(
optarg
);
output_name
=
xstrdup
(
optarg
);
break
;
break
;
case
'O'
:
case
'O'
:
if
(
!
strcmp
(
optarg
,
"s"
))
stub_mode
=
MODE_Os
;
if
(
!
strcmp
(
optarg
,
"s"
))
interpreted_mode
=
0
;
else
if
(
!
strcmp
(
optarg
,
"i"
))
stub_mode
=
MODE_Oi
;
else
if
(
!
strcmp
(
optarg
,
"i"
))
interpreted_mode
=
1
;
else
if
(
!
strcmp
(
optarg
,
"ic"
))
stub_mode
=
MODE_Oif
;
else
if
(
!
strcmp
(
optarg
,
"ic"
))
interpreted_mode
=
1
;
else
if
(
!
strcmp
(
optarg
,
"if"
))
stub_mode
=
MODE_Oif
;
else
if
(
!
strcmp
(
optarg
,
"if"
))
interpreted_mode
=
1
;
else
if
(
!
strcmp
(
optarg
,
"icf"
))
stub_mode
=
MODE_Oif
;
else
if
(
!
strcmp
(
optarg
,
"icf"
))
interpreted_mode
=
1
;
else
error
(
"Invalid argument '-O%s'
\n
"
,
optarg
);
else
error
(
"Invalid argument '-O%s'
\n
"
,
optarg
);
break
;
break
;
case
'p'
:
case
'p'
:
...
...
tools/widl/widl.h
View file @
896b4f05
...
@@ -48,6 +48,7 @@ extern int do_idfile;
...
@@ -48,6 +48,7 @@ extern int do_idfile;
extern
int
do_dlldata
;
extern
int
do_dlldata
;
extern
int
old_names
;
extern
int
old_names
;
extern
int
winrt_mode
;
extern
int
winrt_mode
;
extern
int
interpreted_mode
;
extern
int
use_abi_namespace
;
extern
int
use_abi_namespace
;
extern
char
*
input_name
;
extern
char
*
input_name
;
...
@@ -72,13 +73,6 @@ extern unsigned int packing;
...
@@ -72,13 +73,6 @@ extern unsigned int packing;
extern
unsigned
int
pointer_size
;
extern
unsigned
int
pointer_size
;
extern
time_t
now
;
extern
time_t
now
;
enum
stub_mode
{
MODE_Os
,
/* inline stubs */
MODE_Oi
,
/* old-style interpreted stubs */
MODE_Oif
/* new-style fully interpreted stubs */
};
extern
enum
stub_mode
get_stub_mode
(
void
);
extern
int
open_typelib
(
const
char
*
name
);
extern
int
open_typelib
(
const
char
*
name
);
extern
void
write_header
(
const
statement_list_t
*
stmts
);
extern
void
write_header
(
const
statement_list_t
*
stmts
);
...
...
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