Autosyncing with Wine HEAD

svn path=/trunk/; revision=27919
This commit is contained in:
The Wine Synchronizer
2007-07-27 10:11:12 +00:00
parent f0f9ff6251
commit 0c37710c2c
19 changed files with 3005 additions and 498 deletions
File diff suppressed because it is too large Load Diff
+500
View File
@@ -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;
}
+18 -12
View File
@@ -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;
+6 -6
View File
@@ -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");
+10 -10
View File
@@ -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
View File
@@ -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);
+56 -17
View File
@@ -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;
}
+322
View File
@@ -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;
}
+26 -10
View File
@@ -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]);
+2 -1
View File
@@ -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"
+30 -26
View File
@@ -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);
}
+215 -25
View File
@@ -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
View File
@@ -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;
}
/***********************************************************************
+17 -19
View File
@@ -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;
+9 -7
View File
@@ -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>
+2 -1
View 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
+337 -112
View File
@@ -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);
}
+6 -2
View File
@@ -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 */
+1 -1
View File
@@ -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"