2 * Copyright 2005 Jacek Caban
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "urlmon_main.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
35 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
42 #define PROTOCOL_THIS(iface) DEFINE_THIS(FileProtocol, InternetProtocol, iface)
44 #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
46 static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
48 FileProtocol *This = PROTOCOL_THIS(iface);
51 if(IsEqualGUID(&IID_IUnknown, riid)) {
52 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
53 *ppv = PROTOCOL(This);
54 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
55 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
56 *ppv = PROTOCOL(This);
57 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
58 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
59 *ppv = PROTOCOL(This);
63 IInternetProtocol_AddRef(iface);
67 WARN("not supported interface %s\n", debugstr_guid(riid));
71 static ULONG WINAPI FileProtocol_AddRef(IInternetProtocol *iface)
73 FileProtocol *This = PROTOCOL_THIS(iface);
74 LONG ref = InterlockedIncrement(&This->ref);
75 TRACE("(%p) ref=%ld\n", This, ref);
79 static ULONG WINAPI FileProtocol_Release(IInternetProtocol *iface)
81 FileProtocol *This = PROTOCOL_THIS(iface);
82 LONG ref = InterlockedDecrement(&This->ref);
84 TRACE("(%p) ref=%ld\n", This, ref);
88 CloseHandle(This->file);
89 HeapFree(GetProcessHeap(), 0, This);
91 URLMON_UnlockModule();
97 static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
98 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
99 DWORD grfPI, DWORD dwReserved)
101 FileProtocol *This = PROTOCOL_THIS(iface);
106 static const WCHAR wszFile[] = {'f','i','l','e',':'};
108 TRACE("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
109 pOIBindInfo, grfPI, dwReserved);
111 memset(&bindinfo, 0, sizeof(bindinfo));
112 bindinfo.cbSize = sizeof(BINDINFO);
113 IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
115 if(lstrlenW(szUrl) < sizeof(wszFile)/sizeof(WCHAR)
116 || memcmp(szUrl, wszFile, sizeof(wszFile)))
120 * Implement MIME type checking
124 This->file = CreateFileW(szUrl+sizeof(wszFile)/sizeof(WCHAR), GENERIC_READ, FILE_SHARE_READ,
125 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
127 if(This->file == INVALID_HANDLE_VALUE) {
129 IInternetProtocolSink_ReportResult(pOIProtSink, INET_E_RESOURCE_NOT_FOUND,
130 GetLastError(), NULL);
131 return INET_E_RESOURCE_NOT_FOUND;
134 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_CACHEFILENAMEAVAILABLE,
135 szUrl+sizeof(wszFile)/sizeof(WCHAR));
136 IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
139 if(GetFileSizeEx(This->file, &size))
140 IInternetProtocolSink_ReportData(pOIProtSink,
141 BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
142 size.u.LowPart, size.u.LowPart);
147 static HRESULT WINAPI FileProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
149 FileProtocol *This = PROTOCOL_THIS(iface);
150 FIXME("(%p)->(%p)\n", This, pProtocolData);
154 static HRESULT WINAPI FileProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
157 FileProtocol *This = PROTOCOL_THIS(iface);
158 FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
162 static HRESULT WINAPI FileProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
164 FileProtocol *This = PROTOCOL_THIS(iface);
166 TRACE("(%p)->(%08lx)\n", This, dwOptions);
171 static HRESULT WINAPI FileProtocol_Suspend(IInternetProtocol *iface)
173 FileProtocol *This = PROTOCOL_THIS(iface);
174 FIXME("(%p)\n", This);
178 static HRESULT WINAPI FileProtocol_Resume(IInternetProtocol *iface)
180 FileProtocol *This = PROTOCOL_THIS(iface);
181 FIXME("(%p)\n", This);
185 static HRESULT WINAPI FileProtocol_Read(IInternetProtocol *iface, void *pv,
186 ULONG cb, ULONG *pcbRead)
188 FileProtocol *This = PROTOCOL_THIS(iface);
191 TRACE("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
194 return INET_E_DATA_NOT_AVAILABLE;
196 ReadFile(This->file, pv, cb, &read, NULL);
201 return cb == read ? S_OK : S_FALSE;
204 static HRESULT WINAPI FileProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
205 DWORD dwOrgin, ULARGE_INTEGER *plibNewPosition)
207 FileProtocol *This = PROTOCOL_THIS(iface);
208 FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrgin, plibNewPosition);
212 static HRESULT WINAPI FileProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
214 FileProtocol *This = PROTOCOL_THIS(iface);
216 TRACE("(%p)->(%08lx)\n", This, dwOptions);
221 static HRESULT WINAPI FileProtocol_UnlockRequest(IInternetProtocol *iface)
223 FileProtocol *This = PROTOCOL_THIS(iface);
225 TRACE("(%p)\n", This);
232 static const IInternetProtocolVtbl FileProtocolVtbl = {
233 FileProtocol_QueryInterface,
235 FileProtocol_Release,
237 FileProtocol_Continue,
239 FileProtocol_Terminate,
240 FileProtocol_Suspend,
244 FileProtocol_LockRequest,
245 FileProtocol_UnlockRequest
248 HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
252 TRACE("(%p %p)\n", pUnkOuter, ppobj);
256 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(FileProtocol));
258 ret->lpInternetProtocolVtbl = &FileProtocolVtbl;
262 *ppobj = PROTOCOL(ret);