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

mk.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2007 Jacek Caban for CodeWeavers
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 "wine/debug.h"
00021 
00022 #define NO_SHLWAPI_REG
00023 #include "shlwapi.h"
00024 
00025 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
00026 
00027 typedef struct {
00028     IInternetProtocolEx IInternetProtocolEx_iface;
00029 
00030     LONG ref;
00031 
00032     IStream *stream;
00033 } MkProtocol;
00034 
00035 static inline MkProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
00036 {
00037     return CONTAINING_RECORD(iface, MkProtocol, IInternetProtocolEx_iface);
00038 }
00039 
00040 static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
00041 {
00042     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00043 
00044     *ppv = NULL;
00045     if(IsEqualGUID(&IID_IUnknown, riid)) {
00046         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
00047         *ppv = &This->IInternetProtocolEx_iface;
00048     }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
00049         TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
00050         *ppv = &This->IInternetProtocolEx_iface;
00051     }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
00052         TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
00053         *ppv = &This->IInternetProtocolEx_iface;
00054     }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
00055         TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
00056         *ppv = &This->IInternetProtocolEx_iface;
00057     }
00058 
00059     if(*ppv) {
00060         IInternetProtocol_AddRef(iface);
00061         return S_OK;
00062     }
00063 
00064     WARN("not supported interface %s\n", debugstr_guid(riid));
00065     return E_NOINTERFACE;
00066 }
00067 
00068 static ULONG WINAPI MkProtocol_AddRef(IInternetProtocolEx *iface)
00069 {
00070     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00071     LONG ref = InterlockedIncrement(&This->ref);
00072     TRACE("(%p) ref=%d\n", This, ref);
00073     return ref;
00074 }
00075 
00076 static ULONG WINAPI MkProtocol_Release(IInternetProtocolEx *iface)
00077 {
00078     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00079     LONG ref = InterlockedDecrement(&This->ref);
00080 
00081     TRACE("(%p) ref=%d\n", This, ref);
00082 
00083     if(!ref) {
00084         if(This->stream)
00085             IStream_Release(This->stream);
00086 
00087         heap_free(This);
00088 
00089         URLMON_UnlockModule();
00090     }
00091 
00092     return ref;
00093 }
00094 
00095 static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres, DWORD dwError)
00096 {
00097     IInternetProtocolSink_ReportResult(sink, hres, dwError, NULL);
00098     return hres;
00099 }
00100 
00101 static HRESULT WINAPI MkProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
00102         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
00103         DWORD grfPI, HANDLE_PTR dwReserved)
00104 {
00105     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00106     HRESULT hres;
00107     IUri *uri;
00108 
00109     TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
00110             pOIBindInfo, grfPI, dwReserved);
00111 
00112     hres = CreateUri(szUrl, 0, 0, &uri);
00113     if(FAILED(hres))
00114         return hres;
00115 
00116     hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
00117             pOIBindInfo, grfPI, (HANDLE*)dwReserved);
00118 
00119     IUri_Release(uri);
00120     return hres;
00121 }
00122 
00123 static HRESULT WINAPI MkProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
00124 {
00125     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00126     FIXME("(%p)->(%p)\n", This, pProtocolData);
00127     return E_NOTIMPL;
00128 }
00129 
00130 static HRESULT WINAPI MkProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
00131         DWORD dwOptions)
00132 {
00133     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00134     FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
00135     return E_NOTIMPL;
00136 }
00137 
00138 static HRESULT WINAPI MkProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
00139 {
00140     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00141 
00142     TRACE("(%p)->(%08x)\n", This, dwOptions);
00143 
00144     return S_OK;
00145 }
00146 
00147 static HRESULT WINAPI MkProtocol_Suspend(IInternetProtocolEx *iface)
00148 {
00149     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00150     FIXME("(%p)\n", This);
00151     return E_NOTIMPL;
00152 }
00153 
00154 static HRESULT WINAPI MkProtocol_Resume(IInternetProtocolEx *iface)
00155 {
00156     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00157     FIXME("(%p)\n", This);
00158     return E_NOTIMPL;
00159 }
00160 
00161 static HRESULT WINAPI MkProtocol_Read(IInternetProtocolEx *iface, void *pv,
00162         ULONG cb, ULONG *pcbRead)
00163 {
00164     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00165 
00166     TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
00167 
00168     if(!This->stream)
00169         return E_FAIL;
00170 
00171     return IStream_Read(This->stream, pv, cb, pcbRead);
00172 }
00173 
00174 static HRESULT WINAPI MkProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
00175         DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
00176 {
00177     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00178     FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
00179     return E_NOTIMPL;
00180 }
00181 
00182 static HRESULT WINAPI MkProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
00183 {
00184     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00185 
00186     TRACE("(%p)->(%08x)\n", This, dwOptions);
00187 
00188     return S_OK;
00189 }
00190 
00191 static HRESULT WINAPI MkProtocol_UnlockRequest(IInternetProtocolEx *iface)
00192 {
00193     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00194 
00195     TRACE("(%p)\n", This);
00196 
00197     return S_OK;
00198 }
00199 
00200 static HRESULT WINAPI MkProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
00201         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
00202         DWORD grfPI, HANDLE *dwReserved)
00203 {
00204     MkProtocol *This = impl_from_IInternetProtocolEx(iface);
00205     LPWSTR mime, progid, display_name, colon_ptr;
00206     DWORD path_size = INTERNET_MAX_URL_LENGTH;
00207     DWORD bindf=0, eaten=0, scheme=0, len;
00208     BSTR url, path_tmp, path = NULL;
00209     IParseDisplayName *pdn;
00210     BINDINFO bindinfo;
00211     STATSTG statstg;
00212     IMoniker *mon;
00213     HRESULT hres;
00214     CLSID clsid;
00215 
00216     TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
00217             pOIBindInfo, grfPI, dwReserved);
00218 
00219     hres = IUri_GetScheme(pUri, &scheme);
00220     if(FAILED(hres))
00221         return hres;
00222     if(scheme != URL_SCHEME_MK)
00223         return INET_E_INVALID_URL;
00224 
00225     memset(&bindinfo, 0, sizeof(bindinfo));
00226     bindinfo.cbSize = sizeof(BINDINFO);
00227     hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
00228     if(FAILED(hres)) {
00229         WARN("GetBindInfo failed: %08x\n", hres);
00230         return hres;
00231     }
00232 
00233     ReleaseBindInfo(&bindinfo);
00234 
00235     IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL);
00236 
00237     hres = IUri_GetDisplayUri(pUri, &url);
00238     if(FAILED(hres))
00239         return hres;
00240     hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
00241     SysFreeString(url);
00242     if(SUCCEEDED(hres)) {
00243         IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
00244         CoTaskMemFree(mime);
00245     }
00246 
00247     hres = IUri_GetPath(pUri, &path_tmp);
00248     if(FAILED(hres))
00249         return hres;
00250     path = heap_alloc(path_size);
00251     hres = UrlUnescapeW((LPWSTR)path_tmp, path, &path_size, 0);
00252     SysFreeString(path_tmp);
00253     if (FAILED(hres))
00254     {
00255         heap_free(path);
00256         return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
00257     }
00258     progid = path+1; /* skip '@' symbol */
00259     colon_ptr = strchrW(path, ':');
00260     if(!colon_ptr)
00261     {
00262         heap_free(path);
00263         return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
00264     }
00265 
00266     len = strlenW(path);
00267     display_name = heap_alloc((len+1)*sizeof(WCHAR));
00268     memcpy(display_name, path, (len+1)*sizeof(WCHAR));
00269 
00270     progid[colon_ptr-progid] = 0; /* overwrite ':' with NULL terminator */
00271     hres = CLSIDFromProgID(progid, &clsid);
00272     heap_free(path);
00273     if(FAILED(hres))
00274     {
00275         heap_free(display_name);
00276         return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
00277     }
00278 
00279     hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
00280             &IID_IParseDisplayName, (void**)&pdn);
00281     if(FAILED(hres)) {
00282         WARN("Could not create object %s\n", debugstr_guid(&clsid));
00283         heap_free(display_name);
00284         return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
00285     }
00286 
00287     hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon);
00288     heap_free(display_name);
00289     IParseDisplayName_Release(pdn);
00290     if(FAILED(hres)) {
00291         WARN("ParseDisplayName failed: %08x\n", hres);
00292         return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
00293     }
00294 
00295     if(This->stream) {
00296         IStream_Release(This->stream);
00297         This->stream = NULL;
00298     }
00299 
00300     hres = IMoniker_BindToStorage(mon, NULL /* FIXME */, NULL, &IID_IStream, (void**)&This->stream);
00301     IMoniker_Release(mon);
00302     if(FAILED(hres)) {
00303         WARN("BindToStorage failed: %08x\n", hres);
00304         return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
00305     }
00306 
00307     hres = IStream_Stat(This->stream, &statstg, STATFLAG_NONAME);
00308     if(FAILED(hres)) {
00309         WARN("Stat failed: %08x\n", hres);
00310         return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
00311     }
00312 
00313     IInternetProtocolSink_ReportData(pOIProtSink,
00314             BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION,
00315             statstg.cbSize.u.LowPart, statstg.cbSize.u.LowPart);
00316     return report_result(pOIProtSink, S_OK, ERROR_SUCCESS);
00317 }
00318 
00319 static const IInternetProtocolExVtbl MkProtocolVtbl = {
00320     MkProtocol_QueryInterface,
00321     MkProtocol_AddRef,
00322     MkProtocol_Release,
00323     MkProtocol_Start,
00324     MkProtocol_Continue,
00325     MkProtocol_Abort,
00326     MkProtocol_Terminate,
00327     MkProtocol_Suspend,
00328     MkProtocol_Resume,
00329     MkProtocol_Read,
00330     MkProtocol_Seek,
00331     MkProtocol_LockRequest,
00332     MkProtocol_UnlockRequest,
00333     MkProtocol_StartEx
00334 };
00335 
00336 HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
00337 {
00338     MkProtocol *ret;
00339 
00340     TRACE("(%p %p)\n", pUnkOuter, ppobj);
00341 
00342     URLMON_LockModule();
00343 
00344     ret = heap_alloc(sizeof(MkProtocol));
00345 
00346     ret->IInternetProtocolEx_iface.lpVtbl = &MkProtocolVtbl;
00347     ret->ref = 1;
00348     ret->stream = NULL;
00349 
00350     /* NOTE:
00351      * Native returns NULL ppobj and S_OK in CreateInstance if called with IID_IUnknown riid.
00352      */
00353     *ppobj = &ret->IInternetProtocolEx_iface;
00354 
00355     return S_OK;
00356 }

Generated on Sun May 27 2012 04:26:40 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.