ReactOS  0.4.14-dev-49-gfb4591c
mk.c
Go to the documentation of this file.
1 /*
2  * Copyright 2007 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #include "urlmon_main.h"
20 #include "wine/debug.h"
21 
22 #define NO_SHLWAPI_REG
23 #include "shlwapi.h"
24 
26 
27 typedef struct {
30 
33 
35 } MkProtocol;
36 
37 static inline MkProtocol *impl_from_IUnknown(IUnknown *iface)
38 {
39  return CONTAINING_RECORD(iface, MkProtocol, IUnknown_outer);
40 }
41 
43 {
44  return CONTAINING_RECORD(iface, MkProtocol, IInternetProtocolEx_iface);
45 }
46 
48 {
50 
52  TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
53  *ppv = &This->IUnknown_outer;
54  }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
55  TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
56  *ppv = &This->IInternetProtocolEx_iface;
57  }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
58  TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
59  *ppv = &This->IInternetProtocolEx_iface;
60  }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
61  TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
62  *ppv = &This->IInternetProtocolEx_iface;
63  }else {
64  *ppv = NULL;
65  WARN("not supported interface %s\n", debugstr_guid(riid));
66  return E_NOINTERFACE;
67  }
68 
69  IUnknown_AddRef((IUnknown*)*ppv);
70  return S_OK;
71 }
72 
74 {
77  TRACE("(%p) ref=%d\n", This, ref);
78  return ref;
79 }
80 
82 {
85 
86  TRACE("(%p) ref=%d\n", This, ref);
87 
88  if(!ref) {
89  if(This->stream)
90  IStream_Release(This->stream);
91 
92  heap_free(This);
93 
95  }
96 
97  return ref;
98 }
99 
100 static const IUnknownVtbl MkProtocolUnkVtbl = {
104 };
105 
107 {
109  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
110  return IUnknown_QueryInterface(This->outer, riid, ppv);
111 }
112 
114 {
116  TRACE("(%p)\n", This);
117  return IUnknown_AddRef(This->outer);
118 }
119 
121 {
123  TRACE("(%p)\n", This);
124  return IUnknown_Release(This->outer);
125 }
126 
128 {
129  IInternetProtocolSink_ReportResult(sink, hres, dwError, NULL);
130  return hres;
131 }
132 
134  IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
135  DWORD grfPI, HANDLE_PTR dwReserved)
136 {
138  HRESULT hres;
139  IUri *uri;
140 
141  TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
142  pOIBindInfo, grfPI, dwReserved);
143 
144  hres = CreateUri(szUrl, 0, 0, &uri);
145  if(FAILED(hres))
146  return hres;
147 
148  hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
149  pOIBindInfo, grfPI, (HANDLE*)dwReserved);
150 
151  IUri_Release(uri);
152  return hres;
153 }
154 
155 static HRESULT WINAPI MkProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
156 {
158  FIXME("(%p)->(%p)\n", This, pProtocolData);
159  return E_NOTIMPL;
160 }
161 
164 {
166  FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
167  return E_NOTIMPL;
168 }
169 
171 {
173 
174  TRACE("(%p)->(%08x)\n", This, dwOptions);
175 
176  return S_OK;
177 }
178 
180 {
182  FIXME("(%p)\n", This);
183  return E_NOTIMPL;
184 }
185 
187 {
189  FIXME("(%p)\n", This);
190  return E_NOTIMPL;
191 }
192 
194  ULONG cb, ULONG *pcbRead)
195 {
197 
198  TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
199 
200  if(!This->stream)
201  return E_FAIL;
202 
203  return IStream_Read(This->stream, pv, cb, pcbRead);
204 }
205 
207  DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
208 {
210  FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
211  return E_NOTIMPL;
212 }
213 
215 {
217 
218  TRACE("(%p)->(%08x)\n", This, dwOptions);
219 
220  return S_OK;
221 }
222 
224 {
226 
227  TRACE("(%p)\n", This);
228 
229  return S_OK;
230 }
231 
233  IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
234  DWORD grfPI, HANDLE *dwReserved)
235 {
237  LPWSTR mime, progid, display_name, colon_ptr;
238  DWORD bindf=0, eaten=0, scheme=0, len;
239  BSTR url, path = NULL;
240  IParseDisplayName *pdn;
241  BINDINFO bindinfo;
242  STATSTG statstg;
243  IMoniker *mon;
244  HRESULT hres;
245  CLSID clsid;
246 
247  TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
248  pOIBindInfo, grfPI, dwReserved);
249 
250  hres = IUri_GetScheme(pUri, &scheme);
251  if(FAILED(hres))
252  return hres;
253  if(scheme != URL_SCHEME_MK)
254  return INET_E_INVALID_URL;
255 
256  memset(&bindinfo, 0, sizeof(bindinfo));
257  bindinfo.cbSize = sizeof(BINDINFO);
258  hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
259  if(FAILED(hres)) {
260  WARN("GetBindInfo failed: %08x\n", hres);
261  return hres;
262  }
263 
264  ReleaseBindInfo(&bindinfo);
265 
266  IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL);
267 
268  hres = IUri_GetDisplayUri(pUri, &url);
269  if(FAILED(hres))
270  return hres;
271  hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
273  if(SUCCEEDED(hres)) {
274  IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
276  }
277 
278  hres = IUri_GetPath(pUri, &path);
279  if(FAILED(hres))
280  return hres;
281  len = SysStringLen(path)+1;
283  if (FAILED(hres)) {
285  return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
286  }
287 
288  progid = path+1; /* skip '@' symbol */
289  colon_ptr = strchrW(path, ':');
290  if(!colon_ptr) {
292  return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
293  }
294 
295  len = strlenW(path);
296  display_name = heap_alloc((len+1)*sizeof(WCHAR));
297  memcpy(display_name, path, (len+1)*sizeof(WCHAR));
298 
299  progid[colon_ptr-progid] = 0; /* overwrite ':' with NULL terminator */
302  if(FAILED(hres))
303  {
304  heap_free(display_name);
305  return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
306  }
307 
308  hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
309  &IID_IParseDisplayName, (void**)&pdn);
310  if(FAILED(hres)) {
311  WARN("Could not create object %s\n", debugstr_guid(&clsid));
312  heap_free(display_name);
313  return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
314  }
315 
316  hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon);
317  heap_free(display_name);
318  IParseDisplayName_Release(pdn);
319  if(FAILED(hres)) {
320  WARN("ParseDisplayName failed: %08x\n", hres);
321  return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
322  }
323 
324  if(This->stream) {
325  IStream_Release(This->stream);
326  This->stream = NULL;
327  }
328 
329  hres = IMoniker_BindToStorage(mon, NULL /* FIXME */, NULL, &IID_IStream, (void**)&This->stream);
330  IMoniker_Release(mon);
331  if(FAILED(hres)) {
332  WARN("BindToStorage failed: %08x\n", hres);
333  return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
334  }
335 
336  hres = IStream_Stat(This->stream, &statstg, STATFLAG_NONAME);
337  if(FAILED(hres)) {
338  WARN("Stat failed: %08x\n", hres);
339  return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
340  }
341 
342  IInternetProtocolSink_ReportData(pOIProtSink,
343  BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION,
344  statstg.cbSize.u.LowPart, statstg.cbSize.u.LowPart);
345  return report_result(pOIProtSink, S_OK, ERROR_SUCCESS);
346 }
347 
348 static const IInternetProtocolExVtbl MkProtocolVtbl = {
363 };
364 
366 {
367  MkProtocol *ret;
368 
369  TRACE("(%p %p)\n", outer, ppv);
370 
372 
373  ret = heap_alloc(sizeof(MkProtocol));
374 
375  ret->IUnknown_outer.lpVtbl = &MkProtocolUnkVtbl;
376  ret->IInternetProtocolEx_iface.lpVtbl = &MkProtocolVtbl;
377  ret->ref = 1;
378  ret->outer = outer ? outer : &ret->IUnknown_outer;
379  ret->stream = NULL;
380 
381  /* NOTE:
382  * Native returns NULL ppobj and S_OK in CreateInstance if called with IID_IUnknown riid and no outer.
383  */
384  *ppv = &ret->IUnknown_outer;
385  return S_OK;
386 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
DWORD dwOptions
Definition: solitaire.cpp:23
static ULONG WINAPI MkProtocolUnk_AddRef(IUnknown *iface)
Definition: mk.c:73
#define REFIID
Definition: guiddef.h:118
static HRESULT WINAPI MkProtocol_Suspend(IInternetProtocolEx *iface)
Definition: mk.c:179
static const IUnknownVtbl MkProtocolUnkVtbl
Definition: mk.c:100
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT WINAPI MkProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
Definition: mk.c:214
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define ERROR_SUCCESS
Definition: deptool.c:10
IStream * stream
Definition: mk.c:34
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
const WCHAR * mime
Definition: mimefilter.c:512
const char * uri
Definition: sec_mgr.c:1594
REFIID riid
Definition: precomp.h:44
static ULONG WINAPI MkProtocol_Release(IInternetProtocolEx *iface)
Definition: mk.c:120
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
#define URL_UNESCAPE_INPLACE
Definition: shlwapi.h:1224
void WINAPI ReleaseBindInfo(BINDINFO *pbindinfo)
Definition: urlmon_main.c:572
static MkProtocol * impl_from_IUnknown(IUnknown *iface)
Definition: mk.c:37
#define WARN(fmt,...)
Definition: debug.h:111
REFIID LPVOID * ppv
Definition: atlbase.h:39
static HRESULT WINAPI MkProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: mk.c:206
DWORD scheme
static HRESULT WINAPI MkProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE *dwReserved)
Definition: mk.c:232
OLECHAR * BSTR
Definition: compat.h:1934
IUnknown IUnknown_outer
Definition: mk.c:28
#define E_FAIL
Definition: ddrawi.h:102
HRESULT WINAPI DECLSPEC_HOTPATCH CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid)
Definition: compobj.c:2511
Definition: send.c:47
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
HRESULT WINAPI UrlUnescapeW(LPWSTR pszUrl, LPWSTR pszUnescaped, LPDWORD pcchUnescaped, DWORD dwFlags)
Definition: url.c:1367
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
long LONG
Definition: pedump.c:60
struct _LARGE_INTEGER::@2201 u
static HRESULT WINAPI MkProtocol_Resume(IInternetProtocolEx *iface)
Definition: mk.c:186
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static HRESULT WINAPI MkProtocol_Read(IInternetProtocolEx *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: mk.c:193
static ULONG WINAPI MkProtocolUnk_Release(IUnknown *iface)
Definition: mk.c:81
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI MkProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
Definition: mk.c:170
const GUID IID_IParseDisplayName
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Definition: mk.c:27
static void URLMON_UnlockModule(void)
Definition: urlmon_main.h:68
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
static ULONG WINAPI MkProtocol_AddRef(IInternetProtocolEx *iface)
Definition: mk.c:113
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static const WCHAR url[]
Definition: encode.c:1432
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
static DWORD cb
Definition: integrity.c:41
int ret
REFCLSID clsid
Definition: msctf.c:84
#define InterlockedDecrement
Definition: armddk.h:52
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HRESULT MkProtocol_Construct(IUnknown *outer, void **ppv)
Definition: mk.c:365
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:199
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
LONG ref
Definition: mk.c:31
IInternetProtocolEx IInternetProtocolEx_iface
Definition: mk.c:29
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
static HRESULT WINAPI MkProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
Definition: mk.c:155
unsigned long HANDLE_PTR
Definition: basetsd.h:78
#define E_NOTIMPL
Definition: ddrawi.h:99
Definition: services.c:325
static const IInternetProtocolExVtbl MkProtocolVtbl
Definition: mk.c:348
static HRESULT WINAPI MkProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: mk.c:47
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
WINE_DEFAULT_DEBUG_CHANNEL(urlmon)
IUnknown * outer
Definition: mk.c:32
static MkProtocol * impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
Definition: mk.c:42
HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IUri **ppURI)
Definition: uri.c:5701
unsigned int ULONG
Definition: retypes.h:1
#define progid(str)
Definition: exdisp.idl:31
static HRESULT WINAPI MkProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved)
Definition: mk.c:133
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static void URLMON_LockModule(void)
Definition: urlmon_main.h:67
static HRESULT WINAPI MkProtocol_UnlockRequest(IInternetProtocolEx *iface)
Definition: mk.c:223
#define memset(x, y, z)
Definition: compat.h:39
HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer, DWORD cbSize, LPCWSTR pwzMimeProposed, DWORD dwMimeFlags, LPWSTR *ppwzMimeOut, DWORD dwReserved)
Definition: mimefilter.c:680
static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
Definition: mk.c:106
static HRESULT WINAPI MkProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason, DWORD dwOptions)
Definition: mk.c:162
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres, DWORD dwError)
Definition: mk.c:127
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static DWORD bindf
Definition: protocol.c:70