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
66baee8b
Commit
66baee8b
authored
Jan 11, 2024
by
Rémi Bernon
Committed by
Alexandre Julliard
Mar 05, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
win32u: Use NtUserCallHwndParam interface for __wine_send_input.
parent
ad921b3c
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
69 additions
and
54 deletions
+69
-54
device.c
dlls/hidclass.sys/device.c
+1
-1
pnp.c
dlls/hidclass.sys/pnp.c
+1
-1
input.c
dlls/win32u/input.c
+1
-11
main.c
dlls/win32u/main.c
+0
-5
message.c
dlls/win32u/message.c
+11
-4
win32syscalls.h
dlls/win32u/win32syscalls.h
+2
-4
win32u.spec
dlls/win32u/win32u.spec
+0
-1
win32u_private.h
dlls/win32u/win32u_private.h
+1
-2
window.c
dlls/win32u/window.c
+6
-0
keyboard.c
dlls/wineandroid.drv/keyboard.c
+1
-1
window.c
dlls/wineandroid.drv/window.c
+2
-2
keyboard.c
dlls/winemac.drv/keyboard.c
+1
-1
mouse.c
dlls/winemac.drv/mouse.c
+1
-1
wayland_keyboard.c
dlls/winewayland.drv/wayland_keyboard.c
+3
-3
wayland_pointer.c
dlls/winewayland.drv/wayland_pointer.c
+4
-4
keyboard.c
dlls/winex11.drv/keyboard.c
+1
-1
mouse.c
dlls/winex11.drv/mouse.c
+4
-4
user.c
dlls/wow64win/user.c
+16
-6
ntuser.h
include/ntuser.h
+13
-2
No files found.
dlls/hidclass.sys/device.c
View file @
66baee8b
...
...
@@ -252,7 +252,7 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack
input
.
hi
.
uMsg
=
WM_INPUT
;
input
.
hi
.
wParamH
=
0
;
input
.
hi
.
wParamL
=
0
;
__wine_send_input
(
0
,
&
input
,
rawinput
);
NtUserSendHardwareInput
(
0
,
0
,
&
input
,
(
LPARAM
)
rawinput
);
free
(
rawinput
);
}
...
...
dlls/hidclass.sys/pnp.c
View file @
66baee8b
...
...
@@ -134,7 +134,7 @@ static void send_wm_input_device_change(BASE_DEVICE_EXTENSION *ext, LPARAM param
input
.
hi
.
uMsg
=
WM_INPUT_DEVICE_CHANGE
;
input
.
hi
.
wParamH
=
0
;
input
.
hi
.
wParamL
=
0
;
__wine_send_input
(
0
,
&
input
,
&
rawinput
);
NtUserSendHardwareInput
(
0
,
0
,
&
input
,
(
LPARAM
)
&
rawinput
);
}
static
NTSTATUS
WINAPI
driver_add_device
(
DRIVER_OBJECT
*
driver
,
DEVICE_OBJECT
*
bus_pdo
)
...
...
dlls/win32u/input.c
View file @
66baee8b
...
...
@@ -605,16 +605,6 @@ BOOL WINAPI NtUserAttachThreadInput( DWORD from, DWORD to, BOOL attach )
}
/***********************************************************************
* __wine_send_input (win32u.@)
*
* Internal SendInput function to allow the graphics driver to inject real events.
*/
BOOL
WINAPI
__wine_send_input
(
HWND
hwnd
,
const
INPUT
*
input
,
const
RAWINPUT
*
rawinput
)
{
return
set_ntstatus
(
send_hardware_message
(
hwnd
,
input
,
rawinput
,
0
));
}
/***********************************************************************
* update_mouse_coords
*
* Helper for NtUserSendInput.
...
...
@@ -693,7 +683,7 @@ UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size )
update_mouse_coords
(
&
input
);
/* fallthrough */
case
INPUT_KEYBOARD
:
status
=
send_hardware_message
(
0
,
&
input
,
NULL
,
SEND_HWMSG_INJECTED
);
status
=
send_hardware_message
(
0
,
SEND_HWMSG_INJECTED
,
&
input
,
0
);
break
;
case
INPUT_HARDWARE
:
RtlSetLastWin32Error
(
ERROR_CALL_NOT_IMPLEMENTED
);
...
...
dlls/win32u/main.c
View file @
66baee8b
...
...
@@ -2163,11 +2163,6 @@ BOOL SYSCALL_API __wine_get_icm_profile( HDC hdc, BOOL allow_default, DWORD *siz
SYSCALL_FUNC
(
__wine_get_icm_profile
);
}
BOOL
SYSCALL_API
__wine_send_input
(
HWND
hwnd
,
const
INPUT
*
input
,
const
RAWINPUT
*
rawinput
)
{
SYSCALL_FUNC
(
__wine_send_input
);
}
#else
/* __arm64ec__ */
#ifdef _WIN64
...
...
dlls/win32u/message.c
View file @
66baee8b
...
...
@@ -3482,7 +3482,7 @@ LRESULT send_internal_message_timeout( DWORD dest_pid, DWORD dest_tid,
/***********************************************************************
* send_hardware_message
*/
NTSTATUS
send_hardware_message
(
HWND
hwnd
,
const
INPUT
*
input
,
const
RAWINPUT
*
rawinput
,
UINT
flags
)
NTSTATUS
send_hardware_message
(
HWND
hwnd
,
UINT
flags
,
const
INPUT
*
input
,
LPARAM
lparam
)
{
struct
send_message_info
info
;
int
prev_x
,
prev_y
,
new_x
,
new_y
;
...
...
@@ -3500,20 +3500,24 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
if
(
input
->
type
==
INPUT_MOUSE
&&
(
input
->
mi
.
dwFlags
&
(
MOUSEEVENTF_LEFTDOWN
|
MOUSEEVENTF_RIGHTDOWN
)))
clip_fullscreen_window
(
hwnd
,
FALSE
);
if
(
input
->
type
==
INPUT_HARDWARE
&&
rawinput
->
header
.
dwType
==
RIM_TYPEHID
)
if
(
input
->
type
==
INPUT_HARDWARE
)
{
if
(
input
->
hi
.
uMsg
==
WM_INPUT_DEVICE_CHANGE
)
{
const
RAWINPUT
*
rawinput
=
(
const
RAWINPUT
*
)
lparam
;
hid_usage_page
=
((
USAGE
*
)
rawinput
->
data
.
hid
.
bRawData
)[
0
];
hid_usage
=
((
USAGE
*
)
rawinput
->
data
.
hid
.
bRawData
)[
1
];
}
if
(
input
->
hi
.
uMsg
==
WM_INPUT
&&
!
rawinput_device_get_usages
(
rawinput
->
header
.
hDevice
,
&
hid_usage_page
,
&
hid_usage
))
if
(
input
->
hi
.
uMsg
==
WM_INPUT
)
{
const
RAWINPUT
*
rawinput
=
(
const
RAWINPUT
*
)
lparam
;
if
(
!
rawinput_device_get_usages
(
rawinput
->
header
.
hDevice
,
&
hid_usage_page
,
&
hid_usage
))
{
WARN
(
"unable to get HID usages for device %p
\n
"
,
rawinput
->
header
.
hDevice
);
return
STATUS_INVALID_HANDLE
;
}
}
}
SERVER_START_REQ
(
send_hardware_message
)
{
...
...
@@ -3549,6 +3553,8 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
{
case
WM_INPUT
:
case
WM_INPUT_DEVICE_CHANGE
:
{
const
RAWINPUT
*
rawinput
=
(
const
RAWINPUT
*
)
lparam
;
switch
(
rawinput
->
header
.
dwType
)
{
case
RIM_TYPEHID
:
...
...
@@ -3565,6 +3571,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
break
;
}
}
}
break
;
}
ret
=
wine_server_call
(
req
);
...
...
dlls/win32u/win32syscalls.h
View file @
66baee8b
...
...
@@ -402,8 +402,7 @@
SYSCALL_ENTRY( 0x018e, NtUserWindowFromDC, 4 ) \
SYSCALL_ENTRY( 0x018f, NtUserWindowFromPoint, 8 ) \
SYSCALL_ENTRY( 0x0190, __wine_get_file_outline_text_metric, 16 ) \
SYSCALL_ENTRY( 0x0191, __wine_get_icm_profile, 16 ) \
SYSCALL_ENTRY( 0x0192, __wine_send_input, 12 )
SYSCALL_ENTRY( 0x0191, __wine_get_icm_profile, 16 )
#define ALL_SYSCALLS64 \
SYSCALL_ENTRY( 0x0000, NtGdiAbortDoc, 8 ) \
...
...
@@ -807,5 +806,4 @@
SYSCALL_ENTRY( 0x018e, NtUserWindowFromDC, 8 ) \
SYSCALL_ENTRY( 0x018f, NtUserWindowFromPoint, 16 ) \
SYSCALL_ENTRY( 0x0190, __wine_get_file_outline_text_metric, 32 ) \
SYSCALL_ENTRY( 0x0191, __wine_get_icm_profile, 32 ) \
SYSCALL_ENTRY( 0x0192, __wine_send_input, 24 )
SYSCALL_ENTRY( 0x0191, __wine_get_icm_profile, 32 )
dlls/win32u/win32u.spec
View file @
66baee8b
...
...
@@ -1322,4 +1322,3 @@
@ stdcall -syscall __wine_get_icm_profile(long long ptr ptr)
@ stdcall -syscall __wine_get_file_outline_text_metric(wstr ptr ptr ptr)
@ stdcall -syscall __wine_send_input(long ptr ptr)
dlls/win32u/win32u_private.h
View file @
66baee8b
...
...
@@ -131,8 +131,7 @@ extern void track_mouse_menu_bar( HWND hwnd, INT ht, int x, int y );
/* message.c */
extern
BOOL
kill_system_timer
(
HWND
hwnd
,
UINT_PTR
id
);
extern
BOOL
reply_message_result
(
LRESULT
result
);
extern
NTSTATUS
send_hardware_message
(
HWND
hwnd
,
const
INPUT
*
input
,
const
RAWINPUT
*
rawinput
,
UINT
flags
);
extern
NTSTATUS
send_hardware_message
(
HWND
hwnd
,
UINT
flags
,
const
INPUT
*
input
,
LPARAM
lparam
);
extern
LRESULT
send_internal_message_timeout
(
DWORD
dest_pid
,
DWORD
dest_tid
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
,
UINT
flags
,
UINT
timeout
,
PDWORD_PTR
res_ptr
);
...
...
dlls/win32u/window.c
View file @
66baee8b
...
...
@@ -5590,6 +5590,12 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
case
NtUserCallHwndParam_ShowOwnedPopups
:
return
show_owned_popups
(
hwnd
,
param
);
case
NtUserCallHwndParam_SendHardwareInput
:
{
struct
send_hardware_input_params
*
params
=
(
void
*
)
param
;
return
send_hardware_message
(
hwnd
,
params
->
flags
,
params
->
input
,
params
->
lparam
);
}
/* temporary exports */
case
NtUserSetWindowStyle
:
{
...
...
dlls/wineandroid.drv/keyboard.c
View file @
66baee8b
...
...
@@ -680,7 +680,7 @@ static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags )
input
.
ki
.
time
=
0
;
input
.
ki
.
dwExtraInfo
=
0
;
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
/***********************************************************************
...
...
dlls/wineandroid.drv/window.c
View file @
66baee8b
...
...
@@ -514,7 +514,7 @@ static int process_events( DWORD mask )
}
SERVER_END_REQ
;
}
__wine_send_input
(
capture
?
capture
:
event
->
data
.
motion
.
hwnd
,
&
event
->
data
.
motion
.
input
,
NULL
);
NtUserSendHardwareInput
(
capture
?
capture
:
event
->
data
.
motion
.
hwnd
,
&
event
->
data
.
motion
.
input
,
0
,
0
);
}
break
;
...
...
@@ -528,7 +528,7 @@ static int process_events( DWORD mask )
event
->
data
.
kbd
.
input
.
ki
.
wVk
,
event
->
data
.
kbd
.
input
.
ki
.
wVk
,
event
->
data
.
kbd
.
input
.
ki
.
wScan
);
update_keyboard_lock_state
(
event
->
data
.
kbd
.
input
.
ki
.
wVk
,
event
->
data
.
kbd
.
lock_state
);
__wine_send_input
(
0
,
&
event
->
data
.
kbd
.
input
,
NULL
);
NtUserSendHardwareInput
(
0
,
0
,
&
event
->
data
.
kbd
.
input
,
0
);
break
;
default:
...
...
dlls/winemac.drv/keyboard.c
View file @
66baee8b
...
...
@@ -1001,7 +1001,7 @@ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, unsigned
input
.
ki
.
time
=
time
;
input
.
ki
.
dwExtraInfo
=
0
;
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
...
...
dlls/winemac.drv/mouse.c
View file @
66baee8b
...
...
@@ -158,7 +158,7 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags,
input
.
mi
.
time
=
time
;
input
.
mi
.
dwExtraInfo
=
0
;
__wine_send_input
(
top_level_hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
top_level_hwnd
,
0
,
&
input
,
0
);
}
...
...
dlls/winewayland.drv/wayland_keyboard.c
View file @
66baee8b
...
...
@@ -642,7 +642,7 @@ static void release_all_keys(HWND hwnd)
input
.
ki
.
wScan
=
scan
&
0xff
;
input
.
ki
.
dwFlags
=
KEYEVENTF_KEYUP
;
if
(
scan
&
~
0xff
)
input
.
ki
.
dwFlags
|=
KEYEVENTF_EXTENDEDKEY
;
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
}
}
...
...
@@ -805,7 +805,7 @@ static void send_right_control(HWND hwnd, uint32_t state)
input
.
ki
.
wVk
=
VK_RCONTROL
;
input
.
ki
.
dwFlags
|=
KEYEVENTF_EXTENDEDKEY
;
if
(
state
==
WL_KEYBOARD_KEY_STATE_RELEASED
)
input
.
ki
.
dwFlags
|=
KEYEVENTF_KEYUP
;
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
static
void
keyboard_handle_key
(
void
*
data
,
struct
wl_keyboard
*
wl_keyboard
,
...
...
@@ -829,7 +829,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
if
(
scan
&
~
0xff
)
input
.
ki
.
dwFlags
|=
KEYEVENTF_EXTENDEDKEY
;
if
(
state
==
WL_KEYBOARD_KEY_STATE_RELEASED
)
input
.
ki
.
dwFlags
|=
KEYEVENTF_KEYUP
;
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
static
void
keyboard_handle_modifiers
(
void
*
data
,
struct
wl_keyboard
*
wl_keyboard
,
...
...
dlls/winewayland.drv/wayland_pointer.c
View file @
66baee8b
...
...
@@ -86,7 +86,7 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy)
hwnd
,
wl_fixed_to_double
(
sx
),
wl_fixed_to_double
(
sy
),
(
int
)
screen
.
x
,
(
int
)
screen
.
y
);
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
static
void
pointer_handle_motion
(
void
*
data
,
struct
wl_pointer
*
wl_pointer
,
...
...
@@ -185,7 +185,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
TRACE
(
"hwnd=%p button=%#x state=%u
\n
"
,
hwnd
,
button
,
state
);
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
static
void
pointer_handle_axis
(
void
*
data
,
struct
wl_pointer
*
wl_pointer
,
...
...
@@ -232,7 +232,7 @@ static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_point
TRACE
(
"hwnd=%p axis=%u discrete=%d
\n
"
,
hwnd
,
axis
,
discrete
);
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
static
const
struct
wl_pointer_listener
pointer_listener
=
...
...
@@ -317,7 +317,7 @@ static void relative_pointer_v1_relative_motion(void *data,
hwnd
,
wl_fixed_to_double
(
dx
),
wl_fixed_to_double
(
dy
),
(
int
)
screen
.
x
,
(
int
)
screen
.
y
);
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
static
const
struct
zwp_relative_pointer_v1_listener
relative_pointer_v1_listener
=
...
...
dlls/winex11.drv/keyboard.c
View file @
66baee8b
...
...
@@ -1131,7 +1131,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, UINT fl
input
.
ki
.
time
=
time
;
input
.
ki
.
dwExtraInfo
=
0
;
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
...
...
dlls/winex11.drv/mouse.c
View file @
66baee8b
...
...
@@ -524,7 +524,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
{
struct
x11drv_thread_data
*
thread_data
=
x11drv_thread_data
();
if
(
!
thread_data
->
clipping_cursor
||
thread_data
->
clip_window
!=
window
)
return
;
__wine_send_input
(
hwnd
,
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
input
,
0
);
return
;
}
...
...
@@ -551,7 +551,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
SERVER_END_REQ
;
}
__wine_send_input
(
hwnd
,
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
input
,
0
);
}
#ifdef SONAME_LIBXCURSOR
...
...
@@ -1494,7 +1494,7 @@ void move_resize_window( HWND hwnd, int dir )
input
.
mi
.
dwFlags
=
button_up_flags
[
button
-
1
]
|
MOUSEEVENTF_ABSOLUTE
|
MOUSEEVENTF_MOVE
;
input
.
mi
.
time
=
NtGetTickCount
();
input
.
mi
.
dwExtraInfo
=
0
;
__wine_send_input
(
hwnd
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
hwnd
,
0
,
&
input
,
0
);
}
while
(
NtUserPeekMessage
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
...
...
@@ -1722,7 +1722,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input
.
mi
.
dy
=
0
;
if
(
!
map_raw_event_coords
(
event
,
&
input
))
return
FALSE
;
__wine_send_input
(
0
,
&
input
,
NULL
);
NtUserSendHardwareInput
(
0
,
0
,
&
input
,
0
);
return
TRUE
;
}
...
...
dlls/wow64win/user.c
View file @
66baee8b
...
...
@@ -1710,6 +1710,22 @@ NTSTATUS WINAPI wow64_NtUserCallHwndParam( UINT *args )
return
NtUserCallHwndParam
(
hwnd
,
(
UINT_PTR
)
&
params
,
code
);
}
case
NtUserCallHwndParam_SendHardwareInput
:
{
struct
{
UINT
flags
;
ULONG
input
;
ULONG
lparam
;
}
*
params32
=
UlongToPtr
(
param
);
struct
send_hardware_input_params
params
;
params
.
flags
=
params32
->
flags
;
params
.
input
=
UlongToPtr
(
params32
->
input
);
params
.
lparam
=
params32
->
lparam
;
return
NtUserCallHwndParam
(
hwnd
,
(
UINT_PTR
)
&
params
,
code
);
}
default:
return
NtUserCallHwndParam
(
hwnd
,
param
,
code
);
}
...
...
@@ -4875,9 +4891,3 @@ NTSTATUS WINAPI wow64_NtUserDisplayConfigGetDeviceInfo( UINT *args )
return
NtUserDisplayConfigGetDeviceInfo
(
packet
);
}
NTSTATUS
WINAPI
wow64___wine_send_input
(
UINT
*
args
)
{
ERR
(
"not supported
\n
"
);
return
0
;
}
include/ntuser.h
View file @
66baee8b
...
...
@@ -1236,6 +1236,7 @@ enum
NtUserCallHwndParam_SetMDIClientInfo
,
NtUserCallHwndParam_SetWindowContextHelpId
,
NtUserCallHwndParam_ShowOwnedPopups
,
NtUserCallHwndParam_SendHardwareInput
,
/* temporary exports */
NtUserSetWindowStyle
,
};
...
...
@@ -1406,7 +1407,17 @@ static inline BOOL NtUserShowOwnedPopups( HWND hwnd, BOOL show )
return
NtUserCallHwndParam
(
hwnd
,
show
,
NtUserCallHwndParam_ShowOwnedPopups
);
}
/* Wine extensions */
W32KAPI
BOOL
WINAPI
__wine_send_input
(
HWND
hwnd
,
const
INPUT
*
input
,
const
RAWINPUT
*
rawinput
);
struct
send_hardware_input_params
{
UINT
flags
;
const
INPUT
*
input
;
LPARAM
lparam
;
/* RAWINPUT pointer for WM_INPUT* messages */
};
static
inline
BOOL
NtUserSendHardwareInput
(
HWND
hwnd
,
UINT
flags
,
const
INPUT
*
input
,
LPARAM
lparam
)
{
struct
send_hardware_input_params
params
=
{.
flags
=
flags
,
.
input
=
input
,
.
lparam
=
lparam
};
return
NtUserCallHwndParam
(
hwnd
,
(
UINT_PTR
)
&
params
,
NtUserCallHwndParam_SendHardwareInput
);
}
#endif
/* _NTUSER_ */
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