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
85f472b3
Commit
85f472b3
authored
Dec 30, 2007
by
Jacek Caban
Committed by
Alexandre Julliard
Dec 31, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
urlmon: Added BindToObject implementation.
parent
a16ae2e8
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
212 additions
and
16 deletions
+212
-16
binding.c
dlls/urlmon/binding.c
+192
-10
url.c
dlls/urlmon/tests/url.c
+9
-1
umon.c
dlls/urlmon/umon.c
+10
-5
urlmon_main.h
dlls/urlmon/urlmon_main.h
+1
-0
No files found.
dlls/urlmon/binding.c
View file @
85f472b3
...
...
@@ -17,11 +17,14 @@
*/
#include "urlmon_main.h"
#include "winreg.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
urlmon
);
static
WCHAR
cbinding_contextW
[]
=
{
'C'
,
'B'
,
'i'
,
'n'
,
'd'
,
'i'
,
'n'
,
'g'
,
' '
,
'C'
,
'o'
,
'n'
,
't'
,
'e'
,
'x'
,
't'
,
0
};
static
WCHAR
bscb_holderW
[]
=
{
'_'
,
'B'
,
'S'
,
'C'
,
'B'
,
'_'
,
'H'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
'_'
,
0
};
typedef
struct
Binding
Binding
;
...
...
@@ -55,6 +58,7 @@ typedef enum {
#define BINDING_LOCKED 0x0001
#define BINDING_STOPPED 0x0002
#define BINDING_OBJAVAIL 0x0004
struct
Binding
{
const
IBindingVtbl
*
lpBindingVtbl
;
...
...
@@ -71,14 +75,19 @@ struct Binding {
BINDINFO
bindinfo
;
DWORD
bindf
;
BOOL
to_object
;
LPWSTR
mime
;
UINT
clipboard_format
;
LPWSTR
url
;
IID
iid
;
BOOL
report_mime
;
DWORD
continue_call
;
DWORD
state
;
HRESULT
hres
;
download_state_t
download_state
;
IUnknown
*
obj
;
IMoniker
*
mon
;
IBindCtx
*
bctx
;
DWORD
apartment_thread
;
HWND
notif_hwnd
;
...
...
@@ -329,6 +338,128 @@ static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str)
}
}
static
LPWSTR
get_mime_clsid
(
LPCWSTR
mime
,
CLSID
*
clsid
)
{
LPWSTR
key_name
,
ret
;
DWORD
res
,
type
,
size
;
HKEY
hkey
;
int
len
;
HRESULT
hres
;
static
const
WCHAR
mime_keyW
[]
=
{
'M'
,
'I'
,
'M'
,
'E'
,
'\\'
,
'D'
,
'a'
,
't'
,
'a'
,
'b'
,
'a'
,
's'
,
'e'
,
'\\'
,
'C'
,
'o'
,
'n'
,
't'
,
'e'
,
'n'
,
't'
,
' '
,
'T'
,
'y'
,
'p'
,
'e'
,
'\\'
};
static
const
WCHAR
clsidW
[]
=
{
'C'
,
'L'
,
'S'
,
'I'
,
'D'
,
0
};
len
=
strlenW
(
mime
)
+
1
;
key_name
=
heap_alloc
(
sizeof
(
mime_keyW
)
+
len
*
sizeof
(
WCHAR
));
memcpy
(
key_name
,
mime_keyW
,
sizeof
(
mime_keyW
));
strcpyW
(
key_name
+
sizeof
(
mime_keyW
)
/
sizeof
(
WCHAR
),
mime
);
res
=
RegOpenKeyW
(
HKEY_CLASSES_ROOT
,
key_name
,
&
hkey
);
heap_free
(
key_name
);
if
(
res
!=
ERROR_SUCCESS
)
{
WARN
(
"Could not open MIME key: %x
\n
"
,
res
);
return
NULL
;
}
size
=
50
*
sizeof
(
WCHAR
);
ret
=
heap_alloc
(
size
);
res
=
RegQueryValueExW
(
hkey
,
clsidW
,
NULL
,
&
type
,
(
LPBYTE
)
ret
,
&
size
);
RegCloseKey
(
hkey
);
if
(
res
!=
ERROR_SUCCESS
)
{
WARN
(
"Could not get CLSID: %08x
\n
"
,
res
);
heap_free
(
ret
);
return
NULL
;
}
hres
=
CLSIDFromString
(
ret
,
clsid
);
if
(
FAILED
(
hres
))
{
WARN
(
"Could not parse CLSID: %08x
\n
"
,
hres
);
heap_free
(
ret
);
return
NULL
;
}
return
ret
;
}
static
void
load_doc_mon
(
Binding
*
binding
,
IPersistMoniker
*
persist
)
{
IBindCtx
*
bctx
;
HRESULT
hres
;
hres
=
CreateAsyncBindCtxEx
(
binding
->
bctx
,
0
,
NULL
,
NULL
,
&
bctx
,
0
);
if
(
FAILED
(
hres
))
{
WARN
(
"CreateAsyncBindCtxEx failed: %08x
\n
"
,
hres
);
return
;
}
IBindCtx_RevokeObjectParam
(
bctx
,
bscb_holderW
);
IBindCtx_RegisterObjectParam
(
bctx
,
cbinding_contextW
,
(
IUnknown
*
)
BINDING
(
binding
));
hres
=
IPersistMoniker_Load
(
persist
,
binding
->
download_state
==
END_DOWNLOAD
,
binding
->
mon
,
bctx
,
0x12
);
IBindCtx_RevokeObjectParam
(
bctx
,
cbinding_contextW
);
IBindCtx_Release
(
bctx
);
if
(
FAILED
(
hres
))
FIXME
(
"Load failed: %08x
\n
"
,
hres
);
}
static
void
create_object
(
Binding
*
binding
)
{
IPersistMoniker
*
persist
;
LPWSTR
clsid_str
;
CLSID
clsid
;
HRESULT
hres
;
if
(
!
binding
->
mime
)
{
FIXME
(
"MIME unavailable
\n
"
);
return
;
}
if
(
!
(
clsid_str
=
get_mime_clsid
(
binding
->
mime
,
&
clsid
)))
{
FIXME
(
"Could not find object for MIME %s
\n
"
,
debugstr_w
(
binding
->
mime
));
return
;
}
IBindStatusCallback_OnProgress
(
binding
->
callback
,
0
,
0
,
BINDSTATUS_CLASSIDAVAILABLE
,
clsid_str
);
IBindStatusCallback_OnProgress
(
binding
->
callback
,
0
,
0
,
BINDSTATUS_BEGINSYNCOPERATION
,
NULL
);
hres
=
CoCreateInstance
(
&
clsid
,
NULL
,
CLSCTX_INPROC_SERVER
|
CLSCTX_INPROC_HANDLER
,
&
binding
->
iid
,
(
void
**
)
&
binding
->
obj
);
if
(
FAILED
(
hres
))
FIXME
(
"CoCreateInstance failed: %08x
\n
"
,
hres
);
binding
->
state
|=
BINDING_OBJAVAIL
;
hres
=
IUnknown_QueryInterface
(
binding
->
obj
,
&
IID_IPersistMoniker
,
(
void
**
)
&
persist
);
if
(
SUCCEEDED
(
hres
))
{
IMonikerProp
*
prop
;
hres
=
IPersistMoniker_QueryInterface
(
persist
,
&
IID_IMonikerProp
,
(
void
**
)
&
prop
);
if
(
SUCCEEDED
(
hres
))
{
IMonikerProp_PutProperty
(
prop
,
MIMETYPEPROP
,
binding
->
mime
);
IMonikerProp_PutProperty
(
prop
,
CLASSIDPROP
,
clsid_str
);
IMonikerProp_Release
(
prop
);
}
load_doc_mon
(
binding
,
persist
);
IPersistMoniker_Release
(
persist
);
}
else
{
FIXME
(
"Could not get IPersistMoniker: %08x
\n
"
,
hres
);
/* FIXME: Try query IPersistFile */
}
heap_free
(
clsid_str
);
IBindStatusCallback_OnObjectAvailable
(
binding
->
callback
,
&
binding
->
iid
,
binding
->
obj
);
IBindStatusCallback_OnProgress
(
binding
->
callback
,
0
,
0
,
BINDSTATUS_ENDSYNCOPERATION
,
NULL
);
stop_binding
(
binding
,
S_OK
,
NULL
);
}
#define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface)
static
HRESULT
WINAPI
ProtocolStream_QueryInterface
(
IStream
*
iface
,
...
...
@@ -597,6 +728,8 @@ static ULONG WINAPI Binding_Release(IBinding *iface)
if
(
!
ref
)
{
if
(
This
->
notif_hwnd
)
DestroyWindow
(
This
->
notif_hwnd
);
if
(
This
->
mon
)
IMoniker_Release
(
This
->
mon
);
if
(
This
->
callback
)
IBindStatusCallback_Release
(
This
->
callback
);
if
(
This
->
protocol
)
...
...
@@ -605,6 +738,10 @@ static ULONG WINAPI Binding_Release(IBinding *iface)
IServiceProvider_Release
(
This
->
service_provider
);
if
(
This
->
stream
)
IStream_Release
(
STREAM
(
This
->
stream
));
if
(
This
->
obj
)
IUnknown_Release
(
This
->
obj
);
if
(
This
->
bctx
)
IBindCtx_Release
(
This
->
bctx
);
ReleaseBindInfo
(
&
This
->
bindinfo
);
This
->
section
.
DebugInfo
->
Spare
[
0
]
=
0
;
...
...
@@ -857,7 +994,7 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
return
;
if
(
GetCurrentThreadId
()
!=
This
->
apartment_thread
)
FIXME
(
"called from worke
d
hread
\n
"
);
FIXME
(
"called from worke
r t
hread
\n
"
);
if
(
This
->
report_mime
)
mime_available
(
This
,
NULL
,
TRUE
);
...
...
@@ -880,6 +1017,10 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
BINDSTATUS_DOWNLOADINGDATA
,
This
->
url
);
}
if
(
This
->
to_object
)
{
if
(
!
(
This
->
state
&
BINDING_OBJAVAIL
))
create_object
(
This
);
}
else
{
if
(
!
(
This
->
state
&
BINDING_LOCKED
))
{
HRESULT
hres
=
IInternetProtocol_LockRequest
(
This
->
protocol
,
0
);
if
(
SUCCEEDED
(
hres
))
...
...
@@ -892,6 +1033,7 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
if
(
This
->
download_state
==
END_DOWNLOAD
)
stop_binding
(
This
,
S_OK
,
NULL
);
}
}
typedef
struct
{
...
...
@@ -1135,9 +1277,7 @@ static HRESULT get_callback(IBindCtx *pbc, IBindStatusCallback **callback)
IUnknown
*
unk
;
HRESULT
hres
;
static
WCHAR
wszBSCBHolder
[]
=
{
'_'
,
'B'
,
'S'
,
'C'
,
'B'
,
'_'
,
'H'
,
'o'
,
'l'
,
'd'
,
'e'
,
'r'
,
'_'
,
0
};
hres
=
IBindCtx_GetObjectParam
(
pbc
,
wszBSCBHolder
,
&
unk
);
hres
=
IBindCtx_GetObjectParam
(
pbc
,
bscb_holderW
,
&
unk
);
if
(
SUCCEEDED
(
hres
))
{
hres
=
IUnknown_QueryInterface
(
unk
,
&
IID_IBindStatusCallback
,
(
void
**
)
callback
);
IUnknown_Release
(
unk
);
...
...
@@ -1180,12 +1320,13 @@ static BOOL is_urlmon_protocol(LPCWSTR url)
return
FALSE
;
}
static
HRESULT
Binding_Create
(
Binding
*
binding_ctx
,
LPCWSTR
url
,
IBindCtx
*
pbc
,
REFIID
riid
,
Binding
**
binding
)
static
HRESULT
Binding_Create
(
IMoniker
*
mon
,
Binding
*
binding_ctx
,
LPCWSTR
url
,
IBindCtx
*
pbc
,
BOOL
to_obj
,
REFIID
riid
,
Binding
**
binding
)
{
Binding
*
ret
;
HRESULT
hres
;
if
(
!
IsEqualGUID
(
&
IID_IStream
,
riid
))
{
if
(
!
to_obj
&&
!
IsEqualGUID
(
&
IID_IStream
,
riid
))
{
FIXME
(
"Unsupported riid %s
\n
"
,
debugstr_guid
(
riid
));
return
E_NOTIMPL
;
}
...
...
@@ -1201,11 +1342,23 @@ static HRESULT Binding_Create(Binding *binding_ctx, LPCWSTR url, IBindCtx *pbc,
ret
->
ref
=
1
;
ret
->
to_object
=
to_obj
;
ret
->
iid
=
*
riid
;
ret
->
apartment_thread
=
GetCurrentThreadId
();
ret
->
notif_hwnd
=
get_notif_hwnd
();
ret
->
report_mime
=
!
binding_ctx
;
ret
->
download_state
=
BEFORE_DOWNLOAD
;
if
(
to_obj
)
{
IBindCtx_AddRef
(
pbc
);
ret
->
bctx
=
pbc
;
}
if
(
mon
)
{
IMoniker_AddRef
(
mon
);
ret
->
mon
=
mon
;
}
ret
->
bindinfo
.
cbSize
=
sizeof
(
BINDINFO
);
InitializeCriticalSection
(
&
ret
->
section
);
...
...
@@ -1240,9 +1393,12 @@ static HRESULT Binding_Create(Binding *binding_ctx, LPCWSTR url, IBindCtx *pbc,
return
hres
;
}
TRACE
(
"bindf %08x
\n
"
,
ret
->
bindf
);
dump_BINDINFO
(
&
ret
->
bindinfo
);
ret
->
bindf
|=
BINDF_FROMURLMON
;
if
(
to_obj
)
ret
->
bindinfo
.
dwOptions
|=
0x100000
;
if
(
!
is_urlmon_protocol
(
url
))
ret
->
bindf
|=
BINDF_NEEDFILE
;
...
...
@@ -1256,7 +1412,6 @@ static HRESULT Binding_Create(Binding *binding_ctx, LPCWSTR url, IBindCtx *pbc,
}
else
{
ret
->
stream
=
create_stream
(
ret
->
protocol
);
}
ret
->
stgmed
.
tymed
=
TYMED_ISTREAM
;
ret
->
stgmed
.
u
.
pstm
=
STREAM
(
ret
->
stream
);
ret
->
stgmed
.
pUnkForRelease
=
(
IUnknown
*
)
BINDING
(
ret
);
/* NOTE: Windows uses other IUnknown */
...
...
@@ -1265,13 +1420,14 @@ static HRESULT Binding_Create(Binding *binding_ctx, LPCWSTR url, IBindCtx *pbc,
return
S_OK
;
}
static
HRESULT
start_binding
(
Binding
*
binding_ctx
,
LPCWSTR
url
,
IBindCtx
*
pbc
,
REFIID
riid
,
Binding
**
ret
)
static
HRESULT
start_binding
(
IMoniker
*
mon
,
Binding
*
binding_ctx
,
LPCWSTR
url
,
IBindCtx
*
pbc
,
BOOL
to_obj
,
REFIID
riid
,
Binding
**
ret
)
{
Binding
*
binding
=
NULL
;
HRESULT
hres
;
MSG
msg
;
hres
=
Binding_Create
(
binding_ctx
,
url
,
pbc
,
riid
,
&
binding
);
hres
=
Binding_Create
(
mon
,
binding_ctx
,
url
,
pbc
,
to_obj
,
riid
,
&
binding
);
if
(
FAILED
(
hres
))
return
hres
;
...
...
@@ -1322,7 +1478,7 @@ HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
binding_ctx
=
get_bctx_binding
(
pbc
);
hres
=
start_binding
(
binding_ctx
,
url
,
pbc
,
riid
,
&
binding
);
hres
=
start_binding
(
NULL
,
binding_ctx
,
url
,
pbc
,
FALSE
,
riid
,
&
binding
);
if
(
binding_ctx
)
IBinding_Release
(
BINDING
(
binding_ctx
));
if
(
FAILED
(
hres
))
...
...
@@ -1346,3 +1502,29 @@ HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
return
hres
;
}
HRESULT
bind_to_object
(
IMoniker
*
mon
,
LPCWSTR
url
,
IBindCtx
*
pbc
,
REFIID
riid
,
void
**
ppv
)
{
Binding
*
binding
;
HRESULT
hres
;
*
ppv
=
NULL
;
hres
=
start_binding
(
mon
,
NULL
,
url
,
pbc
,
TRUE
,
riid
,
&
binding
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
binding
->
hres
!=
S_OK
)
{
hres
=
SUCCEEDED
(
binding
->
hres
)
?
S_OK
:
binding
->
hres
;
}
else
if
(
binding
->
bindf
&
BINDF_ASYNCHRONOUS
)
{
hres
=
MK_S_ASYNCHRONOUS
;
}
else
{
*
ppv
=
binding
->
obj
;
IUnknown_AddRef
(
binding
->
obj
);
hres
=
S_OK
;
}
IBinding_Release
(
BINDING
(
binding
));
return
hres
;
}
dlls/urlmon/tests/url.c
View file @
85f472b3
...
...
@@ -1698,7 +1698,7 @@ static void test_BindToObject(int protocol, BOOL emul)
trace
(
"Network unreachable, skipping tests
\n
"
);
return
;
}
todo_wine
ok
(
SUCCEEDED
(
hres
),
"IMoniker_BindToObject failed with error 0x%08x
\n
"
,
hres
);
ok
(
SUCCEEDED
(
hres
),
"IMoniker_BindToObject failed with error 0x%08x
\n
"
,
hres
);
/* no point testing the calls if binding didn't even work */
if
(
!
SUCCEEDED
(
hres
))
return
;
...
...
@@ -1750,6 +1750,9 @@ static void test_BindToObject(int protocol, BOOL emul)
CHECK_CALLED
(
OnProgress_BEGINDOWNLOADDATA
);
if
(
test_protocol
==
HTTP_TEST
)
CLEAR_CALLED
(
OnProgress_DOWNLOADINGDATA
);
if
(
test_protocol
==
HTTP_TEST
&&
urls
[
test_protocol
]
!=
SHORT_RESPONSE_URL
)
todo_wine
CHECK_CALLED
(
OnProgress_ENDDOWNLOADDATA
);
else
CHECK_CALLED
(
OnProgress_ENDDOWNLOADDATA
);
CHECK_CALLED
(
OnProgress_CLASSIDAVAILABLE
);
CHECK_CALLED
(
OnProgress_BEGINSYNCOPERATION
);
...
...
@@ -1758,8 +1761,13 @@ static void test_BindToObject(int protocol, BOOL emul)
CHECK_CALLED
(
OnStopBinding
);
}
if
(
test_protocol
!=
HTTP_TEST
||
emul
||
urls
[
test_protocol
]
==
SHORT_RESPONSE_URL
)
{
ok
(
IMoniker_Release
(
mon
)
==
0
,
"mon should be destroyed here
\n
"
);
ok
(
IBindCtx_Release
(
bctx
)
==
0
,
"bctx should be destroyed here
\n
"
);
}
else
todo_wine
{
ok
(
IMoniker_Release
(
mon
)
==
0
,
"mon should be destroyed here
\n
"
);
ok
(
IBindCtx_Release
(
bctx
)
==
0
,
"bctx should be destroyed here
\n
"
);
}
if
(
test_protocol
==
HTTP_TEST
)
http_is_first
=
FALSE
;
...
...
dlls/urlmon/umon.c
View file @
85f472b3
...
...
@@ -473,16 +473,21 @@ static HRESULT WINAPI URLMonikerImpl_BindToObject(IMoniker* iface,
IBindCtx
*
pbc
,
IMoniker
*
pmkToLeft
,
REFIID
riid
,
VOID
**
ppv
Result
)
VOID
**
ppv
)
{
URLMonikerImpl
*
This
=
(
URLMonikerImpl
*
)
iface
;
IRunningObjectTable
*
obj_tbl
;
HRESULT
hres
;
*
ppvResult
=
0
;
TRACE
(
"(%p)->(%p,%p,%s,%p): stub
\n
"
,
This
,
pbc
,
pmkToLeft
,
debugstr_guid
(
riid
),
ppv
)
;
FIXME
(
"(%p)->(%p,%p,%s,%p): stub
\n
"
,
This
,
pbc
,
pmkToLeft
,
debugstr_guid
(
riid
),
ppvResult
);
hres
=
IBindCtx_GetRunningObjectTable
(
pbc
,
&
obj_tbl
);
if
(
SUCCEEDED
(
hres
))
{
FIXME
(
"use running object table
\n
"
);
IRunningObjectTable_Release
(
obj_tbl
);
}
return
E_NOTIMPL
;
return
bind_to_object
(
iface
,
This
->
URLName
,
pbc
,
riid
,
ppv
)
;
}
/******************************************************************************
...
...
dlls/urlmon/urlmon_main.h
View file @
85f472b3
...
...
@@ -69,6 +69,7 @@ IInternetProtocolInfo *get_protocol_info(LPCWSTR url);
HRESULT
get_protocol_handler
(
LPCWSTR
url
,
CLSID
*
clsid
,
IClassFactory
**
ret
);
HRESULT
bind_to_storage
(
LPCWSTR
url
,
IBindCtx
*
pbc
,
REFIID
riid
,
void
**
ppv
);
HRESULT
bind_to_object
(
IMoniker
*
mon
,
LPCWSTR
url
,
IBindCtx
*
pbc
,
REFIID
riid
,
void
**
ppv
);
HRESULT
create_binding_protocol
(
LPCWSTR
url
,
BOOL
from_urlmon
,
IInternetProtocol
**
protocol
);
void
set_binding_sink
(
IInternetProtocol
*
bind_protocol
,
IInternetProtocolSink
*
sink
);
...
...
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