ReactOS 0.4.15-dev-8219-ge8b88cf
file.c
Go to the documentation of this file.
1/*
2 * Copyright 2005 Jacek Caban
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 "winreg.h"
21#include "shlwapi.h"
22
23#include "wine/debug.h"
24
26
27typedef struct {
31
33
37
40
42{
43 return CONTAINING_RECORD(iface, FileProtocol, IUnknown_inner);
44}
45
47{
48 return CONTAINING_RECORD(iface, FileProtocol, IInternetProtocolEx_iface);
49}
50
52{
53 return CONTAINING_RECORD(iface, FileProtocol, IInternetPriority_iface);
54}
55
57{
59
60 *ppv = NULL;
62 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
63 *ppv = &This->IUnknown_inner;
64 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
65 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
66 *ppv = &This->IInternetProtocolEx_iface;
67 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
68 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
69 *ppv = &This->IInternetProtocolEx_iface;
70 }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
71 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
72 *ppv = &This->IInternetProtocolEx_iface;
73 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
74 TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
75 *ppv = &This->IInternetPriority_iface;
76 }
77
78 if(*ppv) {
79 IUnknown_AddRef((IUnknown*)*ppv);
80 return S_OK;
81 }
82
83 WARN("not supported interface %s\n", debugstr_guid(riid));
84 return E_NOINTERFACE;
85}
86
88{
91 TRACE("(%p) ref=%d\n", This, ref);
92 return ref;
93}
94
96{
99
100 TRACE("(%p) ref=%d\n", This, ref);
101
102 if(!ref) {
103 if(This->file != INVALID_HANDLE_VALUE)
104 CloseHandle(This->file);
106
108 }
109
110 return ref;
111}
112
113static const IUnknownVtbl FileProtocolUnkVtbl = {
117};
118
120{
122 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
123 return IUnknown_QueryInterface(This->outer, riid, ppv);
124}
125
127{
129 TRACE("(%p)\n", This);
130 return IUnknown_AddRef(This->outer);
131}
132
134{
136 TRACE("(%p)\n", This);
137 return IUnknown_Release(This->outer);
138}
139
141 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
143{
145 IUri *uri;
147
148 TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
149 pOIBindInfo, grfPI, dwReserved);
150
151 hres = CreateUri(szUrl, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
152 if(FAILED(hres))
153 return hres;
154
155 hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
156 pOIBindInfo, grfPI, (HANDLE*)dwReserved);
157
158 IUri_Release(uri);
159 return hres;
160}
161
162static HRESULT WINAPI FileProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
163{
165 FIXME("(%p)->(%p)\n", This, pProtocolData);
166 return E_NOTIMPL;
167}
168
171{
173 FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
174 return E_NOTIMPL;
175}
176
178{
180
181 TRACE("(%p)->(%08x)\n", This, dwOptions);
182
183 return S_OK;
184}
185
187{
189 FIXME("(%p)\n", This);
190 return E_NOTIMPL;
191}
192
194{
196 FIXME("(%p)\n", This);
197 return E_NOTIMPL;
198}
199
201 ULONG cb, ULONG *pcbRead)
202{
204 DWORD read = 0;
205
206 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
207
208 if (pcbRead)
209 *pcbRead = 0;
210
211 if(This->file == INVALID_HANDLE_VALUE)
212 return INET_E_DATA_NOT_AVAILABLE;
213
214 if (!ReadFile(This->file, pv, cb, &read, NULL))
215 return INET_E_DOWNLOAD_FAILURE;
216
217 if(pcbRead)
218 *pcbRead = read;
219
220 return cb == read ? S_OK : S_FALSE;
221}
222
224 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
225{
227 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
228 return E_NOTIMPL;
229}
230
232{
234
235 TRACE("(%p)->(%08x)\n", This, dwOptions);
236
237 return S_OK;
238}
239
241{
243
244 TRACE("(%p)\n", This);
245
246 return S_OK;
247}
248
250{
251 IInternetProtocolSink_ReportResult(protocol_sink, hres, res, NULL);
252 return hres;
253}
254
256 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
257 DWORD grfPI, HANDLE *dwReserved)
258{
263 BINDINFO bindinfo;
264 DWORD grfBINDF = 0;
266 LPWSTR mime = NULL;
267 WCHAR null_char = 0;
268 BSTR ext;
270
271 TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
272 pOIBindInfo, grfPI, dwReserved);
273
274 if(!pUri)
275 return E_INVALIDARG;
276
277 scheme = 0;
278 hres = IUri_GetScheme(pUri, &scheme);
279 if(FAILED(hres))
280 return hres;
282 return E_INVALIDARG;
283
284 memset(&bindinfo, 0, sizeof(bindinfo));
285 bindinfo.cbSize = sizeof(BINDINFO);
286 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
287 if(FAILED(hres)) {
288 WARN("GetBindInfo failed: %08x\n", hres);
289 return hres;
290 }
291
292 ReleaseBindInfo(&bindinfo);
293
294 if(!(grfBINDF & BINDF_FROMURLMON))
295 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL);
296
297 if(This->file != INVALID_HANDLE_VALUE) {
298 IInternetProtocolSink_ReportData(pOIProtSink,
299 BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
300 This->size, This->size);
301 return S_OK;
302 }
303
304 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
305
306 size = 0;
307 hres = CoInternetParseIUri(pUri, PARSE_PATH_FROM_URL, 0, path, ARRAY_SIZE(path), &size, 0);
308 if(FAILED(hres)) {
309 WARN("CoInternetParseIUri failed: %08x\n", hres);
310 return report_result(pOIProtSink, hres, 0);
311 }
312
315 if(file_handle == INVALID_HANDLE_VALUE && (ptr = wcsrchr(path, '#'))) {
316 /* If path contains fragment part, try without it. */
317 *ptr = 0;
320 }
322 return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
323
326 return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
327 }
328
329 This->file = file_handle;
330 This->size = file_size.u.LowPart;
331 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_CACHEFILENAMEAVAILABLE, path);
332
333 hres = IUri_GetExtension(pUri, &ext);
334 if(SUCCEEDED(hres)) {
335 if(hres == S_OK && *ext) {
336 if((ptr = wcschr(ext, '#')))
337 *ptr = 0;
339 if(SUCCEEDED(hres)) {
340 IInternetProtocolSink_ReportProgress(pOIProtSink,
341 (grfBINDF & BINDF_FROMURLMON) ?
342 BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE,
343 mime);
345 }
346 }
348 }
349
350 IInternetProtocolSink_ReportData(pOIProtSink,
351 BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
352 This->size, This->size);
353
354 return report_result(pOIProtSink, S_OK, 0);
355}
356
357static const IInternetProtocolExVtbl FileProtocolExVtbl = {
372};
373
375 REFIID riid, void **ppv)
376{
378 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
379}
380
382{
384 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
385}
386
388{
390 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
391}
392
394{
396
397 TRACE("(%p)->(%d)\n", This, nPriority);
398
399 This->priority = nPriority;
400 return S_OK;
401}
402
404{
406
407 TRACE("(%p)->(%p)\n", This, pnPriority);
408
409 *pnPriority = This->priority;
410 return S_OK;
411}
412
413static const IInternetPriorityVtbl FilePriorityVtbl = {
419};
420
422{
424
425 TRACE("(%p %p)\n", outer, ppobj);
426
428
429 ret = heap_alloc(sizeof(FileProtocol));
430
431 ret->IUnknown_inner.lpVtbl = &FileProtocolUnkVtbl;
432 ret->IInternetProtocolEx_iface.lpVtbl = &FileProtocolExVtbl;
433 ret->IInternetPriority_iface.lpVtbl = &FilePriorityVtbl;
435 ret->priority = 0;
436 ret->ref = 1;
437 ret->outer = outer ? outer : &ret->IUnknown_inner;
438
439 *ppobj = &ret->IUnknown_inner;
440 return S_OK;
441}
#define read
Definition: acwin.h:96
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
unsigned long HANDLE_PTR
Definition: basetsd.h:78
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:114
#define WARN(fmt,...)
Definition: debug.h:115
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define wcsrchr
Definition: compat.h:16
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
OLECHAR * BSTR
Definition: compat.h:2293
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define GetFileSizeEx
Definition: compat.h:757
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
static const WCHAR *const ext[]
Definition: module.c:53
static HRESULT WINAPI FileProtocol_Resume(IInternetProtocolEx *iface)
Definition: file.c:193
static HRESULT report_result(IInternetProtocolSink *protocol_sink, HRESULT hres, DWORD res)
Definition: file.c:249
static ULONG WINAPI FileProtocolUnk_AddRef(IUnknown *iface)
Definition: file.c:87
static HRESULT WINAPI FilePriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
Definition: file.c:374
static HRESULT WINAPI FileProtocol_Suspend(IInternetProtocolEx *iface)
Definition: file.c:186
static HRESULT WINAPI FileProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved)
Definition: file.c:140
static HRESULT WINAPI FileProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
Definition: file.c:162
static HRESULT WINAPI FileProtocol_Read(IInternetProtocolEx *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: file.c:200
static HRESULT WINAPI FileProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
Definition: file.c:231
static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
Definition: file.c:119
static FileProtocol * impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
Definition: file.c:46
static ULONG WINAPI FilePriority_AddRef(IInternetPriority *iface)
Definition: file.c:381
static HRESULT WINAPI FileProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
Definition: file.c:177
static HRESULT WINAPI FilePriority_SetPriority(IInternetPriority *iface, LONG nPriority)
Definition: file.c:393
static FileProtocol * impl_from_IInternetPriority(IInternetPriority *iface)
Definition: file.c:51
static HRESULT WINAPI FileProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason, DWORD dwOptions)
Definition: file.c:169
static ULONG WINAPI FileProtocol_AddRef(IInternetProtocolEx *iface)
Definition: file.c:126
static ULONG WINAPI FileProtocolUnk_Release(IUnknown *iface)
Definition: file.c:95
static HRESULT WINAPI FilePriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
Definition: file.c:403
static ULONG WINAPI FilePriority_Release(IInternetPriority *iface)
Definition: file.c:387
HRESULT FileProtocol_Construct(IUnknown *outer, LPVOID *ppobj)
Definition: file.c:421
static HRESULT WINAPI FileProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: file.c:223
static ULONG WINAPI FileProtocol_Release(IInternetProtocolEx *iface)
Definition: file.c:133
static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE *dwReserved)
Definition: file.c:255
static HRESULT WINAPI FileProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: file.c:56
static const IUnknownVtbl FileProtocolUnkVtbl
Definition: file.c:113
static FileProtocol * impl_from_IUnknown(IUnknown *iface)
Definition: file.c:41
static const IInternetPriorityVtbl FilePriorityVtbl
Definition: file.c:413
static const IInternetProtocolExVtbl FileProtocolExVtbl
Definition: file.c:357
static HRESULT WINAPI FileProtocol_UnlockRequest(IInternetProtocolEx *iface)
Definition: file.c:240
HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IUri **ppURI)
Definition: uri.c:5700
HRESULT WINAPI CoInternetParseIUri(IUri *pIUri, PARSEACTION ParseAction, DWORD dwFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD_PTR dwReserved)
Definition: uri.c:7247
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
HRESULT find_mime_from_ext(const WCHAR *ext, WCHAR **ret)
Definition: mimefilter.c:425
const WCHAR * mime
Definition: mimefilter.c:512
static PVOID ptr
Definition: dispmode.c:27
static IInternetProtocolSink protocol_sink
Definition: mimeole.c:1411
HRESULT hres
Definition: protocol.c:465
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
const char * uri
Definition: sec_mgr.c:1588
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
static unsigned int file_size
Definition: regtests2xml.c:47
static FILE * file_handle
Definition: regtests2xml.c:45
DWORD scheme
#define memset(x, y, z)
Definition: compat.h:39
@ URL_SCHEME_FILE
Definition: shlwapi.h:1155
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwOptions
Definition: solitaire.cpp:25
LONG priority
Definition: file.c:36
IUnknown IUnknown_inner
Definition: file.c:28
HANDLE file
Definition: file.c:34
IUnknown * outer
Definition: file.c:32
IInternetPriority IInternetPriority_iface
Definition: file.c:30
ULONG size
Definition: file.c:35
IInternetProtocolEx IInternetProtocolEx_iface
Definition: file.c:29
LONG ref
Definition: file.c:38
Definition: send.c:48
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
struct _LARGE_INTEGER::@2306 u
void WINAPI ReleaseBindInfo(BINDINFO *pbindinfo)
Definition: urlmon_main.c:572
static void URLMON_LockModule(void)
Definition: urlmon_main.h:68
static void URLMON_UnlockModule(void)
Definition: urlmon_main.h:69
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185