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"
22 IInternetProtocolEx IInternetProtocolEx_iface
;
29 static inline MkProtocol
*impl_from_IInternetProtocolEx(IInternetProtocolEx
*iface
)
31 return CONTAINING_RECORD(iface
, MkProtocol
, IInternetProtocolEx_iface
);
34 static HRESULT WINAPI
MkProtocol_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
36 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
39 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
40 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
41 *ppv
= &This
->IInternetProtocolEx_iface
;
42 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
43 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
44 *ppv
= &This
->IInternetProtocolEx_iface
;
45 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
46 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
47 *ppv
= &This
->IInternetProtocolEx_iface
;
48 }else if(IsEqualGUID(&IID_IInternetProtocolEx
, riid
)) {
49 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This
, ppv
);
50 *ppv
= &This
->IInternetProtocolEx_iface
;
54 IInternetProtocolEx_AddRef(iface
);
58 WARN("not supported interface %s\n", debugstr_guid(riid
));
62 static ULONG WINAPI
MkProtocol_AddRef(IInternetProtocolEx
*iface
)
64 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
65 LONG ref
= InterlockedIncrement(&This
->ref
);
66 TRACE("(%p) ref=%d\n", This
, ref
);
70 static ULONG WINAPI
MkProtocol_Release(IInternetProtocolEx
*iface
)
72 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
73 LONG ref
= InterlockedDecrement(&This
->ref
);
75 TRACE("(%p) ref=%d\n", This
, ref
);
79 IStream_Release(This
->stream
);
83 URLMON_UnlockModule();
89 static HRESULT
report_result(IInternetProtocolSink
*sink
, HRESULT hres
, DWORD dwError
)
91 IInternetProtocolSink_ReportResult(sink
, hres
, dwError
, NULL
);
95 static HRESULT WINAPI
MkProtocol_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
96 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
97 DWORD grfPI
, HANDLE_PTR dwReserved
)
99 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
103 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
104 pOIBindInfo
, grfPI
, dwReserved
);
106 hres
= CreateUri(szUrl
, 0, 0, &uri
);
110 hres
= IInternetProtocolEx_StartEx(&This
->IInternetProtocolEx_iface
, uri
, pOIProtSink
,
111 pOIBindInfo
, grfPI
, (HANDLE
*)dwReserved
);
117 static HRESULT WINAPI
MkProtocol_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
119 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
120 FIXME("(%p)->(%p)\n", This
, pProtocolData
);
124 static HRESULT WINAPI
MkProtocol_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
127 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
128 FIXME("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
132 static HRESULT WINAPI
MkProtocol_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
134 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
136 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
141 static HRESULT WINAPI
MkProtocol_Suspend(IInternetProtocolEx
*iface
)
143 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
144 FIXME("(%p)\n", This
);
148 static HRESULT WINAPI
MkProtocol_Resume(IInternetProtocolEx
*iface
)
150 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
151 FIXME("(%p)\n", This
);
155 static HRESULT WINAPI
MkProtocol_Read(IInternetProtocolEx
*iface
, void *pv
,
156 ULONG cb
, ULONG
*pcbRead
)
158 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
160 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
165 return IStream_Read(This
->stream
, pv
, cb
, pcbRead
);
168 static HRESULT WINAPI
MkProtocol_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
169 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
171 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
172 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
176 static HRESULT WINAPI
MkProtocol_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
178 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
180 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
185 static HRESULT WINAPI
MkProtocol_UnlockRequest(IInternetProtocolEx
*iface
)
187 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
189 TRACE("(%p)\n", This
);
194 static HRESULT WINAPI
MkProtocol_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
195 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
196 DWORD grfPI
, HANDLE
*dwReserved
)
198 MkProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
199 LPWSTR mime
, progid
, display_name
, colon_ptr
;
200 DWORD path_size
= INTERNET_MAX_URL_LENGTH
;
201 DWORD bindf
=0, eaten
=0, scheme
=0, len
;
202 BSTR url
, path_tmp
, path
= NULL
;
203 IParseDisplayName
*pdn
;
210 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
,
211 pOIBindInfo
, grfPI
, dwReserved
);
213 hres
= IUri_GetScheme(pUri
, &scheme
);
216 if(scheme
!= URL_SCHEME_MK
)
217 return INET_E_INVALID_URL
;
219 memset(&bindinfo
, 0, sizeof(bindinfo
));
220 bindinfo
.cbSize
= sizeof(BINDINFO
);
221 hres
= IInternetBindInfo_GetBindInfo(pOIBindInfo
, &bindf
, &bindinfo
);
223 WARN("GetBindInfo failed: %08x\n", hres
);
227 ReleaseBindInfo(&bindinfo
);
229 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_SENDINGREQUEST
, NULL
);
231 hres
= IUri_GetDisplayUri(pUri
, &url
);
234 hres
= FindMimeFromData(NULL
, url
, NULL
, 0, NULL
, 0, &mime
, 0);
236 if(SUCCEEDED(hres
)) {
237 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
241 hres
= IUri_GetPath(pUri
, &path_tmp
);
244 path
= heap_alloc(path_size
);
245 hres
= UrlUnescapeW((LPWSTR
)path_tmp
, path
, &path_size
, 0);
246 SysFreeString(path_tmp
);
250 return report_result(pOIProtSink
, INET_E_RESOURCE_NOT_FOUND
, ERROR_INVALID_PARAMETER
);
252 progid
= path
+1; /* skip '@' symbol */
253 colon_ptr
= strchrW(path
, ':');
257 return report_result(pOIProtSink
, INET_E_RESOURCE_NOT_FOUND
, ERROR_INVALID_PARAMETER
);
261 display_name
= heap_alloc((len
+1)*sizeof(WCHAR
));
262 memcpy(display_name
, path
, (len
+1)*sizeof(WCHAR
));
264 progid
[colon_ptr
-progid
] = 0; /* overwrite ':' with NULL terminator */
265 hres
= CLSIDFromProgID(progid
, &clsid
);
269 heap_free(display_name
);
270 return report_result(pOIProtSink
, INET_E_RESOURCE_NOT_FOUND
, ERROR_INVALID_PARAMETER
);
273 hres
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
274 &IID_IParseDisplayName
, (void**)&pdn
);
276 WARN("Could not create object %s\n", debugstr_guid(&clsid
));
277 heap_free(display_name
);
278 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
281 hres
= IParseDisplayName_ParseDisplayName(pdn
, NULL
/* FIXME */, display_name
, &eaten
, &mon
);
282 heap_free(display_name
);
283 IParseDisplayName_Release(pdn
);
285 WARN("ParseDisplayName failed: %08x\n", hres
);
286 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
290 IStream_Release(This
->stream
);
294 hres
= IMoniker_BindToStorage(mon
, NULL
/* FIXME */, NULL
, &IID_IStream
, (void**)&This
->stream
);
295 IMoniker_Release(mon
);
297 WARN("BindToStorage failed: %08x\n", hres
);
298 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
301 hres
= IStream_Stat(This
->stream
, &statstg
, STATFLAG_NONAME
);
303 WARN("Stat failed: %08x\n", hres
);
304 return report_result(pOIProtSink
, hres
, ERROR_INVALID_PARAMETER
);
307 IInternetProtocolSink_ReportData(pOIProtSink
,
308 BSCF_FIRSTDATANOTIFICATION
| BSCF_LASTDATANOTIFICATION
,
309 statstg
.cbSize
.u
.LowPart
, statstg
.cbSize
.u
.LowPart
);
310 return report_result(pOIProtSink
, S_OK
, ERROR_SUCCESS
);
313 static const IInternetProtocolExVtbl MkProtocolVtbl
= {
314 MkProtocol_QueryInterface
,
320 MkProtocol_Terminate
,
325 MkProtocol_LockRequest
,
326 MkProtocol_UnlockRequest
,
330 HRESULT
MkProtocol_Construct(IUnknown
*pUnkOuter
, LPVOID
*ppobj
)
334 TRACE("(%p %p)\n", pUnkOuter
, ppobj
);
338 ret
= heap_alloc(sizeof(MkProtocol
));
340 ret
->IInternetProtocolEx_iface
.lpVtbl
= &MkProtocolVtbl
;
345 * Native returns NULL ppobj and S_OK in CreateInstance if called with IID_IUnknown riid.
347 *ppobj
= &ret
->IInternetProtocolEx_iface
;