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
59df6651
Commit
59df6651
authored
Dec 13, 2018
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
commdlg: Add support for 16-bit file dialog hooks.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
25b136d4
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
404 additions
and
4 deletions
+404
-4
filedlg.c
dlls/commdlg.dll16/filedlg.c
+404
-4
No files found.
dlls/commdlg.dll16/filedlg.c
View file @
59df6651
...
@@ -132,6 +132,408 @@ static LPDLGTEMPLATEA convert_dialog( const char *p, DWORD size )
...
@@ -132,6 +132,408 @@ static LPDLGTEMPLATEA convert_dialog( const char *p, DWORD size )
return
dlg
;
return
dlg
;
}
}
static
void
RECT16to32
(
const
RECT16
*
from
,
RECT
*
to
)
{
to
->
left
=
from
->
left
;
to
->
top
=
from
->
top
;
to
->
right
=
from
->
right
;
to
->
bottom
=
from
->
bottom
;
}
static
void
RECT32to16
(
const
RECT
*
from
,
RECT16
*
to
)
{
to
->
left
=
from
->
left
;
to
->
top
=
from
->
top
;
to
->
right
=
from
->
right
;
to
->
bottom
=
from
->
bottom
;
}
static
void
MINMAXINFO32to16
(
const
MINMAXINFO
*
from
,
MINMAXINFO16
*
to
)
{
to
->
ptReserved
.
x
=
from
->
ptReserved
.
x
;
to
->
ptReserved
.
y
=
from
->
ptReserved
.
y
;
to
->
ptMaxSize
.
x
=
from
->
ptMaxSize
.
x
;
to
->
ptMaxSize
.
y
=
from
->
ptMaxSize
.
y
;
to
->
ptMaxPosition
.
x
=
from
->
ptMaxPosition
.
x
;
to
->
ptMaxPosition
.
y
=
from
->
ptMaxPosition
.
y
;
to
->
ptMinTrackSize
.
x
=
from
->
ptMinTrackSize
.
x
;
to
->
ptMinTrackSize
.
y
=
from
->
ptMinTrackSize
.
y
;
to
->
ptMaxTrackSize
.
x
=
from
->
ptMaxTrackSize
.
x
;
to
->
ptMaxTrackSize
.
y
=
from
->
ptMaxTrackSize
.
y
;
}
static
void
MINMAXINFO16to32
(
const
MINMAXINFO16
*
from
,
MINMAXINFO
*
to
)
{
to
->
ptReserved
.
x
=
from
->
ptReserved
.
x
;
to
->
ptReserved
.
y
=
from
->
ptReserved
.
y
;
to
->
ptMaxSize
.
x
=
from
->
ptMaxSize
.
x
;
to
->
ptMaxSize
.
y
=
from
->
ptMaxSize
.
y
;
to
->
ptMaxPosition
.
x
=
from
->
ptMaxPosition
.
x
;
to
->
ptMaxPosition
.
y
=
from
->
ptMaxPosition
.
y
;
to
->
ptMinTrackSize
.
x
=
from
->
ptMinTrackSize
.
x
;
to
->
ptMinTrackSize
.
y
=
from
->
ptMinTrackSize
.
y
;
to
->
ptMaxTrackSize
.
x
=
from
->
ptMaxTrackSize
.
x
;
to
->
ptMaxTrackSize
.
y
=
from
->
ptMaxTrackSize
.
y
;
}
static
void
WINDOWPOS32to16
(
const
WINDOWPOS
*
from
,
WINDOWPOS16
*
to
)
{
to
->
hwnd
=
HWND_16
(
from
->
hwnd
);
to
->
hwndInsertAfter
=
HWND_16
(
from
->
hwndInsertAfter
);
to
->
x
=
from
->
x
;
to
->
y
=
from
->
y
;
to
->
cx
=
from
->
cx
;
to
->
cy
=
from
->
cy
;
to
->
flags
=
from
->
flags
;
}
static
void
WINDOWPOS16to32
(
const
WINDOWPOS16
*
from
,
WINDOWPOS
*
to
)
{
to
->
hwnd
=
HWND_32
(
from
->
hwnd
);
to
->
hwndInsertAfter
=
(
from
->
hwndInsertAfter
==
(
HWND16
)
-
1
)
?
HWND_TOPMOST
:
HWND_32
(
from
->
hwndInsertAfter
);
to
->
x
=
from
->
x
;
to
->
y
=
from
->
y
;
to
->
cx
=
from
->
cx
;
to
->
cy
=
from
->
cy
;
to
->
flags
=
from
->
flags
;
}
static
void
CREATESTRUCT32Ato16
(
const
CREATESTRUCTA
*
from
,
CREATESTRUCT16
*
to
)
{
to
->
lpCreateParams
=
(
SEGPTR
)
from
->
lpCreateParams
;
to
->
hInstance
=
0
;
to
->
hMenu
=
HMENU_16
(
from
->
hMenu
);
to
->
hwndParent
=
HWND_16
(
from
->
hwndParent
);
to
->
cy
=
from
->
cy
;
to
->
cx
=
from
->
cx
;
to
->
y
=
from
->
y
;
to
->
x
=
from
->
x
;
to
->
style
=
from
->
style
;
to
->
dwExStyle
=
from
->
dwExStyle
;
}
static
LRESULT
call_hook16
(
WNDPROC16
hook
,
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
)
{
CONTEXT
context
;
WORD
params
[
5
];
TRACE
(
"%p: %p %08x %lx %lx: stub
\n
"
,
hook
,
hwnd
,
msg
,
wp
,
lp
);
memset
(
&
context
,
0
,
sizeof
(
context
)
);
context
.
SegDs
=
context
.
SegEs
=
SELECTOROF
(
NtCurrentTeb
()
->
WOW32Reserved
);
context
.
SegFs
=
wine_get_fs
();
context
.
SegGs
=
wine_get_gs
();
context
.
SegCs
=
SELECTOROF
(
hook
);
context
.
Eip
=
OFFSETOF
(
hook
);
context
.
Ebp
=
OFFSETOF
(
NtCurrentTeb
()
->
WOW32Reserved
)
+
FIELD_OFFSET
(
STACK16FRAME
,
bp
);
context
.
Eax
=
context
.
SegDs
;
params
[
4
]
=
HWND_16
(
hwnd
);
params
[
3
]
=
msg
;
params
[
2
]
=
wp
;
params
[
1
]
=
HIWORD
(
lp
);
params
[
0
]
=
LOWORD
(
lp
);
WOWCallback16Ex
(
0
,
WCB16_REGS
,
sizeof
(
params
),
params
,
(
DWORD
*
)
&
context
);
return
LOWORD
(
context
.
Eax
);
}
static
UINT_PTR
CALLBACK
call_hook_proc
(
WNDPROC16
hook
,
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
)
{
LRESULT
ret
=
0
;
switch
(
msg
)
{
case
WM_NCCREATE
:
case
WM_CREATE
:
{
CREATESTRUCTA
*
cs32
=
(
CREATESTRUCTA
*
)
lp
;
CREATESTRUCT16
cs
;
CREATESTRUCT32Ato16
(
cs32
,
&
cs
);
cs
.
lpszName
=
MapLS
(
cs32
->
lpszName
);
cs
.
lpszClass
=
MapLS
(
cs32
->
lpszClass
);
lp
=
MapLS
(
&
cs
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
UnMapLS
(
cs
.
lpszName
);
UnMapLS
(
cs
.
lpszClass
);
}
break
;
case
WM_GETMINMAXINFO
:
{
MINMAXINFO
*
mmi32
=
(
MINMAXINFO
*
)
lp
;
MINMAXINFO16
mmi
;
MINMAXINFO32to16
(
mmi32
,
&
mmi
);
lp
=
MapLS
(
&
mmi
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
MINMAXINFO16to32
(
&
mmi
,
mmi32
);
}
break
;
case
WM_NCCALCSIZE
:
{
NCCALCSIZE_PARAMS
*
nc32
=
(
NCCALCSIZE_PARAMS
*
)
lp
;
NCCALCSIZE_PARAMS16
nc
;
WINDOWPOS16
winpos
;
RECT32to16
(
&
nc32
->
rgrc
[
0
],
&
nc
.
rgrc
[
0
]
);
if
(
wp
)
{
RECT32to16
(
&
nc32
->
rgrc
[
1
],
&
nc
.
rgrc
[
1
]
);
RECT32to16
(
&
nc32
->
rgrc
[
2
],
&
nc
.
rgrc
[
2
]
);
WINDOWPOS32to16
(
nc32
->
lppos
,
&
winpos
);
nc
.
lppos
=
MapLS
(
&
winpos
);
}
lp
=
MapLS
(
&
nc
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
RECT16to32
(
&
nc
.
rgrc
[
0
],
&
nc32
->
rgrc
[
0
]
);
if
(
wp
)
{
RECT16to32
(
&
nc
.
rgrc
[
1
],
&
nc32
->
rgrc
[
1
]
);
RECT16to32
(
&
nc
.
rgrc
[
2
],
&
nc32
->
rgrc
[
2
]
);
WINDOWPOS16to32
(
&
winpos
,
nc32
->
lppos
);
UnMapLS
(
nc
.
lppos
);
}
}
break
;
case
WM_WINDOWPOSCHANGING
:
case
WM_WINDOWPOSCHANGED
:
{
WINDOWPOS
*
winpos32
=
(
WINDOWPOS
*
)
lp
;
WINDOWPOS16
winpos
;
WINDOWPOS32to16
(
winpos32
,
&
winpos
);
lp
=
MapLS
(
&
winpos
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
WINDOWPOS16to32
(
&
winpos
,
winpos32
);
}
break
;
case
WM_COMPAREITEM
:
{
COMPAREITEMSTRUCT
*
cis32
=
(
COMPAREITEMSTRUCT
*
)
lp
;
COMPAREITEMSTRUCT16
cis
;
cis
.
CtlType
=
cis32
->
CtlType
;
cis
.
CtlID
=
cis32
->
CtlID
;
cis
.
hwndItem
=
HWND_16
(
cis32
->
hwndItem
);
cis
.
itemID1
=
cis32
->
itemID1
;
cis
.
itemData1
=
cis32
->
itemData1
;
cis
.
itemID2
=
cis32
->
itemID2
;
cis
.
itemData2
=
cis32
->
itemData2
;
lp
=
MapLS
(
&
cis
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
}
break
;
case
WM_DELETEITEM
:
{
DELETEITEMSTRUCT
*
dis32
=
(
DELETEITEMSTRUCT
*
)
lp
;
DELETEITEMSTRUCT16
dis
;
dis
.
CtlType
=
dis32
->
CtlType
;
dis
.
CtlID
=
dis32
->
CtlID
;
dis
.
itemID
=
dis32
->
itemID
;
dis
.
hwndItem
=
(
dis
.
CtlType
==
ODT_MENU
)
?
(
HWND16
)
LOWORD
(
dis32
->
hwndItem
)
:
HWND_16
(
dis32
->
hwndItem
);
dis
.
itemData
=
dis32
->
itemData
;
lp
=
MapLS
(
&
dis
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
}
break
;
case
WM_DRAWITEM
:
{
DRAWITEMSTRUCT
*
dis32
=
(
DRAWITEMSTRUCT
*
)
lp
;
DRAWITEMSTRUCT16
dis
;
dis
.
CtlType
=
dis32
->
CtlType
;
dis
.
CtlID
=
dis32
->
CtlID
;
dis
.
itemID
=
dis32
->
itemID
;
dis
.
itemAction
=
dis32
->
itemAction
;
dis
.
itemState
=
dis32
->
itemState
;
dis
.
hwndItem
=
HWND_16
(
dis32
->
hwndItem
);
dis
.
hDC
=
HDC_16
(
dis32
->
hDC
);
dis
.
itemData
=
dis32
->
itemData
;
dis
.
rcItem
.
left
=
dis32
->
rcItem
.
left
;
dis
.
rcItem
.
top
=
dis32
->
rcItem
.
top
;
dis
.
rcItem
.
right
=
dis32
->
rcItem
.
right
;
dis
.
rcItem
.
bottom
=
dis32
->
rcItem
.
bottom
;
lp
=
MapLS
(
&
dis
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
}
break
;
case
WM_MEASUREITEM
:
{
MEASUREITEMSTRUCT
*
mis32
=
(
MEASUREITEMSTRUCT
*
)
lp
;
MEASUREITEMSTRUCT16
mis
;
mis
.
CtlType
=
mis32
->
CtlType
;
mis
.
CtlID
=
mis32
->
CtlID
;
mis
.
itemID
=
mis32
->
itemID
;
mis
.
itemWidth
=
mis32
->
itemWidth
;
mis
.
itemHeight
=
mis32
->
itemHeight
;
mis
.
itemData
=
mis32
->
itemData
;
lp
=
MapLS
(
&
mis
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
mis32
->
itemWidth
=
mis
.
itemWidth
;
mis32
->
itemHeight
=
mis
.
itemHeight
;
}
break
;
case
WM_COPYDATA
:
{
COPYDATASTRUCT
*
cds32
=
(
COPYDATASTRUCT
*
)
lp
;
COPYDATASTRUCT16
cds
;
cds
.
dwData
=
cds32
->
dwData
;
cds
.
cbData
=
cds32
->
cbData
;
cds
.
lpData
=
MapLS
(
cds32
->
lpData
);
lp
=
MapLS
(
&
cds
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
UnMapLS
(
cds
.
lpData
);
}
break
;
case
WM_GETDLGCODE
:
if
(
lp
)
{
MSG
*
msg32
=
(
MSG
*
)
lp
;
MSG16
msg16
;
msg16
.
hwnd
=
HWND_16
(
msg32
->
hwnd
);
msg16
.
message
=
msg32
->
message
;
msg16
.
wParam
=
msg32
->
wParam
;
msg16
.
lParam
=
msg32
->
lParam
;
msg16
.
time
=
msg32
->
time
;
msg16
.
pt
.
x
=
msg32
->
pt
.
x
;
msg16
.
pt
.
y
=
msg32
->
pt
.
y
;
lp
=
MapLS
(
&
msg16
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
}
else
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
break
;
case
WM_NEXTMENU
:
{
LRESULT
result
;
MDINEXTMENU
*
next
=
(
MDINEXTMENU
*
)
lp
;
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
(
LPARAM
)
next
->
hmenuIn
);
result
=
GetWindowLongPtrW
(
hwnd
,
DWLP_MSGRESULT
);
next
->
hmenuNext
=
HMENU_32
(
LOWORD
(
result
)
);
next
->
hwndNext
=
HWND_32
(
HIWORD
(
result
)
);
SetWindowLongPtrW
(
hwnd
,
DWLP_MSGRESULT
,
0
);
}
break
;
case
WM_GETTEXT
:
case
WM_ASKCBFORMATNAME
:
wp
=
min
(
wp
,
0xff80
);
/* Must be < 64K */
/* fall through */
case
WM_NOTIFY
:
case
WM_SETTEXT
:
case
WM_WININICHANGE
:
case
WM_DEVMODECHANGE
:
lp
=
MapLS
(
(
void
*
)
lp
);
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
UnMapLS
(
lp
);
break
;
case
WM_ACTIVATE
:
case
WM_CHARTOITEM
:
case
WM_COMMAND
:
case
WM_VKEYTOITEM
:
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
MAKELPARAM
(
(
HWND16
)
lp
,
HIWORD
(
wp
)
));
break
;
case
WM_HSCROLL
:
case
WM_VSCROLL
:
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
MAKELPARAM
(
HIWORD
(
wp
),
(
HWND16
)
lp
));
break
;
case
WM_CTLCOLORMSGBOX
:
case
WM_CTLCOLOREDIT
:
case
WM_CTLCOLORLISTBOX
:
case
WM_CTLCOLORBTN
:
case
WM_CTLCOLORDLG
:
case
WM_CTLCOLORSCROLLBAR
:
case
WM_CTLCOLORSTATIC
:
ret
=
call_hook16
(
hook
,
hwnd
,
WM_CTLCOLOR
,
wp
,
MAKELPARAM
(
(
HWND16
)
lp
,
msg
-
WM_CTLCOLORMSGBOX
));
break
;
case
WM_MENUSELECT
:
if
(
HIWORD
(
wp
)
&
MF_POPUP
)
{
HMENU
hmenu
;
if
((
HIWORD
(
wp
)
!=
0xffff
)
||
lp
)
{
if
((
hmenu
=
GetSubMenu
(
(
HMENU
)
lp
,
LOWORD
(
wp
)
)))
{
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
HMENU_16
(
hmenu
),
MAKELPARAM
(
HIWORD
(
wp
),
(
HMENU16
)
lp
)
);
break
;
}
}
}
/* fall through */
case
WM_MENUCHAR
:
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
MAKELPARAM
(
HIWORD
(
wp
),
(
HMENU16
)
lp
));
break
;
case
WM_PARENTNOTIFY
:
if
((
LOWORD
(
wp
)
==
WM_CREATE
)
||
(
LOWORD
(
wp
)
==
WM_DESTROY
))
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
MAKELPARAM
(
(
HWND16
)
lp
,
HIWORD
(
wp
)
));
else
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
break
;
case
WM_ACTIVATEAPP
:
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
HTASK_16
(
lp
));
break
;
default:
ret
=
call_hook16
(
hook
,
hwnd
,
msg
,
wp
,
lp
);
break
;
}
return
LOWORD
(
ret
);
}
#include "pshpack1.h"
struct
hook_proc
{
BYTE
popl_eax
;
/* popl %eax */
BYTE
pushl_hook
;
/* pushl $hook_ptr */
LPOFNHOOKPROC16
hook_ptr
;
BYTE
pushl_eax
;
/* pushl %eax */
BYTE
jmp
;
/* jmp call_hook */
DWORD
call_hook
;
};
#include "poppack.h"
static
LPOFNHOOKPROC
alloc_hook
(
LPOFNHOOKPROC16
hook16
)
{
static
struct
hook_proc
*
hooks
;
static
unsigned
int
count
;
SIZE_T
size
=
0x1000
;
unsigned
int
i
;
if
(
!
hooks
&&
NtAllocateVirtualMemory
(
GetCurrentProcess
(),
(
void
**
)
&
hooks
,
12
,
&
size
,
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
))
return
NULL
;
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
hooks
[
i
].
hook_ptr
==
hook16
)
return
(
LPOFNHOOKPROC
)
&
hooks
[
i
];
if
(
count
>=
size
/
sizeof
(
*
hooks
))
{
FIXME
(
"all hooks are in use
\n
"
);
return
NULL
;
}
hooks
[
count
].
popl_eax
=
0x58
;
hooks
[
count
].
pushl_hook
=
0x68
;
hooks
[
count
].
hook_ptr
=
hook16
;
hooks
[
count
].
pushl_eax
=
0x50
;
hooks
[
count
].
jmp
=
0xe9
;
hooks
[
count
].
call_hook
=
(
char
*
)
call_hook_proc
-
(
char
*
)(
&
hooks
[
count
].
call_hook
+
1
);
return
(
LPOFNHOOKPROC
)
&
hooks
[
count
++
];
}
static
UINT_PTR
CALLBACK
dummy_hook
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
)
static
UINT_PTR
CALLBACK
dummy_hook
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
)
{
{
return
FALSE
;
return
FALSE
;
...
@@ -210,8 +612,7 @@ BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) /* [in/out] address of structure w
...
@@ -210,8 +612,7 @@ BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) /* [in/out] address of structure w
FreeResource16
(
handle
);
FreeResource16
(
handle
);
}
}
if
(
lpofn
->
Flags
&
OFN_ENABLEHOOK
)
if
(
lpofn
->
Flags
&
OFN_ENABLEHOOK
)
ofn32
.
lpfnHook
=
alloc_hook
(
lpofn
->
lpfnHook
);
FIXME
(
"custom hook %p no longer supported
\n
"
,
lpofn
->
lpfnHook
);
if
((
ret
=
GetOpenFileNameA
(
&
ofn32
)))
if
((
ret
=
GetOpenFileNameA
(
&
ofn32
)))
{
{
...
@@ -278,8 +679,7 @@ BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn ) /* [in/out] address of structure w
...
@@ -278,8 +679,7 @@ BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn ) /* [in/out] address of structure w
FreeResource16
(
handle
);
FreeResource16
(
handle
);
}
}
if
(
lpofn
->
Flags
&
OFN_ENABLEHOOK
)
if
(
lpofn
->
Flags
&
OFN_ENABLEHOOK
)
ofn32
.
lpfnHook
=
alloc_hook
(
lpofn
->
lpfnHook
);
FIXME
(
"custom hook %p no longer supported
\n
"
,
lpofn
->
lpfnHook
);
if
((
ret
=
GetSaveFileNameA
(
&
ofn32
)))
if
((
ret
=
GetSaveFileNameA
(
&
ofn32
)))
{
{
...
...
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