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
2d8b65c2
Commit
2d8b65c2
authored
Jul 17, 2023
by
Jacek Caban
Committed by
Alexandre Julliard
Jul 24, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
win32u: Use CREATESTRUCTW struct layout to pass WM_CREATE message params to client.
parent
eac34b9c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
262 additions
and
51 deletions
+262
-51
winproc.c
dlls/user32/winproc.c
+27
-27
message.c
dlls/win32u/message.c
+166
-21
user.c
dlls/wow64win/user.c
+69
-3
No files found.
dlls/user32/winproc.c
View file @
2d8b65c2
...
...
@@ -789,13 +789,18 @@ static inline BOOL check_string( LPCWSTR str, size_t size )
return
FALSE
;
}
static
size_t
string_size
(
const
void
*
str
,
BOOL
ansi
)
{
return
ansi
?
strlen
(
str
)
+
1
:
(
wcslen
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
}
/***********************************************************************
* unpack_message
*
* Unpack a message received from another process.
*/
static
BOOL
unpack_message
(
HWND
hwnd
,
UINT
message
,
WPARAM
*
wparam
,
LPARAM
*
lparam
,
void
**
buffer
,
size_t
size
)
void
**
buffer
,
size_t
size
,
BOOL
ansi
)
{
size_t
minsize
=
0
,
prev_size
=
size
;
union
packed_structs
*
ps
=
*
buffer
;
...
...
@@ -805,35 +810,18 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
case
WM_NCCREATE
:
case
WM_CREATE
:
{
CREATESTRUCTW
cs
;
WCHAR
*
str
=
(
WCHAR
*
)(
&
ps
->
cs
+
1
);
if
(
size
<
sizeof
(
ps
->
cs
))
return
FALSE
;
size
-=
sizeof
(
ps
->
cs
);
cs
.
lpCreateParams
=
unpack_ptr
(
ps
->
cs
.
lpCreateParams
);
cs
.
hInstance
=
unpack_ptr
(
ps
->
cs
.
hInstance
);
cs
.
hMenu
=
unpack_handle
(
ps
->
cs
.
hMenu
);
cs
.
hwndParent
=
unpack_handle
(
ps
->
cs
.
hwndParent
);
cs
.
cy
=
ps
->
cs
.
cy
;
cs
.
cx
=
ps
->
cs
.
cx
;
cs
.
y
=
ps
->
cs
.
y
;
cs
.
x
=
ps
->
cs
.
x
;
cs
.
style
=
ps
->
cs
.
style
;
cs
.
dwExStyle
=
ps
->
cs
.
dwExStyle
;
cs
.
lpszName
=
unpack_ptr
(
ps
->
cs
.
lpszName
);
cs
.
lpszClass
=
unpack_ptr
(
ps
->
cs
.
lpszClass
);
if
(
ps
->
cs
.
lpszName
>>
16
)
CREATESTRUCTA
*
cs
=
*
buffer
;
char
*
str
=
(
char
*
)(
cs
+
1
);
if
(
!
IS_INTRESOURCE
(
cs
->
lpszName
))
{
if
(
!
check_string
(
str
,
size
))
return
FALSE
;
cs
.
lpszName
=
str
;
size
-=
(
lstrlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
str
+=
lstrlenW
(
str
)
+
1
;
cs
->
lpszName
=
str
;
str
+=
string_size
(
str
,
ansi
);
}
if
(
ps
->
cs
.
lpszClass
>>
16
)
if
(
!
IS_INTRESOURCE
(
cs
->
lpszClass
)
)
{
if
(
!
check_string
(
str
,
size
))
return
FALSE
;
cs
.
lpszClass
=
str
;
cs
->
lpszClass
=
str
;
}
memcpy
(
*
buffer
,
&
cs
,
sizeof
(
cs
)
);
break
;
}
case
WM_GETTEXT
:
...
...
@@ -1186,6 +1174,7 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size )
if
(
params
->
needs_unpack
)
{
char
stack_buffer
[
128
];
size_t
msg_size
=
size
-
sizeof
(
*
params
);
void
*
buffer
;
if
(
size
>
sizeof
(
*
params
))
...
...
@@ -1199,11 +1188,22 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size )
buffer
=
stack_buffer
;
}
if
(
!
unpack_message
(
params
->
hwnd
,
params
->
msg
,
&
params
->
wparam
,
&
params
->
lparam
,
&
buffer
,
size
))
&
params
->
lparam
,
&
buffer
,
size
,
params
->
ansi
))
return
0
;
result
=
dispatch_win_proc_params
(
params
);
switch
(
params
->
msg
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
{
LRESULT
*
result_ptr
=
(
LRESULT
*
)
buffer
-
1
;
*
result_ptr
=
result
;
return
NtCallbackReturn
(
result_ptr
,
sizeof
(
*
result_ptr
)
+
msg_size
,
TRUE
);
}
}
NtUserMessageCall
(
params
->
hwnd
,
params
->
msg
,
params
->
wparam
,
params
->
lparam
,
(
void
*
)
result
,
NtUserWinProcResult
,
FALSE
);
if
(
buffer
!=
stack_buffer
&&
buffer
!=
params
+
1
)
...
...
dlls/win32u/message.c
View file @
2d8b65c2
...
...
@@ -255,7 +255,8 @@ static BOOL init_window_call_params( struct win_proc_params *params, HWND hwnd,
return
TRUE
;
}
static
LRESULT
dispatch_win_proc_params
(
struct
win_proc_params
*
params
,
size_t
size
)
static
LRESULT
dispatch_win_proc_params
(
struct
win_proc_params
*
params
,
size_t
size
,
void
**
client_ret
,
size_t
*
client_ret_size
)
{
struct
ntuser_thread_info
*
thread_info
=
NtUserGetThreadInfo
();
LRESULT
result
=
0
;
...
...
@@ -264,11 +265,19 @@ static LRESULT dispatch_win_proc_params( struct win_proc_params *params, size_t
if
(
thread_info
->
recursion_count
>
MAX_WINPROC_RECURSION
)
return
0
;
thread_info
->
recursion_count
++
;
KeUserModeCallback
(
NtUserCallWinProc
,
params
,
size
,
&
ret_ptr
,
&
ret_len
);
if
(
ret_len
==
sizeof
(
result
))
result
=
*
(
LRESULT
*
)
ret_ptr
;
thread_info
->
recursion_count
--
;
if
(
ret_len
>=
sizeof
(
result
))
{
result
=
*
(
LRESULT
*
)
ret_ptr
;
if
(
client_ret
)
{
*
client_ret
=
(
LRESULT
*
)
ret_ptr
+
1
;
*
client_ret_size
=
ret_len
-
sizeof
(
result
);
}
}
return
result
;
}
...
...
@@ -346,6 +355,38 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
switch
(
message
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
{
CREATESTRUCTW
cs
;
WCHAR
*
str
=
(
WCHAR
*
)(
&
ps
->
cs
+
1
);
if
(
size
<
sizeof
(
ps
->
cs
))
return
FALSE
;
size
-=
sizeof
(
ps
->
cs
);
cs
.
lpCreateParams
=
unpack_ptr
(
ps
->
cs
.
lpCreateParams
);
cs
.
hInstance
=
unpack_ptr
(
ps
->
cs
.
hInstance
);
cs
.
hMenu
=
wine_server_ptr_handle
(
ps
->
cs
.
hMenu
);
cs
.
hwndParent
=
wine_server_ptr_handle
(
ps
->
cs
.
hwndParent
);
cs
.
cy
=
ps
->
cs
.
cy
;
cs
.
cx
=
ps
->
cs
.
cx
;
cs
.
y
=
ps
->
cs
.
y
;
cs
.
x
=
ps
->
cs
.
x
;
cs
.
style
=
ps
->
cs
.
style
;
cs
.
dwExStyle
=
ps
->
cs
.
dwExStyle
;
cs
.
lpszName
=
unpack_ptr
(
ps
->
cs
.
lpszName
);
cs
.
lpszClass
=
unpack_ptr
(
ps
->
cs
.
lpszClass
);
if
(
ps
->
cs
.
lpszName
>>
16
)
{
cs
.
lpszName
=
str
;
size
-=
(
lstrlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
str
+=
lstrlenW
(
str
)
+
1
;
}
if
(
ps
->
cs
.
lpszClass
>>
16
)
{
cs
.
lpszClass
=
str
;
}
memcpy
(
*
buffer
,
&
cs
,
sizeof
(
cs
)
);
break
;
}
case
WM_WINE_SETWINDOWPOS
:
{
WINDOWPOS
wp
;
...
...
@@ -1076,23 +1117,100 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
}
}
static
size_t
string_size
(
const
void
*
str
,
BOOL
ansi
)
{
return
ansi
?
strlen
(
str
)
+
1
:
(
wcslen
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
}
static
size_t
copy_string
(
void
*
ptr
,
const
void
*
str
,
BOOL
ansi
)
{
size_t
size
=
string_size
(
str
,
ansi
);
memcpy
(
ptr
,
str
,
size
);
return
size
;
}
/***********************************************************************
*
copy_reply
*
user_message_size
*
* C
opy a message reply received from client
.
* C
alculate size of packed message buffer
.
*/
static
void
copy_reply
(
LRESULT
result
,
HWND
hwnd
,
UINT
message
,
WPARAM
wparam
,
LPARAM
lparam
,
WPARAM
wparam_src
,
LPARAM
lparam_src
)
static
size_t
user_message_size
(
UINT
message
,
LPARAM
lparam
,
BOOL
ansi
)
{
size_t
copy_size
=
0
;
const
void
*
lparam_ptr
=
(
const
void
*
)
lparam
;
size_t
size
=
0
;
switch
(
message
)
switch
(
message
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
{
const
CREATESTRUCTW
*
cs
=
lparam_ptr
;
size
=
sizeof
(
*
cs
);
if
(
!
IS_INTRESOURCE
(
cs
->
lpszName
))
size
+=
string_size
(
cs
->
lpszName
,
ansi
);
if
(
!
IS_INTRESOURCE
(
cs
->
lpszClass
))
size
+=
string_size
(
cs
->
lpszClass
,
ansi
);
break
;
}
}
return
size
;
}
/***********************************************************************
* pack_user_message
*
* Copy message to a buffer for passing to client.
*/
static
void
pack_user_message
(
void
*
buffer
,
size_t
size
,
UINT
message
,
LPARAM
lparam
,
BOOL
ansi
)
{
const
void
*
lparam_ptr
=
(
const
void
*
)
lparam
;
void
const
*
inline_ptr
=
(
void
*
)
0xffffffff
;
if
(
!
size
)
return
;
switch
(
message
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
{
CREATESTRUCTW
*
cs
=
buffer
;
char
*
ptr
=
(
char
*
)(
cs
+
1
);
memcpy
(
cs
,
lparam_ptr
,
sizeof
(
*
cs
)
);
if
(
!
IS_INTRESOURCE
(
cs
->
lpszName
))
{
ptr
+=
copy_string
(
ptr
,
cs
->
lpszName
,
ansi
);
cs
->
lpszName
=
inline_ptr
;
}
if
(
!
IS_INTRESOURCE
(
cs
->
lpszClass
))
{
CREATESTRUCTW
*
dst
=
(
CREATESTRUCTW
*
)
lparam
;
CREATESTRUCTW
*
src
=
(
CREATESTRUCTW
*
)
lparam_src
;
copy_string
(
ptr
,
cs
->
lpszClass
,
ansi
);
cs
->
lpszClass
=
inline_ptr
;
}
return
;
}
}
}
/***********************************************************************
* copy_user_result
*
* Copy a message result received from client.
*/
static
void
copy_user_result
(
void
*
buffer
,
size_t
size
,
UINT
message
,
WPARAM
wparam
,
LPARAM
lparam
)
{
void
*
lparam_ptr
=
(
void
*
)
lparam
;
if
(
!
size
)
return
;
switch
(
message
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
if
(
size
>=
sizeof
(
CREATESTRUCTW
))
{
CREATESTRUCTW
*
dst
=
lparam_ptr
;
const
CREATESTRUCTW
*
src
=
buffer
;
dst
->
lpCreateParams
=
src
->
lpCreateParams
;
dst
->
hInstance
=
src
->
hInstance
;
dst
->
hMenu
=
src
->
hMenu
;
...
...
@@ -1106,6 +1224,23 @@ static void copy_reply( LRESULT result, HWND hwnd, UINT message, WPARAM wparam,
/* don't allow changing name and class pointers */
}
return
;
default:
return
;
}
}
/***********************************************************************
* copy_reply
*
* Copy a message reply received from client.
*/
static
void
copy_reply
(
LRESULT
result
,
HWND
hwnd
,
UINT
message
,
WPARAM
wparam
,
LPARAM
lparam
,
WPARAM
wparam_src
,
LPARAM
lparam_src
)
{
size_t
copy_size
=
0
;
switch
(
message
)
{
case
WM_GETTEXT
:
case
CB_GETLBTEXT
:
case
LB_GETTEXT
:
...
...
@@ -1373,9 +1508,13 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
BOOL
needs_unpack
,
void
*
buffer
,
size_t
size
)
{
struct
win_proc_params
p
,
*
params
=
&
p
;
BOOL
ansi
=
!
unicode
&&
!
needs_unpack
;
LRESULT
result
=
0
;
CWPSTRUCT
cwp
;
CWPRETSTRUCT
cwpret
;
size_t
packed_size
=
0
;
void
*
ret_ptr
;
size_t
ret_len
=
0
;
if
(
msg
&
0x80000000
)
return
handle_internal_message
(
hwnd
,
msg
,
wparam
,
lparam
);
...
...
@@ -1383,6 +1522,9 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
if
(
!
needs_unpack
)
size
=
0
;
if
(
!
is_current_thread_window
(
hwnd
))
return
0
;
packed_size
=
user_message_size
(
msg
,
lparam
,
ansi
);
if
(
packed_size
)
size
=
packed_size
;
/* first the WH_CALLWNDPROC hook */
cwp
.
lParam
=
lparam
;
cwp
.
wParam
=
wparam
;
...
...
@@ -1397,15 +1539,18 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
return
0
;
}
if
(
needs_unpack
)
{
params
->
needs_unpack
=
TRUE
;
params
->
ansi
=
FALSE
;
if
(
size
)
memcpy
(
params
+
1
,
buffer
,
size
);
}
result
=
dispatch_win_proc_params
(
params
,
sizeof
(
*
params
)
+
size
);
if
(
needs_unpack
)
params
->
ansi
=
FALSE
;
params
->
needs_unpack
=
needs_unpack
||
packed_size
;
if
(
packed_size
)
pack_user_message
(
params
+
1
,
packed_size
,
msg
,
lparam
,
ansi
);
else
if
(
size
)
memcpy
(
params
+
1
,
buffer
,
size
);
result
=
dispatch_win_proc_params
(
params
,
sizeof
(
*
params
)
+
size
,
&
ret_ptr
,
&
ret_len
);
if
(
params
!=
&
p
)
free
(
params
);
copy_user_result
(
ret_ptr
,
min
(
ret_len
,
packed_size
),
msg
,
wparam
,
lparam
);
/* and finally the WH_CALLWNDPROCRET hook */
cwpret
.
lResult
=
result
;
cwpret
.
lParam
=
lparam
;
...
...
@@ -2750,7 +2895,7 @@ LRESULT WINAPI NtUserDispatchMessage( const MSG *msg )
if
(
!
init_win_proc_params
(
&
params
,
msg
->
hwnd
,
msg
->
message
,
msg
->
wParam
,
NtGetTickCount
(),
FALSE
))
return
0
;
return
dispatch_win_proc_params
(
&
params
,
sizeof
(
params
)
);
return
dispatch_win_proc_params
(
&
params
,
sizeof
(
params
)
,
NULL
,
NULL
);
}
if
(
msg
->
message
==
WM_SYSTIMER
)
{
...
...
@@ -2772,7 +2917,7 @@ LRESULT WINAPI NtUserDispatchMessage( const MSG *msg )
if
(
init_window_call_params
(
&
params
,
msg
->
hwnd
,
msg
->
message
,
msg
->
wParam
,
msg
->
lParam
,
FALSE
,
WMCHAR_MAP_DISPATCHMESSAGE
))
retval
=
dispatch_win_proc_params
(
&
params
,
sizeof
(
params
)
);
retval
=
dispatch_win_proc_params
(
&
params
,
sizeof
(
params
)
,
NULL
,
NULL
);
else
if
(
!
is_window
(
msg
->
hwnd
))
RtlSetLastWin32Error
(
ERROR_INVALID_WINDOW_HANDLE
);
else
RtlSetLastWin32Error
(
ERROR_MESSAGE_SYNC_ONLY
);
...
...
dlls/wow64win/user.c
View file @
2d8b65c2
...
...
@@ -614,10 +614,66 @@ static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size )
FIELD_OFFSET
(
struct
win_event_hook_params32
,
module
)
+
size
);
}
static
size_t
packed_message_64to32
(
UINT
message
,
const
void
*
params64
,
void
*
params32
,
size_t
size
)
{
if
(
!
size
)
return
0
;
switch
(
message
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
{
CREATESTRUCT32
*
cs32
=
params32
;
const
CREATESTRUCTW
*
cs64
=
params64
;
createstruct_64to32
(
cs64
,
cs32
);
size
-=
sizeof
(
*
cs64
);
if
(
size
)
memmove
(
cs32
+
1
,
cs64
+
1
,
size
);
return
sizeof
(
*
cs32
)
+
size
;
}
}
memmove
(
params32
,
params64
,
size
);
return
size
;
}
static
size_t
packed_result_32to64
(
UINT
message
,
const
void
*
params32
,
size_t
size
,
void
*
params64
)
{
switch
(
message
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
if
(
size
>=
sizeof
(
CREATESTRUCT32
))
{
const
CREATESTRUCT32
*
cs32
=
params32
;
CREATESTRUCTW
*
cs64
=
params64
;
cs64
->
lpCreateParams
=
UlongToPtr
(
cs32
->
lpCreateParams
);
cs64
->
hInstance
=
UlongToPtr
(
cs32
->
hInstance
);
cs64
->
hMenu
=
LongToHandle
(
cs32
->
hMenu
);
cs64
->
hwndParent
=
LongToHandle
(
cs32
->
hwndParent
);
cs64
->
cy
=
cs32
->
cy
;
cs64
->
cx
=
cs32
->
cx
;
cs64
->
y
=
cs32
->
y
;
cs64
->
x
=
cs32
->
x
;
cs64
->
style
=
cs32
->
style
;
cs64
->
dwExStyle
=
cs32
->
dwExStyle
;
return
sizeof
(
*
cs64
);
}
default:
return
0
;
}
if
(
size
)
memcpy
(
params64
,
params32
,
size
);
return
size
;
}
static
NTSTATUS
WINAPI
wow64_NtUserCallWinProc
(
void
*
arg
,
ULONG
size
)
{
struct
win_proc_params
*
params
=
arg
;
struct
win_proc_params32
*
params32
=
arg
;
size_t
lparam_size
=
0
;
LRESULT
result
=
0
;
void
*
ret_ptr
;
ULONG
ret_len
;
...
...
@@ -625,13 +681,23 @@ static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size )
win_proc_params_64to32
(
params
,
params32
);
if
(
size
>
sizeof
(
*
params
))
memmove
(
params32
+
1
,
params
+
1
,
size
-
sizeof
(
*
params
)
);
lparam_size
=
packed_message_64to32
(
params32
->
msg
,
params
+
1
,
params32
+
1
,
size
-
sizeof
(
*
params
)
);
status
=
Wow64KiUserCallbackDispatcher
(
NtUserCallWinProc
,
params32
,
size
-
sizeof
(
*
params
)
+
sizeof
(
*
params32
)
,
size
of
(
*
params32
)
+
lparam_size
,
&
ret_ptr
,
&
ret_len
);
if
(
ret_len
==
sizeof
(
LONG
))
result
=
*
(
LONG
*
)
ret_ptr
;
if
(
ret_len
>=
sizeof
(
LONG
))
{
LRESULT
*
result_ptr
=
arg
;
result
=
*
(
LONG
*
)
ret_ptr
;
ret_len
=
packed_result_32to64
(
params32
->
msg
,
(
LONG
*
)
ret_ptr
+
1
,
ret_len
-
sizeof
(
LONG
),
result_ptr
+
1
);
*
result_ptr
=
result
;
return
NtCallbackReturn
(
result_ptr
,
sizeof
(
*
result_ptr
)
+
ret_len
,
status
);
}
return
NtCallbackReturn
(
&
result
,
sizeof
(
result
),
status
);
}
...
...
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