ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

file.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2005 Jacek Caban
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include "urlmon_main.h"
00020 #include "winreg.h"
00021 #include "shlwapi.h"
00022 
00023 #include "wine/debug.h"
00024 
00025 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
00026 
00027 typedef struct {
00028     IInternetProtocolEx IInternetProtocolEx_iface;
00029     IInternetPriority   IInternetPriority_iface;
00030 
00031     HANDLE file;
00032     ULONG size;
00033     LONG priority;
00034 
00035     LONG ref;
00036 } FileProtocol;
00037 
00038 static inline FileProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
00039 {
00040     return CONTAINING_RECORD(iface, FileProtocol, IInternetProtocolEx_iface);
00041 }
00042 
00043 static inline FileProtocol *impl_from_IInternetPriority(IInternetPriority *iface)
00044 {
00045     return CONTAINING_RECORD(iface, FileProtocol, IInternetPriority_iface);
00046 }
00047 
00048 static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
00049 {
00050     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00051 
00052     *ppv = NULL;
00053     if(IsEqualGUID(&IID_IUnknown, riid)) {
00054         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
00055         *ppv = &This->IInternetProtocolEx_iface;
00056     }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
00057         TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
00058         *ppv = &This->IInternetProtocolEx_iface;
00059     }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
00060         TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
00061         *ppv = &This->IInternetProtocolEx_iface;
00062     }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
00063         TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
00064         *ppv = &This->IInternetProtocolEx_iface;
00065     }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
00066         TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
00067         *ppv = &This->IInternetPriority_iface;
00068     }
00069 
00070     if(*ppv) {
00071         IInternetProtocol_AddRef(iface);
00072         return S_OK;
00073     }
00074 
00075     WARN("not supported interface %s\n", debugstr_guid(riid));
00076     return E_NOINTERFACE;
00077 }
00078 
00079 static ULONG WINAPI FileProtocol_AddRef(IInternetProtocolEx *iface)
00080 {
00081     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00082     LONG ref = InterlockedIncrement(&This->ref);
00083     TRACE("(%p) ref=%d\n", This, ref);
00084     return ref;
00085 }
00086 
00087 static ULONG WINAPI FileProtocol_Release(IInternetProtocolEx *iface)
00088 {
00089     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00090     LONG ref = InterlockedDecrement(&This->ref);
00091 
00092     TRACE("(%p) ref=%d\n", This, ref);
00093 
00094     if(!ref) {
00095         if(This->file != INVALID_HANDLE_VALUE)
00096             CloseHandle(This->file);
00097         heap_free(This);
00098 
00099         URLMON_UnlockModule();
00100     }
00101 
00102     return ref;
00103 }
00104 
00105 static HRESULT WINAPI FileProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
00106         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
00107         DWORD grfPI, HANDLE_PTR dwReserved)
00108 {
00109     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00110     IUri *uri;
00111     HRESULT hres;
00112 
00113     TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
00114             pOIBindInfo, grfPI, dwReserved);
00115 
00116     hres = CreateUri(szUrl, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
00117     if(FAILED(hres))
00118         return hres;
00119 
00120     hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
00121             pOIBindInfo, grfPI, (HANDLE*)dwReserved);
00122 
00123     IUri_Release(uri);
00124     return hres;
00125 }
00126 
00127 static HRESULT WINAPI FileProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
00128 {
00129     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00130     FIXME("(%p)->(%p)\n", This, pProtocolData);
00131     return E_NOTIMPL;
00132 }
00133 
00134 static HRESULT WINAPI FileProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
00135         DWORD dwOptions)
00136 {
00137     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00138     FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
00139     return E_NOTIMPL;
00140 }
00141 
00142 static HRESULT WINAPI FileProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
00143 {
00144     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00145 
00146     TRACE("(%p)->(%08x)\n", This, dwOptions);
00147 
00148     return S_OK;
00149 }
00150 
00151 static HRESULT WINAPI FileProtocol_Suspend(IInternetProtocolEx *iface)
00152 {
00153     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00154     FIXME("(%p)\n", This);
00155     return E_NOTIMPL;
00156 }
00157 
00158 static HRESULT WINAPI FileProtocol_Resume(IInternetProtocolEx *iface)
00159 {
00160     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00161     FIXME("(%p)\n", This);
00162     return E_NOTIMPL;
00163 }
00164 
00165 static HRESULT WINAPI FileProtocol_Read(IInternetProtocolEx *iface, void *pv,
00166         ULONG cb, ULONG *pcbRead)
00167 {
00168     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00169     DWORD read = 0;
00170 
00171     TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
00172 
00173     if (pcbRead)
00174         *pcbRead = 0;
00175 
00176     if(This->file == INVALID_HANDLE_VALUE)
00177         return INET_E_DATA_NOT_AVAILABLE;
00178 
00179     if (!ReadFile(This->file, pv, cb, &read, NULL))
00180         return INET_E_DOWNLOAD_FAILURE;
00181 
00182     if(pcbRead)
00183         *pcbRead = read;
00184     
00185     return cb == read ? S_OK : S_FALSE;
00186 }
00187 
00188 static HRESULT WINAPI FileProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
00189         DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
00190 {
00191     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00192     FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
00193     return E_NOTIMPL;
00194 }
00195 
00196 static HRESULT WINAPI FileProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
00197 {
00198     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00199 
00200     TRACE("(%p)->(%08x)\n", This, dwOptions);
00201 
00202     return S_OK;
00203 }
00204 
00205 static HRESULT WINAPI FileProtocol_UnlockRequest(IInternetProtocolEx *iface)
00206 {
00207     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00208 
00209     TRACE("(%p)\n", This);
00210 
00211     return S_OK;
00212 }
00213 
00214 static inline HRESULT report_result(IInternetProtocolSink *protocol_sink, HRESULT hres, DWORD res)
00215 {
00216     IInternetProtocolSink_ReportResult(protocol_sink, hres, res, NULL);
00217     return hres;
00218 }
00219 
00220 static HRESULT open_file(FileProtocol *This, const WCHAR *path, IInternetProtocolSink *protocol_sink)
00221 {
00222     LARGE_INTEGER size;
00223     HANDLE file;
00224 
00225     file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
00226             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00227     if(file == INVALID_HANDLE_VALUE)
00228         return report_result(protocol_sink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
00229 
00230     if(!GetFileSizeEx(file, &size)) {
00231         CloseHandle(file);
00232         return report_result(protocol_sink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
00233     }
00234 
00235     This->file = file;
00236     This->size = size.u.LowPart;
00237 
00238     IInternetProtocolSink_ReportProgress(protocol_sink,
00239             BINDSTATUS_CACHEFILENAMEAVAILABLE, path);
00240     return S_OK;
00241 }
00242 
00243 static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
00244         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
00245         DWORD grfPI, HANDLE *dwReserved)
00246 {
00247     FileProtocol *This = impl_from_IInternetProtocolEx(iface);
00248     BINDINFO bindinfo;
00249     DWORD grfBINDF = 0;
00250     DWORD scheme;
00251     LPWSTR mime = NULL;
00252     WCHAR null_char = 0;
00253     BSTR path, url;
00254     HRESULT hres;
00255 
00256     TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
00257             pOIBindInfo, grfPI, dwReserved);
00258 
00259     if(!pUri)
00260         return E_INVALIDARG;
00261 
00262     scheme = 0;
00263     hres = IUri_GetScheme(pUri, &scheme);
00264     if(FAILED(hres))
00265         return hres;
00266     if(scheme != URL_SCHEME_FILE)
00267         return E_INVALIDARG;
00268 
00269     memset(&bindinfo, 0, sizeof(bindinfo));
00270     bindinfo.cbSize = sizeof(BINDINFO);
00271     hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
00272     if(FAILED(hres)) {
00273         WARN("GetBindInfo failed: %08x\n", hres);
00274         return hres;
00275     }
00276 
00277     ReleaseBindInfo(&bindinfo);
00278 
00279     if(!(grfBINDF & BINDF_FROMURLMON))
00280         IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL);
00281 
00282     if(This->file != INVALID_HANDLE_VALUE) {
00283         IInternetProtocolSink_ReportData(pOIProtSink,
00284                 BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
00285                 This->size, This->size);
00286         return S_OK;
00287     }
00288 
00289     IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
00290 
00291     hres = IUri_GetPath(pUri, &path);
00292     if(FAILED(hres)) {
00293         ERR("GetPath failed: %08x\n", hres);
00294         return report_result(pOIProtSink, hres, 0);
00295     }
00296 
00297     hres = open_file(This, path, pOIProtSink);
00298     SysFreeString(path);
00299     if(FAILED(hres))
00300         return hres;
00301 
00302     hres = IUri_GetDisplayUri(pUri, &url);
00303     if(hres == S_OK) {
00304         hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
00305         SysFreeString(url);
00306         if(SUCCEEDED(hres)) {
00307             IInternetProtocolSink_ReportProgress(pOIProtSink,
00308                     (grfBINDF & BINDF_FROMURLMON) ?
00309                      BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE,
00310                     mime);
00311             CoTaskMemFree(mime);
00312         }
00313     }
00314 
00315     IInternetProtocolSink_ReportData(pOIProtSink,
00316             BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
00317             This->size, This->size);
00318 
00319     return report_result(pOIProtSink, S_OK, 0);
00320 }
00321 
00322 static const IInternetProtocolExVtbl FileProtocolExVtbl = {
00323     FileProtocol_QueryInterface,
00324     FileProtocol_AddRef,
00325     FileProtocol_Release,
00326     FileProtocol_Start,
00327     FileProtocol_Continue,
00328     FileProtocol_Abort,
00329     FileProtocol_Terminate,
00330     FileProtocol_Suspend,
00331     FileProtocol_Resume,
00332     FileProtocol_Read,
00333     FileProtocol_Seek,
00334     FileProtocol_LockRequest,
00335     FileProtocol_UnlockRequest,
00336     FileProtocol_StartEx
00337 };
00338 
00339 static HRESULT WINAPI FilePriority_QueryInterface(IInternetPriority *iface,
00340                                                   REFIID riid, void **ppv)
00341 {
00342     FileProtocol *This = impl_from_IInternetPriority(iface);
00343     return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
00344 }
00345 
00346 static ULONG WINAPI FilePriority_AddRef(IInternetPriority *iface)
00347 {
00348     FileProtocol *This = impl_from_IInternetPriority(iface);
00349     return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
00350 }
00351 
00352 static ULONG WINAPI FilePriority_Release(IInternetPriority *iface)
00353 {
00354     FileProtocol *This = impl_from_IInternetPriority(iface);
00355     return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
00356 }
00357 
00358 static HRESULT WINAPI FilePriority_SetPriority(IInternetPriority *iface, LONG nPriority)
00359 {
00360     FileProtocol *This = impl_from_IInternetPriority(iface);
00361 
00362     TRACE("(%p)->(%d)\n", This, nPriority);
00363 
00364     This->priority = nPriority;
00365     return S_OK;
00366 }
00367 
00368 static HRESULT WINAPI FilePriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
00369 {
00370     FileProtocol *This = impl_from_IInternetPriority(iface);
00371 
00372     TRACE("(%p)->(%p)\n", This, pnPriority);
00373 
00374     *pnPriority = This->priority;
00375     return S_OK;
00376 }
00377 
00378 static const IInternetPriorityVtbl FilePriorityVtbl = {
00379     FilePriority_QueryInterface,
00380     FilePriority_AddRef,
00381     FilePriority_Release,
00382     FilePriority_SetPriority,
00383     FilePriority_GetPriority
00384 };
00385 
00386 HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
00387 {
00388     FileProtocol *ret;
00389 
00390     TRACE("(%p %p)\n", pUnkOuter, ppobj);
00391 
00392     URLMON_LockModule();
00393 
00394     ret = heap_alloc(sizeof(FileProtocol));
00395 
00396     ret->IInternetProtocolEx_iface.lpVtbl = &FileProtocolExVtbl;
00397     ret->IInternetPriority_iface.lpVtbl = &FilePriorityVtbl;
00398     ret->file = INVALID_HANDLE_VALUE;
00399     ret->priority = 0;
00400     ret->ref = 1;
00401 
00402     *ppobj = &ret->IInternetProtocolEx_iface;
00403     return S_OK;
00404 }

Generated on Mon May 28 2012 04:17:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.