2 * Copyright 2007 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "urlmon_main.h"
20 #include "wine/debug.h"
22 #define NO_SHLWAPI_REG
25 WINE_DEFAULT_DEBUG_CHANNEL(urlmon
);
28 IInternetProtocolEx IInternetProtocolEx_iface
;
35 static inline MkProtocol
*impl_from_IInternetProtocolEx(IInternetProtocolEx
*iface
)
37 return CONTAINING_RECORD(iface
, MkProtocol
, IInternetProtocolEx_iface
);
40 static HRESULT WINAPI
MkProtocol_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
42 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
45 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
46 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
47 *ppv
= &This
->IInternetProtocolEx_iface
;
48 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
49 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
50 *ppv
= &This
->IInternetProtocolEx_iface
;
51 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
52 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
53 *ppv
= &This
->IInternetProtocolEx_iface
;
54 }else if(IsEqualGUID(&IID_IInternetProtocolEx
, riid
)) {
55 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This
, ppv
);
56 *ppv
= &This
->IInternetProtocolEx_iface
;
60 IInternetProtocol_AddRef(iface
);
64 WARN("not supported interface %s\n", debugstr_guid(riid
));
68 static ULONG WINAPI
MkProtocol_AddRef(IInternetProtocolEx
*iface
)
70 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
71 LONG ref
= InterlockedIncrement(&This
->ref
);
72 TRACE("(%p) ref=%d\n", This
, ref
);
76 static ULONG WINAPI
MkProtocol_Release(IInternetProtocolEx
*iface
)
78 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
79 LONG ref
= InterlockedDecrement(&This
->ref
);
81 TRACE("(%p) ref=%d\n", This
, ref
);
85 IStream_Release(This
->stream
);
89 URLMON_UnlockModule();
95 static HRESULT
report_result(IInternetProtocolSink
*sink
, HRESULT hres
, DWORD dwError
)
97 IInternetProtocolSink_ReportResult(sink
, hres
, dwError
, NULL
);
101 static HRESULT WINAPI
MkProtocol_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
102 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
103 DWORD grfPI
, HANDLE_PTR dwReserved
)
105 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
109 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
110 pOIBindInfo
, grfPI
, dwReserved
);
112 hres
= CreateUri(szUrl
, 0, 0, &uri
);
116 hres
= IInternetProtocolEx_StartEx(&This
->IInternetProtocolEx_iface
, uri
, pOIProtSink
,
117 pOIBindInfo
, grfPI
, (HANDLE
*)dwReserved
);
123 static HRESULT WINAPI
MkProtocol_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
125 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
126 FIXME("(%p)->(%p)\n", This
, pProtocolData
);
130 static HRESULT WINAPI
MkProtocol_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
133 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
134 FIXME("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
138 static HRESULT WINAPI
MkProtocol_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
140 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
142 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
147 static HRESULT WINAPI
MkProtocol_Suspend(IInternetProtocolEx
*iface
)
149 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
150 FIXME("(%p)\n", This
);
154 static HRESULT WINAPI
MkProtocol_Resume(IInternetProtocolEx
*iface
)
156 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
157 FIXME("(%p)\n", This
);
161 static HRESULT WINAPI
MkProtocol_Read(IInternetProtocolEx
*iface
, void *pv
,
162 ULONG cb
, ULONG
*pcbRead
)
164 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
166 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
171 return IStream_Read(This
->stream
, pv
, cb
, pcbRead
);
174 static HRESULT WINAPI
MkProtocol_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
175 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
177 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
178 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
182 static HRESULT WINAPI
MkProtocol_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
184 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
186 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
191 static HRESULT WINAPI
MkProtocol_UnlockRequest(IInternetProtocolEx
*iface
)
193 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
195 TRACE("(%p)\n", This
);
200 static HRESULT WINAPI
MkProtocol_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
201 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
202 DWORD grfPI
, HANDLE
*dwReserved
)
204 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
205 LPWSTR mime
, progid
, display_name
, colon_ptr
;
206 DWORD path_size
= INTERNET_MAX_URL_LENGTH
;
207 DWORD bindf
=0, eaten
=0, scheme
=0, len
;
208 BSTR url
, path_tmp
, path
= NULL
;
209 IParseDisplayName
*pdn
;
216 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
,
217 pOIBindInfo
, grfPI
, dwReserved
);
219 hres
= IUri_GetScheme(pUri
, &scheme
);
222 if(scheme
!= URL_SCHEME_MK
)
223 return INET_E_INVALID_URL
;
225 memset(&bindinfo
, 0, sizeof(bindinfo
));
226 bindinfo
.cbSize
= sizeof(BINDINFO
);
227 hres
= IInternetBindInfo_GetBindInfo(pOIBindInfo
, &bindf
, &bindinfo
);
229 WARN("GetBindInfo failed: %08x\n", hres
);
233 ReleaseBindInfo(&bindinfo
);
235 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_SENDINGREQUEST
, NULL
);
237 hres
= IUri_GetDisplayUri(pUri
, &url
);
240 hres
= FindMimeFromData(NULL
, url
, NULL
, 0, NULL
, 0, &mime
, 0);
242 if(SUCCEEDED(hres
)) {
243 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
247 hres
= IUri_GetPath(pUri
, &path_tmp
);
250 path
= heap_alloc(path_size
);
251 hres
= UrlUnescapeW((LPWSTR
)path_tmp
, path
, &path_size
, 0);
252 SysFreeString(path_tmp
);
256 return report_result(pOIProtSink
, INET_E_RESOURCE_NOT_FOUND
, ERROR_INVALID_PARAMETER
);
258 progid
= path
+1; /* skip '@' symbol */
259 colon_ptr
= strchrW(path
, ':');
263 return report_result(pOIProtSink
, INET_E_RESOURCE_NOT_FOUND
, ERROR_INVALID_PARAMETER
);
267 display_name
= heap_alloc((len
+1)*sizeof(WCHAR
));
268 memcpy(display_name
, path
, (len
+1)*sizeof(WCHAR
));
270 progid
[colon_ptr
-progid
] = 0; /* overwrite ':' with NULL terminator */
271 hres
= CLSIDFromProgID(progid
, &clsid
);
275 heap_free(display_name
);
276 return report_result(pOIProtSink
, INET_E_RESOURCE_NOT_FOUND
, ERROR_INVALID_PARAMETER
);
279 hres
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
280 &IID_IParseDisplayName
, (void**)&pdn
);
282 WARN("Could not create object %s\n", debugstr_guid(&clsid
));
283 heap_free(display_name
);
284 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
287 hres
= IParseDisplayName_ParseDisplayName(pdn
, NULL
/* FIXME */, display_name
, &eaten
, &mon
);
288 heap_free(display_name
);
289 IParseDisplayName_Release(pdn
);
291 WARN("ParseDisplayName failed: %08x\n", hres
);
292 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
296 IStream_Release(This
->stream
);
300 hres
= IMoniker_BindToStorage(mon
, NULL
/* FIXME */, NULL
, &IID_IStream
, (void**)&This
->stream
);
301 IMoniker_Release(mon
);
303 WARN("BindToStorage failed: %08x\n", hres
);
304 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
307 hres
= IStream_Stat(This
->stream
, &statstg
, STATFLAG_NONAME
);
309 WARN("Stat failed: %08x\n", hres
);
310 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
313 IInternetProtocolSink_ReportData(pOIProtSink
,
314 BSCF_FIRSTDATANOTIFICATION
| BSCF_LASTDATANOTIFICATION
,
315 statstg
.cbSize
.u
.LowPart
, statstg
.cbSize
.u
.LowPart
);
316 return report_result(pOIProtSink
, S_OK
, ERROR_SUCCESS
);
319 static const IInternetProtocolExVtbl MkProtocolVtbl
= {
320 MkProtocol_QueryInterface
,
326 MkProtocol_Terminate
,
331 MkProtocol_LockRequest
,
332 MkProtocol_UnlockRequest
,
336 HRESULT
MkProtocol_Construct(IUnknown
*pUnkOuter
, LPVOID
*ppobj
)
340 TRACE("(%p %p)\n", pUnkOuter
, ppobj
);
344 ret
= heap_alloc(sizeof(MkProtocol
));
346 ret
->IInternetProtocolEx_iface
.lpVtbl
= &MkProtocolVtbl
;
351 * Native returns NULL ppobj and S_OK in CreateInstance if called with IID_IUnknown riid.
353 *ppobj
= &ret
->IInternetProtocolEx_iface
;