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
e85668b4
Commit
e85668b4
authored
Jun 06, 2011
by
Adam Martinson
Committed by
Alexandre Julliard
Jun 08, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Don't call IDropTarget::QueryInterface() in RegisterDragDrop().
parent
de2c4015
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
120 additions
and
10 deletions
+120
-10
ole2.c
dlls/ole32/ole2.c
+119
-9
dragdrop.c
dlls/ole32/tests/dragdrop.c
+1
-1
No files found.
dlls/ole32/ole2.c
View file @
e85668b4
...
...
@@ -6,6 +6,7 @@
* Copyright 1999 Noel Borthwick
* Copyright 1999, 2000 Marcus Meissner
* Copyright 2005 Juan Lang
* Copyright 2011 Adam Martinson for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -377,6 +378,116 @@ static HRESULT create_stream_from_map(HANDLE map, IStream **stream)
return
hr
;
}
/* This is to work around apps which break COM rules by not implementing
* IDropTarget::QueryInterface(). Windows doesn't expose this because it
* doesn't call CoMarshallInterface() in RegisterDragDrop().
* The wrapper is only used internally, and only exists for the life of
* the marshal. */
typedef
struct
{
IDropTarget
IDropTarget_iface
;
IDropTarget
*
inner
;
LONG
refs
;
}
DropTargetWrapper
;
static
inline
DropTargetWrapper
*
impl_from_IDropTarget
(
IDropTarget
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
DropTargetWrapper
,
IDropTarget_iface
);
}
static
HRESULT
WINAPI
DropTargetWrapper_QueryInterface
(
IDropTarget
*
iface
,
REFIID
riid
,
void
**
ppvObject
)
{
DropTargetWrapper
*
This
=
impl_from_IDropTarget
(
iface
);
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IDropTarget
))
{
IDropTarget_AddRef
(
&
This
->
IDropTarget_iface
);
*
ppvObject
=
&
This
->
IDropTarget_iface
;
return
S_OK
;
}
*
ppvObject
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
DropTargetWrapper_AddRef
(
IDropTarget
*
iface
)
{
DropTargetWrapper
*
This
=
impl_from_IDropTarget
(
iface
);
return
InterlockedIncrement
(
&
This
->
refs
);
}
static
ULONG
WINAPI
DropTargetWrapper_Release
(
IDropTarget
*
iface
)
{
DropTargetWrapper
*
This
=
impl_from_IDropTarget
(
iface
);
ULONG
refs
=
InterlockedDecrement
(
&
This
->
refs
);
if
(
!
refs
)
{
IDropTarget_Release
(
This
->
inner
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
return
refs
;
}
static
HRESULT
WINAPI
DropTargetWrapper_DragEnter
(
IDropTarget
*
iface
,
IDataObject
*
pDataObj
,
DWORD
grfKeyState
,
POINTL
pt
,
DWORD
*
pdwEffect
)
{
DropTargetWrapper
*
This
=
impl_from_IDropTarget
(
iface
);
return
IDropTarget_DragEnter
(
This
->
inner
,
pDataObj
,
grfKeyState
,
pt
,
pdwEffect
);
}
static
HRESULT
WINAPI
DropTargetWrapper_DragOver
(
IDropTarget
*
iface
,
DWORD
grfKeyState
,
POINTL
pt
,
DWORD
*
pdwEffect
)
{
DropTargetWrapper
*
This
=
impl_from_IDropTarget
(
iface
);
return
IDropTarget_DragOver
(
This
->
inner
,
grfKeyState
,
pt
,
pdwEffect
);
}
static
HRESULT
WINAPI
DropTargetWrapper_DragLeave
(
IDropTarget
*
iface
)
{
DropTargetWrapper
*
This
=
impl_from_IDropTarget
(
iface
);
return
IDropTarget_DragLeave
(
This
->
inner
);
}
static
HRESULT
WINAPI
DropTargetWrapper_Drop
(
IDropTarget
*
iface
,
IDataObject
*
pDataObj
,
DWORD
grfKeyState
,
POINTL
pt
,
DWORD
*
pdwEffect
)
{
DropTargetWrapper
*
This
=
impl_from_IDropTarget
(
iface
);
return
IDropTarget_Drop
(
This
->
inner
,
pDataObj
,
grfKeyState
,
pt
,
pdwEffect
);
}
static
const
IDropTargetVtbl
DropTargetWrapperVTbl
=
{
DropTargetWrapper_QueryInterface
,
DropTargetWrapper_AddRef
,
DropTargetWrapper_Release
,
DropTargetWrapper_DragEnter
,
DropTargetWrapper_DragOver
,
DropTargetWrapper_DragLeave
,
DropTargetWrapper_Drop
};
static
IDropTarget
*
WrapDropTarget
(
IDropTarget
*
inner
)
{
DropTargetWrapper
*
This
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
This
));
if
(
This
)
{
IDropTarget_AddRef
(
inner
);
This
->
IDropTarget_iface
.
lpVtbl
=
&
DropTargetWrapperVTbl
;
This
->
inner
=
inner
;
This
->
refs
=
1
;
}
return
&
This
->
IDropTarget_iface
;
}
/***********************************************************************
* get_droptarget_pointer
*
...
...
@@ -409,7 +520,7 @@ HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
HRESULT
hr
;
IStream
*
stream
;
HANDLE
map
;
I
Unknown
*
unk
;
I
DropTarget
*
wrapper
;
TRACE
(
"(%p,%p)
\n
"
,
hwnd
,
pDropTarget
);
...
...
@@ -450,16 +561,15 @@ HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
hr
=
CreateStreamOnHGlobal
(
NULL
,
TRUE
,
&
stream
);
if
(
FAILED
(
hr
))
return
hr
;
unk
=
NULL
;
hr
=
IDropTarget_QueryInterface
(
pDropTarget
,
&
IID_IUnknown
,
(
void
**
)
&
unk
);
if
(
SUCCEEDED
(
hr
)
&&
!
unk
)
hr
=
E_NOINTERFACE
;
if
(
FAILED
(
hr
))
/* IDropTarget::QueryInterface() shouldn't be called, some (broken) apps depend on this. */
wrapper
=
WrapDropTarget
(
pDropTarget
);
if
(
!
wrapper
)
{
IStream_Release
(
stream
);
return
hr
;
IStream_Release
(
stream
);
return
E_OUTOFMEMORY
;
}
hr
=
CoMarshalInterface
(
stream
,
&
IID_IDropTarget
,
unk
,
MSHCTX_LOCAL
,
NULL
,
MSHLFLAGS_TABLESTRONG
);
I
Unknown_Release
(
unk
);
hr
=
CoMarshalInterface
(
stream
,
&
IID_IDropTarget
,
(
IUnknown
*
)
wrapper
,
MSHCTX_LOCAL
,
NULL
,
MSHLFLAGS_TABLESTRONG
);
I
DropTarget_Release
(
wrapper
);
if
(
SUCCEEDED
(
hr
))
{
...
...
dlls/ole32/tests/dragdrop.c
View file @
e85668b4
...
...
@@ -39,7 +39,7 @@ static int droptarget_refs;
static
HRESULT
WINAPI
DropTarget_QueryInterface
(
IDropTarget
*
iface
,
REFIID
riid
,
void
**
ppvObject
)
{
todo_wine
ok
(
0
,
"DropTarget_QueryInterface() shouldn't be called
\n
"
);
ok
(
0
,
"DropTarget_QueryInterface() shouldn't be called
\n
"
);
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IDropTarget
))
{
...
...
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