1c2c66affSColin Finck /*
2c2c66affSColin Finck * Copyright 2005 Jacek Caban
3c2c66affSColin Finck *
4c2c66affSColin Finck * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck * License as published by the Free Software Foundation; either
7c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck *
9c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12c2c66affSColin Finck * Lesser General Public License for more details.
13c2c66affSColin Finck *
14c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck */
18c2c66affSColin Finck
19c2c66affSColin Finck #include "urlmon_main.h"
20143d4fdbSAmine Khaldi #include "winreg.h"
21143d4fdbSAmine Khaldi #include "shlwapi.h"
22143d4fdbSAmine Khaldi
23143d4fdbSAmine Khaldi #include "wine/debug.h"
24143d4fdbSAmine Khaldi
25143d4fdbSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
26c2c66affSColin Finck
27c2c66affSColin Finck typedef struct {
28*6c3c2e33SAmine Khaldi IUnknown IUnknown_inner;
29c2c66affSColin Finck IInternetProtocolEx IInternetProtocolEx_iface;
30c2c66affSColin Finck IInternetPriority IInternetPriority_iface;
31c2c66affSColin Finck
32d0eebfbdSAmine Khaldi IUnknown *outer;
33d0eebfbdSAmine Khaldi
34c2c66affSColin Finck HANDLE file;
35c2c66affSColin Finck ULONG size;
36c2c66affSColin Finck LONG priority;
37c2c66affSColin Finck
38c2c66affSColin Finck LONG ref;
39c2c66affSColin Finck } FileProtocol;
40c2c66affSColin Finck
impl_from_IUnknown(IUnknown * iface)41d0eebfbdSAmine Khaldi static inline FileProtocol *impl_from_IUnknown(IUnknown *iface)
42d0eebfbdSAmine Khaldi {
43*6c3c2e33SAmine Khaldi return CONTAINING_RECORD(iface, FileProtocol, IUnknown_inner);
44d0eebfbdSAmine Khaldi }
45d0eebfbdSAmine Khaldi
impl_from_IInternetProtocolEx(IInternetProtocolEx * iface)46c2c66affSColin Finck static inline FileProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
47c2c66affSColin Finck {
48c2c66affSColin Finck return CONTAINING_RECORD(iface, FileProtocol, IInternetProtocolEx_iface);
49c2c66affSColin Finck }
50c2c66affSColin Finck
impl_from_IInternetPriority(IInternetPriority * iface)51c2c66affSColin Finck static inline FileProtocol *impl_from_IInternetPriority(IInternetPriority *iface)
52c2c66affSColin Finck {
53c2c66affSColin Finck return CONTAINING_RECORD(iface, FileProtocol, IInternetPriority_iface);
54c2c66affSColin Finck }
55c2c66affSColin Finck
FileProtocolUnk_QueryInterface(IUnknown * iface,REFIID riid,void ** ppv)56d0eebfbdSAmine Khaldi static HRESULT WINAPI FileProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
57c2c66affSColin Finck {
58d0eebfbdSAmine Khaldi FileProtocol *This = impl_from_IUnknown(iface);
59c2c66affSColin Finck
60c2c66affSColin Finck *ppv = NULL;
61c2c66affSColin Finck if(IsEqualGUID(&IID_IUnknown, riid)) {
62c2c66affSColin Finck TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
63*6c3c2e33SAmine Khaldi *ppv = &This->IUnknown_inner;
64c2c66affSColin Finck }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
65c2c66affSColin Finck TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
66c2c66affSColin Finck *ppv = &This->IInternetProtocolEx_iface;
67c2c66affSColin Finck }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
68c2c66affSColin Finck TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
69c2c66affSColin Finck *ppv = &This->IInternetProtocolEx_iface;
70c2c66affSColin Finck }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
71c2c66affSColin Finck TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
72c2c66affSColin Finck *ppv = &This->IInternetProtocolEx_iface;
73c2c66affSColin Finck }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
74c2c66affSColin Finck TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
75c2c66affSColin Finck *ppv = &This->IInternetPriority_iface;
76c2c66affSColin Finck }
77c2c66affSColin Finck
78c2c66affSColin Finck if(*ppv) {
79d0eebfbdSAmine Khaldi IUnknown_AddRef((IUnknown*)*ppv);
80c2c66affSColin Finck return S_OK;
81c2c66affSColin Finck }
82c2c66affSColin Finck
83c2c66affSColin Finck WARN("not supported interface %s\n", debugstr_guid(riid));
84c2c66affSColin Finck return E_NOINTERFACE;
85c2c66affSColin Finck }
86c2c66affSColin Finck
FileProtocolUnk_AddRef(IUnknown * iface)87d0eebfbdSAmine Khaldi static ULONG WINAPI FileProtocolUnk_AddRef(IUnknown *iface)
88c2c66affSColin Finck {
89d0eebfbdSAmine Khaldi FileProtocol *This = impl_from_IUnknown(iface);
90c2c66affSColin Finck LONG ref = InterlockedIncrement(&This->ref);
91c2c66affSColin Finck TRACE("(%p) ref=%d\n", This, ref);
92c2c66affSColin Finck return ref;
93c2c66affSColin Finck }
94c2c66affSColin Finck
FileProtocolUnk_Release(IUnknown * iface)95d0eebfbdSAmine Khaldi static ULONG WINAPI FileProtocolUnk_Release(IUnknown *iface)
96c2c66affSColin Finck {
97d0eebfbdSAmine Khaldi FileProtocol *This = impl_from_IUnknown(iface);
98c2c66affSColin Finck LONG ref = InterlockedDecrement(&This->ref);
99c2c66affSColin Finck
100c2c66affSColin Finck TRACE("(%p) ref=%d\n", This, ref);
101c2c66affSColin Finck
102c2c66affSColin Finck if(!ref) {
103c2c66affSColin Finck if(This->file != INVALID_HANDLE_VALUE)
104c2c66affSColin Finck CloseHandle(This->file);
105c2c66affSColin Finck heap_free(This);
106c2c66affSColin Finck
107c2c66affSColin Finck URLMON_UnlockModule();
108c2c66affSColin Finck }
109c2c66affSColin Finck
110c2c66affSColin Finck return ref;
111c2c66affSColin Finck }
112c2c66affSColin Finck
113d0eebfbdSAmine Khaldi static const IUnknownVtbl FileProtocolUnkVtbl = {
114d0eebfbdSAmine Khaldi FileProtocolUnk_QueryInterface,
115d0eebfbdSAmine Khaldi FileProtocolUnk_AddRef,
116d0eebfbdSAmine Khaldi FileProtocolUnk_Release
117d0eebfbdSAmine Khaldi };
118d0eebfbdSAmine Khaldi
FileProtocol_QueryInterface(IInternetProtocolEx * iface,REFIID riid,void ** ppv)119d0eebfbdSAmine Khaldi static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
120d0eebfbdSAmine Khaldi {
121d0eebfbdSAmine Khaldi FileProtocol *This = impl_from_IInternetProtocolEx(iface);
122d0eebfbdSAmine Khaldi TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
123d0eebfbdSAmine Khaldi return IUnknown_QueryInterface(This->outer, riid, ppv);
124d0eebfbdSAmine Khaldi }
125d0eebfbdSAmine Khaldi
FileProtocol_AddRef(IInternetProtocolEx * iface)126d0eebfbdSAmine Khaldi static ULONG WINAPI FileProtocol_AddRef(IInternetProtocolEx *iface)
127d0eebfbdSAmine Khaldi {
128d0eebfbdSAmine Khaldi FileProtocol *This = impl_from_IInternetProtocolEx(iface);
129d0eebfbdSAmine Khaldi TRACE("(%p)\n", This);
130d0eebfbdSAmine Khaldi return IUnknown_AddRef(This->outer);
131d0eebfbdSAmine Khaldi }
132d0eebfbdSAmine Khaldi
FileProtocol_Release(IInternetProtocolEx * iface)133d0eebfbdSAmine Khaldi static ULONG WINAPI FileProtocol_Release(IInternetProtocolEx *iface)
134d0eebfbdSAmine Khaldi {
135d0eebfbdSAmine Khaldi FileProtocol *This = impl_from_IInternetProtocolEx(iface);
136d0eebfbdSAmine Khaldi TRACE("(%p)\n", This);
137d0eebfbdSAmine Khaldi return IUnknown_Release(This->outer);
138d0eebfbdSAmine Khaldi }
139d0eebfbdSAmine Khaldi
FileProtocol_Start(IInternetProtocolEx * iface,LPCWSTR szUrl,IInternetProtocolSink * pOIProtSink,IInternetBindInfo * pOIBindInfo,DWORD grfPI,HANDLE_PTR dwReserved)140c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
141c2c66affSColin Finck IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
142c2c66affSColin Finck DWORD grfPI, HANDLE_PTR dwReserved)
143c2c66affSColin Finck {
144c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
145c2c66affSColin Finck IUri *uri;
146c2c66affSColin Finck HRESULT hres;
147c2c66affSColin Finck
148c2c66affSColin Finck TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
149c2c66affSColin Finck pOIBindInfo, grfPI, dwReserved);
150c2c66affSColin Finck
151c2c66affSColin Finck hres = CreateUri(szUrl, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
152c2c66affSColin Finck if(FAILED(hres))
153c2c66affSColin Finck return hres;
154c2c66affSColin Finck
155c2c66affSColin Finck hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
156c2c66affSColin Finck pOIBindInfo, grfPI, (HANDLE*)dwReserved);
157c2c66affSColin Finck
158c2c66affSColin Finck IUri_Release(uri);
159c2c66affSColin Finck return hres;
160c2c66affSColin Finck }
161c2c66affSColin Finck
FileProtocol_Continue(IInternetProtocolEx * iface,PROTOCOLDATA * pProtocolData)162c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
163c2c66affSColin Finck {
164c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
165c2c66affSColin Finck FIXME("(%p)->(%p)\n", This, pProtocolData);
166c2c66affSColin Finck return E_NOTIMPL;
167c2c66affSColin Finck }
168c2c66affSColin Finck
FileProtocol_Abort(IInternetProtocolEx * iface,HRESULT hrReason,DWORD dwOptions)169c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
170c2c66affSColin Finck DWORD dwOptions)
171c2c66affSColin Finck {
172c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
173c2c66affSColin Finck FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
174c2c66affSColin Finck return E_NOTIMPL;
175c2c66affSColin Finck }
176c2c66affSColin Finck
FileProtocol_Terminate(IInternetProtocolEx * iface,DWORD dwOptions)177c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
178c2c66affSColin Finck {
179c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
180c2c66affSColin Finck
181c2c66affSColin Finck TRACE("(%p)->(%08x)\n", This, dwOptions);
182c2c66affSColin Finck
183c2c66affSColin Finck return S_OK;
184c2c66affSColin Finck }
185c2c66affSColin Finck
FileProtocol_Suspend(IInternetProtocolEx * iface)186c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Suspend(IInternetProtocolEx *iface)
187c2c66affSColin Finck {
188c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
189c2c66affSColin Finck FIXME("(%p)\n", This);
190c2c66affSColin Finck return E_NOTIMPL;
191c2c66affSColin Finck }
192c2c66affSColin Finck
FileProtocol_Resume(IInternetProtocolEx * iface)193c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Resume(IInternetProtocolEx *iface)
194c2c66affSColin Finck {
195c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
196c2c66affSColin Finck FIXME("(%p)\n", This);
197c2c66affSColin Finck return E_NOTIMPL;
198c2c66affSColin Finck }
199c2c66affSColin Finck
FileProtocol_Read(IInternetProtocolEx * iface,void * pv,ULONG cb,ULONG * pcbRead)200c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Read(IInternetProtocolEx *iface, void *pv,
201c2c66affSColin Finck ULONG cb, ULONG *pcbRead)
202c2c66affSColin Finck {
203c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
204c2c66affSColin Finck DWORD read = 0;
205c2c66affSColin Finck
206c2c66affSColin Finck TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
207c2c66affSColin Finck
208c2c66affSColin Finck if (pcbRead)
209c2c66affSColin Finck *pcbRead = 0;
210c2c66affSColin Finck
211c2c66affSColin Finck if(This->file == INVALID_HANDLE_VALUE)
212c2c66affSColin Finck return INET_E_DATA_NOT_AVAILABLE;
213c2c66affSColin Finck
214c2c66affSColin Finck if (!ReadFile(This->file, pv, cb, &read, NULL))
215c2c66affSColin Finck return INET_E_DOWNLOAD_FAILURE;
216c2c66affSColin Finck
217c2c66affSColin Finck if(pcbRead)
218c2c66affSColin Finck *pcbRead = read;
219c2c66affSColin Finck
220c2c66affSColin Finck return cb == read ? S_OK : S_FALSE;
221c2c66affSColin Finck }
222c2c66affSColin Finck
FileProtocol_Seek(IInternetProtocolEx * iface,LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER * plibNewPosition)223c2c66affSColin Finck static HRESULT WINAPI FileProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
224c2c66affSColin Finck DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
225c2c66affSColin Finck {
226c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
227c2c66affSColin Finck FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
228c2c66affSColin Finck return E_NOTIMPL;
229c2c66affSColin Finck }
230c2c66affSColin Finck
FileProtocol_LockRequest(IInternetProtocolEx * iface,DWORD dwOptions)231c2c66affSColin Finck static HRESULT WINAPI FileProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
232c2c66affSColin Finck {
233c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
234c2c66affSColin Finck
235c2c66affSColin Finck TRACE("(%p)->(%08x)\n", This, dwOptions);
236c2c66affSColin Finck
237c2c66affSColin Finck return S_OK;
238c2c66affSColin Finck }
239c2c66affSColin Finck
FileProtocol_UnlockRequest(IInternetProtocolEx * iface)240c2c66affSColin Finck static HRESULT WINAPI FileProtocol_UnlockRequest(IInternetProtocolEx *iface)
241c2c66affSColin Finck {
242c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
243c2c66affSColin Finck
244c2c66affSColin Finck TRACE("(%p)\n", This);
245c2c66affSColin Finck
246c2c66affSColin Finck return S_OK;
247c2c66affSColin Finck }
248c2c66affSColin Finck
report_result(IInternetProtocolSink * protocol_sink,HRESULT hres,DWORD res)249c2c66affSColin Finck static inline HRESULT report_result(IInternetProtocolSink *protocol_sink, HRESULT hres, DWORD res)
250c2c66affSColin Finck {
251c2c66affSColin Finck IInternetProtocolSink_ReportResult(protocol_sink, hres, res, NULL);
252c2c66affSColin Finck return hres;
253c2c66affSColin Finck }
254c2c66affSColin Finck
FileProtocol_StartEx(IInternetProtocolEx * iface,IUri * pUri,IInternetProtocolSink * pOIProtSink,IInternetBindInfo * pOIBindInfo,DWORD grfPI,HANDLE * dwReserved)255c2c66affSColin Finck static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
256c2c66affSColin Finck IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
257c2c66affSColin Finck DWORD grfPI, HANDLE *dwReserved)
258c2c66affSColin Finck {
259c2c66affSColin Finck FileProtocol *This = impl_from_IInternetProtocolEx(iface);
260c2c66affSColin Finck WCHAR path[MAX_PATH], *ptr;
261c2c66affSColin Finck LARGE_INTEGER file_size;
262c2c66affSColin Finck HANDLE file_handle;
263c2c66affSColin Finck BINDINFO bindinfo;
264c2c66affSColin Finck DWORD grfBINDF = 0;
265c2c66affSColin Finck DWORD scheme, size;
266c2c66affSColin Finck LPWSTR mime = NULL;
267c2c66affSColin Finck WCHAR null_char = 0;
268c2c66affSColin Finck BSTR ext;
269c2c66affSColin Finck HRESULT hres;
270c2c66affSColin Finck
271c2c66affSColin Finck TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
272c2c66affSColin Finck pOIBindInfo, grfPI, dwReserved);
273c2c66affSColin Finck
274c2c66affSColin Finck if(!pUri)
275c2c66affSColin Finck return E_INVALIDARG;
276c2c66affSColin Finck
277c2c66affSColin Finck scheme = 0;
278c2c66affSColin Finck hres = IUri_GetScheme(pUri, &scheme);
279c2c66affSColin Finck if(FAILED(hres))
280c2c66affSColin Finck return hres;
281c2c66affSColin Finck if(scheme != URL_SCHEME_FILE)
282c2c66affSColin Finck return E_INVALIDARG;
283c2c66affSColin Finck
284c2c66affSColin Finck memset(&bindinfo, 0, sizeof(bindinfo));
285c2c66affSColin Finck bindinfo.cbSize = sizeof(BINDINFO);
286c2c66affSColin Finck hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
287c2c66affSColin Finck if(FAILED(hres)) {
288c2c66affSColin Finck WARN("GetBindInfo failed: %08x\n", hres);
289c2c66affSColin Finck return hres;
290c2c66affSColin Finck }
291c2c66affSColin Finck
292c2c66affSColin Finck ReleaseBindInfo(&bindinfo);
293c2c66affSColin Finck
294c2c66affSColin Finck if(!(grfBINDF & BINDF_FROMURLMON))
295c2c66affSColin Finck IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL);
296c2c66affSColin Finck
297c2c66affSColin Finck if(This->file != INVALID_HANDLE_VALUE) {
298c2c66affSColin Finck IInternetProtocolSink_ReportData(pOIProtSink,
299c2c66affSColin Finck BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
300c2c66affSColin Finck This->size, This->size);
301c2c66affSColin Finck return S_OK;
302c2c66affSColin Finck }
303c2c66affSColin Finck
304c2c66affSColin Finck IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
305c2c66affSColin Finck
306c2c66affSColin Finck size = 0;
307ad73c0a0SAmine Khaldi hres = CoInternetParseIUri(pUri, PARSE_PATH_FROM_URL, 0, path, ARRAY_SIZE(path), &size, 0);
308c2c66affSColin Finck if(FAILED(hres)) {
309c2c66affSColin Finck WARN("CoInternetParseIUri failed: %08x\n", hres);
310c2c66affSColin Finck return report_result(pOIProtSink, hres, 0);
311c2c66affSColin Finck }
312c2c66affSColin Finck
313c2c66affSColin Finck file_handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
314c2c66affSColin Finck OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
315*6c3c2e33SAmine Khaldi if(file_handle == INVALID_HANDLE_VALUE && (ptr = wcsrchr(path, '#'))) {
316c2c66affSColin Finck /* If path contains fragment part, try without it. */
317c2c66affSColin Finck *ptr = 0;
318c2c66affSColin Finck file_handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
319c2c66affSColin Finck OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
320c2c66affSColin Finck }
321c2c66affSColin Finck if(file_handle == INVALID_HANDLE_VALUE)
322c2c66affSColin Finck return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
323c2c66affSColin Finck
324c2c66affSColin Finck if(!GetFileSizeEx(file_handle, &file_size)) {
325c2c66affSColin Finck CloseHandle(file_handle);
326c2c66affSColin Finck return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
327c2c66affSColin Finck }
328c2c66affSColin Finck
329c2c66affSColin Finck This->file = file_handle;
330c2c66affSColin Finck This->size = file_size.u.LowPart;
331c2c66affSColin Finck IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_CACHEFILENAMEAVAILABLE, path);
332c2c66affSColin Finck
333c2c66affSColin Finck hres = IUri_GetExtension(pUri, &ext);
334c2c66affSColin Finck if(SUCCEEDED(hres)) {
335c2c66affSColin Finck if(hres == S_OK && *ext) {
336*6c3c2e33SAmine Khaldi if((ptr = wcschr(ext, '#')))
337c2c66affSColin Finck *ptr = 0;
338c2c66affSColin Finck hres = find_mime_from_ext(ext, &mime);
339c2c66affSColin Finck if(SUCCEEDED(hres)) {
340c2c66affSColin Finck IInternetProtocolSink_ReportProgress(pOIProtSink,
341c2c66affSColin Finck (grfBINDF & BINDF_FROMURLMON) ?
342c2c66affSColin Finck BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE,
343c2c66affSColin Finck mime);
344c2c66affSColin Finck CoTaskMemFree(mime);
345c2c66affSColin Finck }
346c2c66affSColin Finck }
347c2c66affSColin Finck SysFreeString(ext);
348c2c66affSColin Finck }
349c2c66affSColin Finck
350c2c66affSColin Finck IInternetProtocolSink_ReportData(pOIProtSink,
351c2c66affSColin Finck BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
352c2c66affSColin Finck This->size, This->size);
353c2c66affSColin Finck
354c2c66affSColin Finck return report_result(pOIProtSink, S_OK, 0);
355c2c66affSColin Finck }
356c2c66affSColin Finck
357c2c66affSColin Finck static const IInternetProtocolExVtbl FileProtocolExVtbl = {
358c2c66affSColin Finck FileProtocol_QueryInterface,
359c2c66affSColin Finck FileProtocol_AddRef,
360c2c66affSColin Finck FileProtocol_Release,
361c2c66affSColin Finck FileProtocol_Start,
362c2c66affSColin Finck FileProtocol_Continue,
363c2c66affSColin Finck FileProtocol_Abort,
364c2c66affSColin Finck FileProtocol_Terminate,
365c2c66affSColin Finck FileProtocol_Suspend,
366c2c66affSColin Finck FileProtocol_Resume,
367c2c66affSColin Finck FileProtocol_Read,
368c2c66affSColin Finck FileProtocol_Seek,
369c2c66affSColin Finck FileProtocol_LockRequest,
370c2c66affSColin Finck FileProtocol_UnlockRequest,
371c2c66affSColin Finck FileProtocol_StartEx
372c2c66affSColin Finck };
373c2c66affSColin Finck
FilePriority_QueryInterface(IInternetPriority * iface,REFIID riid,void ** ppv)374c2c66affSColin Finck static HRESULT WINAPI FilePriority_QueryInterface(IInternetPriority *iface,
375c2c66affSColin Finck REFIID riid, void **ppv)
376c2c66affSColin Finck {
377c2c66affSColin Finck FileProtocol *This = impl_from_IInternetPriority(iface);
378c2c66affSColin Finck return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
379c2c66affSColin Finck }
380c2c66affSColin Finck
FilePriority_AddRef(IInternetPriority * iface)381c2c66affSColin Finck static ULONG WINAPI FilePriority_AddRef(IInternetPriority *iface)
382c2c66affSColin Finck {
383c2c66affSColin Finck FileProtocol *This = impl_from_IInternetPriority(iface);
384c2c66affSColin Finck return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
385c2c66affSColin Finck }
386c2c66affSColin Finck
FilePriority_Release(IInternetPriority * iface)387c2c66affSColin Finck static ULONG WINAPI FilePriority_Release(IInternetPriority *iface)
388c2c66affSColin Finck {
389c2c66affSColin Finck FileProtocol *This = impl_from_IInternetPriority(iface);
390c2c66affSColin Finck return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
391c2c66affSColin Finck }
392c2c66affSColin Finck
FilePriority_SetPriority(IInternetPriority * iface,LONG nPriority)393c2c66affSColin Finck static HRESULT WINAPI FilePriority_SetPriority(IInternetPriority *iface, LONG nPriority)
394c2c66affSColin Finck {
395c2c66affSColin Finck FileProtocol *This = impl_from_IInternetPriority(iface);
396c2c66affSColin Finck
397c2c66affSColin Finck TRACE("(%p)->(%d)\n", This, nPriority);
398c2c66affSColin Finck
399c2c66affSColin Finck This->priority = nPriority;
400c2c66affSColin Finck return S_OK;
401c2c66affSColin Finck }
402c2c66affSColin Finck
FilePriority_GetPriority(IInternetPriority * iface,LONG * pnPriority)403c2c66affSColin Finck static HRESULT WINAPI FilePriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
404c2c66affSColin Finck {
405c2c66affSColin Finck FileProtocol *This = impl_from_IInternetPriority(iface);
406c2c66affSColin Finck
407c2c66affSColin Finck TRACE("(%p)->(%p)\n", This, pnPriority);
408c2c66affSColin Finck
409c2c66affSColin Finck *pnPriority = This->priority;
410c2c66affSColin Finck return S_OK;
411c2c66affSColin Finck }
412c2c66affSColin Finck
413c2c66affSColin Finck static const IInternetPriorityVtbl FilePriorityVtbl = {
414c2c66affSColin Finck FilePriority_QueryInterface,
415c2c66affSColin Finck FilePriority_AddRef,
416c2c66affSColin Finck FilePriority_Release,
417c2c66affSColin Finck FilePriority_SetPriority,
418c2c66affSColin Finck FilePriority_GetPriority
419c2c66affSColin Finck };
420c2c66affSColin Finck
FileProtocol_Construct(IUnknown * outer,LPVOID * ppobj)421d0eebfbdSAmine Khaldi HRESULT FileProtocol_Construct(IUnknown *outer, LPVOID *ppobj)
422c2c66affSColin Finck {
423c2c66affSColin Finck FileProtocol *ret;
424c2c66affSColin Finck
425d0eebfbdSAmine Khaldi TRACE("(%p %p)\n", outer, ppobj);
426c2c66affSColin Finck
427c2c66affSColin Finck URLMON_LockModule();
428c2c66affSColin Finck
429c2c66affSColin Finck ret = heap_alloc(sizeof(FileProtocol));
430c2c66affSColin Finck
431*6c3c2e33SAmine Khaldi ret->IUnknown_inner.lpVtbl = &FileProtocolUnkVtbl;
432c2c66affSColin Finck ret->IInternetProtocolEx_iface.lpVtbl = &FileProtocolExVtbl;
433c2c66affSColin Finck ret->IInternetPriority_iface.lpVtbl = &FilePriorityVtbl;
434c2c66affSColin Finck ret->file = INVALID_HANDLE_VALUE;
435c2c66affSColin Finck ret->priority = 0;
436c2c66affSColin Finck ret->ref = 1;
437*6c3c2e33SAmine Khaldi ret->outer = outer ? outer : &ret->IUnknown_inner;
438c2c66affSColin Finck
439*6c3c2e33SAmine Khaldi *ppobj = &ret->IUnknown_inner;
440c2c66affSColin Finck return S_OK;
441c2c66affSColin Finck }
442