Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmk.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
1.7.6.1
|