mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
Autosyncing with Wine HEAD
svn path=/trunk/; revision=27919
This commit is contained in:
+631
-133
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright 2007 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
#include "urlmon.h"
|
||||
#include "urlmon_main.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
typedef struct {
|
||||
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
|
||||
const IInternetBindInfoVtbl *lpInternetBindInfoVtbl;
|
||||
const IInternetPriorityVtbl *lpInternetPriorityVtbl;
|
||||
const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl;
|
||||
|
||||
LONG ref;
|
||||
|
||||
IInternetProtocol *protocol;
|
||||
IInternetBindInfo *bind_info;
|
||||
IInternetProtocolSink *protocol_sink;
|
||||
|
||||
LONG priority;
|
||||
} BindProtocol;
|
||||
|
||||
#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
|
||||
#define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
|
||||
#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
|
||||
#define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl)
|
||||
|
||||
#define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocol, iface)
|
||||
|
||||
static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
*ppv = NULL;
|
||||
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv);
|
||||
*ppv = BINDINFO(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
|
||||
*ppv = PRIORITY(This);
|
||||
}else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
|
||||
FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
|
||||
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
|
||||
FIXME("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
|
||||
*ppv = PROTSINK(This);
|
||||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("not supported interface %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI BindProtocol_AddRef(IInternetProtocol *iface)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->protocol)
|
||||
IInternetProtocol_Release(This->protocol);
|
||||
if(This->bind_info)
|
||||
IInternetBindInfo_Release(This->bind_info);
|
||||
if(This->protocol_sink)
|
||||
IInternetProtocolSink_Release(This->protocol_sink);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
URLMON_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
|
||||
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
|
||||
DWORD grfPI, DWORD dwReserved)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
IInternetProtocol *protocol = NULL;
|
||||
IInternetPriority *priority;
|
||||
IServiceProvider *service_provider;
|
||||
CLSID clsid = IID_NULL;
|
||||
LPOLESTR clsid_str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
pOIBindInfo, grfPI, dwReserved);
|
||||
|
||||
if(!szUrl || !pOIProtSink || !pOIBindInfo)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider,
|
||||
(void**)&service_provider);
|
||||
if(SUCCEEDED(hres)) {
|
||||
/* FIXME: What's protocol CLSID here? */
|
||||
IServiceProvider_QueryService(service_provider, &IID_IInternetProtocol,
|
||||
&IID_IInternetProtocol, (void**)&protocol);
|
||||
IServiceProvider_Release(service_provider);
|
||||
}
|
||||
|
||||
if(!protocol) {
|
||||
IClassFactory *cf;
|
||||
IUnknown *unk;
|
||||
|
||||
hres = get_protocol_handler(szUrl, &clsid, &cf);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IClassFactory_CreateInstance(cf, (IUnknown*)BINDINFO(This),
|
||||
&IID_IUnknown, (void**)&unk);
|
||||
IClassFactory_Release(cf);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol);
|
||||
IUnknown_Release(unk);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
StringFromCLSID(&clsid, &clsid_str);
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str);
|
||||
CoTaskMemFree(clsid_str);
|
||||
|
||||
This->protocol = protocol;
|
||||
|
||||
IInternetBindInfo_AddRef(pOIBindInfo);
|
||||
This->bind_info = pOIBindInfo;
|
||||
|
||||
IInternetProtocolSink_AddRef(pOIProtSink);
|
||||
This->protocol_sink = pOIProtSink;
|
||||
|
||||
hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
|
||||
if(SUCCEEDED(hres)) {
|
||||
IInternetPriority_SetPriority(priority, This->priority);
|
||||
IInternetPriority_Release(priority);
|
||||
}
|
||||
|
||||
return IInternetProtocol_Start(protocol, szUrl, PROTSINK(This), BINDINFO(This), 0, 0);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%p)\n", This, pProtocolData);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
|
||||
DWORD dwOptions)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
IInternetProtocol_Terminate(This->protocol, 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Suspend(IInternetProtocol *iface)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Resume(IInternetProtocol *iface)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Read(IInternetProtocol *iface, void *pv,
|
||||
ULONG cb, ULONG *pcbRead)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
ULONG read = 0;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
|
||||
|
||||
hres = IInternetProtocol_Read(This->protocol, pv, cb, &read);
|
||||
|
||||
*pcbRead = read;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08x)\n", This, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocol *iface)
|
||||
{
|
||||
BindProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#undef PROTOCOL_THIS
|
||||
|
||||
static const IInternetProtocolVtbl BindProtocolVtbl = {
|
||||
BindProtocol_QueryInterface,
|
||||
BindProtocol_AddRef,
|
||||
BindProtocol_Release,
|
||||
BindProtocol_Start,
|
||||
BindProtocol_Continue,
|
||||
BindProtocol_Abort,
|
||||
BindProtocol_Terminate,
|
||||
BindProtocol_Suspend,
|
||||
BindProtocol_Resume,
|
||||
BindProtocol_Read,
|
||||
BindProtocol_Seek,
|
||||
BindProtocol_LockRequest,
|
||||
BindProtocol_UnlockRequest
|
||||
};
|
||||
|
||||
#define BINDINFO_THIS(iface) DEFINE_THIS(BindProtocol, InternetBindInfo, iface)
|
||||
|
||||
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
BindProtocol *This = BINDINFO_THIS(iface);
|
||||
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
|
||||
{
|
||||
BindProtocol *This = BINDINFO_THIS(iface);
|
||||
return IBinding_AddRef(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
|
||||
{
|
||||
BindProtocol *This = BINDINFO_THIS(iface);
|
||||
return IBinding_Release(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface,
|
||||
DWORD *grfBINDF, BINDINFO *pbindinfo)
|
||||
{
|
||||
BindProtocol *This = BINDINFO_THIS(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
|
||||
|
||||
hres = IInternetBindInfo_GetBindInfo(This->bind_info, grfBINDF, pbindinfo);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetBindInfo failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
*grfBINDF |= BINDF_FROMURLMON;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface,
|
||||
ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
|
||||
{
|
||||
BindProtocol *This = BINDINFO_THIS(iface);
|
||||
FIXME("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#undef BINDFO_THIS
|
||||
|
||||
static const IInternetBindInfoVtbl InternetBindInfoVtbl = {
|
||||
BindInfo_QueryInterface,
|
||||
BindInfo_AddRef,
|
||||
BindInfo_Release,
|
||||
BindInfo_GetBindInfo,
|
||||
BindInfo_GetBindString
|
||||
};
|
||||
|
||||
#define PRIORITY_THIS(iface) DEFINE_THIS(BindProtocol, InternetPriority, iface)
|
||||
|
||||
static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
BindProtocol *This = PRIORITY_THIS(iface);
|
||||
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
|
||||
{
|
||||
BindProtocol *This = PRIORITY_THIS(iface);
|
||||
return IInternetProtocol_AddRef(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
|
||||
{
|
||||
BindProtocol *This = PRIORITY_THIS(iface);
|
||||
return IInternetProtocol_Release(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
|
||||
{
|
||||
BindProtocol *This = PRIORITY_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%d)\n", This, nPriority);
|
||||
|
||||
This->priority = nPriority;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
|
||||
{
|
||||
BindProtocol *This = PRIORITY_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, pnPriority);
|
||||
|
||||
*pnPriority = This->priority;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#undef PRIORITY_THIS
|
||||
|
||||
static const IInternetPriorityVtbl InternetPriorityVtbl = {
|
||||
InternetPriority_QueryInterface,
|
||||
InternetPriority_AddRef,
|
||||
InternetPriority_Release,
|
||||
InternetPriority_SetPriority,
|
||||
InternetPriority_GetPriority
|
||||
|
||||
};
|
||||
|
||||
#define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocolSink, iface)
|
||||
|
||||
static HRESULT WINAPI InternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
BindProtocol *This = PROTSINK_THIS(iface);
|
||||
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI InternetProtocolSink_AddRef(IInternetProtocolSink *iface)
|
||||
{
|
||||
BindProtocol *This = PROTSINK_THIS(iface);
|
||||
return IInternetProtocol_AddRef(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface)
|
||||
{
|
||||
BindProtocol *This = PROTSINK_THIS(iface);
|
||||
return IInternetProtocol_Release(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface,
|
||||
PROTOCOLDATA *pProtocolData)
|
||||
{
|
||||
BindProtocol *This = PROTSINK_THIS(iface);
|
||||
FIXME("(%p)->(%p)\n", This, pProtocolData);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
|
||||
ULONG ulStatusCode, LPCWSTR szStatusText)
|
||||
{
|
||||
BindProtocol *This = PROTSINK_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
|
||||
|
||||
switch(ulStatusCode) {
|
||||
case BINDSTATUS_SENDINGREQUEST:
|
||||
return IInternetProtocolSink_ReportProgress(This->protocol_sink,
|
||||
ulStatusCode, NULL);
|
||||
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
|
||||
return IInternetProtocolSink_ReportProgress(This->protocol_sink,
|
||||
ulStatusCode, szStatusText);
|
||||
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
|
||||
return IInternetProtocolSink_ReportProgress(This->protocol_sink,
|
||||
BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
|
||||
default:
|
||||
FIXME("unsupported ulStatusCode %u\n", ulStatusCode);
|
||||
}
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface,
|
||||
DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
|
||||
{
|
||||
BindProtocol *This = PROTSINK_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
|
||||
HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
|
||||
{
|
||||
BindProtocol *This = PROTSINK_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
|
||||
|
||||
return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult);
|
||||
}
|
||||
|
||||
#undef PROTSINK_THIS
|
||||
|
||||
static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
|
||||
InternetProtocolSink_QueryInterface,
|
||||
InternetProtocolSink_AddRef,
|
||||
InternetProtocolSink_Release,
|
||||
InternetProtocolSink_Switch,
|
||||
InternetProtocolSink_ReportProgress,
|
||||
InternetProtocolSink_ReportData,
|
||||
InternetProtocolSink_ReportResult
|
||||
};
|
||||
|
||||
HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol)
|
||||
{
|
||||
BindProtocol *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(BindProtocol));
|
||||
|
||||
ret->lpInternetProtocolVtbl = &BindProtocolVtbl;
|
||||
ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl;
|
||||
ret->lpInternetPriorityVtbl = &InternetPriorityVtbl;
|
||||
ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
|
||||
|
||||
ret->ref = 1;
|
||||
ret->protocol = NULL;
|
||||
ret->bind_info = NULL;
|
||||
ret->protocol_sink = NULL;
|
||||
ret->priority = 0;
|
||||
|
||||
URLMON_LockModule();
|
||||
|
||||
*protocol = PROTOCOL(ret);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -78,7 +78,7 @@ static ULONG WINAPI FileProtocol_AddRef(IInternetProtocol *iface)
|
||||
{
|
||||
FileProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ static ULONG WINAPI FileProtocol_Release(IInternetProtocol *iface)
|
||||
FileProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->file)
|
||||
@@ -117,12 +117,18 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
|
||||
|
||||
static const WCHAR wszFile[] = {'f','i','l','e',':'};
|
||||
|
||||
TRACE("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
pOIBindInfo, grfPI, dwReserved);
|
||||
|
||||
memset(&bindinfo, 0, sizeof(bindinfo));
|
||||
bindinfo.cbSize = sizeof(BINDINFO);
|
||||
IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
|
||||
hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetBindInfo failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
ReleaseBindInfo(&bindinfo);
|
||||
|
||||
if(lstrlenW(szUrl) < sizeof(wszFile)/sizeof(WCHAR)
|
||||
|| memcmp(szUrl, wszFile, sizeof(wszFile)))
|
||||
@@ -198,7 +204,7 @@ static HRESULT WINAPI FileProtocol_Abort(IInternetProtocol *iface, HRESULT hrRea
|
||||
DWORD dwOptions)
|
||||
{
|
||||
FileProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
|
||||
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -206,7 +212,7 @@ static HRESULT WINAPI FileProtocol_Terminate(IInternetProtocol *iface, DWORD dwO
|
||||
{
|
||||
FileProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08lx)\n", This, dwOptions);
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -231,7 +237,7 @@ static HRESULT WINAPI FileProtocol_Read(IInternetProtocol *iface, void *pv,
|
||||
FileProtocol *This = PROTOCOL_THIS(iface);
|
||||
DWORD read = 0;
|
||||
|
||||
TRACE("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
|
||||
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
|
||||
|
||||
if(!This->file)
|
||||
return INET_E_DATA_NOT_AVAILABLE;
|
||||
@@ -245,10 +251,10 @@ static HRESULT WINAPI FileProtocol_Read(IInternetProtocol *iface, void *pv,
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FileProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrgin, ULARGE_INTEGER *plibNewPosition)
|
||||
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
|
||||
{
|
||||
FileProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrgin, plibNewPosition);
|
||||
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -256,7 +262,7 @@ static HRESULT WINAPI FileProtocol_LockRequest(IInternetProtocol *iface, DWORD d
|
||||
{
|
||||
FileProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08lx)\n", This, dwOptions);
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -313,7 +319,7 @@ static HRESULT WINAPI FilePriority_SetPriority(IInternetPriority *iface, LONG nP
|
||||
{
|
||||
FileProtocol *This = PRIORITY_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%ld)\n", This, nPriority);
|
||||
TRACE("(%p)->(%d)\n", This, nPriority);
|
||||
|
||||
This->priority = nPriority;
|
||||
return S_OK;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -66,7 +66,7 @@ static ULONG WINAPI EnumFORMATETC_AddRef(IEnumFORMATETC *iface)
|
||||
{
|
||||
ENUMF_THIS(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ static ULONG WINAPI EnumFORMATETC_Release(IEnumFORMATETC *iface)
|
||||
ENUMF_THIS(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
HeapFree(GetProcessHeap(), 0, This->fetc);
|
||||
@@ -93,7 +93,7 @@ static HRESULT WINAPI EnumFORMATETC_Next(IEnumFORMATETC *iface, ULONG celt,
|
||||
ENUMF_THIS(iface);
|
||||
ULONG cnt;
|
||||
|
||||
TRACE("(%p)->(%ld %p %p)\n", This, celt, rgelt, pceltFetched);
|
||||
TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched);
|
||||
|
||||
if(!rgelt)
|
||||
return E_INVALIDARG;
|
||||
@@ -119,7 +119,7 @@ static HRESULT WINAPI EnumFORMATETC_Skip(IEnumFORMATETC *iface, ULONG celt)
|
||||
{
|
||||
ENUMF_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%ld)\n", This, celt);
|
||||
TRACE("(%p)->(%d)\n", This, celt);
|
||||
|
||||
This->it += celt;
|
||||
return This->it > This->fetc_cnt ? S_FALSE : S_OK;
|
||||
@@ -197,7 +197,7 @@ HRESULT WINAPI CreateFormatEnumerator(UINT cfmtetc, FORMATETC *rgfmtetc,
|
||||
*/
|
||||
HRESULT WINAPI RegisterFormatEnumerator(LPBC pBC, IEnumFORMATETC *pEFetc, DWORD reserved)
|
||||
{
|
||||
TRACE("(%p %p %ld)\n", pBC, pEFetc, reserved);
|
||||
TRACE("(%p %p %d)\n", pBC, pEFetc, reserved);
|
||||
|
||||
if(reserved)
|
||||
WARN("reserved != 0\n");
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -69,7 +69,7 @@ static ULONG WINAPI FtpProtocol_AddRef(IInternetProtocol *iface)
|
||||
{
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ static ULONG WINAPI FtpProtocol_Release(IInternetProtocol *iface)
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
@@ -94,7 +94,7 @@ static HRESULT WINAPI FtpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
|
||||
DWORD grfPI, DWORD dwReserved)
|
||||
{
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
FIXME("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
pOIBindInfo, grfPI, dwReserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -110,14 +110,14 @@ static HRESULT WINAPI FtpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReas
|
||||
DWORD dwOptions)
|
||||
{
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
|
||||
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FtpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08lx)\n", This, dwOptions);
|
||||
FIXME("(%p)->(%08x)\n", This, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -139,22 +139,22 @@ static HRESULT WINAPI FtpProtocol_Read(IInternetProtocol *iface, void *pv,
|
||||
ULONG cb, ULONG *pcbRead)
|
||||
{
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
|
||||
FIXME("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FtpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrgin, ULARGE_INTEGER *plibNewPosition)
|
||||
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
|
||||
{
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrgin, plibNewPosition);
|
||||
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FtpProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
FtpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08lx)\n", This, dwOptions);
|
||||
FIXME("(%p)->(%08x)\n", This, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
+690
-22
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2005 Jacek Caban
|
||||
* Copyright 2007 Misha Koshelev
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -13,7 +14,12 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - Handle redirects as native.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -25,21 +31,212 @@
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
#include "urlmon.h"
|
||||
#include "wininet.h"
|
||||
#include "urlmon_main.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
/* Flags are needed for, among other things, return HRESULTs from the Read function
|
||||
* to conform to native. For example, Read returns:
|
||||
*
|
||||
* 1. E_PENDING if called before the request has completed,
|
||||
* (flags = 0)
|
||||
* 2. S_FALSE after all data has been read and S_OK has been reported,
|
||||
* (flags = FLAG_REQUEST_COMPLETE | FLAG_ALL_DATA_READ | FLAG_RESULT_REPORTED)
|
||||
* 3. INET_E_DATA_NOT_AVAILABLE if InternetQueryDataAvailable fails. The first time
|
||||
* this occurs, INET_E_DATA_NOT_AVAILABLE will also be reported to the sink,
|
||||
* (flags = FLAG_REQUEST_COMPLETE)
|
||||
* but upon subsequent calls to Read no reporting will take place, yet
|
||||
* InternetQueryDataAvailable will still be called, and, on failure,
|
||||
* INET_E_DATA_NOT_AVAILABLE will still be returned.
|
||||
* (flags = FLAG_REQUEST_COMPLETE | FLAG_RESULT_REPORTED)
|
||||
*
|
||||
* FLAG_FIRST_DATA_REPORTED and FLAG_LAST_DATA_REPORTED are needed for proper
|
||||
* ReportData reporting. For example, if OnResponse returns S_OK, Continue will
|
||||
* report BSCF_FIRSTDATANOTIFICATION, and when all data has been read Read will
|
||||
* report BSCF_INTERMEDIATEDATANOTIFICATION|BSCF_LASTDATANOTIFICATION. However,
|
||||
* if OnResponse does not return S_OK, Continue will not report data, and Read
|
||||
* will report BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION when all
|
||||
* data has been read.
|
||||
*/
|
||||
#define FLAG_REQUEST_COMPLETE 0x1
|
||||
#define FLAG_FIRST_CONTINUE_COMPLETE 0x2
|
||||
#define FLAG_FIRST_DATA_REPORTED 0x4
|
||||
#define FLAG_ALL_DATA_READ 0x8
|
||||
#define FLAG_LAST_DATA_REPORTED 0x10
|
||||
#define FLAG_RESULT_REPORTED 0x20
|
||||
|
||||
typedef struct {
|
||||
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
|
||||
const IInternetPriorityVtbl *lpInternetPriorityVtbl;
|
||||
|
||||
DWORD flags, grfBINDF;
|
||||
BINDINFO bind_info;
|
||||
IInternetProtocolSink *protocol_sink;
|
||||
IHttpNegotiate *http_negotiate;
|
||||
HINTERNET internet, connect, request;
|
||||
LPWSTR full_header;
|
||||
HANDLE lock;
|
||||
ULONG current_position, content_length, available_bytes;
|
||||
LONG priority;
|
||||
|
||||
LONG ref;
|
||||
} HttpProtocol;
|
||||
|
||||
/* Default headers from native */
|
||||
static const WCHAR wszHeaders[] = {'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',
|
||||
':',' ','g','z','i','p',',',' ','d','e','f','l','a','t','e',0};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
static void HTTPPROTOCOL_ReportResult(HttpProtocol *This, HRESULT hres)
|
||||
{
|
||||
if (!(This->flags & FLAG_RESULT_REPORTED) &&
|
||||
This->protocol_sink)
|
||||
{
|
||||
This->flags |= FLAG_RESULT_REPORTED;
|
||||
IInternetProtocolSink_ReportResult(This->protocol_sink, hres, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void HTTPPROTOCOL_ReportData(HttpProtocol *This)
|
||||
{
|
||||
DWORD bscf;
|
||||
if (!(This->flags & FLAG_LAST_DATA_REPORTED) &&
|
||||
This->protocol_sink)
|
||||
{
|
||||
if (This->flags & FLAG_FIRST_DATA_REPORTED)
|
||||
{
|
||||
bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
This->flags |= FLAG_FIRST_DATA_REPORTED;
|
||||
bscf = BSCF_FIRSTDATANOTIFICATION;
|
||||
}
|
||||
if (This->flags & FLAG_ALL_DATA_READ &&
|
||||
!(This->flags & FLAG_LAST_DATA_REPORTED))
|
||||
{
|
||||
This->flags |= FLAG_LAST_DATA_REPORTED;
|
||||
bscf |= BSCF_LASTDATANOTIFICATION;
|
||||
}
|
||||
IInternetProtocolSink_ReportData(This->protocol_sink, bscf,
|
||||
This->current_position+This->available_bytes,
|
||||
This->content_length);
|
||||
}
|
||||
}
|
||||
|
||||
static void HTTPPROTOCOL_AllDataRead(HttpProtocol *This)
|
||||
{
|
||||
if (!(This->flags & FLAG_ALL_DATA_READ))
|
||||
This->flags |= FLAG_ALL_DATA_READ;
|
||||
HTTPPROTOCOL_ReportData(This);
|
||||
HTTPPROTOCOL_ReportResult(This, S_OK);
|
||||
}
|
||||
|
||||
static void HTTPPROTOCOL_Close(HttpProtocol *This)
|
||||
{
|
||||
if (This->protocol_sink)
|
||||
{
|
||||
IInternetProtocolSink_Release(This->protocol_sink);
|
||||
This->protocol_sink = 0;
|
||||
}
|
||||
if (This->http_negotiate)
|
||||
{
|
||||
IHttpNegotiate_Release(This->http_negotiate);
|
||||
This->http_negotiate = 0;
|
||||
}
|
||||
if (This->request)
|
||||
{
|
||||
InternetCloseHandle(This->request);
|
||||
This->request = 0;
|
||||
}
|
||||
if (This->connect)
|
||||
{
|
||||
InternetCloseHandle(This->connect);
|
||||
This->connect = 0;
|
||||
}
|
||||
if (This->internet)
|
||||
{
|
||||
InternetCloseHandle(This->internet);
|
||||
This->internet = 0;
|
||||
}
|
||||
if (This->full_header)
|
||||
{
|
||||
if (This->full_header != wszHeaders)
|
||||
HeapFree(GetProcessHeap(), 0, This->full_header);
|
||||
This->full_header = 0;
|
||||
}
|
||||
if (This->bind_info.cbSize)
|
||||
{
|
||||
ReleaseBindInfo(&This->bind_info);
|
||||
memset(&This->bind_info, 0, sizeof(This->bind_info));
|
||||
}
|
||||
This->flags = 0;
|
||||
}
|
||||
|
||||
static void CALLBACK HTTPPROTOCOL_InternetStatusCallback(
|
||||
HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
|
||||
LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
|
||||
{
|
||||
HttpProtocol *This = (HttpProtocol *)dwContext;
|
||||
PROTOCOLDATA data;
|
||||
ULONG ulStatusCode;
|
||||
|
||||
switch (dwInternetStatus)
|
||||
{
|
||||
case INTERNET_STATUS_RESOLVING_NAME:
|
||||
ulStatusCode = BINDSTATUS_FINDINGRESOURCE;
|
||||
break;
|
||||
case INTERNET_STATUS_CONNECTING_TO_SERVER:
|
||||
ulStatusCode = BINDSTATUS_CONNECTING;
|
||||
break;
|
||||
case INTERNET_STATUS_SENDING_REQUEST:
|
||||
ulStatusCode = BINDSTATUS_SENDINGREQUEST;
|
||||
break;
|
||||
case INTERNET_STATUS_REQUEST_COMPLETE:
|
||||
This->flags |= FLAG_REQUEST_COMPLETE;
|
||||
/* PROTOCOLDATA same as native */
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.dwState = 0xf1000000;
|
||||
if (This->flags & FLAG_FIRST_CONTINUE_COMPLETE)
|
||||
data.pData = (LPVOID)BINDSTATUS_ENDDOWNLOADCOMPONENTS;
|
||||
else
|
||||
data.pData = (LPVOID)BINDSTATUS_DOWNLOADINGDATA;
|
||||
if (This->grfBINDF & BINDF_FROMURLMON)
|
||||
IInternetProtocolSink_Switch(This->protocol_sink, &data);
|
||||
else
|
||||
IInternetProtocol_Continue((IInternetProtocol *)This, &data);
|
||||
return;
|
||||
default:
|
||||
WARN("Unhandled Internet status callback %d\n", dwInternetStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink, ulStatusCode, (LPWSTR)lpvStatusInformation);
|
||||
}
|
||||
|
||||
static inline LPWSTR strndupW(LPWSTR string, int len)
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
if (string &&
|
||||
(ret = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR))) != NULL)
|
||||
{
|
||||
memcpy(ret, string, len*sizeof(WCHAR));
|
||||
ret[len] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface implementations
|
||||
*/
|
||||
|
||||
#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
|
||||
#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
|
||||
|
||||
@@ -77,7 +274,7 @@ static ULONG WINAPI HttpProtocol_AddRef(IInternetProtocol *iface)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -86,9 +283,10 @@ static ULONG WINAPI HttpProtocol_Release(IInternetProtocol *iface)
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
HTTPPROTOCOL_Close(This);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
URLMON_UnlockModule();
|
||||
@@ -102,31 +300,409 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
|
||||
DWORD grfPI, DWORD dwReserved)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
URL_COMPONENTSW url;
|
||||
DWORD len = 0, request_flags = INTERNET_FLAG_KEEP_CONNECTION;
|
||||
ULONG num = 0;
|
||||
IServiceProvider *service_provider = 0;
|
||||
IHttpNegotiate2 *http_negotiate2 = 0;
|
||||
LPWSTR host = 0, path = 0, user = 0, pass = 0, addl_header = 0,
|
||||
post_cookie = 0, optional = 0;
|
||||
BYTE security_id[512];
|
||||
LPOLESTR user_agent, accept_mimes[257];
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR wszHttp[] = {'h','t','t','p',':'};
|
||||
static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
|
||||
{{'G','E','T',0},
|
||||
{'P','O','S','T',0},
|
||||
{'P','U','T',0}};
|
||||
|
||||
TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
pOIBindInfo, grfPI, dwReserved);
|
||||
return E_NOTIMPL;
|
||||
|
||||
memset(&This->bind_info, 0, sizeof(This->bind_info));
|
||||
This->bind_info.cbSize = sizeof(BINDINFO);
|
||||
hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &This->grfBINDF, &This->bind_info);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("GetBindInfo failed: %08x\n", hres);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (lstrlenW(szUrl) < sizeof(wszHttp)/sizeof(WCHAR)
|
||||
|| memcmp(szUrl, wszHttp, sizeof(wszHttp)))
|
||||
{
|
||||
hres = MK_E_SYNTAX;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(&url, 0, sizeof(url));
|
||||
url.dwStructSize = sizeof(url);
|
||||
url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength =
|
||||
url.dwPasswordLength = 1;
|
||||
if (!InternetCrackUrlW(szUrl, 0, 0, &url))
|
||||
{
|
||||
hres = MK_E_SYNTAX;
|
||||
goto done;
|
||||
}
|
||||
host = strndupW(url.lpszHostName, url.dwHostNameLength);
|
||||
path = strndupW(url.lpszUrlPath, url.dwUrlPathLength);
|
||||
user = strndupW(url.lpszUserName, url.dwUserNameLength);
|
||||
pass = strndupW(url.lpszPassword, url.dwPasswordLength);
|
||||
if (!url.nPort)
|
||||
url.nPort = INTERNET_DEFAULT_HTTP_PORT;
|
||||
|
||||
if(!(This->grfBINDF & BINDF_FROMURLMON))
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL);
|
||||
|
||||
hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT, &user_agent,
|
||||
1, &num);
|
||||
if (hres != S_OK || !num)
|
||||
{
|
||||
CHAR null_char = 0;
|
||||
LPSTR user_agenta = NULL;
|
||||
len = 0;
|
||||
if ((hres = ObtainUserAgentString(0, &null_char, &len)) != E_OUTOFMEMORY)
|
||||
{
|
||||
WARN("ObtainUserAgentString failed: %08x\n", hres);
|
||||
}
|
||||
else if (!(user_agenta = HeapAlloc(GetProcessHeap(), 0, len*sizeof(CHAR))))
|
||||
{
|
||||
WARN("Out of memory\n");
|
||||
}
|
||||
else if ((hres = ObtainUserAgentString(0, user_agenta, &len)) != S_OK)
|
||||
{
|
||||
WARN("ObtainUserAgentString failed: %08x\n", hres);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(user_agent = CoTaskMemAlloc((len)*sizeof(WCHAR))))
|
||||
WARN("Out of memory\n");
|
||||
else
|
||||
MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len*sizeof(WCHAR));
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, user_agenta);
|
||||
}
|
||||
|
||||
This->internet = InternetOpenW(user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
|
||||
if (!This->internet)
|
||||
{
|
||||
WARN("InternetOpen failed: %d\n", GetLastError());
|
||||
hres = INET_E_NO_SESSION;
|
||||
goto done;
|
||||
}
|
||||
|
||||
IInternetProtocolSink_AddRef(pOIProtSink);
|
||||
This->protocol_sink = pOIProtSink;
|
||||
|
||||
/* Native does not check for success of next call, so we won't either */
|
||||
InternetSetStatusCallbackW(This->internet, HTTPPROTOCOL_InternetStatusCallback);
|
||||
|
||||
This->connect = InternetConnectW(This->internet, host, url.nPort, user,
|
||||
pass, INTERNET_SERVICE_HTTP, 0, (DWORD)This);
|
||||
if (!This->connect)
|
||||
{
|
||||
WARN("InternetConnect failed: %d\n", GetLastError());
|
||||
hres = INET_E_CANNOT_CONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
|
||||
hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
|
||||
accept_mimes,
|
||||
num, &num);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
|
||||
hres = INET_E_NO_VALID_MEDIA;
|
||||
goto done;
|
||||
}
|
||||
accept_mimes[num] = 0;
|
||||
|
||||
if (This->grfBINDF & BINDF_NOWRITECACHE)
|
||||
request_flags |= INTERNET_FLAG_NO_CACHE_WRITE;
|
||||
This->request = HttpOpenRequestW(This->connect, This->bind_info.dwBindVerb < BINDVERB_CUSTOM ?
|
||||
wszBindVerb[This->bind_info.dwBindVerb] :
|
||||
This->bind_info.szCustomVerb,
|
||||
path, NULL, NULL, (LPCWSTR *)accept_mimes,
|
||||
request_flags, (DWORD)This);
|
||||
if (!This->request)
|
||||
{
|
||||
WARN("HttpOpenRequest failed: %d\n", GetLastError());
|
||||
hres = INET_E_RESOURCE_NOT_FOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider,
|
||||
(void **)&service_provider);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed: %08x\n", hres);
|
||||
goto done;
|
||||
}
|
||||
|
||||
hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
|
||||
&IID_IHttpNegotiate, (void **)&This->http_negotiate);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n", hres);
|
||||
goto done;
|
||||
}
|
||||
|
||||
hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, szUrl, wszHeaders,
|
||||
0, &addl_header);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
|
||||
goto done;
|
||||
}
|
||||
else if (addl_header == NULL)
|
||||
{
|
||||
This->full_header = (LPWSTR)wszHeaders;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len_addl_header = lstrlenW(addl_header);
|
||||
This->full_header = HeapAlloc(GetProcessHeap(), 0,
|
||||
len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));
|
||||
if (!This->full_header)
|
||||
{
|
||||
WARN("Out of memory\n");
|
||||
hres = E_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
lstrcpyW(This->full_header, addl_header);
|
||||
lstrcpyW(&This->full_header[len_addl_header], wszHeaders);
|
||||
}
|
||||
|
||||
hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
|
||||
&IID_IHttpNegotiate2, (void **)&http_negotiate2);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed: %08x\n", hres);
|
||||
/* No goto done as per native */
|
||||
}
|
||||
else
|
||||
{
|
||||
len = sizeof(security_id)/sizeof(security_id[0]);
|
||||
hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len, 0);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
|
||||
/* No goto done as per native */
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Handle security_id. Native calls undocumented function IsHostInProxyBypassList. */
|
||||
|
||||
if (This->bind_info.dwBindVerb == BINDVERB_POST)
|
||||
{
|
||||
num = 0;
|
||||
hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_POST_COOKIE, &post_cookie,
|
||||
1, &num);
|
||||
if (hres == S_OK && num &&
|
||||
!InternetSetOptionW(This->request, INTERNET_OPTION_SECONDARY_CACHE_KEY,
|
||||
post_cookie, lstrlenW(post_cookie)))
|
||||
{
|
||||
WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed: %d\n",
|
||||
GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (This->bind_info.dwBindVerb != BINDVERB_GET)
|
||||
{
|
||||
/* Native does not use GlobalLock/GlobalUnlock, so we won't either */
|
||||
if (This->bind_info.stgmedData.tymed != TYMED_HGLOBAL)
|
||||
WARN("Expected This->bind_info.stgmedData.tymed to be TYMED_HGLOBAL, not %d\n",
|
||||
This->bind_info.stgmedData.tymed);
|
||||
else
|
||||
optional = (LPWSTR)This->bind_info.stgmedData.hGlobal;
|
||||
}
|
||||
if (!HttpSendRequestW(This->request, This->full_header, lstrlenW(This->full_header),
|
||||
optional,
|
||||
optional ? This->bind_info.cbstgmedData : 0) &&
|
||||
GetLastError() != ERROR_IO_PENDING)
|
||||
{
|
||||
WARN("HttpSendRequest failed: %d\n", GetLastError());
|
||||
hres = INET_E_DOWNLOAD_FAILURE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hres = S_OK;
|
||||
done:
|
||||
if (hres != S_OK)
|
||||
{
|
||||
IInternetProtocolSink_ReportResult(pOIProtSink, hres, 0, NULL);
|
||||
HTTPPROTOCOL_Close(This);
|
||||
}
|
||||
|
||||
CoTaskMemFree(post_cookie);
|
||||
CoTaskMemFree(addl_header);
|
||||
if (http_negotiate2)
|
||||
IHttpNegotiate2_Release(http_negotiate2);
|
||||
if (service_provider)
|
||||
IServiceProvider_Release(service_provider);
|
||||
|
||||
while (num<sizeof(accept_mimes)/sizeof(accept_mimes[0]) &&
|
||||
accept_mimes[num])
|
||||
CoTaskMemFree(accept_mimes[num++]);
|
||||
CoTaskMemFree(user_agent);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pass);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
HeapFree(GetProcessHeap(), 0, path);
|
||||
HeapFree(GetProcessHeap(), 0, host);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%p)\n", This, pProtocolData);
|
||||
return E_NOTIMPL;
|
||||
DWORD len = sizeof(DWORD), status_code;
|
||||
LPWSTR response_headers = 0, content_type = 0, content_length = 0;
|
||||
|
||||
static const WCHAR wszDefaultContentType[] =
|
||||
{'t','e','x','t','/','h','t','m','l',0};
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, pProtocolData);
|
||||
|
||||
if (!pProtocolData)
|
||||
{
|
||||
WARN("Expected pProtocolData to be non-NULL\n");
|
||||
return S_OK;
|
||||
}
|
||||
else if (!This->request)
|
||||
{
|
||||
WARN("Expected request to be non-NULL\n");
|
||||
return S_OK;
|
||||
}
|
||||
else if (!This->http_negotiate)
|
||||
{
|
||||
WARN("Expected IHttpNegotiate pointer to be non-NULL\n");
|
||||
return S_OK;
|
||||
}
|
||||
else if (!This->protocol_sink)
|
||||
{
|
||||
WARN("Expected IInternetProtocolSink pointer to be non-NULL\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (pProtocolData->pData == (LPVOID)BINDSTATUS_DOWNLOADINGDATA)
|
||||
{
|
||||
if (!HttpQueryInfoW(This->request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
|
||||
&status_code, &len, NULL))
|
||||
{
|
||||
WARN("HttpQueryInfo failed: %d\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len,
|
||||
NULL) &&
|
||||
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
|
||||
!(response_headers = HeapAlloc(GetProcessHeap(), 0, len)) ||
|
||||
!HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len,
|
||||
NULL))
|
||||
{
|
||||
WARN("HttpQueryInfo failed: %d\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT hres = IHttpNegotiate_OnResponse(This->http_negotiate, status_code,
|
||||
response_headers, NULL, NULL);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
WARN("IHttpNegotiate_OnResponse failed: %08x\n", hres);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len = 0;
|
||||
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL) &&
|
||||
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
|
||||
!(content_type = HeapAlloc(GetProcessHeap(), 0, len)) ||
|
||||
!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL))
|
||||
{
|
||||
WARN("HttpQueryInfo failed: %d\n", GetLastError());
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink,
|
||||
(This->grfBINDF & BINDF_FROMURLMON) ?
|
||||
BINDSTATUS_MIMETYPEAVAILABLE :
|
||||
BINDSTATUS_RAWMIMETYPE,
|
||||
wszDefaultContentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
IInternetProtocolSink_ReportProgress(This->protocol_sink,
|
||||
(This->grfBINDF & BINDF_FROMURLMON) ?
|
||||
BINDSTATUS_MIMETYPEAVAILABLE :
|
||||
BINDSTATUS_RAWMIMETYPE,
|
||||
content_type);
|
||||
}
|
||||
|
||||
len = 0;
|
||||
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL) &&
|
||||
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
|
||||
!(content_length = HeapAlloc(GetProcessHeap(), 0, len)) ||
|
||||
!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL))
|
||||
{
|
||||
WARN("HttpQueryInfo failed: %d\n", GetLastError());
|
||||
This->content_length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
This->content_length = atoiW(content_length);
|
||||
}
|
||||
|
||||
This->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
|
||||
}
|
||||
|
||||
if (pProtocolData->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA)
|
||||
{
|
||||
if (!InternetQueryDataAvailable(This->request, &This->available_bytes, 0, 0))
|
||||
{
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
This->flags &= ~FLAG_REQUEST_COMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
|
||||
HTTPPROTOCOL_ReportResult(This, INET_E_DATA_NOT_AVAILABLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HTTPPROTOCOL_ReportData(This);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
HeapFree(GetProcessHeap(), 0, response_headers);
|
||||
HeapFree(GetProcessHeap(), 0, content_type);
|
||||
HeapFree(GetProcessHeap(), 0, content_length);
|
||||
|
||||
/* Returns S_OK on native */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HttpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
|
||||
DWORD dwOptions)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
|
||||
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HttpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08lx)\n", This, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
HTTPPROTOCOL_Close(This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HttpProtocol_Suspend(IInternetProtocol *iface)
|
||||
@@ -147,30 +723,116 @@ static HRESULT WINAPI HttpProtocol_Read(IInternetProtocol *iface, void *pv,
|
||||
ULONG cb, ULONG *pcbRead)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
|
||||
return E_NOTIMPL;
|
||||
ULONG read = 0, len = 0;
|
||||
HRESULT hres = S_FALSE;
|
||||
|
||||
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
|
||||
|
||||
if (!(This->flags & FLAG_REQUEST_COMPLETE))
|
||||
{
|
||||
hres = E_PENDING;
|
||||
}
|
||||
else while (!(This->flags & FLAG_ALL_DATA_READ) &&
|
||||
read < cb)
|
||||
{
|
||||
if (This->available_bytes == 0)
|
||||
{
|
||||
/* InternetQueryDataAvailable may immediately fork and perform its asynchronous
|
||||
* read, so clear the flag _before_ calling so it does not incorrectly get cleared
|
||||
* after the status callback is called */
|
||||
This->flags &= ~FLAG_REQUEST_COMPLETE;
|
||||
if (!InternetQueryDataAvailable(This->request, &This->available_bytes, 0, 0))
|
||||
{
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
hres = E_PENDING;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
|
||||
hres = INET_E_DATA_NOT_AVAILABLE;
|
||||
HTTPPROTOCOL_ReportResult(This, hres);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
else if (This->available_bytes == 0)
|
||||
{
|
||||
HTTPPROTOCOL_AllDataRead(This);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!InternetReadFile(This->request, ((BYTE *)pv)+read,
|
||||
This->available_bytes > cb-read ?
|
||||
cb-read : This->available_bytes, &len))
|
||||
{
|
||||
WARN("InternetReadFile failed: %d\n", GetLastError());
|
||||
hres = INET_E_DOWNLOAD_FAILURE;
|
||||
HTTPPROTOCOL_ReportResult(This, hres);
|
||||
goto done;
|
||||
}
|
||||
else if (len == 0)
|
||||
{
|
||||
HTTPPROTOCOL_AllDataRead(This);
|
||||
}
|
||||
else
|
||||
{
|
||||
read += len;
|
||||
This->current_position += len;
|
||||
This->available_bytes -= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Per MSDN this should be if (read == cb), but native returns S_OK
|
||||
* if any bytes were read, so we will too */
|
||||
if (read)
|
||||
hres = S_OK;
|
||||
|
||||
done:
|
||||
if (pcbRead)
|
||||
*pcbRead = read;
|
||||
|
||||
if (hres != E_PENDING)
|
||||
This->flags |= FLAG_REQUEST_COMPLETE;
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HttpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrgin, ULARGE_INTEGER *plibNewPosition)
|
||||
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrgin, plibNewPosition);
|
||||
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HttpProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08lx)\n", This, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
if (!InternetLockRequestFile(This->request, &This->lock))
|
||||
WARN("InternetLockRequest failed: %d\n", GetLastError());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HttpProtocol_UnlockRequest(IInternetProtocol *iface)
|
||||
{
|
||||
HttpProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (This->lock)
|
||||
{
|
||||
if (!InternetUnlockRequestFile(This->lock))
|
||||
WARN("InternetUnlockRequest failed: %d\n", GetLastError());
|
||||
This->lock = 0;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#undef PROTOCOL_THIS
|
||||
@@ -199,7 +861,7 @@ static HRESULT WINAPI HttpPriority_SetPriority(IInternetPriority *iface, LONG nP
|
||||
{
|
||||
HttpProtocol *This = PRIORITY_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%ld)\n", This, nPriority);
|
||||
TRACE("(%p)->(%d)\n", This, nPriority);
|
||||
|
||||
This->priority = nPriority;
|
||||
return S_OK;
|
||||
@@ -253,10 +915,16 @@ HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
|
||||
|
||||
ret->lpInternetProtocolVtbl = &HttpProtocolVtbl;
|
||||
ret->lpInternetPriorityVtbl = &HttpPriorityVtbl;
|
||||
|
||||
ret->ref = 1;
|
||||
|
||||
ret->flags = ret->grfBINDF = 0;
|
||||
memset(&ret->bind_info, 0, sizeof(ret->bind_info));
|
||||
ret->protocol_sink = 0;
|
||||
ret->http_negotiate = 0;
|
||||
ret->internet = ret->connect = ret->request = 0;
|
||||
ret->full_header = 0;
|
||||
ret->lock = 0;
|
||||
ret->current_position = ret->content_length = ret->available_bytes = 0;
|
||||
ret->priority = 0;
|
||||
ret->ref = 1;
|
||||
|
||||
*ppobj = PROTOCOL(ret);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -39,7 +39,7 @@ static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size,
|
||||
WCHAR *ptr;
|
||||
DWORD len = 0;
|
||||
|
||||
TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
|
||||
if(flags)
|
||||
ERR("wrong flags\n");
|
||||
@@ -61,20 +61,30 @@ static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IInternetProtocolInfo *get_protocol_info(LPCWSTR url)
|
||||
static HRESULT parse_canonicalize_url(LPCWSTR url, DWORD flags, LPWSTR result,
|
||||
DWORD size, DWORD *rsize)
|
||||
{
|
||||
IInternetProtocolInfo *ret = NULL;
|
||||
IUnknown *unk;
|
||||
IInternetProtocolInfo *protocol_info;
|
||||
DWORD prsize = size;
|
||||
HRESULT hres;
|
||||
|
||||
hres = get_protocol_iface(url, &unk);
|
||||
if(FAILED(hres))
|
||||
return NULL;
|
||||
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
|
||||
IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&ret);
|
||||
IUnknown_Release(unk);
|
||||
protocol_info = get_protocol_info(url);
|
||||
|
||||
return ret;
|
||||
if(protocol_info) {
|
||||
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_CANONICALIZE,
|
||||
flags, result, size, rsize, 0);
|
||||
IInternetProtocolInfo_Release(protocol_info);
|
||||
if(SUCCEEDED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = UrlCanonicalizeW(url, result, &prsize, flags);
|
||||
|
||||
if(rsize)
|
||||
*rsize = prsize;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT parse_security_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
|
||||
@@ -82,13 +92,14 @@ static HRESULT parse_security_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD
|
||||
IInternetProtocolInfo *protocol_info;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
|
||||
protocol_info = get_protocol_info(url);
|
||||
|
||||
if(protocol_info) {
|
||||
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL,
|
||||
flags, result, size, rsize, 0);
|
||||
IInternetProtocolInfo_Release(protocol_info);
|
||||
return hres;
|
||||
}
|
||||
|
||||
@@ -101,13 +112,14 @@ static HRESULT parse_encode(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size,
|
||||
DWORD prsize;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
|
||||
protocol_info = get_protocol_info(url);
|
||||
|
||||
if(protocol_info) {
|
||||
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ENCODE,
|
||||
flags, result, size, rsize, 0);
|
||||
IInternetProtocolInfo_Release(protocol_info);
|
||||
if(SUCCEEDED(hres))
|
||||
return hres;
|
||||
}
|
||||
@@ -127,13 +139,14 @@ static HRESULT parse_path_from_url(LPCWSTR url, DWORD flags, LPWSTR result, DWOR
|
||||
DWORD prsize;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
|
||||
protocol_info = get_protocol_info(url);
|
||||
|
||||
if(protocol_info) {
|
||||
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_PATH_FROM_URL,
|
||||
flags, result, size, rsize, 0);
|
||||
IInternetProtocolInfo_Release(protocol_info);
|
||||
if(SUCCEEDED(hres))
|
||||
return hres;
|
||||
}
|
||||
@@ -152,13 +165,14 @@ static HRESULT parse_security_domain(LPCWSTR url, DWORD flags, LPWSTR result,
|
||||
IInternetProtocolInfo *protocol_info;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s %08lx %p %ld %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
|
||||
|
||||
protocol_info = get_protocol_info(url);
|
||||
|
||||
if(protocol_info) {
|
||||
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN,
|
||||
flags, result, size, rsize, 0);
|
||||
IInternetProtocolInfo_Release(protocol_info);
|
||||
if(SUCCEEDED(hres))
|
||||
return hres;
|
||||
}
|
||||
@@ -173,9 +187,11 @@ HRESULT WINAPI CoInternetParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD
|
||||
LPWSTR pszResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
|
||||
{
|
||||
if(dwReserved)
|
||||
WARN("dwReserved = %ld\n", dwReserved);
|
||||
WARN("dwReserved = %d\n", dwReserved);
|
||||
|
||||
switch(ParseAction) {
|
||||
case PARSE_CANONICALIZE:
|
||||
return parse_canonicalize_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
|
||||
case PARSE_SECURITY_URL:
|
||||
return parse_security_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
|
||||
case PARSE_ENCODE:
|
||||
@@ -204,7 +220,7 @@ HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
|
||||
DWORD size = cchResult;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s,%s,0x%08lx,%p,%ld,%p,%ld)\n", debugstr_w(pwzBaseUrl),
|
||||
TRACE("(%s,%s,0x%08x,%p,%d,%p,%d)\n", debugstr_w(pwzBaseUrl),
|
||||
debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult, pcchResult,
|
||||
dwReserved);
|
||||
|
||||
@@ -213,6 +229,7 @@ HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
|
||||
if(protocol_info) {
|
||||
hres = IInternetProtocolInfo_CombineUrl(protocol_info, pwzBaseUrl, pwzRelativeUrl,
|
||||
dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
|
||||
IInternetProtocolInfo_Release(protocol_info);
|
||||
if(SUCCEEDED(hres))
|
||||
return hres;
|
||||
}
|
||||
@@ -225,3 +242,25 @@ HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CoInternetCompareUrl (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
|
||||
{
|
||||
IInternetProtocolInfo *protocol_info;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s,%s,%08x)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
|
||||
|
||||
protocol_info = get_protocol_info(pwzUrl1);
|
||||
|
||||
if(protocol_info) {
|
||||
hres = IInternetProtocolInfo_CompareUrl(protocol_info, pwzUrl1, pwzUrl2, dwCompareFlags);
|
||||
IInternetProtocolInfo_Release(protocol_info);
|
||||
if(SUCCEEDED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags) ? S_FALSE : S_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright 2007 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
#include "urlmon.h"
|
||||
#include "urlmon_main.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
typedef struct {
|
||||
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
|
||||
|
||||
LONG ref;
|
||||
|
||||
IStream *stream;
|
||||
} MkProtocol;
|
||||
|
||||
#define PROTOCOL_THIS(iface) DEFINE_THIS(MkProtocol, InternetProtocol, iface)
|
||||
|
||||
#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
|
||||
|
||||
static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
*ppv = NULL;
|
||||
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("not supported interface %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI MkProtocol_AddRef(IInternetProtocol *iface)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI MkProtocol_Release(IInternetProtocol *iface)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->stream)
|
||||
IStream_Release(This->stream);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
URLMON_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres, DWORD dwError)
|
||||
{
|
||||
IInternetProtocolSink_ReportResult(sink, hres, dwError, NULL);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
|
||||
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
|
||||
DWORD grfPI, DWORD dwReserved)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
IParseDisplayName *pdn;
|
||||
IMoniker *mon;
|
||||
LPWSTR mime, progid, display_name;
|
||||
LPCWSTR ptr, ptr2;
|
||||
BINDINFO bindinfo;
|
||||
STATSTG statstg;
|
||||
DWORD bindf=0, eaten=0, len;
|
||||
CLSID clsid;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR wszMK[] = {'m','k',':'};
|
||||
|
||||
TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
pOIBindInfo, grfPI, dwReserved);
|
||||
|
||||
memset(&bindinfo, 0, sizeof(bindinfo));
|
||||
bindinfo.cbSize = sizeof(BINDINFO);
|
||||
hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetBindInfo failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
ReleaseBindInfo(&bindinfo);
|
||||
|
||||
if(strncmpiW(szUrl, wszMK, sizeof(wszMK)/sizeof(WCHAR)))
|
||||
return MK_E_SYNTAX;
|
||||
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL);
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL);
|
||||
|
||||
hres = FindMimeFromData(NULL, szUrl, NULL, 0, NULL, 0, &mime, 0);
|
||||
if(SUCCEEDED(hres)) {
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
|
||||
CoTaskMemFree(mime);
|
||||
}
|
||||
|
||||
ptr2 = szUrl + sizeof(wszMK)/sizeof(WCHAR);
|
||||
if(*ptr2 != '@')
|
||||
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
|
||||
ptr2++;
|
||||
|
||||
ptr = strchrW(ptr2, ':');
|
||||
if(!ptr)
|
||||
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
|
||||
|
||||
progid = HeapAlloc(GetProcessHeap(), 0, (ptr-ptr2+1)*sizeof(WCHAR));
|
||||
memcpy(progid, ptr2, (ptr-ptr2)*sizeof(WCHAR));
|
||||
progid[ptr-ptr2] = 0;
|
||||
hres = CLSIDFromProgID(progid, &clsid);
|
||||
HeapFree(GetProcessHeap(), 0, progid);
|
||||
if(FAILED(hres))
|
||||
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
|
||||
|
||||
hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
|
||||
&IID_IParseDisplayName, (void**)&pdn);
|
||||
if(FAILED(hres)) {
|
||||
WARN("Could not create object %s\n", debugstr_guid(&clsid));
|
||||
return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
len = strlenW(--ptr2);
|
||||
display_name = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
|
||||
memcpy(display_name, ptr2, (len+1)*sizeof(WCHAR));
|
||||
hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon);
|
||||
HeapFree(GetProcessHeap(), 0, display_name);
|
||||
IParseDisplayName_Release(pdn);
|
||||
if(FAILED(hres)) {
|
||||
WARN("ParseDisplayName failed: %08x\n", hres);
|
||||
return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
if(This->stream) {
|
||||
IStream_Release(This->stream);
|
||||
This->stream = NULL;
|
||||
}
|
||||
|
||||
hres = IMoniker_BindToStorage(mon, NULL /* FIXME */, NULL, &IID_IStream, (void**)&This->stream);
|
||||
IMoniker_Release(mon);
|
||||
if(FAILED(hres)) {
|
||||
WARN("BindToStorage failed: %08x\n", hres);
|
||||
return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
hres = IStream_Stat(This->stream, &statstg, STATFLAG_NONAME);
|
||||
if(FAILED(hres)) {
|
||||
WARN("Stat failed: %08x\n", hres);
|
||||
return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
IInternetProtocolSink_ReportData(pOIProtSink,
|
||||
BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION,
|
||||
statstg.cbSize.u.LowPart, statstg.cbSize.u.LowPart);
|
||||
|
||||
return report_result(pOIProtSink, S_OK, ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%p)\n", This, pProtocolData);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
|
||||
DWORD dwOptions)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Suspend(IInternetProtocol *iface)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Resume(IInternetProtocol *iface)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Read(IInternetProtocol *iface, void *pv,
|
||||
ULONG cb, ULONG *pcbRead)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
|
||||
|
||||
if(!This->stream)
|
||||
return E_FAIL;
|
||||
|
||||
return IStream_Read(This->stream, pv, cb, pcbRead);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MkProtocol_UnlockRequest(IInternetProtocol *iface)
|
||||
{
|
||||
MkProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#undef PROTOCOL_THIS
|
||||
|
||||
static const IInternetProtocolVtbl MkProtocolVtbl = {
|
||||
MkProtocol_QueryInterface,
|
||||
MkProtocol_AddRef,
|
||||
MkProtocol_Release,
|
||||
MkProtocol_Start,
|
||||
MkProtocol_Continue,
|
||||
MkProtocol_Abort,
|
||||
MkProtocol_Terminate,
|
||||
MkProtocol_Suspend,
|
||||
MkProtocol_Resume,
|
||||
MkProtocol_Read,
|
||||
MkProtocol_Seek,
|
||||
MkProtocol_LockRequest,
|
||||
MkProtocol_UnlockRequest
|
||||
};
|
||||
|
||||
HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
|
||||
{
|
||||
MkProtocol *ret;
|
||||
|
||||
TRACE("(%p %p)\n", pUnkOuter, ppobj);
|
||||
|
||||
URLMON_LockModule();
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(MkProtocol));
|
||||
|
||||
ret->lpInternetProtocolVtbl = &MkProtocolVtbl;
|
||||
ret->ref = 1;
|
||||
ret->stream = NULL;
|
||||
|
||||
/* NOTE:
|
||||
* Native returns NULL ppobj and S_OK in CreateInstance if called with IID_IUnknown riid.
|
||||
*/
|
||||
*ppobj = PROTOCOL(ret);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -15,10 +15,9 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -155,7 +154,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
|
||||
}
|
||||
|
||||
if (list->base_iid) {
|
||||
register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
|
||||
res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
@@ -177,12 +176,12 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
|
||||
}
|
||||
|
||||
if (list->ps_clsid) {
|
||||
register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
|
||||
res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->ps_clsid32) {
|
||||
register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
|
||||
res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
@@ -557,6 +556,18 @@ static struct regsvr_coclass const coclass_list[] = {
|
||||
"urlmon.dll",
|
||||
"Apartment"
|
||||
},
|
||||
{ &CLSID_InternetSecurityManager,
|
||||
"Security Manager",
|
||||
NULL,
|
||||
"urlmon.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_InternetZoneManager,
|
||||
"URL Zone Manager",
|
||||
NULL,
|
||||
"urlmon.dll",
|
||||
"Both"
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
@@ -572,9 +583,14 @@ static struct regsvr_interface const interface_list[] = {
|
||||
* register_inf
|
||||
*/
|
||||
|
||||
#define INF_SET_CLSID(clsid) \
|
||||
pse[i].pszName = "CLSID_" #clsid; \
|
||||
clsids[i++] = &CLSID_ ## clsid;
|
||||
#define INF_SET_CLSID(clsid) \
|
||||
do \
|
||||
{ \
|
||||
static CHAR name[] = "CLSID_" #clsid; \
|
||||
\
|
||||
pse[i].pszName = name; \
|
||||
clsids[i++] = &CLSID_ ## clsid; \
|
||||
} while (0)
|
||||
|
||||
static HRESULT register_inf(BOOL doregister)
|
||||
{
|
||||
@@ -587,7 +603,7 @@ static HRESULT register_inf(BOOL doregister)
|
||||
int i = 0;
|
||||
|
||||
static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
|
||||
|
||||
|
||||
INF_SET_CLSID(CdlProtocol);
|
||||
INF_SET_CLSID(FileProtocol);
|
||||
INF_SET_CLSID(FtpProtocol);
|
||||
@@ -598,7 +614,7 @@ static HRESULT register_inf(BOOL doregister)
|
||||
|
||||
for(i = 0; i < sizeof(pse)/sizeof(pse[0]); i++) {
|
||||
pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, 39);
|
||||
sprintf(pse[i].pszValue, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||
sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||
clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0],
|
||||
clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4],
|
||||
clsids[i]->Data4[5], clsids[i]->Data4[6], clsids[i]->Data4[7]);
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* @makedep: urlmon.inf */
|
||||
REGINST REGINST urlmon.inf
|
||||
|
||||
#include "version.rc"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -68,6 +68,8 @@ static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone)
|
||||
'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0};
|
||||
static const WCHAR wszFile[] = {'f','i','l','e',0};
|
||||
|
||||
*zone = -1;
|
||||
|
||||
hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
@@ -97,6 +99,7 @@ static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone)
|
||||
|
||||
size = sizeof(DWORD);
|
||||
res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
|
||||
RegCloseKey(hkey);
|
||||
if(res == ERROR_SUCCESS)
|
||||
return S_OK;
|
||||
|
||||
@@ -108,6 +111,7 @@ static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone)
|
||||
|
||||
size = sizeof(DWORD);
|
||||
res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
|
||||
RegCloseKey(hkey);
|
||||
if(res == ERROR_SUCCESS)
|
||||
return S_OK;
|
||||
|
||||
@@ -150,7 +154,7 @@ static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManager* iface)
|
||||
SecManagerImpl *This = SECMGR_THIS(iface);
|
||||
ULONG refCount = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%lu\n", This, refCount);
|
||||
TRACE("(%p) ref=%u\n", This, refCount);
|
||||
|
||||
return refCount;
|
||||
}
|
||||
@@ -160,7 +164,7 @@ static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface)
|
||||
SecManagerImpl *This = SECMGR_THIS(iface);
|
||||
ULONG refCount = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%lu\n", This, refCount);
|
||||
TRACE("(%p) ref=%u\n", This, refCount);
|
||||
|
||||
/* destroy the object if there's no more reference on it */
|
||||
if (!refCount){
|
||||
@@ -238,7 +242,7 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac
|
||||
DWORD size;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %p %08lx)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags);
|
||||
TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags);
|
||||
|
||||
if(This->custom_manager) {
|
||||
hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager,
|
||||
@@ -251,7 +255,7 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(dwFlags)
|
||||
FIXME("not supported flags: %08lx\n", dwFlags);
|
||||
FIXME("not supported flags: %08x\n", dwFlags);
|
||||
|
||||
size = (strlenW(pwszUrl)+16) * sizeof(WCHAR);
|
||||
url = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
@@ -358,7 +362,7 @@ static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManager *
|
||||
SecManagerImpl *This = SECMGR_THIS(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %08lx %p %08lx %p %08lx %08lx %08lx)\n", iface, debugstr_w(pwszUrl), dwAction,
|
||||
TRACE("(%p)->(%s %08x %p %08x %p %08x %08x %08x)\n", iface, debugstr_w(pwszUrl), dwAction,
|
||||
pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);
|
||||
|
||||
if(This->custom_manager) {
|
||||
@@ -382,7 +386,7 @@ static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager
|
||||
SecManagerImpl *This = SECMGR_THIS(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%s %s %p %p %p %08lx %08lx )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey),
|
||||
TRACE("(%p)->(%s %s %p %p %p %08x %08x )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey),
|
||||
ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
|
||||
|
||||
if(This->custom_manager) {
|
||||
@@ -402,7 +406,7 @@ static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManager *if
|
||||
SecManagerImpl *This = SECMGR_THIS(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%08lx %s %08lx)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags);
|
||||
TRACE("(%p)->(%08x %s %08x)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags);
|
||||
|
||||
if(This->custom_manager) {
|
||||
hres = IInternetSecurityManager_SetZoneMapping(This->custom_manager, dwZone,
|
||||
@@ -421,7 +425,7 @@ static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManager *i
|
||||
SecManagerImpl *This = SECMGR_THIS(iface);
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%08lx %p %08lx)\n", iface, dwZone, ppenumString,dwFlags);
|
||||
TRACE("(%p)->(%08x %p %08x)\n", iface, dwZone, ppenumString,dwFlags);
|
||||
|
||||
if(This->custom_manager) {
|
||||
hres = IInternetSecurityManager_GetZoneMappings(This->custom_manager, dwZone,
|
||||
@@ -551,7 +555,7 @@ static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManager* iface)
|
||||
ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
|
||||
ULONG refCount = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(ref before=%lu)\n",This, refCount - 1);
|
||||
TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
|
||||
|
||||
return refCount;
|
||||
}
|
||||
@@ -564,7 +568,7 @@ static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManager* iface)
|
||||
ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
|
||||
ULONG refCount = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(ref before=%lu)\n",This, refCount + 1);
|
||||
TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
|
||||
|
||||
if(!refCount) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
@@ -581,7 +585,7 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManager* iface,
|
||||
DWORD dwZone,
|
||||
ZONEATTRIBUTES* pZoneAttributes)
|
||||
{
|
||||
FIXME("(%p)->(%ld %p) stub\n", iface, dwZone, pZoneAttributes);
|
||||
FIXME("(%p)->(%d %p) stub\n", iface, dwZone, pZoneAttributes);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -592,7 +596,7 @@ static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManager* iface,
|
||||
DWORD dwZone,
|
||||
ZONEATTRIBUTES* pZoneAttributes)
|
||||
{
|
||||
FIXME("(%p)->(%08lx %p) stub\n", iface, dwZone, pZoneAttributes);
|
||||
FIXME("(%p)->(%08x %p) stub\n", iface, dwZone, pZoneAttributes);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -606,7 +610,7 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManager* ifac
|
||||
DWORD* pcbPolicy,
|
||||
URLZONEREG ulrZoneReg)
|
||||
{
|
||||
FIXME("(%p)->(%08lx %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
|
||||
FIXME("(%p)->(%08x %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
|
||||
ppPolicy, pcbPolicy, ulrZoneReg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -621,7 +625,7 @@ static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManager* ifac
|
||||
DWORD cbPolicy,
|
||||
URLZONEREG ulrZoneReg)
|
||||
{
|
||||
FIXME("(%p)->(%08lx %s %p %08lx %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
|
||||
FIXME("(%p)->(%08x %s %p %08x %08x) stub\n", iface, dwZone, debugstr_guid(guidKey),
|
||||
ppPolicy, cbPolicy, ulrZoneReg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -640,7 +644,7 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManager* ifac
|
||||
|
||||
static const WCHAR wszFormat[] = {'%','l','X',0};
|
||||
|
||||
TRACE("(%p)->(%ld %08lx %p %ld %d)\n", iface, dwZone, dwAction, pPolicy,
|
||||
TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy,
|
||||
cbPolicy, urlZoneReg);
|
||||
|
||||
if(!pPolicy)
|
||||
@@ -658,7 +662,7 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManager* ifac
|
||||
}else if(res == ERROR_FILE_NOT_FOUND) {
|
||||
hres = E_FAIL;
|
||||
}else if(res != ERROR_SUCCESS) {
|
||||
ERR("RegQueryValue failed: %ld\n", res);
|
||||
ERR("RegQueryValue failed: %d\n", res);
|
||||
hres = E_UNEXPECTED;
|
||||
}
|
||||
|
||||
@@ -677,7 +681,7 @@ static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManager* ifac
|
||||
DWORD cbPolicy,
|
||||
URLZONEREG urlZoneReg)
|
||||
{
|
||||
FIXME("(%p)->(%08lx %08lx %p %08lx %08x) stub\n", iface, dwZone, dwAction, pPolicy,
|
||||
FIXME("(%p)->(%08x %08x %p %08x %08x) stub\n", iface, dwZone, dwAction, pPolicy,
|
||||
cbPolicy, urlZoneReg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -692,7 +696,7 @@ static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManager* iface,
|
||||
LPCWSTR pwszText,
|
||||
DWORD dwPromptFlags)
|
||||
{
|
||||
FIXME("%p %08lx %p %s %s %08lx\n", iface, dwAction, hwndParent,
|
||||
FIXME("%p %08x %p %s %s %08x\n", iface, dwAction, hwndParent,
|
||||
debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -706,7 +710,7 @@ static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManager* iface,
|
||||
LPCWSTR pwszText,
|
||||
DWORD dwLogFlags)
|
||||
{
|
||||
FIXME("(%p)->(%08lx %s %s %08lx) stub\n", iface, dwAction, debugstr_w(pwszUrl),
|
||||
FIXME("(%p)->(%08x %s %s %08x) stub\n", iface, dwAction, debugstr_w(pwszUrl),
|
||||
debugstr_w(pwszText), dwLogFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -719,7 +723,7 @@ static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManager* ifa
|
||||
DWORD* pdwCount,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
FIXME("(%p)->(%p %p %08lx) stub\n", iface, pdwEnum, pdwCount, dwFlags);
|
||||
FIXME("(%p)->(%p %p %08x) stub\n", iface, pdwEnum, pdwCount, dwFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -731,7 +735,7 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManager* iface,
|
||||
DWORD dwIndex,
|
||||
DWORD* pdwZone)
|
||||
{
|
||||
FIXME("(%p)->(%08lx %08lx %p) stub\n", iface, dwEnum, dwIndex, pdwZone);
|
||||
FIXME("(%p)->(%08x %08x %p) stub\n", iface, dwEnum, dwIndex, pdwZone);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -741,7 +745,7 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManager* iface,
|
||||
static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManager* iface,
|
||||
DWORD dwEnum)
|
||||
{
|
||||
FIXME("(%p)->(%08lx) stub\n", iface, dwEnum);
|
||||
FIXME("(%p)->(%08x) stub\n", iface, dwEnum);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -753,7 +757,7 @@ static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManage
|
||||
DWORD dwZone,
|
||||
DWORD dwReserved)
|
||||
{
|
||||
FIXME("(%p)->(%08lx %08lx %08lx) stub\n", iface, dwTemplate, dwZone, dwReserved);
|
||||
FIXME("(%p)->(%08x %08x %08x) stub\n", iface, dwTemplate, dwZone, dwReserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -799,7 +803,7 @@ HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
|
||||
HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP,
|
||||
IInternetSecurityManager **ppSM, DWORD dwReserved )
|
||||
{
|
||||
TRACE("%p %p %ld\n", pSP, ppSM, dwReserved );
|
||||
TRACE("%p %p %d\n", pSP, ppSM, dwReserved );
|
||||
|
||||
if(pSP)
|
||||
FIXME("pSP not supported\n");
|
||||
@@ -812,6 +816,6 @@ HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP,
|
||||
*/
|
||||
HRESULT WINAPI CoInternetCreateZoneManager(IServiceProvider* pSP, IInternetZoneManager** ppZM, DWORD dwReserved)
|
||||
{
|
||||
TRACE("(%p %p %lx)\n", pSP, ppZM, dwReserved);
|
||||
TRACE("(%p %p %x)\n", pSP, ppZM, dwReserved);
|
||||
return ZoneMgrImpl_Construct(NULL, (void**)ppZM);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005 Jacek Caban
|
||||
* Copyright 2005-2006 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -29,14 +29,37 @@
|
||||
#include "urlmon_main.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret)
|
||||
typedef struct name_space {
|
||||
LPWSTR protocol;
|
||||
IClassFactory *cf;
|
||||
CLSID clsid;
|
||||
|
||||
struct name_space *next;
|
||||
} name_space;
|
||||
|
||||
static name_space *name_space_list = NULL;
|
||||
|
||||
static name_space *find_name_space(LPCWSTR protocol)
|
||||
{
|
||||
WCHAR schema[64], str_clsid[64];
|
||||
name_space *iter;
|
||||
|
||||
for(iter = name_space_list; iter; iter = iter->next) {
|
||||
if(!strcmpW(iter->protocol, protocol))
|
||||
return iter;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid, IClassFactory **ret)
|
||||
{
|
||||
WCHAR str_clsid[64];
|
||||
HKEY hkey = NULL;
|
||||
DWORD res, type, size, schema_len;
|
||||
DWORD res, type, size;
|
||||
CLSID clsid;
|
||||
LPWSTR wszKey;
|
||||
HRESULT hres;
|
||||
@@ -45,11 +68,6 @@ HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret)
|
||||
{'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'};
|
||||
static const WCHAR wszCLSID[] = {'C','L','S','I','D',0};
|
||||
|
||||
hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
|
||||
&schema_len, 0);
|
||||
if(FAILED(hres) || !schema_len)
|
||||
return E_FAIL;
|
||||
|
||||
wszKey = HeapAlloc(GetProcessHeap(), 0, sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR));
|
||||
memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey));
|
||||
memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR));
|
||||
@@ -57,7 +75,7 @@ HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret)
|
||||
res = RegOpenKeyW(HKEY_CLASSES_ROOT, wszKey, &hkey);
|
||||
HeapFree(GetProcessHeap(), 0, wszKey);
|
||||
if(res != ERROR_SUCCESS) {
|
||||
TRACE("Could not open key %s\n", debugstr_w(wszKey));
|
||||
TRACE("Could not open protocol handler key\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@@ -65,17 +83,81 @@ HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret)
|
||||
res = RegQueryValueExW(hkey, wszCLSID, NULL, &type, (LPBYTE)str_clsid, &size);
|
||||
RegCloseKey(hkey);
|
||||
if(res != ERROR_SUCCESS || type != REG_SZ) {
|
||||
WARN("Could not get protocol CLSID res=%ld\n", res);
|
||||
WARN("Could not get protocol CLSID res=%d\n", res);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hres = CLSIDFromString(str_clsid, &clsid);
|
||||
if(FAILED(hres)) {
|
||||
WARN("CLSIDFromString failed: %08lx\n", hres);
|
||||
WARN("CLSIDFromString failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)ret);
|
||||
if(pclsid)
|
||||
*pclsid = clsid;
|
||||
|
||||
return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)ret);
|
||||
}
|
||||
|
||||
IInternetProtocolInfo *get_protocol_info(LPCWSTR url)
|
||||
{
|
||||
IInternetProtocolInfo *ret = NULL;
|
||||
IClassFactory *cf;
|
||||
name_space *ns;
|
||||
WCHAR schema[64];
|
||||
DWORD schema_len;
|
||||
HRESULT hres;
|
||||
|
||||
hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
|
||||
&schema_len, 0);
|
||||
if(FAILED(hres) || !schema_len)
|
||||
return NULL;
|
||||
|
||||
ns = find_name_space(schema);
|
||||
if(ns) {
|
||||
hres = IClassFactory_QueryInterface(ns->cf, &IID_IInternetProtocolInfo, (void**)&ret);
|
||||
if(SUCCEEDED(hres))
|
||||
return ret;
|
||||
|
||||
hres = IClassFactory_CreateInstance(ns->cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret);
|
||||
if(SUCCEEDED(hres))
|
||||
return ret;
|
||||
}
|
||||
|
||||
hres = get_protocol_cf(schema, schema_len, NULL, &cf);
|
||||
if(FAILED(hres))
|
||||
return NULL;
|
||||
|
||||
hres = IClassFactory_QueryInterface(cf, &IID_IInternetProtocolInfo, (void**)&ret);
|
||||
if(FAILED(hres))
|
||||
IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret);
|
||||
IClassFactory_Release(cf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret)
|
||||
{
|
||||
name_space *ns;
|
||||
WCHAR schema[64];
|
||||
DWORD schema_len;
|
||||
HRESULT hres;
|
||||
|
||||
hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
|
||||
&schema_len, 0);
|
||||
if(FAILED(hres) || !schema_len)
|
||||
return schema_len ? hres : E_FAIL;
|
||||
|
||||
ns = find_name_space(schema);
|
||||
if(ns) {
|
||||
*ret = ns->cf;
|
||||
IClassFactory_AddRef(*ret);
|
||||
if(clsid)
|
||||
*clsid = ns->clsid;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return get_protocol_cf(schema, schema_len, clsid, ret);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetSession_QueryInterface(IInternetSession *iface,
|
||||
@@ -111,16 +193,64 @@ static HRESULT WINAPI InternetSession_RegisterNameSpace(IInternetSession *iface,
|
||||
IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzProtocol, ULONG cPatterns,
|
||||
const LPCWSTR *ppwzPatterns, DWORD dwReserved)
|
||||
{
|
||||
FIXME("(%p %s %s %ld %p %ld)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzProtocol),
|
||||
cPatterns, ppwzPatterns, dwReserved);
|
||||
return E_NOTIMPL;
|
||||
name_space *new_name_space;
|
||||
int size;
|
||||
|
||||
TRACE("(%p %s %s %d %p %d)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzProtocol),
|
||||
cPatterns, ppwzPatterns, dwReserved);
|
||||
|
||||
if(cPatterns || ppwzPatterns)
|
||||
FIXME("patterns not supported\n");
|
||||
if(dwReserved)
|
||||
WARN("dwReserved = %d\n", dwReserved);
|
||||
|
||||
if(!pCF || !pwzProtocol)
|
||||
return E_INVALIDARG;
|
||||
|
||||
new_name_space = HeapAlloc(GetProcessHeap(), 0, sizeof(name_space));
|
||||
|
||||
size = (strlenW(pwzProtocol)+1)*sizeof(WCHAR);
|
||||
new_name_space->protocol = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
memcpy(new_name_space->protocol, pwzProtocol, size);
|
||||
|
||||
IClassFactory_AddRef(pCF);
|
||||
new_name_space->cf = pCF;
|
||||
new_name_space->clsid = *rclsid;
|
||||
|
||||
new_name_space->next = name_space_list;
|
||||
name_space_list = new_name_space;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetSession_UnregisterNameSpace(IInternetSession *iface,
|
||||
IClassFactory *pCF, LPCWSTR pszProtocol)
|
||||
{
|
||||
FIXME("(%p %s)\n", pCF, debugstr_w(pszProtocol));
|
||||
return E_NOTIMPL;
|
||||
name_space *iter, *last = NULL;
|
||||
|
||||
TRACE("(%p %s)\n", pCF, debugstr_w(pszProtocol));
|
||||
|
||||
if(!pCF || !pszProtocol)
|
||||
return E_INVALIDARG;
|
||||
|
||||
for(iter = name_space_list; iter; iter = iter->next) {
|
||||
if(iter->cf == pCF && !strcmpW(iter->protocol, pszProtocol))
|
||||
break;
|
||||
last = iter;
|
||||
}
|
||||
|
||||
if(!iter)
|
||||
return S_OK;
|
||||
|
||||
if(last)
|
||||
last->next = iter->next;
|
||||
else
|
||||
name_space_list = iter->next;
|
||||
|
||||
IClassFactory_Release(iter->cf);
|
||||
HeapFree(GetProcessHeap(), 0, iter->protocol);
|
||||
HeapFree(GetProcessHeap(), 0, iter);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface,
|
||||
@@ -141,15 +271,19 @@ static HRESULT WINAPI InternetSession_CreateBinding(IInternetSession *iface,
|
||||
LPBC pBC, LPCWSTR szUrl, IUnknown *pUnkOuter, IUnknown **ppUnk,
|
||||
IInternetProtocol **ppOInetProt, DWORD dwOption)
|
||||
{
|
||||
FIXME("(%p %s %p %p %p %08lx)\n", pBC, debugstr_w(szUrl), pUnkOuter, ppUnk,
|
||||
TRACE("(%p %s %p %p %p %08x)\n", pBC, debugstr_w(szUrl), pUnkOuter, ppUnk,
|
||||
ppOInetProt, dwOption);
|
||||
return E_NOTIMPL;
|
||||
|
||||
if(pBC || pUnkOuter || ppUnk || dwOption)
|
||||
FIXME("Unsupported arguments\n");
|
||||
|
||||
return create_binding_protocol(szUrl, ppOInetProt);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InternetSession_SetSessionOption(IInternetSession *iface,
|
||||
DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength, DWORD dwReserved)
|
||||
{
|
||||
FIXME("(%08lx %p %ld %ld)\n", dwOption, pBuffer, dwBufferLength, dwReserved);
|
||||
FIXME("(%08x %p %d %d)\n", dwOption, pBuffer, dwBufferLength, dwReserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -186,13 +320,69 @@ static IInternetSession InternetSession = { &InternetSessionVtbl };
|
||||
HRESULT WINAPI CoInternetGetSession(DWORD dwSessionMode, IInternetSession **ppIInternetSession,
|
||||
DWORD dwReserved)
|
||||
{
|
||||
TRACE("(%ld %p %ld)\n", dwSessionMode, ppIInternetSession, dwReserved);
|
||||
TRACE("(%d %p %d)\n", dwSessionMode, ppIInternetSession, dwReserved);
|
||||
|
||||
if(dwSessionMode)
|
||||
ERR("dwSessionMode=%ld\n", dwSessionMode);
|
||||
ERR("dwSessionMode=%d\n", dwSessionMode);
|
||||
if(dwReserved)
|
||||
ERR("dwReserved=%ld\n", dwReserved);
|
||||
ERR("dwReserved=%d\n", dwReserved);
|
||||
|
||||
IInternetSession_AddRef(&InternetSession);
|
||||
*ppIInternetSession = &InternetSession;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* UrlMkGetSessionOption (URLMON.@)
|
||||
*/
|
||||
static BOOL get_url_encoding(HKEY root, DWORD *encoding)
|
||||
{
|
||||
DWORD size = sizeof(DWORD), res, type;
|
||||
HKEY hkey;
|
||||
|
||||
static const WCHAR wszKeyName[] =
|
||||
{'S','O','F','T','W','A','R','E',
|
||||
'\\','M','i','c','r','o','s','o','f','t',
|
||||
'\\','W','i','n','d','o','w','s',
|
||||
'\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',
|
||||
'\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0};
|
||||
static const WCHAR wszUrlEncoding[] = {'U','r','l','E','n','c','o','d','i','n','g',0};
|
||||
|
||||
res = RegOpenKeyW(root, wszKeyName, &hkey);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
res = RegQueryValueExW(hkey, wszUrlEncoding, NULL, &type, (LPBYTE)encoding, &size);
|
||||
RegCloseKey(hkey);
|
||||
|
||||
return res == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
HRESULT WINAPI UrlMkGetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
|
||||
DWORD* pdwBufferLength, DWORD dwReserved)
|
||||
{
|
||||
TRACE("(%x, %p, %d, %p)\n", dwOption, pBuffer, dwBufferLength, pdwBufferLength);
|
||||
|
||||
if(dwReserved)
|
||||
WARN("dwReserved = %d\n", dwReserved);
|
||||
|
||||
switch(dwOption) {
|
||||
case URLMON_OPTION_URL_ENCODING: {
|
||||
DWORD encoding = 0;
|
||||
|
||||
if(!pBuffer || dwBufferLength < sizeof(DWORD) || !pdwBufferLength)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(!get_url_encoding(HKEY_CURRENT_USER, &encoding))
|
||||
get_url_encoding(HKEY_LOCAL_MACHINE, &encoding);
|
||||
|
||||
*pdwBufferLength = sizeof(DWORD);
|
||||
*(DWORD*)pBuffer = encoding ? URL_ENCODING_DISABLE_UTF8 : URL_ENCODING_ENABLE_UTF8;
|
||||
return S_OK;
|
||||
}
|
||||
default:
|
||||
FIXME("unsupported option %x\n", dwOption);
|
||||
}
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
+127
-94
@@ -17,10 +17,9 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -45,7 +44,7 @@
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
/* native urlmon.dll uses this key, too */
|
||||
static const WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
|
||||
static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
|
||||
|
||||
/*static BOOL registered_wndclass = FALSE;*/
|
||||
|
||||
@@ -89,7 +88,7 @@ static ULONG WINAPI Binding_AddRef(IBinding* iface)
|
||||
Binding *This = (Binding*)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
@@ -99,7 +98,7 @@ static ULONG WINAPI Binding_Release(IBinding* iface)
|
||||
Binding *This = (Binding*)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n",This, ref);
|
||||
TRACE("(%p) ref=%d\n",This, ref);
|
||||
|
||||
if(!ref) {
|
||||
HeapFree(GetProcessHeap(), 0, This->URLName);
|
||||
@@ -161,7 +160,7 @@ static HRESULT WINAPI Binding_SetPriority(IBinding* iface, LONG nPriority)
|
||||
{
|
||||
Binding *This = (Binding*)iface;
|
||||
|
||||
FIXME("(%p)->(%ld): stub\n", This, nPriority);
|
||||
FIXME("(%p)->(%d): stub\n", This, nPriority);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -340,7 +339,7 @@ static ULONG WINAPI URLMonikerImpl_AddRef(IMoniker* iface)
|
||||
URLMonikerImpl *This = (URLMonikerImpl *)iface;
|
||||
ULONG refCount = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(ref before=%lu)\n",This, refCount - 1);
|
||||
TRACE("(%p) ref=%u\n",This, refCount);
|
||||
|
||||
return refCount;
|
||||
}
|
||||
@@ -353,7 +352,7 @@ static ULONG WINAPI URLMonikerImpl_Release(IMoniker* iface)
|
||||
URLMonikerImpl *This = (URLMonikerImpl *)iface;
|
||||
ULONG refCount = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(ref before=%lu)\n",This, refCount + 1);
|
||||
TRACE("(%p) ref=%u\n",This, refCount);
|
||||
|
||||
/* destroy the object if there's no more reference on it */
|
||||
if (!refCount) {
|
||||
@@ -411,23 +410,23 @@ static HRESULT WINAPI URLMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
||||
URLMonikerImpl *This = (URLMonikerImpl *)iface;
|
||||
|
||||
HRESULT res;
|
||||
ULONG len;
|
||||
ULONG size;
|
||||
ULONG got;
|
||||
TRACE("(%p,%p)\n",This,pStm);
|
||||
|
||||
if(!pStm)
|
||||
return E_INVALIDARG;
|
||||
|
||||
res = IStream_Read(pStm, &len, sizeof(ULONG), &got);
|
||||
res = IStream_Read(pStm, &size, sizeof(ULONG), &got);
|
||||
if(SUCCEEDED(res)) {
|
||||
if(got == sizeof(ULONG)) {
|
||||
HeapFree(GetProcessHeap(), 0, This->URLName);
|
||||
This->URLName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(len+1));
|
||||
This->URLName=HeapAlloc(GetProcessHeap(),0,size);
|
||||
if(!This->URLName)
|
||||
res = E_OUTOFMEMORY;
|
||||
else {
|
||||
res = IStream_Read(pStm, This->URLName, len, NULL);
|
||||
This->URLName[len] = 0;
|
||||
res = IStream_Read(pStm, This->URLName, size, NULL);
|
||||
This->URLName[size/sizeof(WCHAR) - 1] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -446,16 +445,16 @@ static HRESULT WINAPI URLMonikerImpl_Save(IMoniker* iface,
|
||||
URLMonikerImpl *This = (URLMonikerImpl *)iface;
|
||||
|
||||
HRESULT res;
|
||||
ULONG len;
|
||||
ULONG size;
|
||||
TRACE("(%p,%p,%d)\n",This,pStm,fClearDirty);
|
||||
|
||||
if(!pStm)
|
||||
return E_INVALIDARG;
|
||||
|
||||
len = strlenW(This->URLName);
|
||||
res=IStream_Write(pStm,&len,sizeof(ULONG),NULL);
|
||||
size = (strlenW(This->URLName) + 1)*sizeof(WCHAR);
|
||||
res=IStream_Write(pStm,&size,sizeof(ULONG),NULL);
|
||||
if(SUCCEEDED(res))
|
||||
res=IStream_Write(pStm,&This->URLName,len*sizeof(WCHAR),NULL);
|
||||
res=IStream_Write(pStm,This->URLName,size,NULL);
|
||||
return res;
|
||||
|
||||
}
|
||||
@@ -473,8 +472,7 @@ static HRESULT WINAPI URLMonikerImpl_GetSizeMax(IMoniker* iface,
|
||||
if(!pcbSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pcbSize->u.LowPart = sizeof(ULONG) + (strlenW(This->URLName) * sizeof(WCHAR));
|
||||
pcbSize->u.HighPart = 0;
|
||||
pcbSize->QuadPart = sizeof(ULONG) + ((strlenW(This->URLName)+1) * sizeof(WCHAR));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -542,7 +540,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
|
||||
*ppvObject = (void *) bind->pstrCache;
|
||||
IStream_AddRef((IStream *) bind->pstrCache);
|
||||
|
||||
hres = IBindCtx_GetObjectParam(pbc, (LPOLESTR)BSCBHolder, (IUnknown**)&bind->pbscb);
|
||||
hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown**)&bind->pbscb);
|
||||
if(SUCCEEDED(hres)) {
|
||||
TRACE("Got IBindStatusCallback...\n");
|
||||
|
||||
@@ -551,28 +549,16 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
|
||||
bindf = 0;
|
||||
hres = IBindStatusCallback_GetBindInfo(bind->pbscb, &bindf, &bi);
|
||||
if(SUCCEEDED(hres)) {
|
||||
WCHAR *urlcopy, *tmpwc;
|
||||
URL_COMPONENTSW url;
|
||||
WCHAR *host, *path, *user, *pass;
|
||||
DWORD lensz = sizeof(bind->expected_size);
|
||||
DWORD dwService = 0;
|
||||
BOOL bSuccess;
|
||||
|
||||
TRACE("got bindinfo. bindf = %08lx extrainfo = %s bindinfof = %08lx bindverb = %08lx iid %s\n",
|
||||
TRACE("got bindinfo. bindf = %08x extrainfo = %s bindinfof = %08x bindverb = %08x iid %s\n",
|
||||
bindf, debugstr_w(bi.szExtraInfo), bi.grfBindInfoF, bi.dwBindVerb, debugstr_guid(&bi.iid));
|
||||
hres = IBindStatusCallback_OnStartBinding(bind->pbscb, 0, (IBinding*)bind);
|
||||
TRACE("OnStartBinding rets %08lx\n", hres);
|
||||
|
||||
/* This class will accept URLs with the backslash in them. But InternetCrackURL will not - it
|
||||
* requires forward slashes (this is the behaviour of Microsoft's INETAPI). So we need to make
|
||||
* a copy of the URL here and change the backslash to a forward slash everywhere it appears -
|
||||
* but only before any '#' or '?', after which backslash should be left alone.
|
||||
*/
|
||||
urlcopy = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (lstrlenW(bind->URLName) + 1));
|
||||
lstrcpyW(urlcopy, bind->URLName);
|
||||
for (tmpwc = urlcopy; *tmpwc && *tmpwc != '#' && *tmpwc != '?'; ++tmpwc)
|
||||
if (*tmpwc == '\\')
|
||||
*tmpwc = '/';
|
||||
TRACE("OnStartBinding rets %08x\n", hres);
|
||||
|
||||
bind->expected_size = 0;
|
||||
bind->total_read = 0;
|
||||
@@ -580,7 +566,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
|
||||
memset(&url, 0, sizeof(url));
|
||||
url.dwStructSize = sizeof(url);
|
||||
url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1;
|
||||
InternetCrackUrlW(urlcopy, 0, ICU_ESCAPE, &url);
|
||||
InternetCrackUrlW(URLName, 0, ICU_ESCAPE, &url);
|
||||
host = HeapAlloc(GetProcessHeap(), 0, (url.dwHostNameLength + 1) * sizeof(WCHAR));
|
||||
memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
|
||||
host[url.dwHostNameLength] = '\0';
|
||||
@@ -712,7 +698,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
|
||||
}
|
||||
if(bSuccess)
|
||||
{
|
||||
TRACE("res = %ld gle = %08lx url len = %ld\n", hres, GetLastError(), bind->expected_size);
|
||||
TRACE("res = %d gle = %u url len = %d\n", hres, GetLastError(), bind->expected_size);
|
||||
|
||||
IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CACHEFILENAMEAVAILABLE, szFileName);
|
||||
|
||||
@@ -720,7 +706,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
|
||||
char buf[4096];
|
||||
DWORD bufread;
|
||||
if(InternetReadFile(bind->hrequest, buf, sizeof(buf), &bufread)) {
|
||||
TRACE("read %ld bytes %s...\n", bufread, debugstr_an(buf, 10));
|
||||
TRACE("read %d bytes %s...\n", bufread, debugstr_an(buf, 10));
|
||||
if(bufread == 0) break;
|
||||
hres = Binding_MoreCacheData(bind, buf, bufread);
|
||||
} else
|
||||
@@ -734,16 +720,13 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
|
||||
InternetCloseHandle(bind->hinternet);
|
||||
} while(0);
|
||||
|
||||
Binding_CloseCacheDownload(bind);
|
||||
Binding_FinishedDownload(bind, hres);
|
||||
Binding_CloseCacheDownload(bind);
|
||||
|
||||
if (user)
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
if (pass)
|
||||
HeapFree(GetProcessHeap(), 0, pass);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
HeapFree(GetProcessHeap(), 0, pass);
|
||||
HeapFree(GetProcessHeap(), 0, path);
|
||||
HeapFree(GetProcessHeap(), 0, host);
|
||||
HeapFree(GetProcessHeap(), 0, urlcopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -768,7 +751,7 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface,
|
||||
|
||||
bret = InternetCrackUrlW(This->URLName, 0, ICU_ESCAPE, &url);
|
||||
if(!bret) {
|
||||
ERR("InternetCrackUrl failed: %ld\n", GetLastError());
|
||||
ERR("InternetCrackUrl failed: %u\n", GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@@ -794,7 +777,7 @@ static HRESULT WINAPI URLMonikerImpl_Reduce(IMoniker* iface,
|
||||
{
|
||||
URLMonikerImpl *This = (URLMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%ld,%p,%p)\n",This,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
||||
TRACE("(%p,%p,%d,%p,%p)\n",This,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
||||
|
||||
if(!ppmkReduced)
|
||||
return E_INVALIDARG;
|
||||
@@ -1062,43 +1045,34 @@ static const IMonikerVtbl VT_URLMonikerImpl =
|
||||
static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeftURLName, LPCOLESTR lpszURLName)
|
||||
{
|
||||
HRESULT hres;
|
||||
DWORD sizeStr = INTERNET_MAX_URL_LENGTH;
|
||||
DWORD sizeStr = 0;
|
||||
|
||||
TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszLeftURLName),debugstr_w(lpszURLName));
|
||||
|
||||
This->lpvtbl = &VT_URLMonikerImpl;
|
||||
This->ref = 0;
|
||||
|
||||
sizeStr = lstrlenW(lpszURLName)+1;
|
||||
This->URLName = HeapAlloc(GetProcessHeap(), 0, INTERNET_MAX_URL_LENGTH*sizeof(WCHAR));
|
||||
|
||||
if(lpszLeftURLName)
|
||||
sizeStr += strlenW(lpszLeftURLName)+32;
|
||||
hres = CoInternetCombineUrl(lpszLeftURLName, lpszURLName, URL_FILE_USE_PATHURL,
|
||||
This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0);
|
||||
else
|
||||
hres = CoInternetParseUrl(lpszURLName, PARSE_CANONICALIZE, URL_FILE_USE_PATHURL,
|
||||
This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0);
|
||||
|
||||
This->URLName = HeapAlloc(GetProcessHeap(), 0, sizeStr*sizeof(WCHAR));
|
||||
|
||||
if(lpszLeftURLName) {
|
||||
hres = CoInternetCombineUrl(lpszLeftURLName, lpszURLName, 0, This->URLName, sizeStr,
|
||||
&sizeStr, 0);
|
||||
if(FAILED(hres)) {
|
||||
HeapFree(GetProcessHeap(), 0, This->URLName);
|
||||
return hres;
|
||||
}
|
||||
}else {
|
||||
/* FIXME:
|
||||
* We probably should use CoInternetParseUrl or something similar here.
|
||||
*/
|
||||
|
||||
static const WCHAR wszFile[] = {'f','i','l','e',':','/','/',};
|
||||
|
||||
/* file protocol is a special case */
|
||||
if(sizeStr > sizeof(wszFile)/sizeof(WCHAR)
|
||||
&& !memcmp(lpszURLName, wszFile, sizeof(wszFile)))
|
||||
UrlCanonicalizeW(lpszURLName, This->URLName, &sizeStr, URL_FILE_USE_PATHURL);
|
||||
else
|
||||
strcpyW(This->URLName,lpszURLName);
|
||||
if(FAILED(hres)) {
|
||||
HeapFree(GetProcessHeap(), 0, This->URLName);
|
||||
return hres;
|
||||
}
|
||||
|
||||
URLMON_LockModule();
|
||||
|
||||
if(sizeStr != INTERNET_MAX_URL_LENGTH)
|
||||
This->URLName = HeapReAlloc(GetProcessHeap(), 0, This->URLName, (sizeStr+1)*sizeof(WCHAR));
|
||||
|
||||
TRACE("URLName = %s\n", debugstr_w(This->URLName));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1108,7 +1082,7 @@ static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeft
|
||||
HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback,
|
||||
IEnumFORMATETC *format, IBindCtx **pbind)
|
||||
{
|
||||
TRACE("(%08lx %p %p %p)\n", reserved, callback, format, pbind);
|
||||
TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind);
|
||||
|
||||
if(!callback)
|
||||
return E_INVALIDARG;
|
||||
@@ -1128,18 +1102,18 @@ HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
|
||||
BIND_OPTS bindopts;
|
||||
IBindCtx *bctx;
|
||||
|
||||
TRACE("(%p %08lx %p %p %p %ld)\n", ibind, options, callback, format, pbind, reserved);
|
||||
TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved);
|
||||
|
||||
if(!pbind)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(options)
|
||||
FIXME("not supported options %08lx", options);
|
||||
FIXME("not supported options %08x\n", options);
|
||||
if(format)
|
||||
FIXME("format is not supported\n");
|
||||
|
||||
if(reserved)
|
||||
WARN("reserved=%ld\n", reserved);
|
||||
WARN("reserved=%d\n", reserved);
|
||||
|
||||
hres = CreateBindCtx(0, &bctx);
|
||||
if(FAILED(hres))
|
||||
@@ -1161,7 +1135,7 @@ HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateURLMoniker (URLMON.@)
|
||||
* CreateURLMonikerEx (URLMON.@)
|
||||
*
|
||||
* Create a url moniker.
|
||||
*
|
||||
@@ -1169,20 +1143,22 @@ HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
|
||||
* pmkContext [I] Context
|
||||
* szURL [I] Url to create the moniker for
|
||||
* ppmk [O] Destination for created moniker.
|
||||
* dwFlags [I] Flags.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. ppmk contains the created IMoniker object.
|
||||
* Failure: MK_E_SYNTAX if szURL is not a valid url, or
|
||||
* E_OUTOFMEMORY if memory allocation fails.
|
||||
*/
|
||||
HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk)
|
||||
HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk, DWORD dwFlags)
|
||||
{
|
||||
URLMonikerImpl *obj;
|
||||
HRESULT hres;
|
||||
IID iid = IID_IMoniker;
|
||||
LPOLESTR lefturl = NULL;
|
||||
|
||||
TRACE("(%p, %s, %p)\n", pmkContext, debugstr_w(szURL), ppmk);
|
||||
TRACE("(%p, %s, %p, %08x)\n", pmkContext, debugstr_w(szURL), ppmk, dwFlags);
|
||||
|
||||
if (dwFlags & URL_MK_UNIFORM) FIXME("ignoring flag URL_MK_UNIFORM\n");
|
||||
|
||||
if(!(obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj))))
|
||||
return E_OUTOFMEMORY;
|
||||
@@ -1201,12 +1177,32 @@ HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **
|
||||
hres = URLMonikerImpl_Construct(obj, lefturl, szURL);
|
||||
CoTaskMemFree(lefturl);
|
||||
if(SUCCEEDED(hres))
|
||||
hres = URLMonikerImpl_QueryInterface((IMoniker*)obj, &iid, (void**)ppmk);
|
||||
hres = URLMonikerImpl_QueryInterface((IMoniker*)obj, &IID_IMoniker, (void**)ppmk);
|
||||
else
|
||||
HeapFree(GetProcessHeap(), 0, obj);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CreateURLMoniker (URLMON.@)
|
||||
*
|
||||
* Create a url moniker.
|
||||
*
|
||||
* PARAMS
|
||||
* pmkContext [I] Context
|
||||
* szURL [I] Url to create the moniker for
|
||||
* ppmk [O] Destination for created moniker.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. ppmk contains the created IMoniker object.
|
||||
* Failure: MK_E_SYNTAX if szURL is not a valid url, or
|
||||
* E_OUTOFMEMORY if memory allocation fails.
|
||||
*/
|
||||
HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk)
|
||||
{
|
||||
return CreateURLMonikerEx(pmkContext, szURL, ppmk, URL_MK_LEGACY);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoInternetQueryInfo (URLMON.@)
|
||||
*
|
||||
@@ -1222,7 +1218,7 @@ HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
|
||||
DWORD dwQueryFlags, LPVOID pvBuffer, DWORD cbBuffer, DWORD * pcbBuffer,
|
||||
DWORD dwReserved)
|
||||
{
|
||||
FIXME("(%s, %x, %lx, %p, %lx, %p, %lx): stub\n", debugstr_w(pwzUrl),
|
||||
FIXME("(%s, %x, %x, %p, %x, %p, %x): stub\n", debugstr_w(pwzUrl),
|
||||
QueryOption, dwQueryFlags, pvBuffer, cbBuffer, pcbBuffer, dwReserved);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1304,21 +1300,21 @@ HRESULT WINAPI RegisterBindStatusCallback(
|
||||
{
|
||||
IBindStatusCallback *prev;
|
||||
|
||||
TRACE("(%p,%p,%p,%lu)\n", pbc, pbsc, ppbscPrevious, dwReserved);
|
||||
TRACE("(%p,%p,%p,%u)\n", pbc, pbsc, ppbscPrevious, dwReserved);
|
||||
|
||||
if (pbc == NULL || pbsc == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)BSCBHolder, (IUnknown **)&prev)))
|
||||
if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&prev)))
|
||||
{
|
||||
IBindCtx_RevokeObjectParam(pbc, (LPOLESTR)BSCBHolder);
|
||||
IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
|
||||
if (ppbscPrevious)
|
||||
*ppbscPrevious = prev;
|
||||
else
|
||||
IBindStatusCallback_Release(prev);
|
||||
}
|
||||
|
||||
return IBindCtx_RegisterObjectParam(pbc, (LPOLESTR)BSCBHolder, (IUnknown *)pbsc);
|
||||
return IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown *)pbsc);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1346,11 +1342,11 @@ HRESULT WINAPI RevokeBindStatusCallback(
|
||||
if (pbc == NULL || pbsc == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)BSCBHolder, (IUnknown **)&callback)))
|
||||
if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&callback)))
|
||||
{
|
||||
if (callback == pbsc)
|
||||
{
|
||||
IBindCtx_RevokeObjectParam(pbc, (LPOLESTR)BSCBHolder);
|
||||
IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
|
||||
hr = S_OK;
|
||||
}
|
||||
IBindStatusCallback_Release(pbsc);
|
||||
@@ -1385,7 +1381,7 @@ HRESULT WINAPI URLDownloadToFileA(LPUNKNOWN pCaller,
|
||||
UNICODE_STRING szURL_w, szFileName_w;
|
||||
|
||||
if ((szURL == NULL) || (szFileName == NULL)) {
|
||||
FIXME("(%p,%s,%s,%08lx,%p) cannot accept NULL strings !\n", pCaller, debugstr_a(szURL), debugstr_a(szFileName), dwReserved, lpfnCB);
|
||||
FIXME("(%p,%s,%s,%08x,%p) cannot accept NULL strings !\n", pCaller, debugstr_a(szURL), debugstr_a(szFileName), dwReserved, lpfnCB);
|
||||
return E_INVALIDARG; /* The error code is not specified in this case... */
|
||||
}
|
||||
|
||||
@@ -1402,7 +1398,7 @@ HRESULT WINAPI URLDownloadToFileA(LPUNKNOWN pCaller,
|
||||
}
|
||||
}
|
||||
|
||||
FIXME("(%p,%s,%s,%08lx,%p) could not allocate W strings !\n", pCaller, szURL, szFileName, dwReserved, lpfnCB);
|
||||
FIXME("(%p,%s,%s,%08x,%p) could not allocate W strings !\n", pCaller, szURL, szFileName, dwReserved, lpfnCB);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
@@ -1440,7 +1436,7 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller,
|
||||
static const WCHAR wszAppName[]={'u','r','l','m','o','n','.','d','l','l',0};
|
||||
|
||||
/* Note: all error codes would need to be checked agains real Windows behaviour... */
|
||||
TRACE("(%p,%s,%s,%08lx,%p) stub!\n", pCaller, debugstr_w(szURL), debugstr_w(szFileName), dwReserved, lpfnCB);
|
||||
TRACE("(%p,%s,%s,%08x,%p) stub!\n", pCaller, debugstr_w(szURL), debugstr_w(szFileName), dwReserved, lpfnCB);
|
||||
|
||||
if ((szURL == NULL) || (szFileName == NULL)) {
|
||||
FIXME(" cannot accept NULL strings !\n");
|
||||
@@ -1496,7 +1492,7 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller,
|
||||
|
||||
if (HttpQueryInfoW(hreq, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
|
||||
&total_size, &arg_size, NULL)) {
|
||||
TRACE(" total size : %ld\n", total_size);
|
||||
TRACE(" total size : %d\n", total_size);
|
||||
}
|
||||
|
||||
hfile = CreateFileW(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
@@ -1583,7 +1579,7 @@ HRESULT WINAPI URLDownloadToCacheFileA(LPUNKNOWN lpUnkCaller, LPCSTR szURL, LPST
|
||||
int len;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p %s %p %ld %ld %p)\n", lpUnkCaller, debugstr_a(szURL), szFileName,
|
||||
TRACE("(%p %s %p %d %d %p)\n", lpUnkCaller, debugstr_a(szURL), szFileName,
|
||||
dwBufLength, dwReserved, pBSC);
|
||||
|
||||
if(szURL) {
|
||||
@@ -1613,9 +1609,46 @@ HRESULT WINAPI URLDownloadToCacheFileA(LPUNKNOWN lpUnkCaller, LPCSTR szURL, LPST
|
||||
HRESULT WINAPI URLDownloadToCacheFileW(LPUNKNOWN lpUnkCaller, LPCWSTR szURL, LPWSTR szFileName,
|
||||
DWORD dwBufLength, DWORD dwReserved, LPBINDSTATUSCALLBACK pBSC)
|
||||
{
|
||||
FIXME("(%p %s %p %ld %ld %p)\n", lpUnkCaller, debugstr_w(szURL), szFileName,
|
||||
dwBufLength, dwReserved, pBSC);
|
||||
return E_NOTIMPL;
|
||||
WCHAR cache_path[MAX_PATH + 1];
|
||||
FILETIME expire, modified;
|
||||
HRESULT hr;
|
||||
LPWSTR ext;
|
||||
|
||||
static WCHAR header[] = {
|
||||
'H','T','T','P','/','1','.','0',' ','2','0','0',' ',
|
||||
'O','K','\\','r','\\','n','\\','r','\\','n',0
|
||||
};
|
||||
|
||||
TRACE("(%p, %s, %p, %d, %d, %p)\n", lpUnkCaller, debugstr_w(szURL),
|
||||
szFileName, dwBufLength, dwReserved, pBSC);
|
||||
|
||||
if (!szURL || !szFileName)
|
||||
return E_INVALIDARG;
|
||||
|
||||
ext = PathFindExtensionW(szURL);
|
||||
|
||||
if (!CreateUrlCacheEntryW(szURL, 0, ext, cache_path, 0))
|
||||
return E_FAIL;
|
||||
|
||||
hr = URLDownloadToFileW(lpUnkCaller, szURL, cache_path, 0, pBSC);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
expire.dwHighDateTime = 0;
|
||||
expire.dwLowDateTime = 0;
|
||||
modified.dwHighDateTime = 0;
|
||||
modified.dwLowDateTime = 0;
|
||||
|
||||
if (!CommitUrlCacheEntryW(szURL, cache_path, expire, modified, NORMAL_CACHE_ENTRY,
|
||||
header, sizeof(header), NULL, NULL))
|
||||
return E_FAIL;
|
||||
|
||||
if (lstrlenW(cache_path) > dwBufLength)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
lstrcpyW(szFileName, cache_path);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -49,32 +49,30 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL,
|
||||
{
|
||||
IUMCacheStream* ucstr;
|
||||
HANDLE handle;
|
||||
LPWSTR ext;
|
||||
LPCWSTR c;
|
||||
LPCWSTR eloc = 0;
|
||||
DWORD size;
|
||||
LPWSTR url, c, ext = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
for (c = pszURL; *c && *c != '#' && *c != '?'; ++c)
|
||||
size = (strlenW(pszURL)+1)*sizeof(WCHAR);
|
||||
url = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
memcpy(url, pszURL, size);
|
||||
|
||||
for (c = url; *c && *c != '#' && *c != '?'; ++c)
|
||||
{
|
||||
if (*c == '.')
|
||||
eloc = c + 1;
|
||||
else if (*c == '/' || *c == '\\')
|
||||
eloc = 0;
|
||||
ext = c+1;
|
||||
else if(*c == '/')
|
||||
ext = NULL;
|
||||
}
|
||||
|
||||
if (!eloc)
|
||||
eloc = c;
|
||||
*c = 0;
|
||||
|
||||
ext = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (c - eloc + 1));
|
||||
memcpy(ext, eloc, sizeof(WCHAR) * (c - eloc));
|
||||
ext[c - eloc] = 0;
|
||||
|
||||
if(!CreateUrlCacheEntryW(pszURL, dwSize, ext, pszFileName, 0))
|
||||
if(!CreateUrlCacheEntryW(url, dwSize, ext, pszFileName, 0))
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
else
|
||||
hr = 0;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ext);
|
||||
HeapFree(GetProcessHeap(), 0, url);
|
||||
|
||||
if (hr)
|
||||
return hr;
|
||||
@@ -193,7 +191,7 @@ static ULONG WINAPI IStream_fnAddRef(IStream *iface)
|
||||
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||
ULONG refCount = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
|
||||
TRACE("(%p)->(count=%u)\n", This, refCount - 1);
|
||||
|
||||
return refCount;
|
||||
}
|
||||
@@ -206,7 +204,7 @@ static ULONG WINAPI IStream_fnRelease(IStream *iface)
|
||||
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||
ULONG refCount = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(count=%lu)\n", This, refCount + 1);
|
||||
TRACE("(%p)->(count=%u)\n", This, refCount + 1);
|
||||
|
||||
if (!refCount)
|
||||
{
|
||||
@@ -228,7 +226,7 @@ static HRESULT WINAPI IStream_fnRead (IStream * iface,
|
||||
ULONG dwBytesRead;
|
||||
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||
|
||||
TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
|
||||
TRACE("(%p)->(%p,0x%08x,%p)\n",This, pv, cb, pcbRead);
|
||||
|
||||
if ( !pv )
|
||||
return STG_E_INVALIDPOINTER;
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
<module name="urlmon" type="win32dll" baseaddress="${BASEADDRESS_URLMON}" installbase="system32" installname="urlmon.dll" allowwarnings="true">
|
||||
<autoregister infsection="OleControlDlls" type="Both" />
|
||||
<importlibrary definition="urlmon.spec.def" />
|
||||
<include base="urlmon">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__REACTOS__" />
|
||||
<define name="__WINESRC__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x501</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<define name="_STDDEF_H" />
|
||||
<library>wine</library>
|
||||
<library>uuid</library>
|
||||
<library>ntdll</library>
|
||||
<library>kernel32</library>
|
||||
<library>advapi32</library>
|
||||
<library>user32</library>
|
||||
<library>ole32</library>
|
||||
<library>shlwapi</library>
|
||||
<library>cabinet</library>
|
||||
<library>wininet</library>
|
||||
<library>user32</library>
|
||||
<library>advapi32</library>
|
||||
<library>kernel32</library>
|
||||
<library>ntdll</library>
|
||||
<library>uuid</library>
|
||||
<file>binding.c</file>
|
||||
<file>bindprot.c</file>
|
||||
<file>file.c</file>
|
||||
<file>format.c</file>
|
||||
<file>ftp.c</file>
|
||||
<file>http.c</file>
|
||||
<file>internet.c</file>
|
||||
<file>mk.c</file>
|
||||
<file>regsvr.c</file>
|
||||
<file>sec_mgr.c</file>
|
||||
<file>session.c</file>
|
||||
|
||||
@@ -26,13 +26,14 @@
|
||||
@ stdcall CreateAsyncBindCtxEx(ptr long ptr ptr ptr long)
|
||||
@ stdcall CreateFormatEnumerator(long ptr ptr)
|
||||
@ stdcall CreateURLMoniker(ptr wstr ptr)
|
||||
@ stdcall CreateURLMonikerEx(ptr wstr ptr long)
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllInstall(long wstr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllRegisterServerEx()
|
||||
@ stdcall -private DllUnregisterServer()
|
||||
@ stdcall Extract(long ptr) cabinet.Extract
|
||||
@ stdcall Extract(long ptr)
|
||||
@ stdcall FaultInIEFeature(long ptr ptr long)
|
||||
@ stub FindMediaType
|
||||
@ stub FindMediaTypeClass
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -28,34 +28,42 @@
|
||||
|
||||
#define NO_SHLWAPI_REG
|
||||
#include "shlwapi.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
#include "winuser.h"
|
||||
#include "urlmon.h"
|
||||
#include "urlmon_main.h"
|
||||
#include "ole2.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||
|
||||
LONG URLMON_refCount = 0;
|
||||
|
||||
HINSTANCE URLMON_hInstance = 0;
|
||||
static HMODULE hCabinet = NULL;
|
||||
|
||||
static void init_session(BOOL);
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (URLMON.init)
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||
{
|
||||
TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
|
||||
TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
|
||||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
URLMON_hInstance = hinstDLL;
|
||||
init_session(TRUE);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (hCabinet)
|
||||
FreeLibrary(hCabinet);
|
||||
hCabinet = NULL;
|
||||
init_session(FALSE);
|
||||
URLMON_hInstance = 0;
|
||||
break;
|
||||
}
|
||||
@@ -88,69 +96,51 @@ HRESULT WINAPI DllCanUnloadNow(void)
|
||||
* Urlmon ClassFactory
|
||||
*/
|
||||
typedef struct {
|
||||
IClassFactory ITF_IClassFactory;
|
||||
const IClassFactoryVtbl *lpClassFactoryVtbl;
|
||||
|
||||
LONG ref;
|
||||
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
} IClassFactoryImpl;
|
||||
} ClassFactory;
|
||||
|
||||
struct object_creation_info
|
||||
{
|
||||
const CLSID *clsid;
|
||||
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
};
|
||||
|
||||
static const struct object_creation_info object_creation[] =
|
||||
{
|
||||
{ &CLSID_FileProtocol, FileProtocol_Construct },
|
||||
{ &CLSID_FtpProtocol, FtpProtocol_Construct },
|
||||
{ &CLSID_HttpProtocol, HttpProtocol_Construct },
|
||||
{ &CLSID_InternetSecurityManager, &SecManagerImpl_Construct },
|
||||
{ &CLSID_InternetZoneManager, ZoneMgrImpl_Construct }
|
||||
};
|
||||
#define CLASSFACTORY(x) ((IClassFactory*) &(x)->lpClassFactoryVtbl)
|
||||
|
||||
static HRESULT WINAPI
|
||||
CF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
|
||||
static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
*ppv = NULL;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IClassFactory))
|
||||
{
|
||||
IClassFactory_AddRef(iface);
|
||||
*ppobj = This;
|
||||
if(IsEqualGUID(riid, &IID_IUnknown)) {
|
||||
TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
|
||||
*ppv = iface;
|
||||
}else if(IsEqualGUID(riid, &IID_IClassFactory)) {
|
||||
TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
|
||||
*ppv = iface;
|
||||
}
|
||||
|
||||
if(*ppv) {
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
|
||||
WARN("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ppv);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI CF_AddRef(LPCLASSFACTORY iface)
|
||||
static ULONG WINAPI CF_AddRef(IClassFactory *iface)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
URLMON_LockModule();
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI CF_Release(LPCLASSFACTORY iface)
|
||||
static ULONG WINAPI CF_Release(IClassFactory *iface)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
URLMON_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
URLMON_UnlockModule();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI CF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
|
||||
static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
|
||||
REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
ClassFactory *This = (ClassFactory*)iface;
|
||||
HRESULT hres;
|
||||
LPUNKNOWN punk;
|
||||
|
||||
@@ -176,7 +166,7 @@ static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IClassFactoryVtbl CF_Vtbl =
|
||||
static const IClassFactoryVtbl ClassFactoryVtbl =
|
||||
{
|
||||
CF_QueryInterface,
|
||||
CF_AddRef,
|
||||
@@ -185,6 +175,70 @@ static const IClassFactoryVtbl CF_Vtbl =
|
||||
CF_LockServer
|
||||
};
|
||||
|
||||
static const ClassFactory FileProtocolCF =
|
||||
{ &ClassFactoryVtbl, FileProtocol_Construct};
|
||||
static const ClassFactory FtpProtocolCF =
|
||||
{ &ClassFactoryVtbl, FtpProtocol_Construct};
|
||||
static const ClassFactory HttpProtocolCF =
|
||||
{ &ClassFactoryVtbl, HttpProtocol_Construct};
|
||||
static const ClassFactory MkProtocolCF =
|
||||
{ &ClassFactoryVtbl, MkProtocol_Construct};
|
||||
static const ClassFactory SecurityManagerCF =
|
||||
{ &ClassFactoryVtbl, SecManagerImpl_Construct};
|
||||
static const ClassFactory ZoneManagerCF =
|
||||
{ &ClassFactoryVtbl, ZoneMgrImpl_Construct};
|
||||
|
||||
struct object_creation_info
|
||||
{
|
||||
const CLSID *clsid;
|
||||
IClassFactory *cf;
|
||||
LPCWSTR protocol;
|
||||
};
|
||||
|
||||
static const WCHAR wszFile[] = {'f','i','l','e',0};
|
||||
static const WCHAR wszFtp[] = {'f','t','p',0};
|
||||
static const WCHAR wszHttp[] = {'h','t','t','p',0};
|
||||
static const WCHAR wszMk[] = {'m','k',0};
|
||||
|
||||
static const struct object_creation_info object_creation[] =
|
||||
{
|
||||
{ &CLSID_FileProtocol, CLASSFACTORY(&FileProtocolCF), wszFile },
|
||||
{ &CLSID_FtpProtocol, CLASSFACTORY(&FtpProtocolCF), wszFtp },
|
||||
{ &CLSID_HttpProtocol, CLASSFACTORY(&HttpProtocolCF), wszHttp },
|
||||
{ &CLSID_MkProtocol, CLASSFACTORY(&MkProtocolCF), wszMk },
|
||||
{ &CLSID_InternetSecurityManager, CLASSFACTORY(&SecurityManagerCF), NULL },
|
||||
{ &CLSID_InternetZoneManager, CLASSFACTORY(&ZoneManagerCF), NULL }
|
||||
};
|
||||
|
||||
static void init_session(BOOL init)
|
||||
{
|
||||
IInternetSession *session;
|
||||
int i;
|
||||
|
||||
CoInternetGetSession(0, &session, 0);
|
||||
|
||||
for(i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) {
|
||||
if(object_creation[i].protocol) {
|
||||
if(init)
|
||||
{
|
||||
IInternetSession_RegisterNameSpace(session, object_creation[i].cf,
|
||||
object_creation[i].clsid, object_creation[i].protocol, 0, NULL, 0);
|
||||
/* make sure that the AddRef on the class factory doesn't keep us loaded */
|
||||
URLMON_UnlockModule();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* make sure that the Release on the class factory doesn't unload us */
|
||||
URLMON_LockModule();
|
||||
IInternetSession_UnregisterNameSpace(session, object_creation[i].cf,
|
||||
object_creation[i].protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IInternetSession_Release(session);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* DllGetClassObject [URLMON.@]
|
||||
* Retrieves class object from a DLL object
|
||||
@@ -206,38 +260,17 @@ static const IClassFactoryVtbl CF_Vtbl =
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
int i;
|
||||
IClassFactoryImpl *factory;
|
||||
|
||||
TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||
|
||||
if ( !IsEqualGUID( &IID_IClassFactory, riid )
|
||||
&& ! IsEqualGUID( &IID_IUnknown, riid) )
|
||||
return E_NOINTERFACE;
|
||||
|
||||
for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
|
||||
{
|
||||
if (IsEqualGUID(object_creation[i].clsid, rclsid))
|
||||
break;
|
||||
return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv);
|
||||
}
|
||||
|
||||
if (i == sizeof(object_creation)/sizeof(object_creation[0]))
|
||||
{
|
||||
FIXME("%s: no class found.\n", debugstr_guid(rclsid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
|
||||
if (factory == NULL) return E_OUTOFMEMORY;
|
||||
|
||||
factory->ITF_IClassFactory.lpVtbl = &CF_Vtbl;
|
||||
factory->ref = 1;
|
||||
factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
|
||||
|
||||
*ppv = &(factory->ITF_IClassFactory);
|
||||
|
||||
URLMON_LockModule();
|
||||
|
||||
return S_OK;
|
||||
FIXME("%s: no class found.\n", debugstr_guid(rclsid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -257,18 +290,7 @@ HRESULT WINAPI DllRegisterServerEx(void)
|
||||
HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
|
||||
DWORD Reserved)
|
||||
{
|
||||
FIXME("(%#lx, %p, %#lx): stub\n", dwOption, pBuffer, dwBufferLength);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* UrlMkGetSessionOption (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI UrlMkGetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
|
||||
DWORD* pdwBufferLength, DWORD dwReserved)
|
||||
{
|
||||
FIXME("(%#lx, %p, %#lx, %p): stub\n", dwOption, pBuffer, dwBufferLength, pdwBufferLength);
|
||||
FIXME("(%#x, %p, %#x): stub\n", dwOption, pBuffer, dwBufferLength);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -280,25 +302,24 @@ static const CHAR Agent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
|
||||
*/
|
||||
HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbSize)
|
||||
{
|
||||
FIXME("(%ld, %p, %p): stub\n", dwOption, pcszUAOut, cbSize);
|
||||
FIXME("(%d, %p, %p): stub\n", dwOption, pcszUAOut, cbSize);
|
||||
|
||||
if(dwOption) {
|
||||
ERR("dwOption: %ld, must be zero\n", dwOption);
|
||||
if (pcszUAOut == NULL || cbSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (*cbSize < sizeof(Agent))
|
||||
{
|
||||
*cbSize = sizeof(Agent);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (sizeof(Agent) < *cbSize)
|
||||
*cbSize = sizeof(Agent);
|
||||
lstrcpynA(pcszUAOut, Agent, *cbSize);
|
||||
lstrcpynA(pcszUAOut, Agent, *cbSize);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
|
||||
{
|
||||
TRACE("(%s,%s,%08lx)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
|
||||
return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags)==0?S_OK:S_FALSE;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* IsValidURL (URLMON.@)
|
||||
*
|
||||
@@ -319,7 +340,7 @@ HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCo
|
||||
*/
|
||||
HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
|
||||
{
|
||||
FIXME("(%p, %s, %ld): stub\n", pBC, debugstr_w(szURL), dwReserved);
|
||||
FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved);
|
||||
|
||||
if (pBC != NULL || dwReserved != 0)
|
||||
return E_INVALIDARG;
|
||||
@@ -335,7 +356,7 @@ HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
|
||||
HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
|
||||
QUERYCONTEXT *pQuery, DWORD flags )
|
||||
{
|
||||
FIXME("%p %p %p %08lx\n", hwnd, pClassSpec, pQuery, flags);
|
||||
FIXME("%p %p %p %08x\n", hwnd, pClassSpec, pQuery, flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -347,7 +368,7 @@ HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWOR
|
||||
LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
|
||||
REFIID riid, LPVOID *ppv )
|
||||
{
|
||||
FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
|
||||
FIXME("(%s %s %d %d %s %p %d %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
|
||||
dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
|
||||
debugstr_guid(riid), ppv);
|
||||
return E_NOINTERFACE;
|
||||
@@ -366,15 +387,25 @@ HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWOR
|
||||
*/
|
||||
void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo)
|
||||
{
|
||||
DWORD size;
|
||||
|
||||
TRACE("(%p)\n", pbindinfo);
|
||||
|
||||
if(!pbindinfo)
|
||||
if(!pbindinfo || !(size = pbindinfo->cbSize))
|
||||
return;
|
||||
|
||||
CoTaskMemFree(pbindinfo->szExtraInfo);
|
||||
ReleaseStgMedium(&pbindinfo->stgmedData);
|
||||
|
||||
if(pbindinfo->pUnk)
|
||||
if(offsetof(BINDINFO, szExtraInfo) < size)
|
||||
CoTaskMemFree(pbindinfo->szCustomVerb);
|
||||
|
||||
|
||||
if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size)
|
||||
IUnknown_Release(pbindinfo->pUnk);
|
||||
|
||||
memset(pbindinfo, 0, size);
|
||||
pbindinfo->cbSize = size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -382,24 +413,133 @@ void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo)
|
||||
*
|
||||
* Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided.
|
||||
*/
|
||||
static BOOL text_html_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(size < 5)
|
||||
return FALSE;
|
||||
|
||||
for(i=0; i < size-5; i++) {
|
||||
if(b[i] == '<'
|
||||
&& (b[i+1] == 'h' || b[i+1] == 'H')
|
||||
&& (b[i+2] == 't' || b[i+2] == 'T')
|
||||
&& (b[i+3] == 'm' || b[i+3] == 'M')
|
||||
&& (b[i+4] == 'l' || b[i+4] == 'L'))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL image_gif_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size >= 6
|
||||
&& (b[0] == 'G' || b[0] == 'g')
|
||||
&& (b[1] == 'I' || b[1] == 'i')
|
||||
&& (b[2] == 'F' || b[2] == 'f')
|
||||
&& b[3] == '8'
|
||||
&& (b[4] == '7' || b[4] == '9')
|
||||
&& (b[5] == 'A' || b[5] == 'a');
|
||||
}
|
||||
|
||||
static BOOL image_pjpeg_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 2 && b[0] == 0xff && b[1] == 0xd8;
|
||||
}
|
||||
|
||||
static BOOL image_tiff_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 2 && b[0] == 0x4d && b[1] == 0x4d;
|
||||
}
|
||||
|
||||
static BOOL image_xpng_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
static const BYTE xpng_header[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a};
|
||||
return size > sizeof(xpng_header) && !memcmp(b, xpng_header, sizeof(xpng_header));
|
||||
}
|
||||
|
||||
static BOOL image_bmp_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size >= 14
|
||||
&& b[0] == 0x42 && b[1] == 0x4d
|
||||
&& *(const DWORD *)(b+6) == 0;
|
||||
}
|
||||
|
||||
static BOOL video_avi_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 12
|
||||
&& b[0] == 'R' && b[1] == 'I' && b[2] == 'F' && b[3] == 'F'
|
||||
&& b[8] == 'A' && b[9] == 'V' && b[10] == 'I' && b[11] == 0x20;
|
||||
}
|
||||
|
||||
static BOOL video_mpeg_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 4
|
||||
&& !b[0] && !b[1] && b[2] == 0x01
|
||||
&& (b[3] == 0xb3 || b[3] == 0xba);
|
||||
}
|
||||
|
||||
static BOOL application_pdf_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 4 && b[0] == 0x25 && b[1] == 0x50 && b[2] == 0x44 && b[3] == 0x46;
|
||||
}
|
||||
|
||||
static BOOL application_xzip_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 2 && b[0] == 0x50 && b[1] == 0x4b;
|
||||
}
|
||||
|
||||
static BOOL application_xgzip_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 2 && b[0] == 0x1f && b[1] == 0x8b;
|
||||
}
|
||||
|
||||
static BOOL application_java_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 4 && b[0] == 0xca && b[1] == 0xfe && b[2] == 0xba && b[3] == 0xbe;
|
||||
}
|
||||
|
||||
static BOOL application_xmsdownload(const BYTE *b, DWORD size)
|
||||
{
|
||||
return size > 2 && b[0] == 'M' && b[1] == 'Z';
|
||||
}
|
||||
|
||||
static BOOL text_plain_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
const BYTE *ptr;
|
||||
|
||||
for(ptr = b; ptr < b+size-1; ptr++) {
|
||||
if(*ptr < 0x20 && *ptr != '\n' && *ptr != '\r' && *ptr != '\t')
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL application_octet_stream_filter(const BYTE *b, DWORD size)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer,
|
||||
DWORD cbSize, LPCWSTR pwzMimeProposed, DWORD dwMimeFlags,
|
||||
LPWSTR* ppwzMimeOut, DWORD dwReserved)
|
||||
{
|
||||
TRACE("(%p,%s,%p,%ld,%s,0x%lx,%p,0x%lx)\n", pBC, debugstr_w(pwzUrl), pBuffer, cbSize,
|
||||
TRACE("(%p,%s,%p,%d,%s,0x%x,%p,0x%x)\n", pBC, debugstr_w(pwzUrl), pBuffer, cbSize,
|
||||
debugstr_w(pwzMimeProposed), dwMimeFlags, ppwzMimeOut, dwReserved);
|
||||
|
||||
if(dwMimeFlags)
|
||||
WARN("dwMimeFlags=%08lx\n", dwMimeFlags);
|
||||
WARN("dwMimeFlags=%08x\n", dwMimeFlags);
|
||||
if(dwReserved)
|
||||
WARN("dwReserved=%ld\n", dwReserved);
|
||||
WARN("dwReserved=%d\n", dwReserved);
|
||||
|
||||
/* pBC seams to not be used */
|
||||
|
||||
if(!ppwzMimeOut || (!pwzUrl && !pBuffer))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(pwzMimeProposed && (!pwzUrl || !pBuffer || (pBuffer && !cbSize))) {
|
||||
if(pwzMimeProposed && (!pBuffer || (pBuffer && !cbSize))) {
|
||||
DWORD len;
|
||||
|
||||
if(!pwzMimeProposed)
|
||||
@@ -412,23 +552,91 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer,
|
||||
}
|
||||
|
||||
if(pBuffer) {
|
||||
UCHAR *ptr = pBuffer;
|
||||
const BYTE *buf = pBuffer;
|
||||
DWORD len;
|
||||
LPCWSTR ret;
|
||||
LPCWSTR ret = NULL;
|
||||
int i;
|
||||
|
||||
static const WCHAR wszAppOctetStream[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
|
||||
'o','c','t','e','t','-','s','t','r','e','a','m','\0'};
|
||||
static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
|
||||
static const WCHAR wszImageGif[] = {'i','m','a','g','e','/','g','i','f',0};
|
||||
static const WCHAR wszImagePjpeg[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
|
||||
static const WCHAR wszImageTiff[] = {'i','m','a','g','e','/','t','i','f','f',0};
|
||||
static const WCHAR wszImageXPng[] = {'i','m','a','g','e','/','x','-','p','n','g',0};
|
||||
static const WCHAR wszImageBmp[] = {'i','m','a','g','e','/','b','m','p',0};
|
||||
static const WCHAR wszVideoAvi[] = {'v','i','d','e','o','/','a','v','i',0};
|
||||
static const WCHAR wszVideoMpeg[] = {'v','i','d','e','o','/','m','p','e','g',0};
|
||||
static const WCHAR wszAppPdf[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
|
||||
'p','d','f',0};
|
||||
static const WCHAR wszAppXZip[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
|
||||
'x','-','z','i','p','-','c','o','m','p','r','e','s','s','e','d',0};
|
||||
static const WCHAR wszAppXGzip[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
|
||||
'x','-','g','z','i','p','-','c','o','m','p','r','e','s','s','e','d',0};
|
||||
static const WCHAR wszAppJava[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
|
||||
'j','a','v','a',0};
|
||||
static const WCHAR wszAppXMSDownload[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
|
||||
'x','-','m','s','d','o','w','n','l','o','a','d',0};
|
||||
static const WCHAR wszTextPlain[] = {'t','e','x','t','/','p','l','a','i','n','\0'};
|
||||
static const WCHAR wszAppOctetStream[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
|
||||
'o','c','t','e','t','-','s','t','r','e','a','m','\0'};
|
||||
|
||||
static const struct {
|
||||
LPCWSTR mime;
|
||||
BOOL (*filter)(const BYTE *,DWORD);
|
||||
} mime_filters[] = {
|
||||
{wszTextHtml, text_html_filter},
|
||||
{wszImageGif, image_gif_filter},
|
||||
{wszImagePjpeg, image_pjpeg_filter},
|
||||
{wszImageTiff, image_tiff_filter},
|
||||
{wszImageXPng, image_xpng_filter},
|
||||
{wszImageBmp, image_bmp_filter},
|
||||
{wszVideoAvi, video_avi_filter},
|
||||
{wszVideoMpeg, video_mpeg_filter},
|
||||
{wszAppPdf, application_pdf_filter},
|
||||
{wszAppXZip, application_xzip_filter},
|
||||
{wszAppXGzip, application_xgzip_filter},
|
||||
{wszAppJava, application_java_filter},
|
||||
{wszAppXMSDownload, application_xmsdownload},
|
||||
{wszTextPlain, text_plain_filter},
|
||||
{wszAppOctetStream, application_octet_stream_filter}
|
||||
};
|
||||
|
||||
if(!cbSize)
|
||||
return E_FAIL;
|
||||
|
||||
ret = wszTextPlain;
|
||||
for(ptr = pBuffer; ptr < (UCHAR*)pBuffer+cbSize-1; ptr++) {
|
||||
if(*ptr < 0x20 && *ptr != '\n' && *ptr != '\r' && *ptr != '\t') {
|
||||
ret = wszAppOctetStream;
|
||||
break;
|
||||
if(pwzMimeProposed && strcmpW(pwzMimeProposed, wszAppOctetStream)) {
|
||||
for(i=0; i < sizeof(mime_filters)/sizeof(*mime_filters); i++) {
|
||||
if(!strcmpW(pwzMimeProposed, mime_filters[i].mime))
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == sizeof(mime_filters)/sizeof(*mime_filters)
|
||||
|| mime_filters[i].filter(buf, cbSize)) {
|
||||
len = strlenW(pwzMimeProposed)+1;
|
||||
*ppwzMimeOut = CoTaskMemAlloc(len*sizeof(WCHAR));
|
||||
memcpy(*ppwzMimeOut, pwzMimeProposed, len*sizeof(WCHAR));
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
i=0;
|
||||
while(!ret) {
|
||||
if(mime_filters[i].filter(buf, cbSize))
|
||||
ret = mime_filters[i].mime;
|
||||
i++;
|
||||
}
|
||||
|
||||
TRACE("found %s for data\n"
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
debugstr_w(ret), buf[0],buf[1],buf[2],buf[3], buf[4],buf[5],buf[6],buf[7],
|
||||
buf[8],buf[9],buf[10],buf[11], buf[12],buf[13],buf[14],buf[15]);
|
||||
|
||||
if(pwzMimeProposed) {
|
||||
if(i == sizeof(mime_filters)/sizeof(*mime_filters))
|
||||
ret = pwzMimeProposed;
|
||||
|
||||
/* text/html is a special case */
|
||||
if(!strcmpW(pwzMimeProposed, wszTextHtml) && !strcmpW(ret, wszTextPlain))
|
||||
ret = wszTextHtml;
|
||||
}
|
||||
|
||||
len = strlenW(ret)+1;
|
||||
@@ -452,13 +660,13 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer,
|
||||
|
||||
res = RegOpenKeyW(HKEY_CLASSES_ROOT, ptr, &hkey);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return E_FAIL;
|
||||
return HRESULT_FROM_WIN32(res);
|
||||
|
||||
size = sizeof(mime);
|
||||
res = RegQueryValueExW(hkey, wszContentType, NULL, NULL, (LPBYTE)mime, &size);
|
||||
RegCloseKey(hkey);
|
||||
if(res != ERROR_SUCCESS)
|
||||
return E_FAIL;
|
||||
return HRESULT_FROM_WIN32(res);
|
||||
|
||||
*ppwzMimeOut = CoTaskMemAlloc(size);
|
||||
memcpy(*ppwzMimeOut, mime, size);
|
||||
@@ -467,3 +675,20 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer,
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Extract (URLMON.@)
|
||||
*/
|
||||
HRESULT WINAPI Extract(void *dest, LPCSTR szCabName)
|
||||
{
|
||||
HRESULT (WINAPI *pExtract)(void *, LPCSTR);
|
||||
|
||||
if (!hCabinet)
|
||||
hCabinet = LoadLibraryA("cabinet.dll");
|
||||
|
||||
if (!hCabinet) return HRESULT_FROM_WIN32(GetLastError());
|
||||
pExtract = (void *)GetProcAddress(hCabinet, "Extract");
|
||||
if (!pExtract) return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
return pExtract(dest, szCabName);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_URLMON_MAIN_H
|
||||
@@ -30,6 +30,7 @@ extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
|
||||
/**********************************************************************
|
||||
* Dll lifetime tracking declaration for urlmon.dll
|
||||
@@ -54,8 +55,11 @@ typedef struct
|
||||
HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, DWORD dwSize, LPWSTR pszFileName, HANDLE *phfile, IUMCacheStream **ppstr);
|
||||
void UMCloseCacheFileStream(IUMCacheStream *pstr);
|
||||
|
||||
HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret);
|
||||
IInternetProtocolInfo *get_protocol_info(LPCWSTR url);
|
||||
HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret);
|
||||
|
||||
HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv);
|
||||
|
||||
HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol);
|
||||
|
||||
#endif /* __WINE_URLMON_MAIN_H */
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define WINE_FILENAME_STR "urlmon.dll"
|
||||
|
||||
Reference in New Issue
Block a user