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
d222dcc2
Commit
d222dcc2
authored
Dec 20, 2022
by
Jacek Caban
Committed by
Alexandre Julliard
Dec 20, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
win32u: Convert inter-process messages to Unicode.
Based on user32 WINPROC_CallProcWtoA. Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=53744
parent
2b0cd25b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
366 additions
and
2 deletions
+366
-2
font.c
dlls/win32u/font.c
+82
-0
message.c
dlls/win32u/message.c
+281
-1
ntgdi_private.h
dlls/win32u/ntgdi_private.h
+0
-1
win32u_private.h
dlls/win32u/win32u_private.h
+3
-0
No files found.
dlls/win32u/font.c
View file @
d222dcc2
...
...
@@ -3619,6 +3619,60 @@ CPTABLEINFO *get_cptable( WORD cp )
return
&
tables
[
i
];
}
/* Based on NlsValidateLocale */
const
NLS_LOCALE_DATA
*
get_locale_data
(
LCID
lcid
)
{
static
const
NLS_LOCALE_HEADER
*
locale_table
;
static
const
NLS_LOCALE_LCID_INDEX
*
lcids_index
;
int
min
=
0
,
max
;
if
(
!
locale_table
)
{
LARGE_INTEGER
size
;
void
*
addr
;
LCID
lcid
;
NTSTATUS
status
;
static
struct
{
UINT
ctypes
;
UINT
unknown1
;
UINT
unknown2
;
UINT
unknown3
;
UINT
locales
;
UINT
charmaps
;
UINT
geoids
;
UINT
scripts
;
}
*
header
;
status
=
NtInitializeNlsFiles
(
&
addr
,
&
lcid
,
&
size
);
if
(
status
)
{
ERR
(
"Failed to load nls file
\n
"
);
return
NULL
;
}
if
(
InterlockedCompareExchangePointer
(
(
void
**
)
&
header
,
addr
,
NULL
))
NtUnmapViewOfSection
(
GetCurrentProcess
(),
addr
);
locale_table
=
(
const
NLS_LOCALE_HEADER
*
)((
char
*
)
header
+
header
->
locales
);
lcids_index
=
(
const
NLS_LOCALE_LCID_INDEX
*
)((
char
*
)
locale_table
+
locale_table
->
lcids_offset
);
}
max
=
locale_table
->
nb_lcids
-
1
;
while
(
min
<=
max
)
{
int
pos
=
(
min
+
max
)
/
2
;
if
(
lcid
<
lcids_index
[
pos
].
id
)
max
=
pos
-
1
;
else
if
(
lcid
>
lcids_index
[
pos
].
id
)
min
=
pos
+
1
;
else
{
ULONG
offset
=
locale_table
->
locales_offset
+
pos
*
locale_table
->
locale_size
;
return
(
const
NLS_LOCALE_DATA
*
)((
const
char
*
)
locale_table
+
offset
);
}
}
return
NULL
;
}
DWORD
win32u_wctomb
(
CPTABLEINFO
*
info
,
char
*
dst
,
DWORD
dstlen
,
const
WCHAR
*
src
,
DWORD
srclen
)
{
DWORD
ret
;
...
...
@@ -3665,6 +3719,34 @@ DWORD win32u_mbtowc( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, const char *sr
return
ret
/
sizeof
(
WCHAR
);
}
DWORD
win32u_mbtowc_size
(
CPTABLEINFO
*
info
,
const
char
*
src
,
DWORD
srclen
)
{
DWORD
ret
;
if
(
info
->
CodePage
==
CP_UTF8
)
{
RtlUTF8ToUnicodeN
(
NULL
,
0
,
&
ret
,
src
,
srclen
);
ret
/=
sizeof
(
WCHAR
);
}
else
if
(
info
->
DBCSCodePage
)
{
for
(
ret
=
0
;
srclen
;
srclen
--
,
src
++
,
ret
++
)
{
if
(
info
->
DBCSOffsets
[(
unsigned
char
)
*
src
]
&&
srclen
>
1
)
{
src
++
;
srclen
--
;
}
}
}
else
{
ret
=
srclen
;
}
return
ret
;
}
static
BOOL
wc_to_index
(
UINT
cp
,
WCHAR
wc
,
unsigned
char
*
dst
,
BOOL
allow_default
)
{
const
CPTABLEINFO
*
info
;
...
...
dlls/win32u/message.c
View file @
d222dcc2
...
...
@@ -29,6 +29,7 @@
#define WIN32_NO_STATUS
#include "win32u_private.h"
#include "ntuser_private.h"
#include "winnls.h"
#include "hidusage.h"
#include "dbt.h"
#include "dde.h"
...
...
@@ -2521,6 +2522,17 @@ static LRESULT send_inter_thread_message( const struct send_message_info *info,
return
retrieve_reply
(
info
,
reply_size
,
res_ptr
);
}
static
LRESULT
send_inter_thread_callback
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
,
LRESULT
*
result
,
void
*
arg
)
{
struct
send_message_info
*
info
=
arg
;
info
->
hwnd
=
hwnd
;
info
->
msg
=
msg
;
info
->
wparam
=
wp
;
info
->
lparam
=
lp
;
return
send_inter_thread_message
(
info
,
result
);
}
/***********************************************************************
* send_internal_message_timeout
*
...
...
@@ -2835,6 +2847,268 @@ static BOOL process_packed_message( struct send_message_info *info, LRESULT *res
return
TRUE
;
}
static
inline
void
*
get_buffer
(
void
*
static_buffer
,
size_t
size
,
size_t
need
)
{
if
(
size
>=
need
)
return
static_buffer
;
return
malloc
(
need
);
}
static
inline
void
free_buffer
(
void
*
static_buffer
,
void
*
buffer
)
{
if
(
buffer
!=
static_buffer
)
free
(
buffer
);
}
typedef
LRESULT
(
*
winproc_callback_t
)(
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
,
LRESULT
*
result
,
void
*
arg
);
/**********************************************************************
* test_lb_for_string
*
* Return TRUE if the lparam is a string
*/
static
inline
BOOL
test_lb_for_string
(
HWND
hwnd
,
UINT
msg
)
{
DWORD
style
=
get_window_long
(
hwnd
,
GWL_STYLE
);
if
(
msg
<=
CB_MSGMAX
)
return
(
!
(
style
&
(
CBS_OWNERDRAWFIXED
|
CBS_OWNERDRAWVARIABLE
))
||
(
style
&
CBS_HASSTRINGS
));
else
return
(
!
(
style
&
(
LBS_OWNERDRAWFIXED
|
LBS_OWNERDRAWVARIABLE
))
||
(
style
&
LBS_HASSTRINGS
));
}
static
CPTABLEINFO
*
get_input_codepage
(
void
)
{
const
NLS_LOCALE_DATA
*
locale
;
HKL
hkl
=
NtUserGetKeyboardLayout
(
0
);
CPTABLEINFO
*
ret
=
NULL
;
locale
=
get_locale_data
(
LOWORD
(
hkl
)
);
if
(
locale
&&
locale
->
idefaultansicodepage
!=
CP_UTF8
)
ret
=
get_cptable
(
locale
->
idefaultansicodepage
);
return
ret
?
ret
:
&
ansi_cp
;
}
/***********************************************************************
* map_wparam_AtoW
*
* Convert the wparam of an ASCII message to Unicode.
*/
static
BOOL
map_wparam_AtoW
(
UINT
message
,
WPARAM
*
wparam
,
enum
wm_char_mapping
mapping
)
{
char
ch
[
2
];
WCHAR
wch
[
2
];
wch
[
0
]
=
wch
[
1
]
=
0
;
switch
(
message
)
{
case
WM_CHARTOITEM
:
case
EM_SETPASSWORDCHAR
:
case
WM_DEADCHAR
:
case
WM_SYSCHAR
:
case
WM_SYSDEADCHAR
:
case
WM_MENUCHAR
:
ch
[
0
]
=
LOBYTE
(
*
wparam
);
ch
[
1
]
=
HIBYTE
(
*
wparam
);
win32u_mbtowc
(
get_input_codepage
(),
wch
,
2
,
ch
,
2
);
*
wparam
=
MAKEWPARAM
(
wch
[
0
],
wch
[
1
]);
break
;
case
WM_IME_CHAR
:
ch
[
0
]
=
HIBYTE
(
*
wparam
);
ch
[
1
]
=
LOBYTE
(
*
wparam
);
if
(
ch
[
0
])
win32u_mbtowc
(
get_input_codepage
(),
wch
,
2
,
ch
,
2
);
else
win32u_mbtowc
(
get_input_codepage
(),
wch
,
1
,
ch
+
1
,
1
);
*
wparam
=
MAKEWPARAM
(
wch
[
0
],
HIWORD
(
*
wparam
));
break
;
}
return
TRUE
;
}
/**********************************************************************
* call_messageAtoW
*
* Call a window procedure, translating args from Ansi to Unicode.
*/
LRESULT
call_messageAtoW
(
winproc_callback_t
callback
,
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
,
LRESULT
*
result
,
void
*
arg
,
enum
wm_char_mapping
mapping
)
{
LRESULT
ret
=
0
;
TRACE
(
"(hwnd=%p,msg=%s,wp=%#lx,lp=%#lx)
\n
"
,
hwnd
,
debugstr_msg_name
(
msg
,
hwnd
),
(
long
)
wparam
,
(
long
)
lparam
);
switch
(
msg
)
{
case
WM_MDICREATE
:
{
WCHAR
*
ptr
,
buffer
[
512
];
DWORD
title_lenA
=
0
,
title_lenW
=
0
,
class_lenA
=
0
,
class_lenW
=
0
;
MDICREATESTRUCTA
*
csA
=
(
MDICREATESTRUCTA
*
)
lparam
;
MDICREATESTRUCTW
csW
;
memcpy
(
&
csW
,
csA
,
sizeof
(
csW
)
);
if
(
!
IS_INTRESOURCE
(
csA
->
szTitle
))
{
title_lenA
=
strlen
(
csA
->
szTitle
)
+
1
;
title_lenW
=
win32u_mbtowc_size
(
&
ansi_cp
,
csA
->
szTitle
,
title_lenA
);
}
if
(
!
IS_INTRESOURCE
(
csA
->
szClass
))
{
class_lenA
=
strlen
(
csA
->
szClass
)
+
1
;
class_lenW
=
win32u_mbtowc_size
(
&
ansi_cp
,
csA
->
szClass
,
class_lenA
);
}
if
(
!
(
ptr
=
get_buffer
(
buffer
,
sizeof
(
buffer
),
(
title_lenW
+
class_lenW
)
*
sizeof
(
WCHAR
)
)))
break
;
if
(
title_lenW
)
{
csW
.
szTitle
=
ptr
;
win32u_mbtowc
(
&
ansi_cp
,
ptr
,
title_lenW
,
csA
->
szTitle
,
title_lenA
);
}
if
(
class_lenW
)
{
csW
.
szClass
=
ptr
+
title_lenW
;
win32u_mbtowc
(
&
ansi_cp
,
ptr
+
title_lenW
,
class_lenW
,
csA
->
szClass
,
class_lenA
);
}
ret
=
callback
(
hwnd
,
msg
,
wparam
,
(
LPARAM
)
&
csW
,
result
,
arg
);
free_buffer
(
buffer
,
ptr
);
}
break
;
case
WM_GETTEXT
:
case
WM_ASKCBFORMATNAME
:
{
WCHAR
*
ptr
,
buffer
[
512
];
LPSTR
str
=
(
LPSTR
)
lparam
;
DWORD
len
=
wparam
*
sizeof
(
WCHAR
);
if
(
!
(
ptr
=
get_buffer
(
buffer
,
sizeof
(
buffer
),
len
)))
break
;
ret
=
callback
(
hwnd
,
msg
,
wparam
,
(
LPARAM
)
ptr
,
result
,
arg
);
if
(
wparam
)
{
len
=
0
;
len
=
*
result
?
win32u_wctomb
(
&
ansi_cp
,
str
,
wparam
-
1
,
ptr
,
*
result
)
:
0
;
str
[
len
]
=
0
;
*
result
=
len
;
}
free_buffer
(
buffer
,
ptr
);
}
break
;
case
LB_ADDSTRING
:
case
LB_INSERTSTRING
:
case
LB_FINDSTRING
:
case
LB_FINDSTRINGEXACT
:
case
LB_SELECTSTRING
:
case
CB_ADDSTRING
:
case
CB_INSERTSTRING
:
case
CB_FINDSTRING
:
case
CB_FINDSTRINGEXACT
:
case
CB_SELECTSTRING
:
if
(
!
lparam
||
!
test_lb_for_string
(
hwnd
,
msg
))
{
ret
=
callback
(
hwnd
,
msg
,
wparam
,
lparam
,
result
,
arg
);
break
;
}
/* fall through */
case
WM_SETTEXT
:
case
WM_WININICHANGE
:
case
WM_DEVMODECHANGE
:
case
CB_DIR
:
case
LB_DIR
:
case
LB_ADDFILE
:
case
EM_REPLACESEL
:
if
(
!
lparam
)
{
ret
=
callback
(
hwnd
,
msg
,
wparam
,
lparam
,
result
,
arg
);
}
else
{
WCHAR
*
ptr
,
buffer
[
512
];
LPCSTR
strA
=
(
LPCSTR
)
lparam
;
DWORD
lenW
,
lenA
=
strlen
(
strA
)
+
1
;
lenW
=
win32u_mbtowc_size
(
&
ansi_cp
,
strA
,
lenA
);
if
((
ptr
=
get_buffer
(
buffer
,
sizeof
(
buffer
),
lenW
*
sizeof
(
WCHAR
)
)))
{
win32u_mbtowc
(
&
ansi_cp
,
ptr
,
lenW
,
strA
,
lenA
);
ret
=
callback
(
hwnd
,
msg
,
wparam
,
(
LPARAM
)
ptr
,
result
,
arg
);
free_buffer
(
buffer
,
ptr
);
}
}
break
;
case
EM_GETLINE
:
{
WCHAR
*
ptr
,
buffer
[
512
];
WORD
len
=
*
(
WORD
*
)
lparam
;
if
(
!
(
ptr
=
get_buffer
(
buffer
,
sizeof
(
buffer
),
len
*
sizeof
(
WCHAR
)
)))
break
;
*
((
WORD
*
)
ptr
)
=
len
;
/* store the length */
ret
=
callback
(
hwnd
,
msg
,
wparam
,
(
LPARAM
)
ptr
,
result
,
arg
);
if
(
*
result
)
{
DWORD
reslen
;
reslen
=
win32u_wctomb
(
&
ansi_cp
,
(
char
*
)
lparam
,
len
,
ptr
,
*
result
);
if
(
reslen
<
len
)
((
LPSTR
)
lparam
)[
reslen
]
=
0
;
*
result
=
reslen
;
}
free_buffer
(
buffer
,
ptr
);
}
break
;
case
WM_GETDLGCODE
:
if
(
lparam
)
{
MSG
newmsg
=
*
(
MSG
*
)
lparam
;
if
(
map_wparam_AtoW
(
newmsg
.
message
,
&
newmsg
.
wParam
,
WMCHAR_MAP_NOMAPPING
))
ret
=
callback
(
hwnd
,
msg
,
wparam
,
(
LPARAM
)
&
newmsg
,
result
,
arg
);
}
else
ret
=
callback
(
hwnd
,
msg
,
wparam
,
lparam
,
result
,
arg
);
break
;
case
WM_CHARTOITEM
:
case
WM_MENUCHAR
:
case
WM_DEADCHAR
:
case
WM_SYSCHAR
:
case
WM_SYSDEADCHAR
:
case
EM_SETPASSWORDCHAR
:
case
WM_IME_CHAR
:
if
(
map_wparam_AtoW
(
msg
,
&
wparam
,
mapping
))
ret
=
callback
(
hwnd
,
msg
,
wparam
,
lparam
,
result
,
arg
);
break
;
case
WM_GETTEXTLENGTH
:
case
CB_GETLBTEXTLEN
:
case
LB_GETTEXTLEN
:
ret
=
callback
(
hwnd
,
msg
,
wparam
,
lparam
,
result
,
arg
);
if
(
*
result
>=
0
)
{
WCHAR
*
ptr
,
buffer
[
512
];
LRESULT
res
;
DWORD
len
=
*
result
+
1
;
/* Determine respective GETTEXT message */
UINT
msg_get_text
=
msg
==
WM_GETTEXTLENGTH
?
WM_GETTEXT
:
(
msg
==
CB_GETLBTEXTLEN
?
CB_GETLBTEXT
:
LB_GETTEXT
);
/* wparam differs between the messages */
WPARAM
wp
=
msg
==
WM_GETTEXTLENGTH
?
len
:
wparam
;
if
(
!
(
ptr
=
get_buffer
(
buffer
,
sizeof
(
buffer
),
len
*
sizeof
(
WCHAR
)
)))
break
;
res
=
send_message
(
hwnd
,
msg_get_text
,
wp
,
(
LPARAM
)
ptr
);
*
result
=
win32u_wctomb_size
(
&
ansi_cp
,
ptr
,
res
);
free_buffer
(
buffer
,
ptr
);
}
break
;
default:
ret
=
callback
(
hwnd
,
msg
,
wparam
,
lparam
,
result
,
arg
);
break
;
}
return
ret
;
}
/***********************************************************************
* process_message
...
...
@@ -2871,7 +3145,13 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr,
{
if
(
dest_pid
!=
GetCurrentProcessId
()
&&
(
info
->
type
==
MSG_ASCII
||
info
->
type
==
MSG_UNICODE
))
info
->
type
=
MSG_OTHER_PROCESS
;
ret
=
send_inter_thread_message
(
info
,
&
result
);
/* MSG_ASCII can be sent unconverted except for WM_CHAR; everything else needs to be Unicode */
if
(
ansi
&&
(
info
->
type
!=
MSG_ASCII
||
info
->
msg
==
WM_CHAR
))
ret
=
call_messageAtoW
(
send_inter_thread_callback
,
info
->
hwnd
,
info
->
msg
,
info
->
wparam
,
info
->
lparam
,
&
result
,
info
,
info
->
wm_char
);
else
ret
=
send_inter_thread_message
(
info
,
&
result
);
}
else
if
(
info
->
type
!=
MSG_OTHER_PROCESS
)
{
...
...
dlls/win32u/ntgdi_private.h
View file @
d222dcc2
...
...
@@ -339,7 +339,6 @@ extern int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name,
DWORD
ntmflags
,
DWORD
version
,
DWORD
flags
,
const
struct
bitmap_font_size
*
size
)
DECLSPEC_HIDDEN
;
extern
UINT
font_init
(
void
)
DECLSPEC_HIDDEN
;
extern
CPTABLEINFO
*
get_cptable
(
WORD
cp
)
DECLSPEC_HIDDEN
;
extern
const
struct
font_backend_funcs
*
init_freetype_lib
(
void
)
DECLSPEC_HIDDEN
;
/* opentype.c */
...
...
dlls/win32u/win32u_private.h
View file @
d222dcc2
...
...
@@ -453,11 +453,14 @@ static inline WCHAR win32u_towupper( WCHAR ch )
extern
CPTABLEINFO
ansi_cp
DECLSPEC_HIDDEN
;
CPTABLEINFO
*
get_cptable
(
WORD
cp
)
DECLSPEC_HIDDEN
;
const
NLS_LOCALE_DATA
*
get_locale_data
(
LCID
lcid
)
DECLSPEC_HIDDEN
;
DWORD
win32u_mbtowc
(
CPTABLEINFO
*
info
,
WCHAR
*
dst
,
DWORD
dstlen
,
const
char
*
src
,
DWORD
srclen
)
DECLSPEC_HIDDEN
;
DWORD
win32u_wctomb
(
CPTABLEINFO
*
info
,
char
*
dst
,
DWORD
dstlen
,
const
WCHAR
*
src
,
DWORD
srclen
)
DECLSPEC_HIDDEN
;
DWORD
win32u_wctomb_size
(
CPTABLEINFO
*
info
,
const
WCHAR
*
src
,
DWORD
srclen
)
DECLSPEC_HIDDEN
;
DWORD
win32u_mbtowc_size
(
CPTABLEINFO
*
info
,
const
char
*
src
,
DWORD
srclen
)
DECLSPEC_HIDDEN
;
static
inline
WCHAR
*
win32u_wcsdup
(
const
WCHAR
*
str
)
{
...
...
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