mk.c
protocol.c
protproxy.c
- regsvr.c
sec_mgr.c
session.c
umon.c
extern IID IID_IBindStatusCallbackHolder;
typedef struct {
- const IBindStatusCallbackExVtbl *lpBindStatusCallbackExVtbl;
- const IServiceProviderVtbl *lpServiceProviderVtbl;
- const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl;
- const IAuthenticateVtbl *lpAuthenticateVtbl;
+ IBindStatusCallbackEx IBindStatusCallbackEx_iface;
+ IServiceProvider IServiceProvider_iface;
+ IHttpNegotiate2 IHttpNegotiate2_iface;
+ IAuthenticate IAuthenticate_iface;
LONG ref;
IServiceProvider *serv_prov;
} BindStatusCallback;
-#define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackExVtbl)
-#define STATUSCLBEX(x) ((IBindStatusCallbackEx*)&(x)->lpBindStatusCallbackExVtbl)
-#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
-#define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl)
-#define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpAuthenticateVtbl)
-
static void *get_callback_iface(BindStatusCallback *This, REFIID riid)
{
void *ret;
return SUCCEEDED(hres) ? ret : NULL;
}
-#define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallbackEx, iface)
+static inline BindStatusCallback *impl_from_IBindStatusCallbackEx(IBindStatusCallbackEx *iface)
+{
+ return CONTAINING_RECORD(iface, BindStatusCallback, IBindStatusCallbackEx_iface);
+}
static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface,
REFIID riid, void **ppv)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
- *ppv = STATUSCLB(This);
+ *ppv = &This->IBindStatusCallbackEx_iface;
}else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
- *ppv = STATUSCLB(This);
+ *ppv = &This->IBindStatusCallbackEx_iface;
}else if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)) {
TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
- *ppv = STATUSCLBEX(This);
+ *ppv = &This->IBindStatusCallbackEx_iface;
}else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) {
TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv);
*ppv = This;
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv);
- *ppv = SERVPROV(This);
+ *ppv = &This->IServiceProvider_iface;
}else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This, ppv);
- *ppv = HTTPNEG2(This);
+ *ppv = &This->IHttpNegotiate2_iface;
}else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This, ppv);
- *ppv = HTTPNEG2(This);
+ *ppv = &This->IHttpNegotiate2_iface;
}else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
TRACE("(%p)->(IID_IAuthenticate, %p)\n", This, ppv);
- *ppv = AUTHENTICATE(This);
+ *ppv = &This->IAuthenticate_iface;
}
if(*ppv) {
static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallbackEx *iface)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref = %d\n", This, ref);
static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallbackEx *iface)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref = %d\n", This, ref);
static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface,
DWORD dwReserved, IBinding *pbind)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
TRACE("(%p)->(%p)\n", This, pnPriority);
static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
TRACE("(%p)->(%d)\n", This, reserved);
static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
debugstr_w(szStatusText));
static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallbackEx *iface,
HRESULT hresult, LPCWSTR szError)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface,
DWORD *grfBINDF, BINDINFO *pbindinfo)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
IBindStatusCallbackEx *bscex;
HRESULT hres;
static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx *iface,
DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface,
REFIID riid, IUnknown *punk)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
static HRESULT WINAPI BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF,
BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
{
- BindStatusCallback *This = STATUSCLB_THIS(iface);
+ BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
IBindStatusCallbackEx *bscex;
HRESULT hres;
return hres;
}
-#undef STATUSCLB_THIS
-
static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
BindStatusCallback_QueryInterface,
BindStatusCallback_AddRef,
BindStatusCallback_GetBindInfoEx
};
-#define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface)
+static inline BindStatusCallback *impl_from_IServiceProvider(IServiceProvider *iface)
+{
+ return CONTAINING_RECORD(iface, BindStatusCallback, IServiceProvider_iface);
+}
static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface,
REFIID riid, void **ppv)
{
- BindStatusCallback *This = SERVPROV_THIS(iface);
- return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
+ BindStatusCallback *This = impl_from_IServiceProvider(iface);
+ return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
}
static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface)
{
- BindStatusCallback *This = SERVPROV_THIS(iface);
- return IBindStatusCallback_AddRef(STATUSCLB(This));
+ BindStatusCallback *This = impl_from_IServiceProvider(iface);
+ return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
}
static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface)
{
- BindStatusCallback *This = SERVPROV_THIS(iface);
- return IBindStatusCallback_Release(STATUSCLB(This));
+ BindStatusCallback *This = impl_from_IServiceProvider(iface);
+ return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
}
static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface,
REFGUID guidService, REFIID riid, void **ppv)
{
- BindStatusCallback *This = SERVPROV_THIS(iface);
+ BindStatusCallback *This = impl_from_IServiceProvider(iface);
HRESULT hres;
if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) {
TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv);
- return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
+ return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
}
if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) {
TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv);
- return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
+ return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
}
if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv);
- return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
+ return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
}
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
return E_NOINTERFACE;
}
-#undef SERVPROV_THIS
-
static const IServiceProviderVtbl BSCServiceProviderVtbl = {
BSCServiceProvider_QueryInterface,
BSCServiceProvider_AddRef,
BSCServiceProvider_QueryService
};
-#define HTTPNEG2_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate2, iface)
+static inline BindStatusCallback *impl_from_IHttpNegotiate2(IHttpNegotiate2 *iface)
+{
+ return CONTAINING_RECORD(iface, BindStatusCallback, IHttpNegotiate2_iface);
+}
static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface,
REFIID riid, void **ppv)
{
- BindStatusCallback *This = HTTPNEG2_THIS(iface);
- return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
+ BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
+ return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
}
static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface)
{
- BindStatusCallback *This = HTTPNEG2_THIS(iface);
- return IBindStatusCallback_AddRef(STATUSCLB(This));
+ BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
+ return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
}
static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface)
{
- BindStatusCallback *This = HTTPNEG2_THIS(iface);
- return IBindStatusCallback_Release(STATUSCLB(This));
+ BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
+ return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
}
static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface,
LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
{
- BindStatusCallback *This = HTTPNEG2_THIS(iface);
+ BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
IHttpNegotiate *http_negotiate;
HRESULT hres = S_OK;
LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,
LPWSTR *pszAdditionalRequestHeaders)
{
- BindStatusCallback *This = HTTPNEG2_THIS(iface);
+ BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
LPWSTR additional_headers = NULL;
IHttpNegotiate *http_negotiate;
HRESULT hres = S_OK;
static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
{
- BindStatusCallback *This = HTTPNEG2_THIS(iface);
+ BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
IHttpNegotiate2 *http_negotiate2;
HRESULT hres = E_FAIL;
return hres;
}
-#undef HTTPNEG2_THIS
-
static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl = {
BSCHttpNegotiate_QueryInterface,
BSCHttpNegotiate_AddRef,
BSCHttpNegotiate_GetRootSecurityId
};
-#define AUTHENTICATE_THIS(iface) DEFINE_THIS(BindStatusCallback, Authenticate, iface)
+static inline BindStatusCallback *impl_from_IAuthenticate(IAuthenticate *iface)
+{
+ return CONTAINING_RECORD(iface, BindStatusCallback, IAuthenticate_iface);
+}
static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
{
- BindStatusCallback *This = AUTHENTICATE_THIS(iface);
- return IBindStatusCallback_QueryInterface(AUTHENTICATE(This), riid, ppv);
+ BindStatusCallback *This = impl_from_IAuthenticate(iface);
+ return IBindStatusCallback_QueryInterface(&This->IAuthenticate_iface, riid, ppv);
}
static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface)
{
- BindStatusCallback *This = AUTHENTICATE_THIS(iface);
- return IBindStatusCallback_AddRef(STATUSCLB(This));
+ BindStatusCallback *This = impl_from_IAuthenticate(iface);
+ return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
}
static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface)
{
- BindStatusCallback *This = AUTHENTICATE_THIS(iface);
- return IBindStatusCallback_Release(STATUSCLB(This));
+ BindStatusCallback *This = impl_from_IAuthenticate(iface);
+ return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
}
static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface,
HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
{
- BindStatusCallback *This = AUTHENTICATE_THIS(iface);
+ BindStatusCallback *This = impl_from_IAuthenticate(iface);
FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
return E_NOTIMPL;
}
-#undef AUTHENTICATE_THIS
-
static const IAuthenticateVtbl BSCAuthenticateVtbl = {
BSCAuthenticate_QueryInterface,
BSCAuthenticate_AddRef,
if(!ret)
return E_OUTOFMEMORY;
- ret->lpBindStatusCallbackExVtbl = &BindStatusCallbackExVtbl;
- ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl;
- ret->lpHttpNegotiate2Vtbl = &BSCHttpNegotiateVtbl;
- ret->lpAuthenticateVtbl = &BSCAuthenticateVtbl;
+ ret->IBindStatusCallbackEx_iface.lpVtbl = &BindStatusCallbackExVtbl;
+ ret->IServiceProvider_iface.lpVtbl = &BSCServiceProviderVtbl;
+ ret->IHttpNegotiate2_iface.lpVtbl = &BSCHttpNegotiateVtbl;
+ ret->IAuthenticate_iface.lpVtbl = &BSCAuthenticateVtbl;
ret->ref = 1;
set_callback(ret, bsc);
- *ret_iface = STATUSCLB(ret);
+ *ret_iface = (IBindStatusCallback*)&ret->IBindStatusCallbackEx_iface;
return S_OK;
}
set_callback(holder, pbsc);
IBindStatusCallback_Release(bsc);
- IBindStatusCallback_Release(STATUSCLB(holder));
+ IBindStatusCallback_Release(&holder->IBindStatusCallbackEx_iface);
return S_OK;
}else {
prev = bsc;
if(SUCCEEDED(hres)) {
if(pbsc == holder->callback)
dorevoke = TRUE;
- IBindStatusCallback_Release(STATUSCLB(holder));
+ IBindStatusCallback_Release(&holder->IBindStatusCallbackEx_iface);
}else if(pbsc == callback) {
dorevoke = TRUE;
}
}
typedef struct {
- const IBindCtxVtbl *lpBindCtxVtbl;
+ IBindCtx IBindCtx_iface;
LONG ref;
IBindCtx *bindctx;
} AsyncBindCtx;
-#define BINDCTX(x) ((IBindCtx*) &(x)->lpBindCtxVtbl)
-
-#define BINDCTX_THIS(iface) DEFINE_THIS(AsyncBindCtx, BindCtx, iface)
+static inline AsyncBindCtx *impl_from_IBindCtx(IBindCtx *iface)
+{
+ return CONTAINING_RECORD(iface, AsyncBindCtx, IBindCtx_iface);
+}
static HRESULT WINAPI AsyncBindCtx_QueryInterface(IBindCtx *iface, REFIID riid, void **ppv)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
*ppv = NULL;
if(IsEqualGUID(riid, &IID_IUnknown)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = BINDCTX(This);
+ *ppv = &This->IBindCtx_iface;
}else if(IsEqualGUID(riid, &IID_IBindCtx)) {
TRACE("(%p)->(IID_IBindCtx %p)\n", This, ppv);
- *ppv = BINDCTX(This);
+ *ppv = &This->IBindCtx_iface;
}else if(IsEqualGUID(riid, &IID_IAsyncBindCtx)) {
TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This, ppv);
- *ppv = BINDCTX(This);
+ *ppv = &This->IBindCtx_iface;
}
if(*ppv) {
static ULONG WINAPI AsyncBindCtx_AddRef(IBindCtx *iface)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
static ULONG WINAPI AsyncBindCtx_Release(IBindCtx *iface)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
static HRESULT WINAPI AsyncBindCtx_RegisterObjectBound(IBindCtx *iface, IUnknown *punk)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%p)\n", This, punk);
static HRESULT WINAPI AsyncBindCtx_RevokeObjectBound(IBindCtx *iface, IUnknown *punk)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p %p)\n", This, punk);
static HRESULT WINAPI AsyncBindCtx_ReleaseBoundObjects(IBindCtx *iface)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)\n", This);
static HRESULT WINAPI AsyncBindCtx_SetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%p)\n", This, pbindopts);
static HRESULT WINAPI AsyncBindCtx_GetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%p)\n", This, pbindopts);
static HRESULT WINAPI AsyncBindCtx_GetRunningObjectTable(IBindCtx *iface, IRunningObjectTable **pprot)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%p)\n", This, pprot);
static HRESULT WINAPI AsyncBindCtx_RegisterObjectParam(IBindCtx *iface, LPOLESTR pszkey, IUnknown *punk)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
static HRESULT WINAPI AsyncBindCtx_GetObjectParam(IBindCtx* iface, LPOLESTR pszkey, IUnknown **punk)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR pszkey)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%s)\n", This, debugstr_w(pszkey));
static HRESULT WINAPI AsyncBindCtx_EnumObjectParam(IBindCtx *iface, IEnumString **pszkey)
{
- AsyncBindCtx *This = BINDCTX_THIS(iface);
+ AsyncBindCtx *This = impl_from_IBindCtx(iface);
TRACE("(%p)->(%p)\n", This, pszkey);
return IBindCtx_EnumObjectParam(This->bindctx, pszkey);
}
-#undef BINDCTX_THIS
-
static const IBindCtxVtbl AsyncBindCtxVtbl =
{
AsyncBindCtx_QueryInterface,
ret = heap_alloc(sizeof(AsyncBindCtx));
- ret->lpBindCtxVtbl = &AsyncBindCtxVtbl;
+ ret->IBindCtx_iface.lpVtbl = &AsyncBindCtxVtbl;
ret->ref = 1;
ret->bindctx = bindctx;
- hres = init_bindctx(BINDCTX(ret), options, callback, format);
+ hres = init_bindctx(&ret->IBindCtx_iface, options, callback, format);
if(FAILED(hres)) {
- IBindCtx_Release(BINDCTX(ret));
+ IBindCtx_Release(&ret->IBindCtx_iface);
return hres;
}
- *pbind = BINDCTX(ret);
+ *pbind = &ret->IBindCtx_iface;
return S_OK;
}
static WCHAR cbinding_contextW[] = {'C','B','i','n','d','i','n','g',' ','C','o','n','t','e','x','t',0};
static WCHAR bscb_holderW[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
-typedef struct Binding Binding;
-
-struct _task_header_t;
-
-typedef void (*task_proc_t)(Binding*, struct _task_header_t*);
-
-typedef struct _task_header_t {
- task_proc_t proc;
- struct _task_header_t *next;
-} task_header_t;
-
typedef struct {
- const IUnknownVtbl *lpUnknownVtbl;
+ IUnknown IUnknown_iface;
LONG ref;
IInternetProtocolEx *protocol;
- BYTE buf[1024*8];
- DWORD size;
- BOOL init;
HANDLE file;
HRESULT hres;
const stgmed_obj_vtbl *vtbl;
};
-#define STGMEDUNK(x) ((IUnknown*) &(x)->lpUnknownVtbl)
-
typedef enum {
BEFORE_DOWNLOAD,
DOWNLOADING,
#define BINDING_OBJAVAIL 0x0004
#define BINDING_ABORTED 0x0008
-struct Binding {
- const IBindingVtbl *lpBindingVtbl;
- const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl;
- const IInternetBindInfoVtbl *lpInternetBindInfoVtbl;
- const IWinInetHttpInfoVtbl *lpWinInetHttpInfoVtbl;
- const IServiceProviderVtbl *lpServiceProviderVtbl;
+typedef struct {
+ IBinding IBinding_iface;
+ IInternetProtocolSink IInternetProtocolSink_iface;
+ IInternetBindInfo IInternetBindInfo_iface;
+ IWinInetHttpInfo IWinInetHttpInfo_iface;
+ IServiceProvider IServiceProvider_iface;
LONG ref;
IBindStatusCallback *callback;
- IInternetProtocolEx *protocol;
IServiceProvider *service_provider;
+ BindProtocol *protocol;
+
stgmed_buf_t *stgmed_buf;
stgmed_obj_t *stgmed_obj;
HWND notif_hwnd;
CRITICAL_SECTION section;
-};
-
-#define BINDING(x) ((IBinding*) &(x)->lpBindingVtbl)
-#define BINDINF(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
-#define INETINFO(x) ((IWinInetHttpInfo*) &(x)->lpWinInetHttpInfoVtbl)
-#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
-
-#define STREAM(x) ((IStream*) &(x)->lpStreamVtbl)
-#define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl)
-
-static void fill_stgmed_buffer(stgmed_buf_t *buf)
-{
- DWORD read = 0;
-
- if(sizeof(buf->buf) == buf->size)
- return;
-
- buf->hres = IInternetProtocol_Read(buf->protocol, buf->buf+buf->size,
- sizeof(buf->buf)-buf->size, &read);
- buf->size += read;
- if(read > 0)
- buf->init = TRUE;
-}
+} Binding;
static void read_protocol_data(stgmed_buf_t *stgmed_buf)
{
DWORD read;
HRESULT hres;
- fill_stgmed_buffer(stgmed_buf);
- if(stgmed_buf->size < sizeof(stgmed_buf->buf))
- return;
-
do hres = IInternetProtocol_Read(stgmed_buf->protocol, buf, sizeof(buf), &read);
while(hres == S_OK);
}
static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str)
{
if(binding->state & BINDING_LOCKED) {
- IInternetProtocol_UnlockRequest(binding->protocol);
+ IInternetProtocolEx_UnlockRequest(&binding->protocol->IInternetProtocolEx_iface);
binding->state &= ~BINDING_LOCKED;
}
}
IBindCtx_RevokeObjectParam(bctx, bscb_holderW);
- IBindCtx_RegisterObjectParam(bctx, cbinding_contextW, (IUnknown*)BINDING(binding));
+ IBindCtx_RegisterObjectParam(bctx, cbinding_contextW, (IUnknown*)&binding->IBinding_iface);
hres = IPersistMoniker_Load(persist, binding->download_state == END_DOWNLOAD, binding->mon, bctx, 0x12);
IBindCtx_RevokeObjectParam(bctx, cbinding_contextW);
stop_binding(binding, hres, NULL);
if(FAILED(hres))
- IInternetProtocol_Terminate(binding->protocol, 0);
+ IInternetProtocolEx_Terminate(&binding->protocol->IInternetProtocolEx_iface, 0);
}
static void cache_file_available(Binding *This, const WCHAR *file_name)
}
}
-#define STGMEDUNK_THIS(iface) DEFINE_THIS(stgmed_buf_t, Unknown, iface)
+static inline stgmed_buf_t *impl_from_IUnknown(IUnknown *iface)
+{
+ return CONTAINING_RECORD(iface, stgmed_buf_t, IUnknown_iface);
+}
static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
- stgmed_buf_t *This = STGMEDUNK_THIS(iface);
+ stgmed_buf_t *This = impl_from_IUnknown(iface);
*ppv = NULL;
if(IsEqualGUID(riid, &IID_IUnknown)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = STGMEDUNK(This);
- IUnknown_AddRef(STGMEDUNK(This));
+ *ppv = &This->IUnknown_iface;
+ IUnknown_AddRef(&This->IUnknown_iface);
return S_OK;
}
static ULONG WINAPI StgMedUnk_AddRef(IUnknown *iface)
{
- stgmed_buf_t *This = STGMEDUNK_THIS(iface);
+ stgmed_buf_t *This = impl_from_IUnknown(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
static ULONG WINAPI StgMedUnk_Release(IUnknown *iface)
{
- stgmed_buf_t *This = STGMEDUNK_THIS(iface);
+ stgmed_buf_t *This = impl_from_IUnknown(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
-#undef STGMEDUNK_THIS
-
static const IUnknownVtbl StgMedUnkVtbl = {
StgMedUnk_QueryInterface,
StgMedUnk_AddRef,
{
stgmed_buf_t *ret = heap_alloc(sizeof(*ret));
- ret->lpUnknownVtbl = &StgMedUnkVtbl;
+ ret->IUnknown_iface.lpVtbl = &StgMedUnkVtbl;
ret->ref = 1;
- ret->size = 0;
- ret->init = FALSE;
ret->file = INVALID_HANDLE_VALUE;
ret->hres = S_OK;
ret->cache_file = NULL;
typedef struct {
stgmed_obj_t stgmed_obj;
- const IStreamVtbl *lpStreamVtbl;
+ IStream IStream_iface;
LONG ref;
stgmed_buf_t *buf;
} ProtocolStream;
-#define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface)
+static inline ProtocolStream *impl_from_IStream(IStream *iface)
+{
+ return CONTAINING_RECORD(iface, ProtocolStream, IStream_iface);
+}
static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface,
REFIID riid, void **ppv)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = STREAM(This);
+ *ppv = &This->IStream_iface;
}else if(IsEqualGUID(&IID_ISequentialStream, riid)) {
TRACE("(%p)->(IID_ISequentialStream %p)\n", This, ppv);
- *ppv = STREAM(This);
+ *ppv = &This->IStream_iface;
}else if(IsEqualGUID(&IID_IStream, riid)) {
TRACE("(%p)->(IID_IStream %p)\n", This, ppv);
- *ppv = STREAM(This);
+ *ppv = &This->IStream_iface;
}
if(*ppv) {
- IStream_AddRef(STREAM(This));
+ IStream_AddRef(&This->IStream_iface);
return S_OK;
}
static ULONG WINAPI ProtocolStream_AddRef(IStream *iface)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
static ULONG WINAPI ProtocolStream_Release(IStream *iface)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
- IUnknown_Release(STGMEDUNK(This->buf));
+ IUnknown_Release(&This->buf->IUnknown_iface);
heap_free(This);
URLMON_UnlockModule();
static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv,
ULONG cb, ULONG *pcbRead)
{
- ProtocolStream *This = STREAM_THIS(iface);
- DWORD read = 0, pread = 0;
+ ProtocolStream *This = impl_from_IStream(iface);
+ DWORD read = 0;
HRESULT hres;
TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead);
- if(This->buf->file != INVALID_HANDLE_VALUE) {
- if (!ReadFile(This->buf->file, pv, cb, &read, NULL))
- return INET_E_DOWNLOAD_FAILURE;
-
- if(pcbRead)
- *pcbRead = read;
- return read ? S_OK : S_FALSE;
- }
-
- if(This->buf->size) {
- read = cb;
-
- if(read > This->buf->size)
- read = This->buf->size;
-
- memcpy(pv, This->buf->buf, read);
-
- if(read < This->buf->size)
- memmove(This->buf->buf, This->buf->buf+read, This->buf->size-read);
- This->buf->size -= read;
- }
-
- if(read == cb) {
- if (pcbRead)
- *pcbRead = read;
- return S_OK;
+ if(This->buf->file == INVALID_HANDLE_VALUE) {
+ hres = This->buf->hres = IInternetProtocol_Read(This->buf->protocol, (PBYTE)pv, cb, &read);
+ }else {
+ hres = ReadFile(This->buf->file, pv, cb, &read, NULL) ? S_OK : INET_E_DOWNLOAD_FAILURE;
}
- hres = This->buf->hres = IInternetProtocol_Read(This->buf->protocol, (PBYTE)pv+read, cb-read, &pread);
if (pcbRead)
- *pcbRead = read + pread;
+ *pcbRead = read;
if(hres == E_PENDING)
return E_PENDING;
else if(FAILED(hres))
FIXME("Read failed: %08x\n", hres);
- return read || pread ? S_OK : S_FALSE;
+ return read ? S_OK : S_FALSE;
}
static HRESULT WINAPI ProtocolStream_Write(IStream *iface, const void *pv,
ULONG cb, ULONG *pcbWritten)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbWritten);
static HRESULT WINAPI ProtocolStream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
FIXME("(%p)->(%d %08x %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolStream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
FIXME("(%p)->(%d)\n", This, libNewSize.u.LowPart);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolStream_CopyTo(IStream *iface, IStream *pstm,
ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
FIXME("(%p)->(%p %d %p %p)\n", This, pstm, cb.u.LowPart, pcbRead, pcbWritten);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolStream_Commit(IStream *iface, DWORD grfCommitFlags)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
TRACE("(%p)->(%08x)\n", This, grfCommitFlags);
static HRESULT WINAPI ProtocolStream_Revert(IStream *iface)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
TRACE("(%p)\n", This);
static HRESULT WINAPI ProtocolStream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb, DWORD dwLockType)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
FIXME("(%p)->(%d %d %d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolStream_UnlockRegion(IStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
FIXME("(%p)->(%d %d %d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolStream_Stat(IStream *iface, STATSTG *pstatstg,
DWORD dwStatFlag)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
TRACE("(%p)->(%p %08x)\n", This, pstatstg, dwStatFlag);
if(!pstatstg)
static HRESULT WINAPI ProtocolStream_Clone(IStream *iface, IStream **ppstm)
{
- ProtocolStream *This = STREAM_THIS(iface);
+ ProtocolStream *This = impl_from_IStream(iface);
FIXME("(%p)->(%p)\n", This, ppstm);
return E_NOTIMPL;
}
-#undef STREAM_THIS
-
static const IStreamVtbl ProtocolStreamVtbl = {
ProtocolStream_QueryInterface,
ProtocolStream_AddRef,
static void stgmed_stream_release(stgmed_obj_t *obj)
{
ProtocolStream *stream = (ProtocolStream*)obj;
- IStream_Release(STREAM(stream));
+ IStream_Release(&stream->IStream_iface);
}
static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
ProtocolStream *stream = (ProtocolStream*)obj;
stgmed->tymed = TYMED_ISTREAM;
- stgmed->u.pstm = STREAM(stream);
- stgmed->pUnkForRelease = STGMEDUNK(stream->buf);
+ stgmed->u.pstm = &stream->IStream_iface;
+ stgmed->pUnkForRelease = &stream->buf->IUnknown_iface;
return S_OK;
}
ProtocolStream *stream = (ProtocolStream*)obj;
if(!(bindf & BINDF_ASYNCHRONOUS) && stream->buf->file == INVALID_HANDLE_VALUE
- && (stream->buf->hres != S_FALSE || stream->buf->size))
+ && stream->buf->hres != S_FALSE)
return INET_E_DATA_NOT_AVAILABLE;
- IStream_AddRef(STREAM(stream));
- *result = STREAM(stream);
+ IStream_AddRef(&stream->IStream_iface);
+ *result = &stream->IStream_iface;
return S_OK;
}
ProtocolStream *ret = heap_alloc(sizeof(ProtocolStream));
ret->stgmed_obj.vtbl = &stgmed_stream_vtbl;
- ret->lpStreamVtbl = &ProtocolStreamVtbl;
+ ret->IStream_iface.lpVtbl = &ProtocolStreamVtbl;
ret->ref = 1;
- IUnknown_AddRef(STGMEDUNK(buf));
+ IUnknown_AddRef(&buf->IUnknown_iface);
ret->buf = buf;
URLMON_LockModule();
{
stgmed_file_obj_t *file_obj = (stgmed_file_obj_t*)obj;
- IUnknown_Release(STGMEDUNK(file_obj->buf));
+ IUnknown_Release(&file_obj->buf->IUnknown_iface);
heap_free(file_obj);
}
stgmed->tymed = TYMED_FILE;
stgmed->u.lpszFileName = file_obj->buf->cache_file;
- stgmed->pUnkForRelease = STGMEDUNK(file_obj->buf);
+ stgmed->pUnkForRelease = &file_obj->buf->IUnknown_iface;
return S_OK;
}
ret->stgmed_obj.vtbl = &stgmed_file_vtbl;
- IUnknown_AddRef(STGMEDUNK(buf));
+ IUnknown_AddRef(&buf->IUnknown_iface);
ret->buf = buf;
return &ret->stgmed_obj;
}
-#define BINDING_THIS(iface) DEFINE_THIS(Binding, Binding, iface)
+static inline Binding *impl_from_IBinding(IBinding *iface)
+{
+ return CONTAINING_RECORD(iface, Binding, IBinding_iface);
+}
static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void **ppv)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = BINDING(This);
+ *ppv = &This->IBinding_iface;
}else if(IsEqualGUID(&IID_IBinding, riid)) {
TRACE("(%p)->(IID_IBinding %p)\n", This, ppv);
- *ppv = BINDING(This);
+ *ppv = &This->IBinding_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
- *ppv = PROTSINK(This);
+ *ppv = &This->IInternetProtocolSink_iface;
}else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv);
- *ppv = BINDINF(This);
+ *ppv = &This->IInternetBindInfo_iface;
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
- *ppv = SERVPROV(This);
+ *ppv = &This->IServiceProvider_iface;
}else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv);
/* NOTE: This violidates COM rules, but tests prove that we should do it */
- if(!get_wininet_info(This->protocol))
+ if(!This->protocol->wininet_info)
return E_NOINTERFACE;
- *ppv = INETINFO(This);
+ *ppv = &This->IWinInetHttpInfo_iface;
}else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
- IWinInetHttpInfo *http_info;
- IWinInetInfo *info;
- HRESULT hres;
-
TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv);
- info = get_wininet_info(This->protocol);
- if(!info)
- return E_NOINTERFACE;
-
- hres = IWinInetInfo_QueryInterface(info, &IID_IWinInetHttpInfo, (void**)&http_info);
- if(FAILED(hres))
+ if(!This->protocol->wininet_http_info)
return E_NOINTERFACE;
- IWinInetHttpInfo_Release(http_info);
- *ppv = INETINFO(This);
+ *ppv = &This->IWinInetHttpInfo_iface;
}
if(*ppv) {
- IBinding_AddRef(BINDING(This));
+ IBinding_AddRef(&This->IBinding_iface);
return S_OK;
}
static ULONG WINAPI Binding_AddRef(IBinding *iface)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
static ULONG WINAPI Binding_Release(IBinding *iface)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(This->callback)
IBindStatusCallback_Release(This->callback);
if(This->protocol)
- IInternetProtocol_Release(This->protocol);
+ IInternetProtocolEx_Release(&This->protocol->IInternetProtocolEx_iface);
if(This->service_provider)
IServiceProvider_Release(This->service_provider);
if(This->stgmed_buf)
- IUnknown_Release(STGMEDUNK(This->stgmed_buf));
+ IUnknown_Release(&This->stgmed_buf->IUnknown_iface);
if(This->stgmed_obj)
This->stgmed_obj->vtbl->release(This->stgmed_obj);
if(This->obj)
static HRESULT WINAPI Binding_Abort(IBinding *iface)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
HRESULT hres;
TRACE("(%p)\n", This);
if(This->state & BINDING_ABORTED)
return E_FAIL;
- hres = IInternetProtocol_Abort(This->protocol, E_ABORT, ERROR_SUCCESS);
+ hres = IInternetProtocolEx_Abort(&This->protocol->IInternetProtocolEx_iface, E_ABORT,
+ ERROR_SUCCESS);
if(FAILED(hres))
return hres;
static HRESULT WINAPI Binding_Suspend(IBinding *iface)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI Binding_Resume(IBinding *iface)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI Binding_SetPriority(IBinding *iface, LONG nPriority)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
FIXME("(%p)->(%d)\n", This, nPriority);
return E_NOTIMPL;
}
static HRESULT WINAPI Binding_GetPriority(IBinding *iface, LONG *pnPriority)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
FIXME("(%p)->(%p)\n", This, pnPriority);
return E_NOTIMPL;
}
static HRESULT WINAPI Binding_GetBindResult(IBinding *iface, CLSID *pclsidProtocol,
DWORD *pdwResult, LPOLESTR *pszResult, DWORD *pdwReserved)
{
- Binding *This = BINDING_THIS(iface);
+ Binding *This = impl_from_IBinding(iface);
FIXME("(%p)->(%p %p %p %p)\n", This, pclsidProtocol, pdwResult, pszResult, pdwReserved);
return E_NOTIMPL;
}
+static const IBindingVtbl BindingVtbl = {
+ Binding_QueryInterface,
+ Binding_AddRef,
+ Binding_Release,
+ Binding_Abort,
+ Binding_Suspend,
+ Binding_Resume,
+ Binding_SetPriority,
+ Binding_GetPriority,
+ Binding_GetBindResult
+};
+
static Binding *get_bctx_binding(IBindCtx *bctx)
{
IBinding *binding;
if(FAILED(hres))
return NULL;
- hres = IUnknown_QueryInterface(unk, &IID_IBinding, (void*)&binding);
+ hres = IUnknown_QueryInterface(unk, &IID_IBinding, (void**)&binding);
IUnknown_Release(unk);
if(FAILED(hres))
return NULL;
- /* FIXME!!! */
- return BINDING_THIS(binding);
+ if (binding->lpVtbl != &BindingVtbl)
+ return NULL;
+ return impl_from_IBinding(binding);
}
-#undef BINDING_THIS
-
-static const IBindingVtbl BindingVtbl = {
- Binding_QueryInterface,
- Binding_AddRef,
- Binding_Release,
- Binding_Abort,
- Binding_Suspend,
- Binding_Resume,
- Binding_SetPriority,
- Binding_GetPriority,
- Binding_GetBindResult
-};
-
-#define PROTSINK_THIS(iface) DEFINE_THIS(Binding, IInternetProtocolSink, iface)
+static inline Binding *impl_from_IInternetProtocolSink(IInternetProtocolSink *iface)
+{
+ return CONTAINING_RECORD(iface, Binding, IInternetProtocolSink_iface);
+}
static HRESULT WINAPI InternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
REFIID riid, void **ppv)
{
- Binding *This = PROTSINK_THIS(iface);
- return IBinding_QueryInterface(BINDING(This), riid, ppv);
+ Binding *This = impl_from_IInternetProtocolSink(iface);
+ return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
}
static ULONG WINAPI InternetProtocolSink_AddRef(IInternetProtocolSink *iface)
{
- Binding *This = PROTSINK_THIS(iface);
- return IBinding_AddRef(BINDING(This));
+ Binding *This = impl_from_IInternetProtocolSink(iface);
+ return IBinding_AddRef(&This->IBinding_iface);
}
static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface)
{
- Binding *This = PROTSINK_THIS(iface);
- return IBinding_Release(BINDING(This));
+ Binding *This = impl_from_IInternetProtocolSink(iface);
+ return IBinding_Release(&This->IBinding_iface);
}
static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface,
PROTOCOLDATA *pProtocolData)
{
- Binding *This = PROTSINK_THIS(iface);
+ Binding *This = impl_from_IInternetProtocolSink(iface);
WARN("(%p)->(%p)\n", This, pProtocolData);
static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
ULONG ulStatusCode, LPCWSTR szStatusText)
{
- Binding *This = PROTSINK_THIS(iface);
+ Binding *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
on_progress(This, 0, 0, BINDSTATUS_REDIRECTING, szStatusText);
break;
case BINDSTATUS_BEGINDOWNLOADDATA:
- fill_stgmed_buffer(This->stgmed_buf);
break;
case BINDSTATUS_SENDINGREQUEST:
on_progress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, szStatusText);
TRACE("(%p)->(%d %u %u)\n", This, bscf, progress, progress_max);
- if(This->download_state == END_DOWNLOAD || (This->state & (BINDING_STOPPED|BINDING_ABORTED)))
+ if(This->download_state == END_DOWNLOAD || (This->state & BINDING_ABORTED)) {
+ read_protocol_data(This->stgmed_buf);
+ return;
+ }
+
+ if(This->state & BINDING_STOPPED)
return;
if(This->stgmed_buf->file != INVALID_HANDLE_VALUE)
read_protocol_data(This->stgmed_buf);
- else if(This->download_state == BEFORE_DOWNLOAD)
- fill_stgmed_buffer(This->stgmed_buf);
if(This->download_state == BEFORE_DOWNLOAD) {
This->download_state = DOWNLOADING;
if(This->to_object) {
if(!(This->state & BINDING_OBJAVAIL)) {
- IBinding_AddRef(BINDING(This));
+ IBinding_AddRef(&This->IBinding_iface);
create_object(This);
- IBinding_Release(BINDING(This));
+ IBinding_Release(&This->IBinding_iface);
}
}else {
STGMEDIUM stgmed;
HRESULT hres;
if(!(This->state & BINDING_LOCKED)) {
- HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0);
+ HRESULT hres = IInternetProtocolEx_LockRequest(
+ &This->protocol->IInternetProtocolEx_iface, 0);
if(SUCCEEDED(hres))
This->state |= BINDING_LOCKED;
}
static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface,
DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
- Binding *This = PROTSINK_THIS(iface);
+ Binding *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
{
- Binding *This = PROTSINK_THIS(iface);
+ Binding *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
stop_binding(This, hrResult, szResult);
- IInternetProtocol_Terminate(This->protocol, 0);
+ IInternetProtocolEx_Terminate(&This->protocol->IInternetProtocolEx_iface, 0);
return S_OK;
}
-#undef PROTSINK_THIS
-
static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
InternetProtocolSink_QueryInterface,
InternetProtocolSink_AddRef,
InternetProtocolSink_ReportResult
};
-#define BINDINF_THIS(iface) DEFINE_THIS(Binding, InternetBindInfo, iface)
+static inline Binding *impl_from_IInternetBindInfo(IInternetBindInfo *iface)
+{
+ return CONTAINING_RECORD(iface, Binding, IInternetBindInfo_iface);
+}
static HRESULT WINAPI InternetBindInfo_QueryInterface(IInternetBindInfo *iface,
REFIID riid, void **ppv)
{
- Binding *This = BINDINF_THIS(iface);
- return IBinding_QueryInterface(BINDING(This), riid, ppv);
+ Binding *This = impl_from_IInternetBindInfo(iface);
+ return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
}
static ULONG WINAPI InternetBindInfo_AddRef(IInternetBindInfo *iface)
{
- Binding *This = BINDINF_THIS(iface);
- return IBinding_AddRef(BINDING(This));
+ Binding *This = impl_from_IInternetBindInfo(iface);
+ return IBinding_AddRef(&This->IBinding_iface);
}
static ULONG WINAPI InternetBindInfo_Release(IInternetBindInfo *iface)
{
- Binding *This = BINDINF_THIS(iface);
- return IBinding_Release(BINDING(This));
+ Binding *This = impl_from_IInternetBindInfo(iface);
+ return IBinding_Release(&This->IBinding_iface);
}
static HRESULT WINAPI InternetBindInfo_GetBindInfo(IInternetBindInfo *iface,
DWORD *grfBINDF, BINDINFO *pbindinfo)
{
- Binding *This = BINDINF_THIS(iface);
+ Binding *This = impl_from_IInternetBindInfo(iface);
TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
static HRESULT WINAPI InternetBindInfo_GetBindString(IInternetBindInfo *iface,
ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
{
- Binding *This = BINDINF_THIS(iface);
+ Binding *This = impl_from_IInternetBindInfo(iface);
TRACE("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
return E_NOTIMPL;
}
-#undef BINDF_THIS
-
static const IInternetBindInfoVtbl InternetBindInfoVtbl = {
InternetBindInfo_QueryInterface,
InternetBindInfo_AddRef,
InternetBindInfo_GetBindString
};
-#define INETINFO_THIS(iface) DEFINE_THIS(Binding, WinInetHttpInfo, iface)
+static inline Binding *impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface)
+{
+ return CONTAINING_RECORD(iface, Binding, IWinInetHttpInfo_iface);
+}
static HRESULT WINAPI WinInetHttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv)
{
- Binding *This = INETINFO_THIS(iface);
- return IBinding_QueryInterface(BINDING(This), riid, ppv);
+ Binding *This = impl_from_IWinInetHttpInfo(iface);
+ return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
}
static ULONG WINAPI WinInetHttpInfo_AddRef(IWinInetHttpInfo *iface)
{
- Binding *This = INETINFO_THIS(iface);
- return IBinding_AddRef(BINDING(This));
+ Binding *This = impl_from_IWinInetHttpInfo(iface);
+ return IBinding_AddRef(&This->IBinding_iface);
}
static ULONG WINAPI WinInetHttpInfo_Release(IWinInetHttpInfo *iface)
{
- Binding *This = INETINFO_THIS(iface);
- return IBinding_Release(BINDING(This));
+ Binding *This = impl_from_IWinInetHttpInfo(iface);
+ return IBinding_Release(&This->IBinding_iface);
}
static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption,
void *pBuffer, DWORD *pcbBuffer)
{
- Binding *This = INETINFO_THIS(iface);
- FIXME("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
- return E_NOTIMPL;
+ Binding *This = impl_from_IWinInetHttpInfo(iface);
+ TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
+
+ if(!This->protocol->wininet_info)
+ return E_FAIL;
+
+ return IWinInetInfo_QueryOption(This->protocol->wininet_info,
+ dwOption, pBuffer, pcbBuffer);
}
static HRESULT WINAPI WinInetHttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption,
void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
{
- Binding *This = INETINFO_THIS(iface);
- FIXME("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
- return E_NOTIMPL;
-}
+ Binding *This = impl_from_IWinInetHttpInfo(iface);
+ TRACE("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
+
+ if(!This->protocol->wininet_http_info)
+ return E_FAIL;
-#undef INETINFO_THIS
+ return IWinInetHttpInfo_QueryInfo(This->protocol->wininet_http_info,
+ dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
+}
static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = {
WinInetHttpInfo_QueryInterface,
WinInetHttpInfo_QueryInfo
};
-#define SERVPROV_THIS(iface) DEFINE_THIS(Binding, ServiceProvider, iface)
+static inline Binding *impl_from_IServiceProvider(IServiceProvider *iface)
+{
+ return CONTAINING_RECORD(iface, Binding, IServiceProvider_iface);
+}
static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface,
REFIID riid, void **ppv)
{
- Binding *This = SERVPROV_THIS(iface);
- return IBinding_QueryInterface(BINDING(This), riid, ppv);
+ Binding *This = impl_from_IServiceProvider(iface);
+ return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
}
static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
{
- Binding *This = SERVPROV_THIS(iface);
- return IBinding_AddRef(BINDING(This));
+ Binding *This = impl_from_IServiceProvider(iface);
+ return IBinding_AddRef(&This->IBinding_iface);
}
static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
{
- Binding *This = SERVPROV_THIS(iface);
- return IBinding_Release(BINDING(This));
+ Binding *This = impl_from_IServiceProvider(iface);
+ return IBinding_Release(&This->IBinding_iface);
}
static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
REFGUID guidService, REFIID riid, void **ppv)
{
- Binding *This = SERVPROV_THIS(iface);
+ Binding *This = impl_from_IServiceProvider(iface);
HRESULT hres;
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
}
WARN("unknown service %s\n", debugstr_guid(guidService));
- return E_NOTIMPL;
+ return E_NOINTERFACE;
}
-#undef SERVPROV_THIS
-
static const IServiceProviderVtbl ServiceProviderVtbl = {
ServiceProvider_QueryInterface,
ServiceProvider_AddRef,
ret = heap_alloc_zero(sizeof(Binding));
- ret->lpBindingVtbl = &BindingVtbl;
- ret->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
- ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl;
- ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl;
- ret->lpServiceProviderVtbl = &ServiceProviderVtbl;
+ ret->IBinding_iface.lpVtbl = &BindingVtbl;
+ ret->IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkVtbl;
+ ret->IInternetBindInfo_iface.lpVtbl = &InternetBindInfoVtbl;
+ ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl;
+ ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
ret->ref = 1;
hres = get_callback(pbc, &ret->callback);
if(FAILED(hres)) {
WARN("Could not get IBindStatusCallback\n");
- IBinding_Release(BINDING(ret));
+ IBinding_Release(&ret->IBinding_iface);
return hres;
}
if(binding_ctx) {
ret->protocol = binding_ctx->protocol;
- IInternetProtocol_AddRef(ret->protocol);
+ IInternetProtocolEx_AddRef(&ret->protocol->IInternetProtocolEx_iface);
}else {
hres = create_binding_protocol(TRUE, &ret->protocol);
if(FAILED(hres)) {
WARN("Could not get protocol handler\n");
- IBinding_Release(BINDING(ret));
+ IBinding_Release(&ret->IBinding_iface);
return hres;
}
}
hres = IBindStatusCallback_GetBindInfo(ret->callback, &ret->bindf, &ret->bindinfo);
if(FAILED(hres)) {
WARN("GetBindInfo failed: %08x\n", hres);
- IBinding_Release(BINDING(ret));
+ IBinding_Release(&ret->IBinding_iface);
return hres;
}
if(to_obj)
ret->bindinfo.dwOptions |= 0x100000;
- if(!(ret->bindf & BINDF_ASYNCHRONOUS)) {
+ if(!(ret->bindf & BINDF_ASYNCHRONOUS) || !(ret->bindf & BINDF_PULLDATA)) {
ret->bindf |= BINDF_NEEDFILE;
ret->use_cache_file = TRUE;
}else if(!is_urlmon_protocol(uri)) {
hres = IUri_GetDisplayUri(uri, &ret->url);
if(FAILED(hres)) {
- IBinding_Release(BINDING(ret));
+ IBinding_Release(&ret->IBinding_iface);
return hres;
}
if(binding_ctx) {
ret->stgmed_buf = binding_ctx->stgmed_buf;
- IUnknown_AddRef(STGMEDUNK(ret->stgmed_buf));
+ IUnknown_AddRef(&ret->stgmed_buf->IUnknown_iface);
ret->clipboard_format = binding_ctx->clipboard_format;
}else {
- ret->stgmed_buf = create_stgmed_buf(ret->protocol);
+ ret->stgmed_buf = create_stgmed_buf(&ret->protocol->IInternetProtocolEx_iface);
}
if(to_obj) {
ret->stgmed_obj = create_stgmed_file(ret->stgmed_buf);
}else {
FIXME("Unsupported riid %s\n", debugstr_guid(riid));
- IBinding_Release(BINDING(ret));
+ IBinding_Release(&ret->IBinding_iface);
return E_NOTIMPL;
}
if(FAILED(hres))
return hres;
- hres = IBindStatusCallback_OnStartBinding(binding->callback, 0, BINDING(binding));
+ hres = IBindStatusCallback_OnStartBinding(binding->callback, 0, &binding->IBinding_iface);
if(FAILED(hres)) {
WARN("OnStartBinding failed: %08x\n", hres);
- stop_binding(binding, INET_E_DOWNLOAD_FAILURE, NULL);
- IBinding_Release(BINDING(binding));
+ if(hres != E_ABORT && hres != E_NOTIMPL)
+ hres = INET_E_DOWNLOAD_FAILURE;
+
+ stop_binding(binding, hres, NULL);
+ IBinding_Release(&binding->IBinding_iface);
return hres;
}
if(binding_ctx) {
- set_binding_sink(binding->protocol, PROTSINK(binding), BINDINF(binding));
+ set_binding_sink(binding->protocol, &binding->IInternetProtocolSink_iface,
+ &binding->IInternetBindInfo_iface);
if(binding_ctx->redirect_url)
IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_REDIRECTING, binding_ctx->redirect_url);
report_data(binding, BSCF_FIRSTDATANOTIFICATION | (binding_ctx->download_state == END_DOWNLOAD ? BSCF_LASTDATANOTIFICATION : 0),
0, 0);
}else {
- hres = IInternetProtocolEx_StartEx(binding->protocol, uri, PROTSINK(binding),
- BINDINF(binding), PI_APARTMENTTHREADED|PI_MIMEVERIFICATION, 0);
+ hres = IInternetProtocolEx_StartEx(&binding->protocol->IInternetProtocolEx_iface, uri,
+ &binding->IInternetProtocolSink_iface, &binding->IInternetBindInfo_iface,
+ PI_APARTMENTTHREADED|PI_MIMEVERIFICATION, 0);
TRACE("start ret %08x\n", hres);
if(FAILED(hres) && hres != E_PENDING) {
stop_binding(binding, hres, NULL);
- IBinding_Release(BINDING(binding));
+ IBinding_Release(&binding->IBinding_iface);
return hres;
}
Binding *binding = NULL, *binding_ctx;
HRESULT hres;
- *ppv = NULL;
-
binding_ctx = get_bctx_binding(pbc);
hres = start_binding(NULL, binding_ctx, uri, pbc, FALSE, riid, &binding);
if(binding_ctx)
- IBinding_Release(BINDING(binding_ctx));
+ IBinding_Release(&binding_ctx->IBinding_iface);
if(FAILED(hres))
return hres;
- if(binding->hres == S_OK && binding->stgmed_buf->init) {
+ if(binding->hres == S_OK && binding->download_state != BEFORE_DOWNLOAD /* FIXME */) {
if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED))
- IInternetProtocol_UnlockRequest(binding->protocol);
+ IInternetProtocolEx_UnlockRequest(&binding->protocol->IInternetProtocolEx_iface);
hres = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj, binding->bindf, ppv);
}else if(binding->bindf & BINDF_ASYNCHRONOUS) {
hres = FAILED(binding->hres) ? binding->hres : S_OK;
}
- IBinding_Release(BINDING(binding));
+ IBinding_Release(&binding->IBinding_iface);
return hres;
}
hres = S_OK;
}
- IBinding_Release(BINDING(binding));
+ IBinding_Release(&binding->IBinding_iface);
return hres;
}
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-typedef struct BindProtocol BindProtocol;
+typedef void (*task_proc_t)(BindProtocol*,task_header_t*);
-struct _task_header_t;
-
-typedef void (*task_proc_t)(BindProtocol*,struct _task_header_t*);
-
-typedef struct _task_header_t {
+struct _task_header_t {
task_proc_t proc;
- struct _task_header_t *next;
-} task_header_t;
-
-struct BindProtocol {
- const IInternetProtocolExVtbl *lpIInternetProtocolExVtbl;
- const IInternetBindInfoVtbl *lpInternetBindInfoVtbl;
- const IInternetPriorityVtbl *lpInternetPriorityVtbl;
- const IServiceProviderVtbl *lpServiceProviderVtbl;
- const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl;
- const IWinInetHttpInfoVtbl *lpIWinInetHttpInfoVtbl;
-
- LONG ref;
-
- IInternetProtocol *protocol;
- IInternetBindInfo *bind_info;
- IInternetProtocolSink *protocol_sink;
- IServiceProvider *service_provider;
- IWinInetInfo *wininet_info;
-
- struct {
- IInternetProtocol IInternetProtocol_iface;
- } default_protocol_handler;
- IInternetProtocol *protocol_handler;
-
- LONG priority;
-
- BOOL reported_result;
- BOOL reported_mime;
- BOOL from_urlmon;
- DWORD pi;
-
- DWORD apartment_thread;
- HWND notif_hwnd;
- DWORD continue_call;
-
- CRITICAL_SECTION section;
- task_header_t *task_queue_head, *task_queue_tail;
-
- BYTE *buf;
- DWORD buf_size;
- LPWSTR mime;
- IUri *uri;
- ProtocolProxy *filter_proxy;
+ task_header_t *next;
};
-#define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
-#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
-#define HTTPINFO(x) ((IWinInetHttpInfo*) &(x)->lpIWinInetHttpInfoVtbl)
-#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
-#define PROTOCOLEX(x) ((IInternetProtocolEx*) &(x)->lpIInternetProtocolExVtbl)
-
-#define PROTOCOLHANDLER(x) ((IInternetProtocol*) &(x)->lpIInternetProtocolHandlerVtbl)
-
#define BUFFER_SIZE 2048
#define MIME_TEST_SIZE 255
This->continue_call--;
}
- IInternetProtocolEx_Release(PROTOCOLEX(This));
+ IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
return 0;
}
case WM_MK_RELEASE: {
LeaveCriticalSection(&This->section);
if(do_post) {
- IInternetProtocolEx_AddRef(PROTOCOLEX(This));
+ IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This);
}
}
IInternetProtocol_AddRef(mime_filter);
This->protocol_handler = mime_filter;
- filter_data.pProtocol = PROTOCOL(filter_proxy);
- hres = IInternetProtocol_Start(mime_filter, mime, PROTSINK(filter_proxy), BINDINFO(This),
- PI_FILTER_MODE|PI_FORCE_ASYNC, (HANDLE_PTR)&filter_data);
+ filter_data.pProtocol = &filter_proxy->IInternetProtocol_iface;
+ hres = IInternetProtocol_Start(mime_filter, mime, &filter_proxy->IInternetProtocolSink_iface,
+ &This->IInternetBindInfo_iface, PI_FILTER_MODE|PI_FORCE_ASYNC,
+ (HANDLE_PTR)&filter_data);
if(FAILED(hres)) {
IInternetProtocolSink_Release(old_sink);
return hres;
}
}
-#define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocolEx, iface)
+static inline BindProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
+{
+ return CONTAINING_RECORD(iface, BindProtocol, IInternetProtocolEx_iface);
+}
static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = PROTOCOLEX(This);
+ *ppv = &This->IInternetProtocolEx_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
- *ppv = PROTOCOLEX(This);
+ *ppv = &This->IInternetProtocolEx_iface;
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
- *ppv = PROTOCOLEX(This);
+ *ppv = &This->IInternetProtocolEx_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
- *ppv = PROTOCOLEX(This);
+ *ppv = &This->IInternetProtocolEx_iface;
}else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv);
- *ppv = BINDINFO(This);
+ *ppv = &This->IInternetBindInfo_iface;
}else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
- *ppv = PRIORITY(This);
+ *ppv = &This->IInternetPriority_iface;
}else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
- *ppv = SERVPROV(This);
+ *ppv = &This->IServiceProvider_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
- *ppv = PROTSINK(This);
+ *ppv = &This->IInternetProtocolSink_iface;
}else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv);
hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetInfo, (void**)&inet_info);
if(SUCCEEDED(hres)) {
- *ppv = HTTPINFO(This);
+ *ppv = &This->IWinInetHttpInfo_iface;
IWinInetInfo_Release(inet_info);
}
}
hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
if(SUCCEEDED(hres)) {
- *ppv = HTTPINFO(This);
+ *ppv = &This->IWinInetHttpInfo_iface;
IWinInetHttpInfo_Release(http_info);
}
}
static ULONG WINAPI BindProtocol_AddRef(IInternetProtocolEx *iface)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
static ULONG WINAPI BindProtocol_Release(IInternetProtocolEx *iface)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
if(This->wininet_info)
IWinInetInfo_Release(This->wininet_info);
+ if(This->wininet_http_info)
+ IWinInetHttpInfo_Release(This->wininet_http_info);
if(This->protocol)
IInternetProtocol_Release(This->protocol);
if(This->bind_info)
if(This->protocol_handler && This->protocol_handler != &This->default_protocol_handler.IInternetProtocol_iface)
IInternetProtocol_Release(This->protocol_handler);
if(This->filter_proxy)
- IInternetProtocol_Release(PROTOCOL(This->filter_proxy));
+ IInternetProtocol_Release(&This->filter_proxy->IInternetProtocol_iface);
if(This->uri)
IUri_Release(This->uri);
- set_binding_sink(PROTOCOLEX(This), NULL, NULL);
+ set_binding_sink(This, NULL, NULL);
if(This->notif_hwnd)
release_notif_hwnd(This->notif_hwnd);
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE_PTR dwReserved)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
IUri *uri;
HRESULT hres;
if(FAILED(hres))
return hres;
- hres = IInternetProtocolEx_StartEx(PROTOCOLEX(This), uri, pOIProtSink, pOIBindInfo,
- grfPI, (HANDLE*)dwReserved);
+ hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
+ pOIBindInfo, grfPI, (HANDLE*)dwReserved);
IUri_Release(uri);
return hres;
static HRESULT WINAPI BindProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
TRACE("(%p)->(%p)\n", This, pProtocolData);
static HRESULT WINAPI BindProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
DWORD dwOptions)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
TRACE("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
static HRESULT WINAPI BindProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
static HRESULT WINAPI BindProtocol_Suspend(IInternetProtocolEx *iface)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI BindProtocol_Resume(IInternetProtocolEx *iface)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI BindProtocol_Read(IInternetProtocolEx *iface, void *pv,
ULONG cb, ULONG *pcbRead)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
static HRESULT WINAPI BindProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
return E_NOTIMPL;
}
static HRESULT WINAPI BindProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocolEx *iface)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
TRACE("(%p)\n", This);
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE *dwReserved)
{
- BindProtocol *This = PROTOCOL_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolEx(iface);
IInternetProtocol *protocol = NULL;
IInternetProtocolEx *protocolex;
IInternetPriority *priority;
if(FAILED(hres))
return hres;
}else {
- hres = IClassFactory_CreateInstance(cf, (IUnknown*)BINDINFO(This),
+ hres = IClassFactory_CreateInstance(cf, (IUnknown*)&This->IInternetBindInfo_iface,
&IID_IUnknown, (void**)&unk);
IClassFactory_Release(cf);
if(FAILED(hres))
This->protocol = protocol;
- if(urlmon_protocol)
+ if(urlmon_protocol) {
IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&This->wininet_info);
+ IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&This->wininet_http_info);
+ }
- set_binding_sink(PROTOCOLEX(This), pOIProtSink, pOIBindInfo);
+ set_binding_sink(This, pOIProtSink, pOIBindInfo);
hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
if(SUCCEEDED(hres)) {
hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
if(SUCCEEDED(hres)) {
- hres = IInternetProtocolEx_StartEx(protocolex, pUri, PROTSINK(This), BINDINFO(This), 0, NULL);
+ hres = IInternetProtocolEx_StartEx(protocolex, pUri, &This->IInternetProtocolSink_iface,
+ &This->IInternetBindInfo_iface, 0, NULL);
IInternetProtocolEx_Release(protocolex);
}else {
BSTR display_uri;
if(FAILED(hres))
return hres;
- hres = IInternetProtocol_Start(protocol, display_uri, PROTSINK(This), BINDINFO(This), 0, 0);
+ hres = IInternetProtocol_Start(protocol, display_uri, &This->IInternetProtocolSink_iface,
+ &This->IInternetBindInfo_iface, 0, 0);
SysFreeString(display_uri);
}
return hres;
}
-void set_binding_sink(IInternetProtocolEx *bind_protocol, IInternetProtocolSink *sink, IInternetBindInfo *bind_info)
+void set_binding_sink(BindProtocol *This, IInternetProtocolSink *sink, IInternetBindInfo *bind_info)
{
- BindProtocol *This = PROTOCOL_THIS(bind_protocol);
IInternetProtocolSink *prev_sink;
IServiceProvider *service_provider = NULL;
IInternetBindInfo_Release(bind_info);
}
-IWinInetInfo *get_wininet_info(IInternetProtocolEx *bind_protocol)
-{
- BindProtocol *This = PROTOCOL_THIS(bind_protocol);
-
- return This->wininet_info;
-}
-
-#undef PROTOCOL_THIS
-
static const IInternetProtocolExVtbl BindProtocolVtbl = {
BindProtocol_QueryInterface,
BindProtocol_AddRef,
static ULONG WINAPI ProtocolHandler_AddRef(IInternetProtocol *iface)
{
BindProtocol *This = impl_from_IInternetProtocol(iface);
- return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
+ return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
}
static ULONG WINAPI ProtocolHandler_Release(IInternetProtocol *iface)
{
BindProtocol *This = impl_from_IInternetProtocol(iface);
- return IInternetProtocolEx_Release(PROTOCOLEX(This));
+ return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
}
static HRESULT WINAPI ProtocolHandler_Start(IInternetProtocol *iface, LPCWSTR szUrl,
IInternetProtocol_Terminate(This->protocol, 0);
if(This->filter_proxy) {
- IInternetProtocol_Release(PROTOCOL(This->filter_proxy));
+ IInternetProtocol_Release(&This->filter_proxy->IInternetProtocol_iface);
This->filter_proxy = NULL;
}
- set_binding_sink(PROTOCOLEX(This), NULL, NULL);
+ set_binding_sink(This, NULL, NULL);
if(This->bind_info) {
IInternetBindInfo_Release(This->bind_info);
ProtocolHandler_UnlockRequest
};
-#define BINDINFO_THIS(iface) DEFINE_THIS(BindProtocol, InternetBindInfo, iface)
+static inline BindProtocol *impl_from_IInternetBindInfo(IInternetBindInfo *iface)
+{
+ return CONTAINING_RECORD(iface, BindProtocol, IInternetBindInfo_iface);
+}
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface,
REFIID riid, void **ppv)
{
- BindProtocol *This = BINDINFO_THIS(iface);
- return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This), riid, ppv);
+ BindProtocol *This = impl_from_IInternetBindInfo(iface);
+ return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
}
static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
{
- BindProtocol *This = BINDINFO_THIS(iface);
- return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IInternetBindInfo(iface);
+ return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
}
static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
{
- BindProtocol *This = BINDINFO_THIS(iface);
- return IInternetProtocolEx_Release(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IInternetBindInfo(iface);
+ return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
}
static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface,
DWORD *grfBINDF, BINDINFO *pbindinfo)
{
- BindProtocol *This = BINDINFO_THIS(iface);
+ BindProtocol *This = impl_from_IInternetBindInfo(iface);
HRESULT hres;
TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface,
ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
{
- BindProtocol *This = BINDINFO_THIS(iface);
+ BindProtocol *This = impl_from_IInternetBindInfo(iface);
TRACE("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
return IInternetBindInfo_GetBindString(This->bind_info, ulStringType, ppwzStr, cEl, pcElFetched);
}
-#undef BINDFO_THIS
-
static const IInternetBindInfoVtbl InternetBindInfoVtbl = {
BindInfo_QueryInterface,
BindInfo_AddRef,
BindInfo_GetBindString
};
-#define PRIORITY_THIS(iface) DEFINE_THIS(BindProtocol, InternetPriority, iface)
+static inline BindProtocol *impl_from_IInternetPriority(IInternetPriority *iface)
+{
+ return CONTAINING_RECORD(iface, BindProtocol, IInternetPriority_iface);
+}
static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
REFIID riid, void **ppv)
{
- BindProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This), riid, ppv);
+ BindProtocol *This = impl_from_IInternetPriority(iface);
+ return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
}
static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
{
- BindProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IInternetPriority(iface);
+ return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
}
static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
{
- BindProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocolEx_Release(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IInternetPriority(iface);
+ return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
}
static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
{
- BindProtocol *This = PRIORITY_THIS(iface);
+ BindProtocol *This = impl_from_IInternetPriority(iface);
TRACE("(%p)->(%d)\n", This, nPriority);
static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
{
- BindProtocol *This = PRIORITY_THIS(iface);
+ BindProtocol *This = impl_from_IInternetPriority(iface);
TRACE("(%p)->(%p)\n", This, pnPriority);
return S_OK;
}
-#undef PRIORITY_THIS
-
static const IInternetPriorityVtbl InternetPriorityVtbl = {
InternetPriority_QueryInterface,
InternetPriority_AddRef,
};
-#define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocolSink, iface)
+static inline BindProtocol *impl_from_IInternetProtocolSink(IInternetProtocolSink *iface)
+{
+ return CONTAINING_RECORD(iface, BindProtocol, IInternetProtocolSink_iface);
+}
static HRESULT WINAPI BPInternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
REFIID riid, void **ppv)
{
- BindProtocol *This = PROTSINK_THIS(iface);
- return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This), riid, ppv);
+ BindProtocol *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
}
static ULONG WINAPI BPInternetProtocolSink_AddRef(IInternetProtocolSink *iface)
{
- BindProtocol *This = PROTSINK_THIS(iface);
- return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
}
static ULONG WINAPI BPInternetProtocolSink_Release(IInternetProtocolSink *iface)
{
- BindProtocol *This = PROTSINK_THIS(iface);
- return IInternetProtocolEx_Release(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
}
typedef struct {
static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface,
PROTOCOLDATA *pProtocolData)
{
- BindProtocol *This = PROTSINK_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolSink(iface);
PROTOCOLDATA *data;
TRACE("(%p)->(%p)\n", This, pProtocolData);
case BINDSTATUS_FINDINGRESOURCE:
case BINDSTATUS_CONNECTING:
case BINDSTATUS_REDIRECTING:
- case BINDSTATUS_BEGINDOWNLOADDATA:
case BINDSTATUS_SENDINGREQUEST:
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
case BINDSTATUS_DIRECTBIND:
IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text);
break;
+ case BINDSTATUS_BEGINDOWNLOADDATA:
+ if(This->protocol_sink)
+ IInternetProtocolSink_ReportData(This->protocol_sink, This->bscf, This->progress, This->progress_max);
+ break;
+
case BINDSTATUS_MIMETYPEAVAILABLE:
mime_available(This, status_text, FALSE);
break;
static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
ULONG ulStatusCode, LPCWSTR szStatusText)
{
- BindProtocol *This = PROTSINK_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
static HRESULT report_data(BindProtocol *This, DWORD bscf, ULONG progress, ULONG progress_max)
{
+ This->bscf = bscf;
+ This->progress = progress;
+ This->progress_max = progress_max;
+
if(!This->protocol_sink)
return S_OK;
static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *iface,
DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
- BindProtocol *This = PROTSINK_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
{
- BindProtocol *This = PROTSINK_THIS(iface);
+ BindProtocol *This = impl_from_IInternetProtocolSink(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 = {
BPInternetProtocolSink_QueryInterface,
BPInternetProtocolSink_AddRef,
BPInternetProtocolSink_ReportResult
};
-#define INETINFO_THIS(iface) DEFINE_THIS(BindProtocol, IWinInetHttpInfo, iface)
+static inline BindProtocol *impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface)
+{
+ return CONTAINING_RECORD(iface, BindProtocol, IWinInetHttpInfo_iface);
+}
static HRESULT WINAPI WinInetHttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv)
{
- BindProtocol *This = INETINFO_THIS(iface);
- return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This), riid, ppv);
+ BindProtocol *This = impl_from_IWinInetHttpInfo(iface);
+ return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
}
static ULONG WINAPI WinInetHttpInfo_AddRef(IWinInetHttpInfo *iface)
{
- BindProtocol *This = INETINFO_THIS(iface);
- return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IWinInetHttpInfo(iface);
+ return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
}
static ULONG WINAPI WinInetHttpInfo_Release(IWinInetHttpInfo *iface)
{
- BindProtocol *This = INETINFO_THIS(iface);
- return IInternetProtocolEx_Release(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IWinInetHttpInfo(iface);
+ return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
}
static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption,
void *pBuffer, DWORD *pcbBuffer)
{
- BindProtocol *This = INETINFO_THIS(iface);
+ BindProtocol *This = impl_from_IWinInetHttpInfo(iface);
FIXME("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
return E_NOTIMPL;
}
static HRESULT WINAPI WinInetHttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption,
void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
{
- BindProtocol *This = INETINFO_THIS(iface);
+ BindProtocol *This = impl_from_IWinInetHttpInfo(iface);
FIXME("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
return E_NOTIMPL;
}
-#undef INETINFO_THIS
-
static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = {
WinInetHttpInfo_QueryInterface,
WinInetHttpInfo_AddRef,
WinInetHttpInfo_QueryInfo
};
-#define SERVPROV_THIS(iface) DEFINE_THIS(BindProtocol, ServiceProvider, iface)
+static inline BindProtocol *impl_from_IServiceProvider(IServiceProvider *iface)
+{
+ return CONTAINING_RECORD(iface, BindProtocol, IServiceProvider_iface);
+}
static HRESULT WINAPI BPServiceProvider_QueryInterface(IServiceProvider *iface,
REFIID riid, void **ppv)
{
- BindProtocol *This = SERVPROV_THIS(iface);
- return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This), riid, ppv);
+ BindProtocol *This = impl_from_IServiceProvider(iface);
+ return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
}
static ULONG WINAPI BPServiceProvider_AddRef(IServiceProvider *iface)
{
- BindProtocol *This = SERVPROV_THIS(iface);
- return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IServiceProvider(iface);
+ return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
}
static ULONG WINAPI BPServiceProvider_Release(IServiceProvider *iface)
{
- BindProtocol *This = SERVPROV_THIS(iface);
- return IInternetProtocolEx_Release(PROTOCOLEX(This));
+ BindProtocol *This = impl_from_IServiceProvider(iface);
+ return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
}
static HRESULT WINAPI BPServiceProvider_QueryService(IServiceProvider *iface,
REFGUID guidService, REFIID riid, void **ppv)
{
- BindProtocol *This = SERVPROV_THIS(iface);
+ BindProtocol *This = impl_from_IServiceProvider(iface);
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
return IServiceProvider_QueryService(This->service_provider, guidService, riid, ppv);
}
-#undef SERVPROV_THIS
-
static const IServiceProviderVtbl ServiceProviderVtbl = {
BPServiceProvider_QueryInterface,
BPServiceProvider_AddRef,
BPServiceProvider_QueryService
};
-HRESULT create_binding_protocol(BOOL from_urlmon, IInternetProtocolEx **protocol)
+HRESULT create_binding_protocol(BOOL from_urlmon, BindProtocol **protocol)
{
BindProtocol *ret = heap_alloc_zero(sizeof(BindProtocol));
- ret->lpIInternetProtocolExVtbl = &BindProtocolVtbl;
- ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl;
- ret->lpInternetPriorityVtbl = &InternetPriorityVtbl;
- ret->lpServiceProviderVtbl = &ServiceProviderVtbl;
- ret->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
- ret->lpIWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl;
+ ret->IInternetProtocolEx_iface.lpVtbl = &BindProtocolVtbl;
+ ret->IInternetBindInfo_iface.lpVtbl = &InternetBindInfoVtbl;
+ ret->IInternetPriority_iface.lpVtbl = &InternetPriorityVtbl;
+ ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
+ ret->IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkVtbl;
+ ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl;
ret->default_protocol_handler.IInternetProtocol_iface.lpVtbl = &InternetProtocolHandlerVtbl;
URLMON_LockModule();
- *protocol = PROTOCOLEX(ret);
+ *protocol = ret;
return S_OK;
}
LONG ref;
IBindStatusCallback *callback;
+ IBinding *binding;
LPWSTR file_name;
LPWSTR cache_file;
} DownloadBSC;
if(!ref) {
if(This->callback)
IBindStatusCallback_Release(This->callback);
+ if(This->binding)
+ IBinding_Release(This->binding);
heap_free(This->file_name);
heap_free(This->cache_file);
heap_free(This);
DWORD dwReserved, IBinding *pbind)
{
DownloadBSC *This = impl_from_IBindStatusCallback(iface);
+ HRESULT hres = S_OK;
TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
- if(This->callback)
- IBindStatusCallback_OnStartBinding(This->callback, dwReserved, pbind);
+ if(This->callback) {
+ hres = IBindStatusCallback_OnStartBinding(This->callback, dwReserved, pbind);
- return S_OK;
+ IBinding_AddRef(pbind);
+ This->binding = pbind;
+ }
+
+ /* Windows seems to ignore E_NOTIMPL if it's returned from the client. */
+ return hres == E_NOTIMPL ? S_OK : hres;
}
static HRESULT WINAPI DownloadBSC_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
return S_OK;
hres = IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text);
+ if(hres == E_ABORT) {
+ if(This->binding)
+ IBinding_Abort(This->binding);
+ else
+ FIXME("No binding, not sure what to do!\n");
+ }
+
return hres;
}
if(This->callback)
IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
+ if(This->binding) {
+ IBinding_Release(This->binding);
+ This->binding = NULL;
+ }
+
return S_OK;
}
ret->ref = 1;
ret->file_name = heap_strdupW(file_name);
ret->cache_file = NULL;
+ ret->binding = NULL;
if(callback)
IBindStatusCallback_AddRef(callback);
return CONTAINING_RECORD(iface, FtpProtocol, IWinInetHttpInfo_iface);
}
-#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(FtpProtocol, base, iface)
+static inline FtpProtocol *impl_from_Protocol(Protocol *prot)
+{
+ return CONTAINING_RECORD(prot, FtpProtocol, base);
+}
static HRESULT FtpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags,
HINTERNET internet_session, IInternetBindInfo *bind_info)
{
- FtpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ FtpProtocol *This = impl_from_Protocol(prot);
BSTR url;
HRESULT hres;
static HRESULT FtpProtocol_start_downloading(Protocol *prot)
{
- FtpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ FtpProtocol *This = impl_from_Protocol(prot);
DWORD size;
BOOL res;
{
}
-#undef ASYNCPROTOCOL_THIS
+static void FtpProtocol_on_error(Protocol *prot, DWORD error)
+{
+ FIXME("(%p) %d - stub\n", prot, error);
+}
static const ProtocolVtbl AsyncProtocolVtbl = {
FtpProtocol_open_request,
FtpProtocol_end_request,
FtpProtocol_start_downloading,
- FtpProtocol_close_connection
+ FtpProtocol_close_connection,
+ FtpProtocol_on_error
};
static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
void *pBuffer, DWORD *pcbBuffer)
{
FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
- FIXME("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
- return E_NOTIMPL;
+ TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
+
+ if(!This->base.request)
+ return E_FAIL;
+
+ if(!InternetQueryOptionW(This->base.request, dwOption, pBuffer, pcbBuffer))
+ return S_FALSE;
+ return S_OK;
}
static HRESULT WINAPI HttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption,
void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
{
FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
- FIXME("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
- return E_NOTIMPL;
+ TRACE("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
+
+ if(!This->base.request)
+ return E_FAIL;
+
+ if(!HttpQueryInfoW(This->base.request, dwOption, pBuffer, pcbBuffer, pdwFlags))
+ return S_FALSE;
+ return S_OK;
}
static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = {
typedef struct {
Protocol base;
- const IInternetProtocolVtbl *lpIInternetProtocolVtbl;
- const IInternetPriorityVtbl *lpInternetPriorityVtbl;
+ IInternetProtocol IInternetProtocol_iface;
+ IInternetPriority IInternetPriority_iface;
LONG ref;
} GopherProtocol;
-#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
-
-#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(GopherProtocol, base, iface)
+static inline GopherProtocol *impl_from_Protocol(Protocol *prot)
+{
+ return CONTAINING_RECORD(prot, GopherProtocol, base);
+}
static HRESULT GopherProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags,
HINTERNET internet_session, IInternetBindInfo *bind_info)
{
- GopherProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ GopherProtocol *This = impl_from_Protocol(prot);
BSTR url;
HRESULT hres;
{
}
-#undef ASYNCPROTOCOL_THIS
+static void GopherProtocol_on_error(Protocol *prot, DWORD error)
+{
+ FIXME("(%p) %d - stub\n", prot, error);
+}
static const ProtocolVtbl AsyncProtocolVtbl = {
GopherProtocol_open_request,
GopherProtocol_end_request,
GopherProtocol_start_downloading,
- GopherProtocol_close_connection
+ GopherProtocol_close_connection,
+ GopherProtocol_on_error
};
-#define PROTOCOL_THIS(iface) DEFINE_THIS(GopherProtocol, IInternetProtocol, iface)
+static inline GopherProtocol *impl_from_IInternetProtocol(IInternetProtocol *iface)
+{
+ return CONTAINING_RECORD(iface, GopherProtocol, IInternetProtocol_iface);
+}
static HRESULT WINAPI GopherProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
- *ppv = PRIORITY(This);
+ *ppv = &This->IInternetPriority_iface;
}
if(*ppv) {
static ULONG WINAPI GopherProtocol_AddRef(IInternetProtocol *iface)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
static ULONG WINAPI GopherProtocol_Release(IInternetProtocol *iface)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE_PTR dwReserved)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
IUri *uri;
HRESULT hres;
if(FAILED(hres))
return hres;
- hres = protocol_start(&This->base, PROTOCOL(This), uri, pOIProtSink, pOIBindInfo);
+ hres = protocol_start(&This->base, &This->IInternetProtocol_iface, uri, pOIProtSink,
+ pOIBindInfo);
IUri_Release(uri);
return hres;
static HRESULT WINAPI GopherProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%p)\n", This, pProtocolData);
static HRESULT WINAPI GopherProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
DWORD dwOptions)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
static HRESULT WINAPI GopherProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
static HRESULT WINAPI GopherProtocol_Suspend(IInternetProtocol *iface)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI GopherProtocol_Resume(IInternetProtocol *iface)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI GopherProtocol_Read(IInternetProtocol *iface, void *pv,
ULONG cb, ULONG *pcbRead)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
static HRESULT WINAPI GopherProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
return E_NOTIMPL;
}
static HRESULT WINAPI GopherProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
static HRESULT WINAPI GopherProtocol_UnlockRequest(IInternetProtocol *iface)
{
- GopherProtocol *This = PROTOCOL_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)\n", This);
return protocol_unlock_request(&This->base);
}
-#undef PROTOCOL_THIS
-
static const IInternetProtocolVtbl GopherProtocolVtbl = {
GopherProtocol_QueryInterface,
GopherProtocol_AddRef,
GopherProtocol_UnlockRequest
};
-#define PRIORITY_THIS(iface) DEFINE_THIS(GopherProtocol, InternetPriority, iface)
+static inline GopherProtocol *impl_from_IInternetPriority(IInternetPriority *iface)
+{
+ return CONTAINING_RECORD(iface, GopherProtocol, IInternetPriority_iface);
+}
static HRESULT WINAPI GopherPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
{
- GopherProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
+ GopherProtocol *This = impl_from_IInternetPriority(iface);
+ return IInternetProtocol_QueryInterface(&This->IInternetProtocol_iface, riid, ppv);
}
static ULONG WINAPI GopherPriority_AddRef(IInternetPriority *iface)
{
- GopherProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocol_AddRef(PROTOCOL(This));
+ GopherProtocol *This = impl_from_IInternetPriority(iface);
+ return IInternetProtocol_AddRef(&This->IInternetProtocol_iface);
}
static ULONG WINAPI GopherPriority_Release(IInternetPriority *iface)
{
- GopherProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocol_Release(PROTOCOL(This));
+ GopherProtocol *This = impl_from_IInternetPriority(iface);
+ return IInternetProtocol_Release(&This->IInternetProtocol_iface);
}
static HRESULT WINAPI GopherPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
{
- GopherProtocol *This = PRIORITY_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetPriority(iface);
TRACE("(%p)->(%d)\n", This, nPriority);
static HRESULT WINAPI GopherPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
{
- GopherProtocol *This = PRIORITY_THIS(iface);
+ GopherProtocol *This = impl_from_IInternetPriority(iface);
TRACE("(%p)->(%p)\n", This, pnPriority);
return S_OK;
}
-#undef PRIORITY_THIS
-
static const IInternetPriorityVtbl GopherPriorityVtbl = {
GopherPriority_QueryInterface,
GopherPriority_AddRef,
ret = heap_alloc_zero(sizeof(GopherProtocol));
ret->base.vtbl = &AsyncProtocolVtbl;
- ret->lpIInternetProtocolVtbl = &GopherProtocolVtbl;
- ret->lpInternetPriorityVtbl = &GopherPriorityVtbl;
+ ret->IInternetProtocol_iface.lpVtbl = &GopherProtocolVtbl;
+ ret->IInternetPriority_iface.lpVtbl = &GopherPriorityVtbl;
ret->ref = 1;
- *ppobj = PROTOCOL(ret);
+ *ppobj = &ret->IInternetProtocol_iface;
return S_OK;
}
BOOL https;
IHttpNegotiate *http_negotiate;
- LPWSTR full_header;
+ WCHAR *full_header;
LONG ref;
} HttpProtocol;
return CONTAINING_RECORD(iface, HttpProtocol, IWinInetHttpInfo_iface);
}
-/* 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};
+static const WCHAR default_headersW[] = {
+ '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};
static LPWSTR query_http_info(HttpProtocol *This, DWORD option)
{
return ret;
}
-#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(HttpProtocol, base, iface)
+static inline BOOL set_security_flag(HttpProtocol *This, DWORD new_flag)
+{
+ DWORD flags, size = sizeof(flags);
+ BOOL res;
+
+ res = InternetQueryOptionW(This->base.request, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
+ if(res) {
+ flags |= new_flag;
+ res = InternetSetOptionW(This->base.request, INTERNET_OPTION_SECURITY_FLAGS, &flags, size);
+ }
+ if(!res)
+ ERR("Failed to set security flag(s): %x\n", new_flag);
+
+ return res;
+}
+
+static inline HRESULT internet_error_to_hres(DWORD error)
+{
+ switch(error)
+ {
+ case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
+ case ERROR_INTERNET_SEC_CERT_CN_INVALID:
+ case ERROR_INTERNET_INVALID_CA:
+ case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
+ return INET_E_INVALID_CERTIFICATE;
+ case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
+ case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
+ case ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION:
+ return INET_E_REDIRECT_FAILED;
+ default:
+ return INET_E_DOWNLOAD_FAILURE;
+ }
+}
+
+static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
+{
+ IServiceProvider *serv_prov;
+ IWindowForBindingUI *wfb_ui;
+ IHttpSecurity *http_security;
+ BOOL security_problem;
+ HRESULT hres;
+
+ switch(error) {
+ case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
+ case ERROR_INTERNET_SEC_CERT_CN_INVALID:
+ case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
+ case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
+ case ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION:
+ case ERROR_INTERNET_INVALID_CA:
+ case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
+ security_problem = TRUE;
+ break;
+ default:
+ security_problem = FALSE;
+ }
+
+ hres = IInternetProtocolSink_QueryInterface(This->base.protocol_sink, &IID_IServiceProvider,
+ (void**)&serv_prov);
+ if(FAILED(hres)) {
+ ERR("Failed to get IServiceProvider.\n");
+ return E_ABORT;
+ }
+
+ if(security_problem) {
+ hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpSecurity, &IID_IHttpSecurity,
+ (void**)&http_security);
+ if(SUCCEEDED(hres)) {
+ hres = IHttpSecurity_OnSecurityProblem(http_security, error);
+ IHttpSecurity_Release(http_security);
+
+ if(hres != S_FALSE)
+ {
+ BOOL res = FALSE;
+
+ IServiceProvider_Release(serv_prov);
+
+ if(hres == S_OK) {
+ if(error == ERROR_INTERNET_SEC_CERT_DATE_INVALID)
+ res = set_security_flag(This, SECURITY_FLAG_IGNORE_CERT_DATE_INVALID);
+ else if(error == ERROR_INTERNET_SEC_CERT_CN_INVALID)
+ res = set_security_flag(This, SECURITY_FLAG_IGNORE_CERT_CN_INVALID);
+ else if(error == ERROR_INTERNET_INVALID_CA)
+ res = set_security_flag(This, SECURITY_FLAG_IGNORE_UNKNOWN_CA);
+
+ if(res)
+ return RPC_E_RETRY;
+
+ FIXME("Don't know how to ignore error %d\n", error);
+ return E_ABORT;
+ }
+
+ if(hres == E_ABORT)
+ return E_ABORT;
+ if(hres == RPC_E_RETRY)
+ return RPC_E_RETRY;
+
+ return internet_error_to_hres(error);
+ }
+ }
+ }
+
+ hres = IServiceProvider_QueryService(serv_prov, &IID_IWindowForBindingUI, &IID_IWindowForBindingUI,
+ (void**)&wfb_ui);
+ if(SUCCEEDED(hres)) {
+ HWND hwnd;
+ const IID *iid_reason;
+
+ if(security_problem)
+ iid_reason = &IID_IHttpSecurity;
+ else if(error == ERROR_INTERNET_INCORRECT_PASSWORD)
+ iid_reason = &IID_IAuthenticate;
+ else
+ iid_reason = &IID_IWindowForBindingUI;
+
+ hres = IWindowForBindingUI_GetWindow(wfb_ui, iid_reason, &hwnd);
+ if(SUCCEEDED(hres) && hwnd)
+ {
+ DWORD res;
+
+ res = InternetErrorDlg(hwnd, This->base.request, error,
+ FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
+ NULL);
+
+ if(res == ERROR_INTERNET_FORCE_RETRY || res == ERROR_SUCCESS)
+ hres = RPC_E_RETRY;
+ else
+ hres = E_FAIL;
+ }
+ IWindowForBindingUI_Release(wfb_ui);
+ }
+
+ IServiceProvider_Release(serv_prov);
+
+ if(hres == RPC_E_RETRY)
+ return hres;
+
+ return internet_error_to_hres(error);
+}
+
+static ULONG send_http_request(HttpProtocol *This)
+{
+ INTERNET_BUFFERSW send_buffer = {sizeof(INTERNET_BUFFERSW)};
+ BOOL res;
+
+ send_buffer.lpcszHeader = This->full_header;
+ send_buffer.dwHeadersLength = send_buffer.dwHeadersTotal = strlenW(This->full_header);
+
+ if(This->base.bind_info.dwBindVerb != BINDVERB_GET) {
+ switch(This->base.bind_info.stgmedData.tymed) {
+ case TYMED_HGLOBAL:
+ /* Native does not use GlobalLock/GlobalUnlock, so we won't either */
+ send_buffer.lpvBuffer = This->base.bind_info.stgmedData.u.hGlobal;
+ send_buffer.dwBufferLength = send_buffer.dwBufferTotal = This->base.bind_info.cbstgmedData;
+ break;
+ case TYMED_ISTREAM: {
+ LARGE_INTEGER offset;
+
+ send_buffer.dwBufferTotal = This->base.bind_info.cbstgmedData;
+ if(!This->base.post_stream) {
+ This->base.post_stream = This->base.bind_info.stgmedData.u.pstm;
+ IStream_AddRef(This->base.post_stream);
+ }
+
+ offset.QuadPart = 0;
+ IStream_Seek(This->base.post_stream, offset, STREAM_SEEK_SET, NULL);
+ break;
+ }
+ default:
+ FIXME("Unsupported This->base.bind_info.stgmedData.tymed %d\n", This->base.bind_info.stgmedData.tymed);
+ }
+ }
+
+ if(This->base.post_stream)
+ res = HttpSendRequestExW(This->base.request, &send_buffer, NULL, 0, 0);
+ else
+ res = HttpSendRequestW(This->base.request, send_buffer.lpcszHeader, send_buffer.dwHeadersLength,
+ send_buffer.lpvBuffer, send_buffer.dwBufferLength);
+
+ return res ? 0 : GetLastError();
+}
+
+static inline HttpProtocol *impl_from_Protocol(Protocol *prot)
+{
+ return CONTAINING_RECORD(prot, HttpProtocol, base);
+}
static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags,
HINTERNET internet_session, IInternetBindInfo *bind_info)
{
- HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
- INTERNET_BUFFERSW send_buffer = {sizeof(INTERNET_BUFFERSW)};
+ HttpProtocol *This = impl_from_Protocol(prot);
LPWSTR addl_header = NULL, post_cookie = NULL;
IServiceProvider *service_provider = NULL;
IHttpNegotiate2 *http_negotiate2 = NULL;
LPOLESTR accept_mimes[257];
const WCHAR **accept_types;
BYTE security_id[512];
- DWORD len = 0, port;
- ULONG num;
+ DWORD len, port;
+ ULONG num, error;
BOOL res, b;
HRESULT hres;
return hres;
}
- hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, wszHeaders,
+ hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, default_headersW,
0, &addl_header);
SysFreeString(url);
if(hres != S_OK) {
return hres;
}
- if(addl_header) {
- int len_addl_header = strlenW(addl_header);
+ len = addl_header ? strlenW(addl_header) : 0;
- This->full_header = heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));
-
- lstrcpyW(This->full_header, addl_header);
- lstrcpyW(&This->full_header[len_addl_header], wszHeaders);
- CoTaskMemFree(addl_header);
- }else {
- This->full_header = (LPWSTR)wszHeaders;
+ This->full_header = heap_alloc(len*sizeof(WCHAR)+sizeof(default_headersW));
+ if(!This->full_header) {
+ IServiceProvider_Release(service_provider);
+ return E_OUTOFMEMORY;
}
+ if(len)
+ memcpy(This->full_header, addl_header, len*sizeof(WCHAR));
+ CoTaskMemFree(addl_header);
+ memcpy(This->full_header+len, default_headersW, sizeof(default_headersW));
+
hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
&IID_IHttpNegotiate2, (void **)&http_negotiate2);
IServiceProvider_Release(service_provider);
}
}
- send_buffer.lpcszHeader = This->full_header;
- send_buffer.dwHeadersLength = send_buffer.dwHeadersTotal = strlenW(This->full_header);
-
- if(This->base.bind_info.dwBindVerb != BINDVERB_GET) {
- switch(This->base.bind_info.stgmedData.tymed) {
- case TYMED_HGLOBAL:
- /* Native does not use GlobalLock/GlobalUnlock, so we won't either */
- send_buffer.lpvBuffer = This->base.bind_info.stgmedData.u.hGlobal;
- send_buffer.dwBufferLength = send_buffer.dwBufferTotal = This->base.bind_info.cbstgmedData;
- break;
- case TYMED_ISTREAM: {
- LARGE_INTEGER offset;
-
- send_buffer.dwBufferTotal = This->base.bind_info.cbstgmedData;
- This->base.post_stream = This->base.bind_info.stgmedData.u.pstm;
- IStream_AddRef(This->base.post_stream);
-
- offset.QuadPart = 0;
- IStream_Seek(This->base.post_stream, offset, STREAM_SEEK_SET, NULL);
- break;
- }
- default:
- FIXME("Unsupported This->base.bind_info.stgmedData.tymed %d\n", This->base.bind_info.stgmedData.tymed);
- }
- }
-
b = TRUE;
res = InternetSetOptionW(This->base.request, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
if(!res)
WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %08x\n", GetLastError());
- if(This->base.post_stream)
- res = HttpSendRequestExW(This->base.request, &send_buffer, NULL, 0, 0);
- else
- res = HttpSendRequestW(This->base.request, send_buffer.lpcszHeader, send_buffer.dwHeadersLength,
- send_buffer.lpvBuffer, send_buffer.dwBufferLength);
- if(!res && GetLastError() != ERROR_IO_PENDING) {
- WARN("HttpSendRequest failed: %d\n", GetLastError());
- return INET_E_DOWNLOAD_FAILURE;
- }
+ do {
+ error = send_http_request(This);
- return S_OK;
+ if(error == ERROR_IO_PENDING || error == ERROR_SUCCESS)
+ return S_OK;
+
+ hres = handle_http_error(This, error);
+
+ } while(hres == RPC_E_RETRY);
+
+ WARN("HttpSendRequest failed: %d\n", error);
+ return hres;
}
static HRESULT HttpProtocol_end_request(Protocol *protocol)
static HRESULT HttpProtocol_start_downloading(Protocol *prot)
{
- HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ HttpProtocol *This = impl_from_Protocol(prot);
LPWSTR content_type, content_length, ranges;
DWORD len = sizeof(DWORD);
DWORD status_code;
static void HttpProtocol_close_connection(Protocol *prot)
{
- HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ HttpProtocol *This = impl_from_Protocol(prot);
if(This->http_negotiate) {
IHttpNegotiate_Release(This->http_negotiate);
- This->http_negotiate = 0;
+ This->http_negotiate = NULL;
}
if(This->full_header) {
- if(This->full_header != wszHeaders)
- heap_free(This->full_header);
- This->full_header = 0;
+ heap_free(This->full_header);
+ This->full_header = NULL;
}
}
-#undef ASYNCPROTOCOL_THIS
+static void HttpProtocol_on_error(Protocol *prot, DWORD error)
+{
+ HttpProtocol *This = impl_from_Protocol(prot);
+ HRESULT hres;
+
+ TRACE("(%p) %d\n", prot, error);
+
+ if(prot->flags & FLAG_FIRST_CONTINUE_COMPLETE) {
+ FIXME("Not handling error %d\n", error);
+ return;
+ }
+
+ while((hres = handle_http_error(This, error)) == RPC_E_RETRY) {
+ error = send_http_request(This);
+
+ if(error == ERROR_IO_PENDING || error == ERROR_SUCCESS)
+ return;
+ }
+
+ protocol_abort(prot, hres);
+ protocol_close_connection(prot);
+ return;
+}
static const ProtocolVtbl AsyncProtocolVtbl = {
HttpProtocol_open_request,
HttpProtocol_end_request,
HttpProtocol_start_downloading,
- HttpProtocol_close_connection
+ HttpProtocol_close_connection,
+ HttpProtocol_on_error
};
static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
void *pBuffer, DWORD *pcbBuffer)
{
HttpProtocol *This = impl_from_IWinInetHttpInfo(iface);
- FIXME("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
- return E_NOTIMPL;
+ TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
+
+ if(!This->base.request)
+ return E_FAIL;
+
+ if(!InternetQueryOptionW(This->base.request, dwOption, pBuffer, pcbBuffer))
+ return S_FALSE;
+ return S_OK;
}
static HRESULT WINAPI HttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption,
void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
{
HttpProtocol *This = impl_from_IWinInetHttpInfo(iface);
- FIXME("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
- return E_NOTIMPL;
+ TRACE("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
+
+ if(!This->base.request)
+ return E_FAIL;
+
+ if(!HttpQueryInfoW(This->base.request, dwOption, pBuffer, pcbBuffer, pdwFlags)) {
+ if(pBuffer)
+ memset(pBuffer, 0, *pcbBuffer);
+ return S_OK;
+ }
+ return S_OK;
}
static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = {
/*
* Copyright 2005 Jacek Caban
+ * Copyright 2011 Thomas Mullaly for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
+static const WCHAR feature_control_keyW[] =
+ {'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\',
+ 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
+ 'M','a','i','n','\\',
+ 'F','e','a','t','u','r','e','C','o','n','t','r','o','l',0};
+
+static const WCHAR feature_object_cachingW[] =
+ {'F','E','A','T','U','R','E','_','O','B','J','E','C','T','_','C','A','C','H','I','N','G',0};
+static const WCHAR feature_zone_elevationW[] =
+ {'F','E','A','T','U','R','E','_','Z','O','N','E','_','E','L','E','V','A','T','I','O','N',0};
+static const WCHAR feature_mime_handlingW[] =
+ {'F','E','A','T','U','R','E','_','M','I','M','E','_','H','A','N','D','L','I','N','G',0};
+static const WCHAR feature_mime_sniffingW[] =
+ {'F','E','A','T','U','R','E','_','M','I','M','E','_','S','N','I','F','F','I','N','G',0};
+static const WCHAR feature_window_restrictionsW[] =
+ {'F','E','A','T','U','R','E','_','W','I','N','D','O','W','_','R','E','S','T','R','I','C','T','I','O','N','S',0};
+static const WCHAR feature_weboc_popupmanagementW[] =
+ {'F','E','A','T','U','R','E','_','W','E','B','O','C','_','P','O','P','U','P','M','A','N','A','G','E','M','E','N','T',0};
+static const WCHAR feature_behaviorsW[] =
+ {'F','E','A','T','U','R','E','_','B','E','H','A','V','I','O','R','S',0};
+static const WCHAR feature_disable_mk_protocolW[] =
+ {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','M','K','_','P','R','O','T','O','C','O','L',0};
+static const WCHAR feature_localmachine_lockdownW[] =
+ {'F','E','A','T','U','R','E','_','L','O','C','A','L','M','A','C','H','I','N','E','_','L','O','C','K','D','O','W','N',0};
+static const WCHAR feature_securitybandW[] =
+ {'F','E','A','T','U','R','E','_','S','E','C','U','R','I','T','Y','B','A','N','D',0};
+static const WCHAR feature_restrict_activexinstallW[] =
+ {'F','E','A','T','U','R','E','_','R','E','S','T','R','I','C','T','_','A','C','T','I','V','E','X','I','N','S','T','A','L','L',0};
+static const WCHAR feature_validate_navigate_urlW[] =
+ {'F','E','A','T','U','R','E','_','V','A','L','I','D','A','T','E','_','N','A','V','I','G','A','T','E','_','U','R','L',0};
+static const WCHAR feature_restrict_filedownloadW[] =
+ {'F','E','A','T','U','R','E','_','R','E','S','T','R','I','C','T','_','F','I','L','E','D','O','W','N','L','O','A','D',0};
+static const WCHAR feature_addon_managementW[] =
+ {'F','E','A','T','U','R','E','_','A','D','D','O','N','_','M','A','N','A','G','E','M','E','N','T',0};
+static const WCHAR feature_protocol_lockdownW[] =
+ {'F','E','A','T','U','R','E','_','P','R','O','T','O','C','O','L','_','L','O','C','K','D','O','W','N',0};
+static const WCHAR feature_http_username_password_disableW[] =
+ {'F','E','A','T','U','R','E','_','H','T','T','P','_','U','S','E','R','N','A','M','E','_',
+ 'P','A','S','S','W','O','R','D','_','D','I','S','A','B','L','E',0};
+static const WCHAR feature_safe_bindtoobjectW[] =
+ {'F','E','A','T','U','R','E','_','S','A','F','E','_','B','I','N','D','T','O','O','B','J','E','C','T',0};
+static const WCHAR feature_unc_savedfilecheckW[] =
+ {'F','E','A','T','U','R','E','_','U','N','C','_','S','A','V','E','D','F','I','L','E','C','H','E','C','K',0};
+static const WCHAR feature_get_url_dom_filepath_unencodedW[] =
+ {'F','E','A','T','U','R','E','_','G','E','T','_','U','R','L','_','D','O','M','_',
+ 'F','I','L','E','P','A','T','H','_','U','N','E','N','C','O','D','E','D',0};
+static const WCHAR feature_tabbed_browsingW[] =
+ {'F','E','A','T','U','R','E','_','T','A','B','B','E','D','_','B','R','O','W','S','I','N','G',0};
+static const WCHAR feature_ssluxW[] =
+ {'F','E','A','T','U','R','E','_','S','S','L','U','X',0};
+static const WCHAR feature_disable_navigation_soundsW[] =
+ {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','N','A','V','I','G','A','T','I','O','N','_',
+ 'S','O','U','N','D','S',0};
+static const WCHAR feature_disable_legacy_compressionW[] =
+ {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','L','E','G','A','C','Y','_',
+ 'C','O','M','P','R','E','S','S','I','O','N',0};
+static const WCHAR feature_force_addr_and_statusW[] =
+ {'F','E','A','T','U','R','E','_','F','O','R','C','E','_','A','D','D','R','_','A','N','D','_',
+ 'S','T','A','T','U','S',0};
+static const WCHAR feature_xmlhttpW[] =
+ {'F','E','A','T','U','R','E','_','X','M','L','H','T','T','P',0};
+static const WCHAR feature_disable_telnet_protocolW[] =
+ {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','T','E','L','N','E','T','_',
+ 'P','R','O','T','O','C','O','L',0};
+static const WCHAR feature_feedsW[] =
+ {'F','E','A','T','U','R','E','_','F','E','E','D','S',0};
+static const WCHAR feature_block_input_promptsW[] =
+ {'F','E','A','T','U','R','E','_','B','L','O','C','K','_','I','N','P','U','T','_','P','R','O','M','P','T','S',0};
+
+static CRITICAL_SECTION process_features_cs;
+static CRITICAL_SECTION_DEBUG process_features_cs_dbg =
+{
+ 0, 0, &process_features_cs,
+ { &process_features_cs_dbg.ProcessLocksList, &process_features_cs_dbg.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": process features") }
+};
+static CRITICAL_SECTION process_features_cs = { &process_features_cs_dbg, -1, 0, 0, 0, 0 };
+
+typedef struct feature_control {
+ LPCWSTR feature_name;
+ BOOL enabled;
+ BOOL check_registry;
+} feature_control;
+
+/* IMPORTANT!!!
+ *
+ * This array is indexed using INTERNETFEATURELIST values, so everything must
+ * appear in the same order as it does in INTERNETFEATURELIST.
+ */
+static feature_control process_feature_controls[FEATURE_ENTRY_COUNT] = {
+ {feature_object_cachingW, TRUE ,TRUE},
+ {feature_zone_elevationW, FALSE,TRUE},
+ {feature_mime_handlingW, FALSE,TRUE},
+ {feature_mime_sniffingW, FALSE,TRUE},
+ {feature_window_restrictionsW, FALSE,TRUE},
+ {feature_weboc_popupmanagementW, FALSE,TRUE},
+ {feature_behaviorsW, TRUE ,TRUE},
+ {feature_disable_mk_protocolW, TRUE ,TRUE},
+ {feature_localmachine_lockdownW, FALSE,TRUE},
+ {feature_securitybandW, FALSE,TRUE},
+ {feature_restrict_activexinstallW, FALSE,TRUE},
+ {feature_validate_navigate_urlW, FALSE,TRUE},
+ {feature_restrict_filedownloadW, FALSE,TRUE},
+ {feature_addon_managementW, FALSE,TRUE},
+ {feature_protocol_lockdownW, FALSE,TRUE},
+ {feature_http_username_password_disableW, FALSE,TRUE},
+ {feature_safe_bindtoobjectW, FALSE,TRUE},
+ {feature_unc_savedfilecheckW, FALSE,TRUE},
+ {feature_get_url_dom_filepath_unencodedW, TRUE ,TRUE},
+ {feature_tabbed_browsingW, FALSE,TRUE},
+ {feature_ssluxW, FALSE,TRUE},
+ {feature_disable_navigation_soundsW, FALSE,TRUE},
+ {feature_disable_legacy_compressionW, TRUE ,TRUE},
+ {feature_force_addr_and_statusW, FALSE,TRUE},
+ {feature_xmlhttpW, TRUE ,TRUE},
+ {feature_disable_telnet_protocolW, FALSE,TRUE},
+ {feature_feedsW, FALSE,TRUE},
+ {feature_block_input_promptsW, FALSE,TRUE}
+};
+
static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
{
WCHAR *ptr;
return S_OK;
}
+static void set_feature_on_process(INTERNETFEATURELIST feature, BOOL enable)
+{
+ EnterCriticalSection(&process_features_cs);
+
+ process_feature_controls[feature].enabled = enable;
+ process_feature_controls[feature].check_registry = FALSE;
+
+ LeaveCriticalSection(&process_features_cs);
+}
+
+static HRESULT set_internet_feature(INTERNETFEATURELIST feature, DWORD flags, BOOL enable)
+{
+ const DWORD supported_flags = SET_FEATURE_ON_PROCESS;
+
+ if(feature >= FEATURE_ENTRY_COUNT)
+ return E_FAIL;
+
+ if(flags & ~supported_flags) {
+ FIXME("Unsupported flags: %08x\n", flags & ~supported_flags);
+ return E_NOTIMPL;
+ }
+
+ if(flags & SET_FEATURE_ON_PROCESS)
+ set_feature_on_process(feature, enable);
+
+ return S_OK;
+}
+
+static BOOL get_feature_from_reg(HKEY feature_control, LPCWSTR feature_name, LPCWSTR process_name, BOOL *enabled)
+{
+ BOOL ret = FALSE;
+ HKEY feature;
+ DWORD res;
+
+ static const WCHAR wildcardW[] = {'*',0};
+
+ res = RegOpenKeyW(feature_control, feature_name, &feature);
+ if(res == ERROR_SUCCESS) {
+ DWORD type, value, size;
+
+ size = sizeof(DWORD);
+ res = RegQueryValueExW(feature, process_name, NULL, &type, (BYTE*)&value, &size);
+ if(type != REG_DWORD)
+ WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(process_name));
+
+ if(res == ERROR_SUCCESS && type == REG_DWORD) {
+ *enabled = value == 1;
+ ret = TRUE;
+ } else {
+ size = sizeof(DWORD);
+ res = RegQueryValueExW(feature, wildcardW, NULL, &type, (BYTE*)&value, &size);
+ if(type != REG_DWORD)
+ WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(wildcardW));
+
+ if(res == ERROR_SUCCESS && type == REG_DWORD) {
+ *enabled = value == 1;
+ ret = TRUE;
+ }
+ }
+ RegCloseKey(feature);
+ }
+
+ return ret;
+}
+
+/* Assumes 'process_features_cs' is held. */
+static HRESULT load_process_feature(INTERNETFEATURELIST feature)
+{
+ DWORD res;
+ HKEY feature_control;
+ WCHAR module_name[MAX_PATH];
+ LPCWSTR process_name, feature_name;
+ HRESULT hres = S_FALSE;
+ BOOL check_hklm = FALSE;
+ BOOL enabled;
+
+ if (!GetModuleFileNameW(NULL, module_name, sizeof(module_name)/sizeof(WCHAR))) {
+ ERR("Failed to get module file name: %u\n", GetLastError());
+ return E_UNEXPECTED;
+ }
+
+ process_name = strrchrW(module_name, '\\');
+ if(!process_name) {
+ ERR("Invalid module file name: %s\n", debugstr_w(module_name));
+ return E_UNEXPECTED;
+ }
+
+ /* Skip past the '\\' in front of the filename. */
+ ++process_name;
+
+ feature_name = process_feature_controls[feature].feature_name;
+
+ res = RegOpenKeyW(HKEY_CURRENT_USER, feature_control_keyW, &feature_control);
+ if(res == ERROR_SUCCESS) {
+ if(get_feature_from_reg(feature_control, feature_name, process_name, &enabled)) {
+ hres = enabled ? S_OK : S_FALSE;
+ process_feature_controls[feature].enabled = enabled;
+ } else
+ /* We didn't find anything in HKCU, so check HKLM. */
+ check_hklm = TRUE;
+
+ RegCloseKey(feature_control);
+ }
+
+ if(check_hklm) {
+ res = RegOpenKeyW(HKEY_LOCAL_MACHINE, feature_control_keyW, &feature_control);
+ if(res == ERROR_SUCCESS) {
+ if(get_feature_from_reg(feature_control, feature_name, process_name, &enabled)) {
+ hres = enabled ? S_OK : S_FALSE;
+ process_feature_controls[feature].enabled = enabled;
+ }
+ RegCloseKey(feature_control);
+ }
+ }
+
+ /* Don't bother checking the registry again for this feature. */
+ process_feature_controls[feature].check_registry = FALSE;
+
+ return hres;
+}
+
+static HRESULT get_feature_from_process(INTERNETFEATURELIST feature)
+{
+ HRESULT hres;
+
+ EnterCriticalSection(&process_features_cs);
+
+ /* Try loading the feature from the registry, if it hasn't already
+ * been done.
+ */
+ if(process_feature_controls[feature].check_registry) {
+ hres = load_process_feature(feature);
+ if(FAILED(hres)) {
+ LeaveCriticalSection(&process_features_cs);
+ return hres;
+ }
+ }
+
+ hres = process_feature_controls[feature].enabled ? S_OK : S_FALSE;
+
+ LeaveCriticalSection(&process_features_cs);
+
+ return hres;
+}
+
+static HRESULT get_internet_feature(INTERNETFEATURELIST feature, DWORD flags)
+{
+ HRESULT hres;
+
+ if(feature >= FEATURE_ENTRY_COUNT)
+ return E_FAIL;
+
+ if(flags == GET_FEATURE_FROM_PROCESS)
+ hres = get_feature_from_process(feature);
+ else {
+ FIXME("Unsupported flags: %08x\n", flags);
+ hres = E_NOTIMPL;
+ }
+
+ return hres;
+}
+
/***********************************************************************
* CoInternetSetFeatureEnabled (URLMON.@)
*/
-HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST feature, DWORD flags, BOOL enable)
+HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags, BOOL fEnable)
{
- FIXME("%d, 0x%08x, %x, stub\n", feature, flags, enable);
- return E_NOTIMPL;
+ TRACE("(%d, %08x, %x)\n", FeatureEntry, dwFlags, fEnable);
+ return set_internet_feature(FeatureEntry, dwFlags, fEnable);
}
/***********************************************************************
* CoInternetIsFeatureEnabled (URLMON.@)
*/
-HRESULT WINAPI CoInternetIsFeatureEnabled(INTERNETFEATURELIST feature, DWORD flags)
+HRESULT WINAPI CoInternetIsFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags)
{
- FIXME("%d, 0x%08x, stub\n", feature, flags);
- return E_NOTIMPL;
+ TRACE("(%d, %08x)\n", FeatureEntry, dwFlags);
+ return get_internet_feature(FeatureEntry, dwFlags);
}
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
typedef struct {
- const IInternetProtocolVtbl *lpIInternetProtocolVtbl;
- const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl;
+ IInternetProtocol IInternetProtocol_iface;
+ IInternetProtocolSink IInternetProtocolSink_iface;
LONG ref;
} MimeFilter;
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpIInternetProtocolVtbl)
-#define PROTOCOLSINK(x) ((IInternetProtocolSink*) &(x)->lpIInternetProtocolSinkVtbl)
-
-#define PROTOCOL_THIS(iface) DEFINE_THIS(MimeFilter, IInternetProtocol, iface)
+static inline MimeFilter *impl_from_IInternetProtocol(IInternetProtocol *iface)
+{
+ return CONTAINING_RECORD(iface, MimeFilter, IInternetProtocol_iface);
+}
static HRESULT WINAPI MimeFilterProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
- *ppv = PROTOCOLSINK(This);
+ *ppv = &This->IInternetProtocolSink_iface;
}
if(*ppv) {
static ULONG WINAPI MimeFilterProtocol_AddRef(IInternetProtocol *iface)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
static ULONG WINAPI MimeFilterProtocol_Release(IInternetProtocol *iface)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE_PTR dwReserved)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
pOIBindInfo, grfPI, dwReserved);
return E_NOTIMPL;
static HRESULT WINAPI MimeFilterProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%p)\n", This, pProtocolData);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
DWORD dwOptions)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%08x)\n", This, dwOptions);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_Suspend(IInternetProtocol *iface)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_Resume(IInternetProtocol *iface)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_Read(IInternetProtocol *iface, void *pv,
ULONG cb, ULONG *pcbRead)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%08x)\n", This, dwOptions);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterProtocol_UnlockRequest(IInternetProtocol *iface)
{
- MimeFilter *This = PROTOCOL_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
-#undef PROTOCOL_THIS
-
static const IInternetProtocolVtbl MimeFilterProtocolVtbl = {
MimeFilterProtocol_QueryInterface,
MimeFilterProtocol_AddRef,
MimeFilterProtocol_UnlockRequest
};
-#define PROTSINK_THIS(iface) DEFINE_THIS(MimeFilter, IInternetProtocolSink, iface)
+static inline MimeFilter *impl_from_IInternetProtocolSink(IInternetProtocolSink *iface)
+{
+ return CONTAINING_RECORD(iface, MimeFilter, IInternetProtocolSink_iface);
+}
static HRESULT WINAPI MimeFilterSink_QueryInterface(IInternetProtocolSink *iface,
REFIID riid, void **ppv)
{
- MimeFilter *This = PROTSINK_THIS(iface);
- return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
+ MimeFilter *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocol_QueryInterface(&This->IInternetProtocol_iface, riid, ppv);
}
static ULONG WINAPI MimeFilterSink_AddRef(IInternetProtocolSink *iface)
{
- MimeFilter *This = PROTSINK_THIS(iface);
- return IInternetProtocol_AddRef(PROTOCOL(This));
+ MimeFilter *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocol_AddRef(&This->IInternetProtocol_iface);
}
static ULONG WINAPI MimeFilterSink_Release(IInternetProtocolSink *iface)
{
- MimeFilter *This = PROTSINK_THIS(iface);
- return IInternetProtocol_Release(PROTOCOL(This));
+ MimeFilter *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocol_Release(&This->IInternetProtocol_iface);
}
static HRESULT WINAPI MimeFilterSink_Switch(IInternetProtocolSink *iface,
PROTOCOLDATA *pProtocolData)
{
- MimeFilter *This = PROTSINK_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocolSink(iface);
FIXME("(%p)->(%p)\n", This, pProtocolData);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterSink_ReportProgress(IInternetProtocolSink *iface,
ULONG ulStatusCode, LPCWSTR szStatusText)
{
- MimeFilter *This = PROTSINK_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocolSink(iface);
FIXME("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterSink_ReportData(IInternetProtocolSink *iface,
DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
- MimeFilter *This = PROTSINK_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocolSink(iface);
FIXME("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
return E_NOTIMPL;
}
static HRESULT WINAPI MimeFilterSink_ReportResult(IInternetProtocolSink *iface,
HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
{
- MimeFilter *This = PROTSINK_THIS(iface);
+ MimeFilter *This = impl_from_IInternetProtocolSink(iface);
FIXME("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
return E_NOTIMPL;
}
-#undef PROTSINK_THIS
-
static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
MimeFilterSink_QueryInterface,
MimeFilterSink_AddRef,
ret = heap_alloc_zero(sizeof(MimeFilter));
- ret->lpIInternetProtocolVtbl = &MimeFilterProtocolVtbl;
- ret->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
+ ret->IInternetProtocol_iface.lpVtbl = &MimeFilterProtocolVtbl;
+ ret->IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkVtbl;
ret->ref = 1;
- *ppobj = PROTOCOL(ret);
+ *ppobj = &ret->IInternetProtocol_iface;
return S_OK;
}
#include "urlmon_main.h"
#include "wine/debug.h"
+#define NO_SHLWAPI_REG
+#include "shlwapi.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
typedef struct {
- const IInternetProtocolVtbl *lpIInternetProtocolVtbl;
+ IInternetProtocolEx IInternetProtocolEx_iface;
LONG ref;
IStream *stream;
} MkProtocol;
-#define PROTOCOL_THIS(iface) DEFINE_THIS(MkProtocol, IInternetProtocol, iface)
+static inline MkProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
+{
+ return CONTAINING_RECORD(iface, MkProtocol, IInternetProtocolEx_iface);
+}
-static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
+static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
{
- MkProtocol *This = PROTOCOL_THIS(iface);
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocolEx_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocolEx_iface;
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocolEx_iface;
+ }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
+ TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
+ *ppv = &This->IInternetProtocolEx_iface;
}
if(*ppv) {
return E_NOINTERFACE;
}
-static ULONG WINAPI MkProtocol_AddRef(IInternetProtocol *iface)
+static ULONG WINAPI MkProtocol_AddRef(IInternetProtocolEx *iface)
{
- MkProtocol *This = PROTOCOL_THIS(iface);
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
-static ULONG WINAPI MkProtocol_Release(IInternetProtocol *iface)
+static ULONG WINAPI MkProtocol_Release(IInternetProtocolEx *iface)
{
- MkProtocol *This = PROTOCOL_THIS(iface);
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return hres;
}
-static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
+static HRESULT WINAPI MkProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE_PTR dwReserved)
{
- MkProtocol *This = PROTOCOL_THIS(iface);
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+ HRESULT hres;
+ IUri *uri;
+
+ TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
+ pOIBindInfo, grfPI, dwReserved);
+
+ hres = CreateUri(szUrl, 0, 0, &uri);
+ if(FAILED(hres))
+ return hres;
+
+ hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
+ pOIBindInfo, grfPI, (HANDLE*)dwReserved);
+
+ IUri_Release(uri);
+ return hres;
+}
+
+static HRESULT WINAPI MkProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+ FIXME("(%p)->(%p)\n", This, pProtocolData);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MkProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
+ DWORD dwOptions)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+ FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MkProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+
+ TRACE("(%p)->(%08x)\n", This, dwOptions);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI MkProtocol_Suspend(IInternetProtocolEx *iface)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+ FIXME("(%p)\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MkProtocol_Resume(IInternetProtocolEx *iface)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+ FIXME("(%p)\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MkProtocol_Read(IInternetProtocolEx *iface, void *pv,
+ ULONG cb, ULONG *pcbRead)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(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(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
+ DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+ FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MkProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+
+ TRACE("(%p)->(%08x)\n", This, dwOptions);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI MkProtocol_UnlockRequest(IInternetProtocolEx *iface)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+
+ TRACE("(%p)\n", This);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI MkProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
+ IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
+ DWORD grfPI, HANDLE *dwReserved)
+{
+ MkProtocol *This = impl_from_IInternetProtocolEx(iface);
+ LPWSTR mime, progid, display_name, colon_ptr;
+ DWORD path_size = INTERNET_MAX_URL_LENGTH;
+ DWORD bindf=0, eaten=0, scheme=0, len;
+ BSTR url, path_tmp, path = NULL;
IParseDisplayName *pdn;
- IMoniker *mon;
- LPWSTR mime, progid, display_name;
- LPCWSTR ptr, ptr2;
BINDINFO bindinfo;
STATSTG statstg;
- DWORD bindf=0, eaten=0, len;
- CLSID clsid;
+ IMoniker *mon;
HRESULT hres;
+ CLSID clsid;
- static const WCHAR wszMK[] = {'m','k',':','@'};
-
- TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
+ TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
pOIBindInfo, grfPI, dwReserved);
- if(strncmpiW(szUrl, wszMK, sizeof(wszMK)/sizeof(WCHAR)))
+ hres = IUri_GetScheme(pUri, &scheme);
+ if(FAILED(hres))
+ return hres;
+ if(scheme != URL_SCHEME_MK)
return INET_E_INVALID_URL;
memset(&bindinfo, 0, sizeof(bindinfo));
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL);
- hres = FindMimeFromData(NULL, szUrl, NULL, 0, NULL, 0, &mime, 0);
+ hres = IUri_GetDisplayUri(pUri, &url);
+ if(FAILED(hres))
+ return hres;
+ hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
+ SysFreeString(url);
if(SUCCEEDED(hres)) {
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
CoTaskMemFree(mime);
}
- ptr2 = szUrl + sizeof(wszMK)/sizeof(WCHAR);
- ptr = strchrW(ptr2, ':');
- if(!ptr)
+ hres = IUri_GetPath(pUri, &path_tmp);
+ if(FAILED(hres))
+ return hres;
+ path = heap_alloc(path_size);
+ hres = UrlUnescapeW((LPWSTR)path_tmp, path, &path_size, 0);
+ SysFreeString(path_tmp);
+ if (FAILED(hres))
+ {
+ heap_free(path);
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
+ }
+ progid = path+1; /* skip '@' symbol */
+ colon_ptr = strchrW(path, ':');
+ if(!colon_ptr)
+ {
+ heap_free(path);
+ return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
+ }
+
+ len = strlenW(path);
+ display_name = heap_alloc((len+1)*sizeof(WCHAR));
+ memcpy(display_name, path, (len+1)*sizeof(WCHAR));
- progid = heap_alloc((ptr-ptr2+1)*sizeof(WCHAR));
- memcpy(progid, ptr2, (ptr-ptr2)*sizeof(WCHAR));
- progid[ptr-ptr2] = 0;
+ progid[colon_ptr-progid] = 0; /* overwrite ':' with NULL terminator */
hres = CLSIDFromProgID(progid, &clsid);
- heap_free(progid);
+ heap_free(path);
if(FAILED(hres))
+ {
+ heap_free(display_name);
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));
+ heap_free(display_name);
return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER);
}
- len = strlenW(--ptr2);
- display_name = heap_alloc((len+1)*sizeof(WCHAR));
- memcpy(display_name, ptr2, (len+1)*sizeof(WCHAR));
hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon);
heap_free(display_name);
IParseDisplayName_Release(pdn);
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 = {
+static const IInternetProtocolExVtbl MkProtocolVtbl = {
MkProtocol_QueryInterface,
MkProtocol_AddRef,
MkProtocol_Release,
MkProtocol_Read,
MkProtocol_Seek,
MkProtocol_LockRequest,
- MkProtocol_UnlockRequest
+ MkProtocol_UnlockRequest,
+ MkProtocol_StartEx
};
HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
ret = heap_alloc(sizeof(MkProtocol));
- ret->lpIInternetProtocolVtbl = &MkProtocolVtbl;
+ ret->IInternetProtocolEx_iface.lpVtbl = &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);
+ *ppobj = &ret->IInternetProtocolEx_iface;
return S_OK;
}
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 0x0001
-#define FLAG_FIRST_CONTINUE_COMPLETE 0x0002
-#define FLAG_FIRST_DATA_REPORTED 0x0004
-#define FLAG_ALL_DATA_READ 0x0008
-#define FLAG_LAST_DATA_REPORTED 0x0010
-#define FLAG_RESULT_REPORTED 0x0020
-
static inline HRESULT report_progress(Protocol *protocol, ULONG status_code, LPCWSTR status_text)
{
return IInternetProtocolSink_ReportProgress(protocol->protocol_sink, status_code, status_text);
TRACE("(%p)->(%p)\n", protocol, ar);
- if(!ar->dwResult) {
- WARN("request failed: %d\n", ar->dwError);
- return;
- }
-
- protocol->flags |= FLAG_REQUEST_COMPLETE;
-
- if(!protocol->request) {
- TRACE("setting request handle %p\n", (HINTERNET)ar->dwResult);
- protocol->request = (HINTERNET)ar->dwResult;
- }
-
/* PROTOCOLDATA same as native */
memset(&data, 0, sizeof(data));
data.dwState = 0xf1000000;
- if(protocol->flags & FLAG_FIRST_CONTINUE_COMPLETE)
- data.pData = (LPVOID)BINDSTATUS_ENDDOWNLOADCOMPONENTS;
- else
- data.pData = (LPVOID)BINDSTATUS_DOWNLOADINGDATA;
+
+ if(ar->dwResult) {
+ protocol->flags |= FLAG_REQUEST_COMPLETE;
+
+ if(!protocol->request) {
+ TRACE("setting request handle %p\n", (HINTERNET)ar->dwResult);
+ protocol->request = (HINTERNET)ar->dwResult;
+ }
+
+ if(protocol->flags & FLAG_FIRST_CONTINUE_COMPLETE)
+ data.pData = (LPVOID)BINDSTATUS_ENDDOWNLOADCOMPONENTS;
+ else
+ data.pData = (LPVOID)BINDSTATUS_DOWNLOADINGDATA;
+
+ }else {
+ protocol->flags |= FLAG_ERROR;
+ data.pData = (LPVOID)ar->dwError;
+ }
if (protocol->bindf & BINDF_FROMURLMON)
IInternetProtocolSink_Switch(protocol->protocol_sink, &data);
return S_OK;
}
+ if(protocol->flags & FLAG_ERROR) {
+ protocol->flags &= ~FLAG_ERROR;
+ protocol->vtbl->on_error(protocol, (DWORD)data->pData);
+ return S_OK;
+ }
+
if(protocol->post_stream)
return write_post_stream(protocol);
protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
}
- if(data->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA) {
+ if(data->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA && !protocol->available_bytes) {
BOOL res;
/* InternetQueryDataAvailable may immediately fork and perform its asynchronous
return S_FALSE;
}
- if(!(protocol->flags & FLAG_REQUEST_COMPLETE)) {
+ if(!(protocol->flags & FLAG_REQUEST_COMPLETE) || !protocol->available_bytes) {
*read_ret = 0;
return E_PENDING;
}
- while(read < size) {
- if(protocol->available_bytes) {
- ULONG len;
+ while(read < size && protocol->available_bytes) {
+ ULONG len;
- res = InternetReadFile(protocol->request, ((BYTE *)buf)+read,
- protocol->available_bytes > size-read ? size-read : protocol->available_bytes, &len);
- if(!res) {
- WARN("InternetReadFile failed: %d\n", GetLastError());
- hres = INET_E_DOWNLOAD_FAILURE;
- report_result(protocol, hres);
- break;
- }
+ res = InternetReadFile(protocol->request, ((BYTE *)buf)+read,
+ protocol->available_bytes > size-read ? size-read : protocol->available_bytes, &len);
+ if(!res) {
+ WARN("InternetReadFile failed: %d\n", GetLastError());
+ hres = INET_E_DOWNLOAD_FAILURE;
+ report_result(protocol, hres);
+ break;
+ }
- if(!len) {
- all_data_read(protocol);
- break;
- }
+ if(!len) {
+ all_data_read(protocol);
+ break;
+ }
+
+ read += len;
+ protocol->current_position += len;
+ protocol->available_bytes -= len;
- read += len;
- protocol->current_position += len;
- protocol->available_bytes -= len;
- }else {
+ if(!protocol->available_bytes) {
/* 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 */
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-#define PROTOCOL_THIS(iface) DEFINE_THIS(ProtocolProxy, IInternetProtocol, iface)
+static inline ProtocolProxy *impl_from_IInternetProtocol(IInternetProtocol *iface)
+{
+ return CONTAINING_RECORD(iface, ProtocolProxy, IInternetProtocol_iface);
+}
static HRESULT WINAPI ProtocolProxy_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
- *ppv = PROTOCOL(This);
+ *ppv = &This->IInternetProtocol_iface;
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
- *ppv = PROTSINK(This);
+ *ppv = &This->IInternetProtocolSink_iface;
}
if(*ppv) {
static ULONG WINAPI ProtocolProxy_AddRef(IInternetProtocol *iface)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
static ULONG WINAPI ProtocolProxy_Release(IInternetProtocol *iface)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE_PTR dwReserved)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
pOIBindInfo, grfPI, dwReserved);
static HRESULT WINAPI ProtocolProxy_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%p)\n", This, pProtocolData);
static HRESULT WINAPI ProtocolProxy_Abort(IInternetProtocol *iface, HRESULT hrReason,
DWORD dwOptions)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolProxy_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
static HRESULT WINAPI ProtocolProxy_Suspend(IInternetProtocol *iface)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolProxy_Resume(IInternetProtocol *iface)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolProxy_Read(IInternetProtocol *iface, void *pv,
ULONG cb, ULONG *pcbRead)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
static HRESULT WINAPI ProtocolProxy_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
return E_NOTIMPL;
}
static HRESULT WINAPI ProtocolProxy_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
static HRESULT WINAPI ProtocolProxy_UnlockRequest(IInternetProtocol *iface)
{
- ProtocolProxy *This = PROTOCOL_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocol(iface);
TRACE("(%p)\n", This);
return IInternetProtocol_UnlockRequest(This->protocol);
}
-#undef PROTOCOL_THIS
-
static const IInternetProtocolVtbl ProtocolProxyVtbl = {
ProtocolProxy_QueryInterface,
ProtocolProxy_AddRef,
ProtocolProxy_UnlockRequest
};
-#define PROTSINK_THIS(iface) DEFINE_THIS(ProtocolProxy, IInternetProtocolSink, iface)
+static inline ProtocolProxy *impl_from_IInternetProtocolSink(IInternetProtocolSink *iface)
+{
+ return CONTAINING_RECORD(iface, ProtocolProxy, IInternetProtocolSink_iface);
+}
static HRESULT WINAPI ProtocolProxySink_QueryInterface(IInternetProtocolSink *iface,
REFIID riid, void **ppv)
{
- ProtocolProxy *This = PROTSINK_THIS(iface);
- return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
+ ProtocolProxy *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocol_QueryInterface(&This->IInternetProtocol_iface, riid, ppv);
}
static ULONG WINAPI ProtocolProxySink_AddRef(IInternetProtocolSink *iface)
{
- ProtocolProxy *This = PROTSINK_THIS(iface);
- return IInternetProtocol_AddRef(PROTOCOL(This));
+ ProtocolProxy *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocol_AddRef(&This->IInternetProtocol_iface);
}
static ULONG WINAPI ProtocolProxySink_Release(IInternetProtocolSink *iface)
{
- ProtocolProxy *This = PROTSINK_THIS(iface);
- return IInternetProtocol_Release(PROTOCOL(This));
+ ProtocolProxy *This = impl_from_IInternetProtocolSink(iface);
+ return IInternetProtocol_Release(&This->IInternetProtocol_iface);
}
static HRESULT WINAPI ProtocolProxySink_Switch(IInternetProtocolSink *iface,
PROTOCOLDATA *pProtocolData)
{
- ProtocolProxy *This = PROTSINK_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%p)\n", This, pProtocolData);
static HRESULT WINAPI ProtocolProxySink_ReportProgress(IInternetProtocolSink *iface,
ULONG ulStatusCode, LPCWSTR szStatusText)
{
- ProtocolProxy *This = PROTSINK_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
static HRESULT WINAPI ProtocolProxySink_ReportData(IInternetProtocolSink *iface,
DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
- ProtocolProxy *This = PROTSINK_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocolSink(iface);
TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
static HRESULT WINAPI ProtocolProxySink_ReportResult(IInternetProtocolSink *iface,
HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
{
- ProtocolProxy *This = PROTSINK_THIS(iface);
+ ProtocolProxy *This = impl_from_IInternetProtocolSink(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 = {
ProtocolProxySink_QueryInterface,
ProtocolProxySink_AddRef,
if(!sink)
return E_OUTOFMEMORY;
- sink->lpIInternetProtocolVtbl = &ProtocolProxyVtbl;
- sink->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
+ sink->IInternetProtocol_iface.lpVtbl = &ProtocolProxyVtbl;
+ sink->IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkVtbl;
sink->ref = 1;
IInternetProtocol_AddRef(protocol);
+++ /dev/null
-/*
- * self-registerable dll functions for urlmon.dll
- *
- * Copyright (C) 2003 John K. Hohm
- *
- * 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 <stdio.h>
-
-#include "urlmon_main.h"
-
-#include "winreg.h"
-#include "advpub.h"
-
-#include "wine/debug.h"
-#include "wine/unicode.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-
-/*
- * Near the bottom of this file are the exported DllRegisterServer and
- * DllUnregisterServer, which make all this worthwhile.
- */
-
-/***********************************************************************
- * interface for self-registering
- */
-struct regsvr_interface
-{
- IID const *iid; /* NULL for end of list */
- LPCSTR name; /* can be NULL to omit */
- IID const *base_iid; /* can be NULL to omit */
- int num_methods; /* can be <0 to omit */
- CLSID const *ps_clsid; /* can be NULL to omit */
- CLSID const *ps_clsid32; /* can be NULL to omit */
-};
-
-static HRESULT register_interfaces(struct regsvr_interface const *list);
-static HRESULT unregister_interfaces(struct regsvr_interface const *list);
-
-struct regsvr_coclass
-{
- CLSID const *clsid; /* NULL for end of list */
- LPCSTR name; /* can be NULL to omit */
- LPCSTR ips; /* can be NULL to omit */
- LPCSTR ips32; /* can be NULL to omit */
- LPCSTR ips32_tmodel; /* can be NULL to omit */
- LPCSTR progid; /* can be NULL to omit */
- LPCSTR viprogid; /* can be NULL to omit */
- LPCSTR progid_extra; /* can be NULL to omit */
-};
-
-static HRESULT register_coclasses(struct regsvr_coclass const *list);
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
-
-/***********************************************************************
- * static string constants
- */
-static WCHAR const interface_keyname[10] = {
- 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
-static WCHAR const base_ifa_keyname[14] = {
- 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
- 'e', 0 };
-static WCHAR const num_methods_keyname[11] = {
- 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
-static WCHAR const ps_clsid_keyname[15] = {
- 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
- 'i', 'd', 0 };
-static WCHAR const ps_clsid32_keyname[17] = {
- 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
- 'i', 'd', '3', '2', 0 };
-static WCHAR const clsid_keyname[6] = {
- 'C', 'L', 'S', 'I', 'D', 0 };
-static WCHAR const curver_keyname[7] = {
- 'C', 'u', 'r', 'V', 'e', 'r', 0 };
-static WCHAR const ips_keyname[13] = {
- 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
- 0 };
-static WCHAR const ips32_keyname[15] = {
- 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
- '3', '2', 0 };
-static WCHAR const progid_keyname[7] = {
- 'P', 'r', 'o', 'g', 'I', 'D', 0 };
-static WCHAR const viprogid_keyname[25] = {
- 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
- 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
- 0 };
-static char const tmodel_valuename[] = "ThreadingModel";
-
-/***********************************************************************
- * static helper functions
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
-static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
- WCHAR const *value);
-static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
- char const *value);
-static LONG register_progid(WCHAR const *clsid,
- char const *progid, char const *curver_progid,
- char const *name, char const *extra);
-
-/***********************************************************************
- * register_interfaces
- */
-static HRESULT register_interfaces(struct regsvr_interface const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY interface_key;
-
- res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->iid; ++list) {
- WCHAR buf[39];
- HKEY iid_key;
-
- StringFromGUID2(list->iid, buf, 39);
- res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_interface_key;
-
- if (list->name) {
- res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
- (CONST BYTE*)(list->name),
- strlen(list->name) + 1);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- if (list->base_iid) {
- res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- if (0 <= list->num_methods) {
- static WCHAR const fmt[3] = { '%', 'd', 0 };
- HKEY key;
-
- res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
-
- sprintfW(buf, fmt, list->num_methods);
- res = RegSetValueExW(key, NULL, 0, REG_SZ,
- (CONST BYTE*)buf,
- (lstrlenW(buf) + 1) * sizeof(WCHAR));
- RegCloseKey(key);
-
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- if (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) {
- res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- error_close_iid_key:
- RegCloseKey(iid_key);
- }
-
-error_close_interface_key:
- RegCloseKey(interface_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * unregister_interfaces
- */
-static HRESULT unregister_interfaces(struct regsvr_interface const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY interface_key;
-
- res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
- KEY_READ | KEY_WRITE, &interface_key);
- if (res == ERROR_FILE_NOT_FOUND) return S_OK;
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->iid; ++list) {
- WCHAR buf[39];
-
- StringFromGUID2(list->iid, buf, 39);
- res = RegDeleteTreeW(interface_key, buf);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- }
-
- RegCloseKey(interface_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * register_coclasses
- */
-static HRESULT register_coclasses(struct regsvr_coclass const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY coclass_key;
-
- res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->clsid; ++list) {
- WCHAR buf[39];
- HKEY clsid_key;
-
- StringFromGUID2(list->clsid, buf, 39);
- res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
- if (list->name) {
- res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
- (CONST BYTE*)(list->name),
- strlen(list->name) + 1);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->ips) {
- res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->ips32) {
- HKEY ips32_key;
-
- res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL,
- &ips32_key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
- res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
- (CONST BYTE*)list->ips32,
- lstrlenA(list->ips32) + 1);
- if (res == ERROR_SUCCESS && list->ips32_tmodel)
- res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
- (CONST BYTE*)list->ips32_tmodel,
- strlen(list->ips32_tmodel) + 1);
- RegCloseKey(ips32_key);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->progid) {
- res = register_key_defvalueA(clsid_key, progid_keyname,
- list->progid);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
- res = register_progid(buf, list->progid, NULL,
- list->name, list->progid_extra);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->viprogid) {
- res = register_key_defvalueA(clsid_key, viprogid_keyname,
- list->viprogid);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
- res = register_progid(buf, list->viprogid, list->progid,
- list->name, list->progid_extra);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- error_close_clsid_key:
- RegCloseKey(clsid_key);
- }
-
-error_close_coclass_key:
- RegCloseKey(coclass_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * unregister_coclasses
- */
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY coclass_key;
-
- res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
- KEY_READ | KEY_WRITE, &coclass_key);
- if (res == ERROR_FILE_NOT_FOUND) return S_OK;
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->clsid; ++list) {
- WCHAR buf[39];
-
- StringFromGUID2(list->clsid, buf, 39);
- res = RegDeleteTreeW(coclass_key, buf);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
- if (list->progid) {
- res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
- }
-
- if (list->viprogid) {
- res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
- }
- }
-
-error_close_coclass_key:
- RegCloseKey(coclass_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * regsvr_key_guid
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
-{
- WCHAR buf[39];
-
- StringFromGUID2(guid, buf, 39);
- return register_key_defvalueW(base, name, buf);
-}
-
-/***********************************************************************
- * regsvr_key_defvalueW
- */
-static LONG register_key_defvalueW(
- HKEY base,
- WCHAR const *name,
- WCHAR const *value)
-{
- LONG res;
- HKEY key;
-
- res = RegCreateKeyExW(base, name, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &key, NULL);
- if (res != ERROR_SUCCESS) return res;
- res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
- (lstrlenW(value) + 1) * sizeof(WCHAR));
- RegCloseKey(key);
- return res;
-}
-
-/***********************************************************************
- * regsvr_key_defvalueA
- */
-static LONG register_key_defvalueA(
- HKEY base,
- WCHAR const *name,
- char const *value)
-{
- LONG res;
- HKEY key;
-
- res = RegCreateKeyExW(base, name, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &key, NULL);
- if (res != ERROR_SUCCESS) return res;
- res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
- lstrlenA(value) + 1);
- RegCloseKey(key);
- return res;
-}
-
-/***********************************************************************
- * regsvr_progid
- */
-static LONG register_progid(
- WCHAR const *clsid,
- char const *progid,
- char const *curver_progid,
- char const *name,
- char const *extra)
-{
- LONG res;
- HKEY progid_key;
-
- res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
- NULL, 0, KEY_READ | KEY_WRITE, NULL,
- &progid_key, NULL);
- if (res != ERROR_SUCCESS) return res;
-
- if (name) {
- res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
- (CONST BYTE*)name, strlen(name) + 1);
- if (res != ERROR_SUCCESS) goto error_close_progid_key;
- }
-
- if (clsid) {
- res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
- if (res != ERROR_SUCCESS) goto error_close_progid_key;
- }
-
- if (curver_progid) {
- res = register_key_defvalueA(progid_key, curver_keyname,
- curver_progid);
- if (res != ERROR_SUCCESS) goto error_close_progid_key;
- }
-
- if (extra) {
- HKEY extra_key;
-
- res = RegCreateKeyExA(progid_key, extra, 0,
- NULL, 0, KEY_READ | KEY_WRITE, NULL,
- &extra_key, NULL);
- if (res == ERROR_SUCCESS)
- RegCloseKey(extra_key);
- }
-
-error_close_progid_key:
- RegCloseKey(progid_key);
- return res;
-}
-
-/***********************************************************************
- * coclass list
- */
-static struct regsvr_coclass const coclass_list[] = {
- { &CLSID_StdURLMoniker,
- "URL Moniker",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_CdlProtocol,
- "CDL: Asynchronous Pluggable Protocol Handler",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_FileProtocol,
- "file:, local: Asynchronous Pluggable Protocol Handler",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_FtpProtocol,
- "ftp: Asynchronous Pluggable Protocol Handler",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_GopherProtocol,
- "gopher: Asynchronous Pluggable Protocol Handler",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_HttpProtocol,
- "http: Asynchronous Pluggable Protocol Handler",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_HttpSProtocol,
- "https: Asynchronous Pluggable Protocol Handler",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_MkProtocol,
- "mk: Asynchronous Pluggable Protocol Handler",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { &CLSID_InternetSecurityManager,
- "Security Manager",
- NULL,
- "urlmon.dll",
- "Both"
- },
- { &CLSID_InternetZoneManager,
- "URL Zone Manager",
- NULL,
- "urlmon.dll",
- "Both"
- },
- { &CLSID_PSFactoryBuffer,
- "URLMoniker ProxyStub Factory",
- NULL,
- "urlmon.dll",
- "Apartment"
- },
- { NULL } /* list terminator */
-};
-
-/***********************************************************************
- * interface list
- */
-
-static struct regsvr_interface const interface_list[] = {
- { NULL } /* list terminator */
-};
-
-/***********************************************************************
- * register_inf
- */
-
-#define INF_SET_CLSID(clsid) \
- do \
- { \
- static CHAR name[] = #clsid; \
- \
- pse[i].pszName = name; \
- clsids[i++] = &clsid; \
- } while (0)
-
-static HRESULT register_inf(BOOL doregister)
-{
- HRESULT hres;
- HMODULE hAdvpack;
- HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
- STRTABLEA strtable;
- STRENTRYA pse[8];
- static CLSID const *clsids[8];
- unsigned int i = 0;
-
- static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
-
- INF_SET_CLSID(CLSID_CdlProtocol);
- INF_SET_CLSID(CLSID_FileProtocol);
- INF_SET_CLSID(CLSID_FtpProtocol);
- INF_SET_CLSID(CLSID_GopherProtocol);
- INF_SET_CLSID(CLSID_HttpProtocol);
- INF_SET_CLSID(CLSID_HttpSProtocol);
- INF_SET_CLSID(CLSID_MkProtocol);
- INF_SET_CLSID(CLSID_DeCompMimeFilter);
-
- for(i = 0; i < sizeof(pse)/sizeof(pse[0]); i++) {
- pse[i].pszValue = heap_alloc(39);
- 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]);
- }
-
- strtable.cEntries = sizeof(pse)/sizeof(pse[0]);
- strtable.pse = pse;
-
- hAdvpack = LoadLibraryW(wszAdvpack);
- pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
-
- hres = pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
-
- for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
- heap_free(pse[i].pszValue);
-
- return hres;
-}
-
-#undef INF_SET_CLSID
-
-/***********************************************************************
- * DllRegisterServer (URLMON.@)
- */
-HRESULT WINAPI DllRegisterServer(void)
-{
- HRESULT hr;
-
- TRACE("\n");
-
- hr = URLMON_DllRegisterServer();
- if(SUCCEEDED(hr))
- hr = register_coclasses(coclass_list);
- if(SUCCEEDED(hr))
- hr = register_interfaces(interface_list);
- if(SUCCEEDED(hr))
- hr = register_inf(TRUE);
- return hr;
-}
-
-/***********************************************************************
- * DllUnregisterServer (URLMON.@)
- */
-HRESULT WINAPI DllUnregisterServer(void)
-{
- HRESULT hr;
-
- TRACE("\n");
-
- hr = URLMON_DllUnregisterServer();
- if(SUCCEEDED(hr))
- hr = unregister_coclasses(coclass_list);
- if(SUCCEEDED(hr))
- hr = unregister_interfaces(interface_list);
- if(SUCCEEDED(hr))
- hr = register_inf(FALSE);
- return hr;
-}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+/* @makedep: urlmon.rgs */
+1 WINE_REGISTRY urlmon.rgs
+
/* @makedep: urlmon.inf */
REGINST REGINST urlmon.inf
* Copyright (c) 2004 Huw D M Davies
* Copyright 2004 Jacek Caban
* Copyright 2009 Detlef Riekenberg
+ * Copyright 2011 Thomas Mullaly for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include "winreg.h"
#include "wininet.h"
+#define NO_SHLWAPI_REG
+#include "shlwapi.h"
+
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
'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','\\',
'Z','o','n','e','s','\\',0};
+static const WCHAR wszZoneMapDomainsKey[] = {'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','\\',
+ 'Z','o','n','e','M','a','p','\\',
+ 'D','o','m','a','i','n','s',0};
/********************************************************************
* get_string_from_reg [internal]
return S_OK;
}
+/********************************************************************
+ * matches_domain_pattern [internal]
+ *
+ * Checks if the given string matches the specified domain pattern.
+ *
+ * This function looks for explicit wildcard domain components iff
+ * they appear at the very beginning of the 'pattern' string
+ *
+ * pattern = "*.google.com"
+ */
+static BOOL matches_domain_pattern(LPCWSTR pattern, LPCWSTR str, BOOL implicit_wildcard, LPCWSTR *matched)
+{
+ BOOL matches = FALSE;
+ DWORD pattern_len = strlenW(pattern);
+ DWORD str_len = strlenW(str);
+
+ TRACE("(%d) Checking if %s matches %s\n", implicit_wildcard, debugstr_w(str), debugstr_w(pattern));
+
+ *matched = NULL;
+ if(str_len >= pattern_len) {
+ /* Check if there's an explicit wildcard in the pattern. */
+ if(pattern[0] == '*' && pattern[1] == '.') {
+ /* Make sure that 'str' matches the wildcard pattern.
+ *
+ * Example:
+ * pattern = "*.google.com"
+ *
+ * So in this case 'str' would have to end with ".google.com" in order
+ * to map to this pattern.
+ */
+ if(str_len >= pattern_len+1 && !strcmpiW(str+(str_len-pattern_len+1), pattern+1)) {
+ /* Check if there's another '.' inside of the "unmatched" portion
+ * of 'str'.
+ *
+ * Example:
+ * pattern = "*.google.com"
+ * str = "test.testing.google.com"
+ *
+ * The currently matched portion is ".google.com" in 'str', we need
+ * see if there's a '.' inside of the unmatched portion ("test.testing"), because
+ * if there is and 'implicit_wildcard' isn't set, then this isn't
+ * a match.
+ */
+ const WCHAR *ptr;
+ if(str_len > pattern_len+1 && (ptr = memrchrW(str, '.', str_len-pattern_len-2))) {
+ if(implicit_wildcard) {
+ matches = TRUE;
+ *matched = ptr+1;
+ }
+ } else {
+ matches = TRUE;
+ *matched = str;
+ }
+ }
+ } else if(implicit_wildcard && str_len > pattern_len) {
+ /* When the pattern has an implicit wildcard component, it means
+ * that anything goes in 'str' as long as it ends with the pattern
+ * and that the beginning of the match has a '.' before it.
+ *
+ * Example:
+ * pattern = "google.com"
+ * str = "www.google.com"
+ *
+ * Implicitly matches the pattern, where as:
+ *
+ * pattern = "google.com"
+ * str = "wwwgoogle.com"
+ *
+ * Doesn't match the pattern.
+ */
+ if(str_len > pattern_len) {
+ if(str[str_len-pattern_len-1] == '.' && !strcmpiW(str+(str_len-pattern_len), pattern)) {
+ matches = TRUE;
+ *matched = str+(str_len-pattern_len);
+ }
+ }
+ } else {
+ /* The pattern doesn't have an implicit wildcard, or an explicit wildcard,
+ * so 'str' has to be an exact match to the 'pattern'.
+ */
+ if(!strcmpiW(str, pattern)) {
+ matches = TRUE;
+ *matched = str;
+ }
+ }
+ }
+
+ if(matches)
+ TRACE("Found a match: matched=%s\n", debugstr_w(*matched));
+ else
+ TRACE("No match found\n");
+
+ return matches;
+}
+
+static BOOL get_zone_for_scheme(HKEY key, LPCWSTR schema, DWORD *zone)
+{
+ static const WCHAR wildcardW[] = {'*',0};
+
+ DWORD res;
+ DWORD size = sizeof(DWORD);
+ DWORD type;
+
+ /* See if the key contains a value for the scheme first. */
+ res = RegQueryValueExW(key, schema, NULL, &type, (BYTE*)zone, &size);
+ if(type != REG_DWORD)
+ WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(schema));
+
+ if(res != ERROR_SUCCESS || type != REG_DWORD) {
+ /* Try to get the zone for the wildcard scheme. */
+ size = sizeof(DWORD);
+ res = RegQueryValueExW(key, wildcardW, NULL, &type, (BYTE*)zone, &size);
+ if(type != REG_DWORD)
+ WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(wildcardW));
+ }
+
+ return res == ERROR_SUCCESS && type == REG_DWORD;
+}
+
+/********************************************************************
+ * search_domain_for_zone [internal]
+ *
+ * Searches the specified 'domain' registry key to see if 'host' maps into it, or any
+ * of it's subdomain registry keys.
+ *
+ * Returns S_OK if a match is found, S_FALSE if no matches were found, or an error code.
+ */
+static HRESULT search_domain_for_zone(HKEY domains, LPCWSTR domain, DWORD domain_len, LPCWSTR schema,
+ LPCWSTR host, DWORD host_len, DWORD *zone)
+{
+ BOOL found = FALSE;
+ HKEY domain_key;
+ DWORD res;
+ LPCWSTR matched;
+
+ if(host_len >= domain_len && matches_domain_pattern(domain, host, TRUE, &matched)) {
+ res = RegOpenKeyW(domains, domain, &domain_key);
+ if(res != ERROR_SUCCESS) {
+ ERR("Failed to open domain key %s: %d\n", debugstr_w(domain), res);
+ return E_UNEXPECTED;
+ }
+
+ if(matched == host)
+ found = get_zone_for_scheme(domain_key, schema, zone);
+ else {
+ INT domain_offset;
+ DWORD subdomain_count, subdomain_len;
+ BOOL check_domain = TRUE;
+
+ find_domain_name(domain, domain_len, &domain_offset);
+
+ res = RegQueryInfoKeyW(domain_key, NULL, NULL, NULL, &subdomain_count, &subdomain_len,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if(res != ERROR_SUCCESS) {
+ ERR("Unable to query info for key %s: %d\n", debugstr_w(domain), res);
+ RegCloseKey(domain_key);
+ return E_UNEXPECTED;
+ }
+
+ if(subdomain_count) {
+ WCHAR *subdomain;
+ WCHAR *component;
+ DWORD i;
+
+ subdomain = heap_alloc((subdomain_len+1)*sizeof(WCHAR));
+ if(!subdomain) {
+ RegCloseKey(domain_key);
+ return E_OUTOFMEMORY;
+ }
+
+ component = heap_strndupW(host, matched-host-1);
+ if(!component) {
+ heap_free(subdomain);
+ RegCloseKey(domain_key);
+ return E_OUTOFMEMORY;
+ }
+
+ for(i = 0; i < subdomain_count; ++i) {
+ DWORD len = subdomain_len+1;
+ const WCHAR *sub_matched;
+
+ res = RegEnumKeyExW(domain_key, i, subdomain, &len, NULL, NULL, NULL, NULL);
+ if(res != ERROR_SUCCESS) {
+ heap_free(component);
+ heap_free(subdomain);
+ RegCloseKey(domain_key);
+ return E_UNEXPECTED;
+ }
+
+ if(matches_domain_pattern(subdomain, component, FALSE, &sub_matched)) {
+ HKEY subdomain_key;
+
+ res = RegOpenKeyW(domain_key, subdomain, &subdomain_key);
+ if(res != ERROR_SUCCESS) {
+ ERR("Unable to open subdomain key %s of %s: %d\n", debugstr_w(subdomain),
+ debugstr_w(domain), res);
+ heap_free(component);
+ heap_free(subdomain);
+ RegCloseKey(domain_key);
+ return E_UNEXPECTED;
+ }
+
+ found = get_zone_for_scheme(subdomain_key, schema, zone);
+ check_domain = FALSE;
+ RegCloseKey(subdomain_key);
+ break;
+ }
+ }
+ heap_free(subdomain);
+ heap_free(component);
+ }
+
+ /* There's a chance that 'host' implicitly mapped into 'domain', in
+ * which case we check to see if 'domain' contains zone information.
+ *
+ * This can only happen if 'domain' is it's own domain name.
+ * Example:
+ * "google.com" (domain name = "google.com")
+ *
+ * So if:
+ * host = "www.google.com"
+ *
+ * Then host would map directly into the "google.com" domain key.
+ *
+ * If 'domain' has more than just it's domain name, or it does not
+ * have a domain name, then we don't perform the check. The reason
+ * for this is that these domains don't allow implicit mappings.
+ * Example:
+ * domain = "org" (has no domain name)
+ * host = "www.org"
+ *
+ * The mapping would only happen if the "org" key had an explicit subkey
+ * called "www".
+ */
+ if(check_domain && !domain_offset && !strchrW(host, matched-host-1))
+ found = get_zone_for_scheme(domain_key, schema, zone);
+ }
+ RegCloseKey(domain_key);
+ }
+
+ return found ? S_OK : S_FALSE;
+}
+
+static HRESULT search_for_domain_mapping(HKEY domains, LPCWSTR schema, LPCWSTR host, DWORD host_len, DWORD *zone)
+{
+ WCHAR *domain;
+ DWORD domain_count, domain_len, i;
+ DWORD res;
+ HRESULT hres = S_FALSE;
+
+ res = RegQueryInfoKeyW(domains, NULL, NULL, NULL, &domain_count, &domain_len,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if(res != ERROR_SUCCESS) {
+ WARN("Failed to retrieve information about key\n");
+ return E_UNEXPECTED;
+ }
+
+ if(!domain_count)
+ return S_FALSE;
+
+ domain = heap_alloc((domain_len+1)*sizeof(WCHAR));
+ if(!domain)
+ return E_OUTOFMEMORY;
+
+ for(i = 0; i < domain_count; ++i) {
+ DWORD len = domain_len+1;
+
+ res = RegEnumKeyExW(domains, i, domain, &len, NULL, NULL, NULL, NULL);
+ if(res != ERROR_SUCCESS) {
+ heap_free(domain);
+ return E_UNEXPECTED;
+ }
+
+ hres = search_domain_for_zone(domains, domain, len, schema, host, host_len, zone);
+ if(FAILED(hres) || hres == S_OK)
+ break;
+ }
+
+ heap_free(domain);
+ return hres;
+}
+
+static HRESULT get_zone_from_domains(LPCWSTR url, LPCWSTR schema, DWORD *zone)
+{
+ HRESULT hres;
+ WCHAR *host_name;
+ DWORD host_len = lstrlenW(url)+1;
+ DWORD res;
+ HKEY domains;
+
+ host_name = heap_alloc(host_len*sizeof(WCHAR));
+ if(!host_name)
+ return E_OUTOFMEMORY;
+
+ hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, host_name, host_len, &host_len, 0);
+ if(hres == S_FALSE) {
+ WCHAR *tmp = heap_realloc(host_name, (host_len+1)*sizeof(WCHAR));
+ if(!tmp) {
+ heap_free(host_name);
+ return E_OUTOFMEMORY;
+ }
+
+ host_name = tmp;
+ hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, host_name, host_len+1, &host_len, 0);
+ }
+
+ /* Windows doesn't play nice with unknown scheme types when it tries
+ * to check if a host name maps into any domains.
+ *
+ * The reason is with how CoInternetParseUrl handles unknown scheme types
+ * when it's parsing the domain of a URL (IE it always returns E_FAIL).
+ *
+ * Windows doesn't compenstate for this and simply doesn't check if
+ * the URL maps into any domains.
+ */
+ if(hres != S_OK) {
+ heap_free(host_name);
+ if(hres == E_FAIL)
+ return S_FALSE;
+ return hres;
+ }
+
+ /* First try CURRENT_USER. */
+ res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapDomainsKey, &domains);
+ if(res == ERROR_SUCCESS) {
+ hres = search_for_domain_mapping(domains, schema, host_name, host_len, zone);
+ RegCloseKey(domains);
+ } else
+ WARN("Failed to open HKCU's %s key\n", debugstr_w(wszZoneMapDomainsKey));
+
+ /* If that doesn't work try LOCAL_MACHINE. */
+ if(hres == S_FALSE) {
+ res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapDomainsKey, &domains);
+ if(res == ERROR_SUCCESS) {
+ hres = search_for_domain_mapping(domains, schema, host_name, host_len, zone);
+ RegCloseKey(domains);
+ } else
+ WARN("Failed to open HKLM's %s key\n", debugstr_w(wszZoneMapDomainsKey));
+ }
+
+ heap_free(host_name);
+ return hres;
+}
+
static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url)
{
LPWSTR secur_url;
DWORD size=0;
HRESULT hres;
- *zone = -1;
+ *zone = URLZONE_INVALID;
hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0);
if(hres != S_OK) {
case DRIVE_FIXED:
case DRIVE_CDROM:
case DRIVE_RAMDISK:
- *zone = 0;
+ *zone = URLZONE_LOCAL_MACHINE;
hres = S_OK;
break;
case DRIVE_REMOTE:
- *zone = 3;
+ *zone = URLZONE_INTERNET;
hres = S_OK;
break;
default:
}
}
- if(*zone == -1) {
- WARN("domains are not yet implemented\n");
- hres = get_zone_from_reg(schema, zone);
+ if(*zone == URLZONE_INVALID) {
+ hres = get_zone_from_domains(secur_url, schema, zone);
+ if(hres == S_FALSE)
+ hres = get_zone_from_reg(schema, zone);
}
if(FAILED(hres) || !ret_url)
static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey)
{
- static const WCHAR wszFormat[] = {'%','s','%','l','d',0};
+ static const WCHAR wszFormat[] = {'%','s','%','u',0};
- WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+8];
+ WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+12];
DWORD res;
wsprintfW(key_name, wszFormat, wszZonesKey, zone);
}
if(!pwszUrl) {
- *pdwZone = -1;
+ *pdwZone = URLZONE_INVALID;
return E_INVALIDARG;
}
DWORD dwZone,
ZONEATTRIBUTES* pZoneAttributes)
{
- FIXME("(%p)->(%08x %p) stub\n", iface, dwZone, pZoneAttributes);
- return E_NOTIMPL;
+ ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface);
+ HRESULT hr;
+ HKEY hcu;
+
+ TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes);
+
+ if (!pZoneAttributes)
+ return E_INVALIDARG;
+
+ hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu);
+ if (FAILED(hr))
+ return S_OK; /* IE6 returned E_FAIL here */
+
+ /* cbSize is ignored */
+ RegSetValueExW(hcu, displaynameW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDisplayName,
+ (lstrlenW(pZoneAttributes->szDisplayName)+1)* sizeof(WCHAR));
+
+ RegSetValueExW(hcu, descriptionW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDescription,
+ (lstrlenW(pZoneAttributes->szDescription)+1)* sizeof(WCHAR));
+
+ RegSetValueExW(hcu, iconW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szIconPath,
+ (lstrlenW(pZoneAttributes->szIconPath)+1)* sizeof(WCHAR));
+
+ RegSetValueExW(hcu, minlevelW, 0, REG_DWORD,
+ (const BYTE*) &pZoneAttributes->dwTemplateMinLevel, sizeof(DWORD));
+
+ RegSetValueExW(hcu, currentlevelW, 0, REG_DWORD,
+ (const BYTE*) &pZoneAttributes->dwTemplateCurrentLevel, sizeof(DWORD));
+
+ RegSetValueExW(hcu, recommendedlevelW, 0, REG_DWORD,
+ (const BYTE*) &pZoneAttributes->dwTemplateRecommended, sizeof(DWORD));
+
+ RegSetValueExW(hcu, flagsW, 0, REG_DWORD, (const BYTE*) &pZoneAttributes->dwFlags, sizeof(DWORD));
+ RegCloseKey(hcu);
+ return S_OK;
+
}
/********************************************************************
return ZoneMgrImpl_Construct(NULL, (void**)ppZM);
}
+static HRESULT parse_security_url(const WCHAR *url, PSUACTION action, WCHAR **result) {
+ IInternetProtocolInfo *protocol_info;
+ WCHAR *tmp, *new_url = NULL, *alloc_url = NULL;
+ DWORD size, new_size;
+ HRESULT hres = S_OK, parse_hres;
+
+ while(1) {
+ TRACE("parsing %s\n", debugstr_w(url));
+
+ protocol_info = get_protocol_info(url);
+ if(!protocol_info)
+ break;
+
+ size = strlenW(url)+1;
+ new_url = CoTaskMemAlloc(size*sizeof(WCHAR));
+ if(!new_url) {
+ hres = E_OUTOFMEMORY;
+ break;
+ }
+
+ new_size = 0;
+ parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, size, &new_size, 0);
+ if(parse_hres == S_FALSE) {
+ if(!new_size) {
+ hres = E_UNEXPECTED;
+ break;
+ }
+
+ tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR));
+ if(!tmp) {
+ hres = E_OUTOFMEMORY;
+ break;
+ }
+ new_url = tmp;
+ parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url,
+ new_size, &new_size, 0);
+ if(parse_hres == S_FALSE) {
+ hres = E_FAIL;
+ break;
+ }
+ }
+
+ if(parse_hres != S_OK || !strcmpW(url, new_url))
+ break;
+
+ CoTaskMemFree(alloc_url);
+ url = alloc_url = new_url;
+ new_url = NULL;
+ }
+
+ CoTaskMemFree(new_url);
+
+ if(hres != S_OK) {
+ WARN("failed: %08x\n", hres);
+ CoTaskMemFree(alloc_url);
+ return hres;
+ }
+
+ if(action == PSU_DEFAULT && (protocol_info = get_protocol_info(url))) {
+ size = strlenW(url)+1;
+ new_url = CoTaskMemAlloc(size * sizeof(WCHAR));
+ if(new_url) {
+ new_size = 0;
+ parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0,
+ new_url, size, &new_size, 0);
+ if(parse_hres == S_FALSE) {
+ if(new_size) {
+ tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR));
+ if(tmp) {
+ new_url = tmp;
+ parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, new_url,
+ new_size, &new_size, 0);
+ if(parse_hres == S_FALSE)
+ hres = E_FAIL;
+ }else {
+ hres = E_OUTOFMEMORY;
+ }
+ }else {
+ hres = E_UNEXPECTED;
+ }
+ }
+
+ if(hres == S_OK && parse_hres == S_OK) {
+ CoTaskMemFree(alloc_url);
+ url = alloc_url = new_url;
+ new_url = NULL;
+ }
+
+ CoTaskMemFree(new_url);
+ }else {
+ hres = E_OUTOFMEMORY;
+ }
+ IInternetProtocolInfo_Release(protocol_info);
+ }
+
+ if(FAILED(hres)) {
+ WARN("failed %08x\n", hres);
+ CoTaskMemFree(alloc_url);
+ return hres;
+ }
+
+ if(!alloc_url) {
+ size = strlenW(url)+1;
+ alloc_url = CoTaskMemAlloc(size * sizeof(WCHAR));
+ if(!alloc_url)
+ return E_OUTOFMEMORY;
+ memcpy(alloc_url, url, size * sizeof(WCHAR));
+ }
+
+ *result = alloc_url;
+ return S_OK;
+}
+
/********************************************************************
* CoInternetGetSecurityUrl (URLMON.@)
*/
HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUACTION psuAction, DWORD dwReserved)
{
- WCHAR buf1[INTERNET_MAX_URL_LENGTH], buf2[INTERNET_MAX_URL_LENGTH];
- LPWSTR url, domain;
- DWORD len;
+ WCHAR *secure_url;
HRESULT hres;
TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved);
- url = buf1;
- domain = buf2;
- strcpyW(url, pwzUrl);
-
- while(1) {
- hres = CoInternetParseUrl(url, PARSE_SECURITY_URL, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0);
- if(hres!=S_OK || !strcmpW(url, domain))
- break;
+ hres = parse_security_url(pwzUrl, psuAction, &secure_url);
+ if(FAILED(hres))
+ return hres;
- if(url == buf1) {
- url = buf2;
- domain = buf1;
- } else {
- url = buf1;
- domain = buf2;
+ if(psuAction != PSU_SECURITY_URL_ONLY) {
+ PARSEDURLW parsed_url = { sizeof(parsed_url) };
+ DWORD size;
+
+ /* FIXME: Use helpers from uri.c */
+ if(SUCCEEDED(ParseURLW(secure_url, &parsed_url))) {
+ WCHAR *new_url;
+
+ switch(parsed_url.nScheme) {
+ case URL_SCHEME_FTP:
+ case URL_SCHEME_HTTP:
+ case URL_SCHEME_HTTPS:
+ size = strlenW(secure_url)+1;
+ new_url = CoTaskMemAlloc(size * sizeof(WCHAR));
+ if(new_url)
+ hres = UrlGetPartW(secure_url, new_url, &size, URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME);
+ else
+ hres = E_OUTOFMEMORY;
+ CoTaskMemFree(secure_url);
+ if(hres != S_OK) {
+ WARN("UrlGetPart failed: %08x\n", hres);
+ CoTaskMemFree(new_url);
+ return FAILED(hres) ? hres : E_FAIL;
+ }
+ secure_url = new_url;
+ }
}
}
- if(psuAction==PSU_SECURITY_URL_ONLY) {
- len = lstrlenW(url)+1;
- *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
- if(!*ppwzSecUrl)
- return E_OUTOFMEMORY;
+ *ppwzSecUrl = secure_url;
+ return S_OK;
+}
- memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR));
- return S_OK;
- }
+/********************************************************************
+ * CoInternetGetSecurityUrlEx (URLMON.@)
+ */
+HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION psuAction, DWORD_PTR dwReserved)
+{
+ URL_SCHEME scheme_type;
+ BSTR secure_uri;
+ WCHAR *ret_url;
+ HRESULT hres;
- hres = CoInternetParseUrl(url, PARSE_SECURITY_DOMAIN, 0, domain,
- INTERNET_MAX_URL_LENGTH, &len, 0);
- if(SUCCEEDED(hres)) {
- len++;
- *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
- if(!*ppwzSecUrl)
- return E_OUTOFMEMORY;
+ TRACE("(%p,%p,%u,%u)\n", pUri, ppSecUri, psuAction, (DWORD)dwReserved);
- memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR));
- return S_OK;
- }
+ if(!pUri || !ppSecUri)
+ return E_INVALIDARG;
- hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, domain,
- INTERNET_MAX_URL_LENGTH, &len, 0);
- if(hres == S_OK){
- const WCHAR fileW[] = {'f','i','l','e',0};
- if(!strcmpW(domain, fileW)){
- hres = CoInternetParseUrl(url, PARSE_ROOTDOCUMENT, 0, domain, INTERNET_MAX_URL_LENGTH, &len, 0);
- }else{
- domain[len] = ':';
- hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, domain+len+1,
- INTERNET_MAX_URL_LENGTH-len-1, &len, 0);
- if(hres == S_OK) {
- len = lstrlenW(domain)+1;
- *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
- if(!*ppwzSecUrl)
- return E_OUTOFMEMORY;
+ hres = IUri_GetDisplayUri(pUri, &secure_uri);
+ if(FAILED(hres))
+ return hres;
- memcpy(*ppwzSecUrl, domain, len*sizeof(WCHAR));
- return S_OK;
- }
- }
- }else
+ hres = parse_security_url(secure_uri, psuAction, &ret_url);
+ SysFreeString(secure_uri);
+ if(FAILED(hres))
return hres;
- len = lstrlenW(url)+1;
- *ppwzSecUrl = CoTaskMemAlloc(len*sizeof(WCHAR));
- if(!*ppwzSecUrl)
- return E_OUTOFMEMORY;
+ hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri);
+ if(FAILED(hres)) {
+ CoTaskMemFree(ret_url);
+ return hres;
+ }
- memcpy(*ppwzSecUrl, url, len*sizeof(WCHAR));
- return S_OK;
+ /* File URIs have to hierarchical. */
+ hres = IUri_GetScheme(pUri, (DWORD*)&scheme_type);
+ if(SUCCEEDED(hres) && scheme_type == URL_SCHEME_FILE) {
+ const WCHAR *tmp = ret_url;
+
+ /* Check and see if a "//" is after the scheme name. */
+ tmp += sizeof(fileW)/sizeof(WCHAR);
+ if(*tmp != '/' || *(tmp+1) != '/')
+ hres = E_INVALIDARG;
+ }
+
+ if(SUCCEEDED(hres))
+ hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri);
+ CoTaskMemFree(ret_url);
+ return hres;
}
LPBC pBC, LPCWSTR szUrl, IUnknown *pUnkOuter, IUnknown **ppUnk,
IInternetProtocol **ppOInetProt, DWORD dwOption)
{
- IInternetProtocolEx *protocol;
+ BindProtocol *protocol;
HRESULT hres;
TRACE("(%p %s %p %p %p %08x)\n", pBC, debugstr_w(szUrl), pUnkOuter, ppUnk,
if(FAILED(hres))
return hres;
- *ppOInetProt = (IInternetProtocol*)protocol;
+ *ppOInetProt = (IInternetProtocol*)&protocol->IInternetProtocolEx_iface;
return S_OK;
}
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
typedef struct {
- const IMonikerVtbl *lpIMonikerVtbl;
+ IMoniker IMoniker_iface;
+ IUriContainer IUriContainer_iface;
LONG ref;
LPOLESTR URLName; /* URL string identified by this URLmoniker */
} URLMoniker;
-#define MONIKER_THIS(iface) DEFINE_THIS(URLMoniker, IMoniker, iface)
+static inline URLMoniker *impl_from_IMoniker(IMoniker *iface)
+{
+ return CONTAINING_RECORD(iface, URLMoniker, IMoniker_iface);
+}
static HRESULT WINAPI URLMoniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
if(!ppv)
return E_INVALIDARG;
}else if(IsEqualIID(&IID_IAsyncMoniker, riid)) {
TRACE("(%p)->(IID_IAsyncMoniker %p)\n", This, ppv);
*ppv = iface;
+ }else if(IsEqualIID(&IID_IUriContainer, riid)) {
+ TRACE("(%p)->(IID_IUriContainer %p)\n", This, ppv);
+ *ppv = &This->IUriContainer_iface;
}else {
WARN("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
static ULONG WINAPI URLMoniker_AddRef(IMoniker *iface)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%u\n",This, refCount);
static ULONG WINAPI URLMoniker_Release(IMoniker *iface)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%u\n",This, refCount);
static HRESULT WINAPI URLMoniker_GetClassID(IMoniker *iface, CLSID *pClassID)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
TRACE("(%p,%p)\n", This, pClassID);
static HRESULT WINAPI URLMoniker_IsDirty(IMoniker *iface)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
TRACE("(%p)\n",This);
static HRESULT WINAPI URLMoniker_Load(IMoniker* iface,IStream* pStm)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
HRESULT res;
ULONG size;
ULONG got;
static HRESULT WINAPI URLMoniker_Save(IMoniker *iface, IStream* pStm, BOOL fClearDirty)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
HRESULT res;
ULONG size;
static HRESULT WINAPI URLMoniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER *pcbSize)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
TRACE("(%p,%p)\n",This,pcbSize);
static HRESULT WINAPI URLMoniker_BindToObject(IMoniker *iface, IBindCtx* pbc, IMoniker *pmkToLeft,
REFIID riid, void **ppv)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
IRunningObjectTable *obj_tbl;
IUri *uri;
HRESULT hres;
static HRESULT WINAPI URLMoniker_BindToStorage(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, REFIID riid, void **ppvObject)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
IUri *uri;
HRESULT hres;
TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject);
+ if(ppvObject) *ppvObject = NULL;
+
+ if(!pbc || !ppvObject) return E_INVALIDARG;
+
if(pmkToLeft)
FIXME("Unsupported pmkToLeft\n");
static HRESULT WINAPI URLMoniker_Reduce(IMoniker *iface, IBindCtx *pbc,
DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
{
- URLMoniker *This = MONIKER_THIS(iface);
-
+ URLMoniker *This = impl_from_IMoniker(iface);
+
TRACE("(%p,%p,%d,%p,%p)\n", This, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced);
if(!ppmkReduced)
static HRESULT WINAPI URLMoniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
FIXME("(%p)->(%p,%d,%p): stub\n",This,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
return E_NOTIMPL;
}
static HRESULT WINAPI URLMoniker_Enum(IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
TRACE("(%p,%d,%p)\n", This, fForward, ppenumMoniker);
static HRESULT WINAPI URLMoniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
CLSID clsid;
LPOLESTR urlPath;
IBindCtx* bind;
static HRESULT WINAPI URLMoniker_Hash(IMoniker *iface, DWORD *pdwHash)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
int h = 0,i,skip,len;
int off = 0;
LPOLESTR val;
static HRESULT WINAPI URLMoniker_IsRunning(IMoniker* iface, IBindCtx* pbc,
IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
FIXME("(%p)->(%p,%p,%p): stub\n",This,pbc,pmkToLeft,pmkNewlyRunning);
return E_NOTIMPL;
}
static HRESULT WINAPI URLMoniker_GetTimeOfLastChange(IMoniker *iface,
IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
FIXME("(%p)->(%p,%p,%p): stub\n", This, pbc, pmkToLeft, pFileTime);
return E_NOTIMPL;
}
static HRESULT WINAPI URLMoniker_Inverse(IMoniker *iface, IMoniker **ppmk)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
TRACE("(%p,%p)\n",This,ppmk);
return MK_E_NOINVERSE;
}
static HRESULT WINAPI URLMoniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkPrefix)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
FIXME("(%p)->(%p,%p): stub\n",This,pmkOther,ppmkPrefix);
return E_NOTIMPL;
}
static HRESULT WINAPI URLMoniker_RelativePathTo(IMoniker *iface, IMoniker *pmOther, IMoniker **ppmkRelPath)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
FIXME("(%p)->(%p,%p): stub\n",This,pmOther,ppmkRelPath);
return E_NOTIMPL;
}
static HRESULT WINAPI URLMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
LPOLESTR *ppszDisplayName)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
int len;
TRACE("(%p,%p,%p,%p)\n", This, pbc, pmkToLeft, ppszDisplayName);
static HRESULT WINAPI URLMoniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
FIXME("(%p)->(%p,%p,%p,%p,%p): stub\n",This,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
return E_NOTIMPL;
}
static HRESULT WINAPI URLMoniker_IsSystemMoniker(IMoniker *iface, DWORD *pwdMksys)
{
- URLMoniker *This = MONIKER_THIS(iface);
+ URLMoniker *This = impl_from_IMoniker(iface);
TRACE("(%p,%p)\n",This,pwdMksys);
URLMoniker_IsSystemMoniker
};
+static inline URLMoniker *impl_from_IUriContainer(IUriContainer *iface)
+{
+ return CONTAINING_RECORD(iface, URLMoniker, IUriContainer_iface);
+}
+
+static HRESULT WINAPI UriContainer_QueryInterface(IUriContainer *iface, REFIID riid, void **ppv)
+{
+ URLMoniker *This = impl_from_IUriContainer(iface);
+ return IMoniker_QueryInterface(&This->IMoniker_iface, riid, ppv);
+}
+
+static ULONG WINAPI UriContainer_AddRef(IUriContainer *iface)
+{
+ URLMoniker *This = impl_from_IUriContainer(iface);
+ return IMoniker_AddRef(&This->IMoniker_iface);
+}
+
+static ULONG WINAPI UriContainer_Release(IUriContainer *iface)
+{
+ URLMoniker *This = impl_from_IUriContainer(iface);
+ return IMoniker_Release(&This->IMoniker_iface);
+}
+
+static HRESULT WINAPI UriContainer_GetIUri(IUriContainer *iface, IUri **ppIUri)
+{
+ URLMoniker *This = impl_from_IUriContainer(iface);
+
+ FIXME("(%p)->(%p)\n", This, ppIUri);
+
+ *ppIUri = NULL;
+ return S_FALSE;
+}
+
+static const IUriContainerVtbl UriContainerVtbl = {
+ UriContainer_QueryInterface,
+ UriContainer_AddRef,
+ UriContainer_Release,
+ UriContainer_GetIUri
+};
+
static URLMoniker *alloc_moniker(void)
{
URLMoniker *ret;
if(!ret)
return NULL;
- ret->lpIMonikerVtbl = &URLMonikerVtbl;
+ ret->IMoniker_iface.lpVtbl = &URLMonikerVtbl;
+ ret->IUriContainer_iface.lpVtbl = &UriContainerVtbl;
ret->ref = 1;
ret->URLName = NULL;
hres = URLMoniker_Init(obj, lefturl, szURL);
CoTaskMemFree(lefturl);
if(SUCCEEDED(hres))
- hres = URLMoniker_QueryInterface((IMoniker*)obj, &IID_IMoniker, (void**)ppmk);
- IMoniker_Release((IMoniker*)obj);
+ hres = URLMoniker_QueryInterface(&obj->IMoniker_iface, &IID_IMoniker, (void**)ppmk);
+ IMoniker_Release(&obj->IMoniker_iface);
return hres;
}
typedef struct ProxyBindStatusCallback
{
- const IBindStatusCallbackVtbl *lpVtbl;
+ IBindStatusCallback IBindStatusCallback_iface;
IBindStatusCallback *pBSC;
} ProxyBindStatusCallback;
+static inline ProxyBindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
+{
+ return CONTAINING_RECORD(iface, ProxyBindStatusCallback, IBindStatusCallback_iface);
+}
+
static HRESULT WINAPI ProxyBindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
{
if (IsEqualGUID(&IID_IBindStatusCallback, riid) ||
static HRESULT WINAPI ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
IBinding *pib)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_OnStartBinding(This->pBSC, dwReserved, pib);
static HRESULT WINAPI ProxyBindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_GetPriority(This->pBSC, pnPriority);
static HRESULT WINAPI ProxyBindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_OnLowResource(This->pBSC, reserved);
static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_OnProgress(This->pBSC, ulProgress,
static HRESULT WINAPI ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_OnStopBinding(This->pBSC, hresult, szError);
static HRESULT WINAPI ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
static HRESULT WINAPI ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_OnDataAvailable(This->pBSC, grfBSCF, dwSize,
static HRESULT WINAPI ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
if(This->pBSC)
return IBindStatusCallback_OnObjectAvailable(This->pBSC, riid, punk);
static HRESULT WINAPI AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
{
- ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
HRESULT hr = IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
*grfBINDF |= BINDF_PULLDATA | BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE;
return hr;
if (!szURL || !ppStream)
return E_INVALIDARG;
- blocking_bsc.lpVtbl = &BlockingBindStatusCallbackVtbl;
+ blocking_bsc.IBindStatusCallback_iface.lpVtbl = &BlockingBindStatusCallbackVtbl;
blocking_bsc.pBSC = lpfnCB;
- return URLStartDownload(szURL, ppStream, (IBindStatusCallback *)&blocking_bsc);
+ return URLStartDownload(szURL, ppStream, &blocking_bsc.IBindStatusCallback_iface);
}
/***********************************************************************
if (!szURL)
return E_INVALIDARG;
- async_bsc.lpVtbl = &AsyncBindStatusCallbackVtbl;
+ async_bsc.IBindStatusCallback_iface.lpVtbl = &AsyncBindStatusCallbackVtbl;
async_bsc.pBSC = lpfnCB;
- hr = URLStartDownload(szURL, &pStream, (IBindStatusCallback *)&async_bsc);
+ hr = URLStartDownload(szURL, &pStream, &async_bsc.IBindStatusCallback_iface);
if (SUCCEEDED(hr) && pStream)
IStream_Release(pStream);
}
static inline BOOL is_alpha(WCHAR val) {
- return ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'));
+ return ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'));
}
static inline BOOL is_num(WCHAR val) {
- return (val >= '0' && val <= '9');
+ return (val >= '0' && val <= '9');
}
static inline BOOL is_drive_path(const WCHAR *str) {
return (!val || val == '#' || val == '?');
}
+static inline BOOL is_slash(WCHAR c)
+{
+ return c == '/' || c == '\\';
+}
+
static BOOL is_default_port(URL_SCHEME scheme, DWORD port) {
DWORD i;
dest[2] = hexDigits[val & 0xf];
}
-/* Scans the range of characters [str, end] and returns the last occurrence
- * of 'ch' or returns NULL.
- */
-static const WCHAR *str_last_of(const WCHAR *str, const WCHAR *end, WCHAR ch) {
- const WCHAR *ptr = end;
-
- while(ptr >= str) {
- if(*ptr == ch)
- return ptr;
- --ptr;
- }
-
- return NULL;
-}
-
/* Attempts to parse the domain name from the host.
*
* This function also includes the Top-level Domain (TLD) name
* a valid domain name it will assign 'domain_start' the offset
* into 'host' where the domain name starts.
*
- * It's implied that if a domain name its range is implied to be
+ * It's implied that if there is a domain name its range is:
* [host+domain_start, host+host_len).
*/
-static void find_domain_name(const WCHAR *host, DWORD host_len,
+void find_domain_name(const WCHAR *host, DWORD host_len,
INT *domain_start) {
const WCHAR *last_tld, *sec_last_tld, *end;
if(host_len < 4)
return;
- last_tld = str_last_of(host, end, '.');
+ last_tld = memrchrW(host, '.', host_len);
if(!last_tld)
/* http://hostname -> has no domain name. */
return;
- sec_last_tld = str_last_of(host, last_tld-1, '.');
+ sec_last_tld = memrchrW(host, '.', last_tld-host);
if(!sec_last_tld) {
/* If the '.' is at the beginning of the host there
* has to be at least 3 characters in the TLD for it
if(last_tld - (sec_last_tld+1) == 3) {
for(i = 0; i < sizeof(recognized_tlds)/sizeof(recognized_tlds[0]); ++i) {
if(!StrCmpNIW(sec_last_tld+1, recognized_tlds[i].tld_name, 3)) {
- const WCHAR *domain = str_last_of(host, sec_last_tld-1, '.');
+ const WCHAR *domain = memrchrW(host, '.', sec_last_tld-host);
if(!domain)
*domain_start = 0;
* part of the TLD.
* Ex: www.google.fo.uk -> google.fo.uk as the domain name.
*/
- const WCHAR *domain = str_last_of(host, sec_last_tld-1, '.');
+ const WCHAR *domain = memrchrW(host, '.', sec_last_tld-host);
if(!domain)
*domain_start = 0;
/* Removes the dot segments from a hierarchical URIs path component. This
* function performs the removal in place.
*
- * This is a modified version of Qt's QUrl function "removeDotsFromPath".
- *
* This function returns the new length of the path string.
*/
static DWORD remove_dot_segments(WCHAR *path, DWORD path_len) {
DWORD len;
while(in < end) {
- /* A. if the input buffer begins with a prefix of "/./" or "/.",
- * where "." is a complete path segment, then replace that
- * prefix with "/" in the input buffer; otherwise,
+ /* Move the first path segment in the input buffer to the end of
+ * the output buffer, and any subsequent characters up to, including
+ * the next "/" character (if any) or the end of the input buffer.
*/
- if(in <= end - 3 && in[0] == '/' && in[1] == '.' && in[2] == '/') {
- in += 2;
- continue;
- } else if(in == end - 2 && in[0] == '/' && in[1] == '.') {
- *out++ = '/';
- in += 2;
+ while(in < end && !is_slash(*in))
+ *out++ = *in++;
+ if(in == end)
break;
- }
+ *out++ = *in++;
- /* B. if the input buffer begins with a prefix of "/../" or "/..",
- * where ".." is a complete path segment, then replace that
- * prefix with "/" in the input buffer and remove the last
- * segment and its preceding "/" (if any) from the output
- * buffer; otherwise,
- */
- if(in <= end - 4 && in[0] == '/' && in[1] == '.' && in[2] == '.' && in[3] == '/') {
- while(out > path && *(--out) != '/');
+ while(in < end) {
+ if(*in != '.')
+ break;
- in += 3;
- continue;
- } else if(in == end - 3 && in[0] == '/' && in[1] == '.' && in[2] == '.') {
- while(out > path && *(--out) != '/');
+ /* Handle ending "/." */
+ if(in + 1 == end) {
+ ++in;
+ break;
+ }
- if(*out == '/')
- ++out;
+ /* Handle "/./" */
+ if(is_slash(in[1])) {
+ in += 2;
+ continue;
+ }
- in += 3;
- break;
- }
+ /* If we don't have "/../" or ending "/.." */
+ if(in[1] != '.' || (in + 2 != end && !is_slash(in[2])))
+ break;
- /* C. move the first path segment in the input buffer to the end of
- * the output buffer, including the initial "/" character (if
- * any) and any subsequent characters up to, but not including,
- * the next "/" character or the end of the input buffer.
- */
- *out++ = *in++;
- while(in < end && *in != '/')
- *out++ = *in++;
+ /* Find the slash preceding out pointer and move out pointer to it */
+ if(out > path+1 && is_slash(*--out))
+ --out;
+ while(out > path && !is_slash(*(--out)));
+ if(is_slash(*out))
+ ++out;
+ in += 2;
+ if(in != end)
+ ++in;
+ }
}
len = out - path;
*
* NOTES:
* Windows will expand an elision if the elision only represents 1 h16
- * component of the URI.
+ * component of the address.
*
* Ex: [1::2:3:4:5:6:7] -> [1:0:2:3:4:5:6:7]
*
* If the IPv6 address contains an IPv4 address, the IPv4 address is also
- * considered for being included as part of an elision if all it's components
+ * considered for being included as part of an elision if all its components
* are zeros.
*
* Ex: [1:2:3:4:5:6:0.0.0.0] -> [1:2:3:4:5:6::]
return ret;
}
-/* Converts an IPv6 address into it's 128 bits (16 bytes) numerical value.
+/* Converts an IPv6 address into its 128 bits (16 bytes) numerical value.
*
* This function assumes that the ipv6_address has already been validated.
*/
for(i = 0; i < address->h16_count; ++i) {
if(address->elision) {
if(address->components[i].str > address->elision && !already_passed_elision) {
- /* Means we just passed the elision and need to add it's values to
+ /* Means we just passed the elision and need to add its values to
* 'number' before we do anything else.
*/
DWORD j = 0;
if(!already_passed_elision && address->elision) {
for(i = 0; i < address->elision_size; i+=2)
number[cur_component++] = 0;
- already_passed_elision = TRUE;
}
if(address->ipv4) {
TRACE("(%p %p %x): Found valid IPv6 literal %s len=%d\n",
ptr, data, flags, debugstr_wn(start, *ptr-start),
- *ptr-start);
+ (int)(*ptr-start));
return TRUE;
}
data->host_type = Uri_HOST_UNKNOWN;
TRACE("(%p %p %x): Parsed IPvFuture address %s len=%d\n", ptr, data, flags,
- debugstr_wn(start, *ptr-start), *ptr-start);
+ debugstr_wn(start, *ptr-start), (int)(*ptr-start));
return TRUE;
}
}
}
+ if(data->scheme_type == URL_SCHEME_MK && !computeOnly && !(flags & Uri_CREATE_NO_CANONICALIZE)) {
+ DWORD new_len = remove_dot_segments(uri->canon_uri + uri->path_start,
+ uri->canon_len - uri->path_start);
+ uri->canon_len = uri->path_start + new_len;
+ }
+
uri->path_len = uri->canon_len - uri->path_start;
- TRACE("(%p %p %x %d): Canonicalized opaque URI path %s len=%d\n", data, uri, flags, computeOnly,
- debugstr_wn(uri->canon_uri+uri->path_start, uri->path_len), uri->path_len);
+ if(!computeOnly)
+ TRACE("(%p %p %x %d): Canonicalized opaque URI path %s len=%d\n", data, uri, flags, computeOnly,
+ debugstr_wn(uri->canon_uri+uri->path_start, uri->path_len), uri->path_len);
return TRUE;
}
INT len;
uri->canon_uri = NULL;
- len = uri->canon_size = uri->canon_len = 0;
+ uri->canon_size = uri->canon_len = 0;
TRACE("(%p %p %x): beginning to canonicalize URI %s.\n", data, uri, flags, debugstr_w(data->uri));
return ref;
}
-static HRESULT WINAPI UriBuilderFactory_CreateInitializedIUriBuilder(IUriBuilderFactory *iface,
- DWORD dwFlags,
- DWORD_PTR dwReserved,
- IUriBuilder **ppIUriBuilder)
+static HRESULT WINAPI UriBuilderFactory_CreateIUriBuilder(IUriBuilderFactory *iface,
+ DWORD dwFlags,
+ DWORD_PTR dwReserved,
+ IUriBuilder **ppIUriBuilder)
{
Uri *This = impl_from_IUriBuilderFactory(iface);
TRACE("(%p)->(%08x %08x %p)\n", This, dwFlags, (DWORD)dwReserved, ppIUriBuilder);
return CreateIUriBuilder(NULL, 0, 0, ppIUriBuilder);
}
-static HRESULT WINAPI UriBuilderFactory_CreateIUriBuilder(IUriBuilderFactory *iface,
- DWORD dwFlags,
- DWORD_PTR dwReserved,
- IUriBuilder **ppIUriBuilder)
+static HRESULT WINAPI UriBuilderFactory_CreateInitializedIUriBuilder(IUriBuilderFactory *iface,
+ DWORD dwFlags,
+ DWORD_PTR dwReserved,
+ IUriBuilder **ppIUriBuilder)
{
Uri *This = impl_from_IUriBuilderFactory(iface);
TRACE("(%p)->(%08x %08x %p)\n", This, dwFlags, (DWORD)dwReserved, ppIUriBuilder);
UriBuilderFactory_QueryInterface,
UriBuilderFactory_AddRef,
UriBuilderFactory_Release,
- UriBuilderFactory_CreateInitializedIUriBuilder,
- UriBuilderFactory_CreateIUriBuilder
+ UriBuilderFactory_CreateIUriBuilder,
+ UriBuilderFactory_CreateInitializedIUriBuilder
};
static Uri* create_uri_obj(void) {
/* Find the characters the will be copied over from
* the base path.
*/
- end = str_last_of(base, base+(base_len-1), '/');
+ end = memrchrW(base, '/', base_len);
if(!end && data->scheme_type == URL_SCHEME_FILE)
/* Try looking for a '\\'. */
- end = str_last_of(base, base+(base_len-1), '\\');
+ end = memrchrW(base, '\\', base_len);
}
if(end) {
DWORD new_len = remove_dot_segments(path+offset,path_len-offset);
if(new_len != path_len) {
- WCHAR *tmp = heap_realloc(path, (path_offset+new_len+1)*sizeof(WCHAR));
+ WCHAR *tmp = heap_realloc(path, (offset+new_len+1)*sizeof(WCHAR));
if(!tmp) {
heap_free(path);
*result = NULL;
}
}
+ if(relative->query_start > -1) {
+ data.query = relative->canon_uri+relative->query_start;
+ data.query_len = relative->query_len;
+ }
+
/* Make sure the path component is valid. */
ptr = path;
pptr = &ptr;
[RegisterDll]
-AddReg=Classes.Reg, Protocols.Reg, ZoneMap.Reg, Zones.Reg, Misc.Reg
+AddReg=ZoneMap.Reg, Zones.Reg
[UnregisterDll]
-DelReg=Classes.Reg, Protocols.Reg, ZoneMap.Reg, Zones.Reg, Misc.Reg
-
-
-[Classes.Reg]
-
-;; CLSID_DeCompMimeFilter
-HKCR,"CLSID\%CLSID_DeCompMimeFilter%",,,"AP lzdhtml encoding/decoding Filter"
-HKCR,"CLSID\%CLSID_DeCompMimeFilter%\InProcServer32",,,"%MODULE%"
-HKCR,"CLSID\%CLSID_DeCompMimeFilter%\InProcServer32","ThreadingModel",,"Apartment"
-
-
-[Protocols.Reg]
-HKCR,"PROTOCOLS\Handler\cdl",,,"CDL: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Handler\cdl","CLSID",,"%CLSID_CdlProtocol%"
-HKCR,"PROTOCOLS\Handler\file",,,"file:, local: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Handler\file","CLSID",,"%CLSID_FileProtocol%"
-HKCR,"PROTOCOLS\Handler\local",,,"file:, local: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Handler\local","CLSID",,"%CLSID_FileProtocol%"
-HKCR,"PROTOCOLS\Handler\ftp",,,"ftp: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Handler\ftp","CLSID",,"%CLSID_FtpProtocol%"
-HKCR,"PROTOCOLS\Handler\gopher",,,"gopher: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Handler\gopher","CLSID",,"%CLSID_GopherProtocol%"
-HKCR,"PROTOCOLS\Handler\http",,,"http: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Handler\http","CLSID",,"%CLSID_HttpProtocol%"
-HKCR,"PROTOCOLS\Handler\https",,,"https: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Handler\https","CLSID",,"%CLSID_HttpsProtocol%"
-HKCR,"PROTOCOLS\Handler\mk",,,"mk: Asynchronous Pluggable Protocol Handler"
-HKCR,"PROTOCOLS\Filter\deflate",,,"AP Deflate Encoding/Decoding Filter"
-HKCR,"PROTOCOLS\Filter\deflate","CLSID",,"%CLSID_DeCompMimeFilter%"
-HKCR,"PROTOCOLS\Filter\gzip",,,"AP Deflate Encoding/Decoding Filter"
-HKCR,"PROTOCOLS\Filter\gzip","CLSID",,"%CLSID_DeCompMimeFilter%"
-HKCR,"PROTOCOLS\Filter\lzdhtml",,,"AP Deflate Encoding/Decoding Filter"
-HKCR,"PROTOCOLS\Filter\lzdhtml","CLSID",,"%CLSID_DeCompMimeFilter%"
+DelReg=ZoneMap.Reg, Zones.Reg
[ZoneMap.Reg]
HKLM,"%ZONES_UNTRUSTED%","1E05",0x10003,0x10000
-[Misc.Reg]
-HKCU,"%INTERNET_SETTINGS%","User Agent",,"%USER_AGENT%"
-
-
[Strings]
-MODULE="urlmon.dll"
-
-USER_AGENT="Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
-INTERNET_SETTINGS="Software\Microsoft\Windows\CurrentVersion\Internet Settings"
-
PATH_ZONEMAP="Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap"
PATH_ZONEMAP_PROTOCOLS="Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\ProtocolDefaults"
PATH_ZONEMAP_DOMAINS="Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains"
<file>mk.c</file>
<file>protocol.c</file>
<file>protproxy.c</file>
- <file>regsvr.c</file>
<file>sec_mgr.c</file>
<file>session.c</file>
<file>umon.c</file>
--- /dev/null
+HKCR
+{
+ NoRemove PROTOCOLS
+ {
+ NoRemove Handler
+ {
+ ForceRemove cdl = s 'CDL: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{3dd53d40-7b8b-11d0-b013-00aa0059ce02}'
+ }
+ ForceRemove file = s 'file:, local: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{79eac9e7-baf9-11ce-8c82-00aa004ba90b}'
+ }
+ ForceRemove local = s 'file:, local: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{79eac9e7-baf9-11ce-8c82-00aa004ba90b}'
+ }
+ ForceRemove ftp = s 'ftp: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{79eac9e3-baf9-11ce-8c82-00aa004ba90b}'
+ }
+ ForceRemove gopher = s 'gopher: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{79eac9e4-baf9-11ce-8c82-00aa004ba90b}'
+ }
+ ForceRemove http = s 'http: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{79eac9e2-baf9-11ce-8c82-00aa004ba90b}'
+ }
+ ForceRemove https = s 'https: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{79eac9e5-baf9-11ce-8c82-00aa004ba90b}'
+ }
+ ForceRemove mk = s 'mk: Asynchronous Pluggable Protocol Handler'
+ {
+ val CLSID = s '{79eac9e6-baf9-11ce-8c82-00aa004ba90b}'
+ }
+ }
+ NoRemove Filter
+ {
+ ForceRemove deflate = s 'AP Deflate Encoding/Decoding Filter'
+ {
+ val CLSID = s '{8f6b0360-b80d-11d0-a9b3-006097942311}'
+ }
+ ForceRemove gzip = s 'AP Deflate Encoding/Decoding Filter'
+ {
+ val CLSID = s '{8f6b0360-b80d-11d0-a9b3-006097942311}'
+ }
+ ForceRemove lzdhtml = s 'AP Deflate Encoding/Decoding Filter'
+ {
+ val CLSID = s '{8f6b0360-b80d-11d0-a9b3-006097942311}'
+ }
+ }
+ }
+}
+HKCU
+{
+ NoRemove Software
+ {
+ NoRemove Microsoft
+ {
+ NoRemove Windows
+ {
+ NoRemove CurrentVersion
+ {
+ NoRemove 'Internet Settings'
+ {
+ val 'User Agent' = s 'Mozilla/4.0 (compatible; MSIE 8.0; Win32)'
+ }
+ }
+ }
+ NoRemove 'Internet Explorer'
+ {
+ NoRemove Main
+ {
+ FeatureControl
+ }
+ }
+ }
+ }
+}
+HKLM
+{
+ NoRemove Software
+ {
+ NoRemove Microsoft
+ {
+ NoRemove 'Internet Explorer'
+ {
+ NoRemove Main
+ {
+ FeatureControl
+ {
+ FEATURE_OBJECT_CACHING
+ FEATURE_ZONE_ELEVATION
+ FEATURE_MIME_HANDLING
+ FEATURE_MIME_SNIFFING
+ FEATURE_WINDOW_RESTRICTIONS
+ FEATURE_WEBOC_POPUPMANAGEMENT
+ FEATURE_BEHAVIORS
+ FEATURE_DISABLE_MK_PROTOCOL
+ FEATURE_LOCALMACHINE_LOCKDOWN
+ FEATURE_SECURITYBAND
+ FEATURE_RESTRICT_ACTIVEXINSTALL
+ FEATURE_VALIDATE_NAVIGATE_URL
+ FEATURE_RESTRICT_FILEDOWNLOAD
+ FEATURE_ADDON_MANAGEMENT
+ FEATURE_PROTOCOL_LOCKDOWN
+ FEATURE_HTTP_USERNAME_PASSWORD_DISABLE
+ FEATURE_SAFE_BINDTOOBJECT
+ FEATURE_UNC_SAVEDFILECHECK
+ FEATURE_SSLUX
+ FEATURE_DISABLE_LEGACY_COMPRESSION
+ FEATURE_FORCE_ADDR_AND_STATUS
+ FEATURE_DISABLE_TELNET_PROTOCOL
+ FEATURE_FEEDS
+ }
+ }
+ }
+ }
+ }
+}
@ stdcall CoInternetCreateZoneManager(ptr ptr long)
@ stub CoInternetGetProtocolFlags
@ stdcall CoInternetGetSecurityUrl(ptr ptr long long)
+@ stdcall CoInternetGetSecurityUrlEx(ptr ptr long long)
@ stdcall CoInternetGetSession(long ptr long)
@ stdcall CoInternetIsFeatureEnabled(long long)
@ stdcall CoInternetParseUrl(wstr long long wstr long ptr long)
@ stdcall HlinkNavigateString(ptr wstr)
@ stdcall HlinkSimpleNavigateToMoniker(ptr wstr wstr ptr ptr ptr long long)
@ stdcall HlinkSimpleNavigateToString(wstr wstr wstr ptr ptr ptr long long)
+@ stub IEInstallScope
@ stdcall IsAsyncMoniker(ptr)
@ stdcall IsLoggingEnabledA(str)
@ stdcall IsLoggingEnabledW(wstr)
@ stdcall UrlMkSetSessionOption(long ptr long long)
@ stub WriteHitLogging
@ stub ZonesReInit
+
+410 stdcall @(long long) URLMON_410
+423 stdcall @(long long long long) URLMON_423
#define NO_SHLWAPI_REG
#include "shlwapi.h"
+#include "advpub.h"
+
#include "wine/debug.h"
#include "urlmon.h"
* Urlmon ClassFactory
*/
typedef struct {
- const IClassFactoryVtbl *lpClassFactoryVtbl;
+ IClassFactory IClassFactory_iface;
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
} ClassFactory;
-#define CLASSFACTORY(x) ((IClassFactory*) &(x)->lpClassFactoryVtbl)
+static inline ClassFactory *impl_from_IClassFactory(IClassFactory *iface)
+{
+ return CONTAINING_RECORD(iface, ClassFactory, IClassFactory_iface);
+}
static HRESULT WINAPI CF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppv)
{
static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
REFIID riid, LPVOID *ppobj)
{
- ClassFactory *This = (ClassFactory*)iface;
+ ClassFactory *This = impl_from_IClassFactory(iface);
HRESULT hres;
LPUNKNOWN punk;
CF_LockServer
};
-static const ClassFactory FileProtocolCF =
- { &ClassFactoryVtbl, FileProtocol_Construct};
-static const ClassFactory FtpProtocolCF =
- { &ClassFactoryVtbl, FtpProtocol_Construct};
-static const ClassFactory GopherProtocolCF =
- { &ClassFactoryVtbl, GopherProtocol_Construct};
-static const ClassFactory HttpProtocolCF =
- { &ClassFactoryVtbl, HttpProtocol_Construct};
-static const ClassFactory HttpSProtocolCF =
- { &ClassFactoryVtbl, HttpSProtocol_Construct};
-static const ClassFactory MkProtocolCF =
- { &ClassFactoryVtbl, MkProtocol_Construct};
-static const ClassFactory SecurityManagerCF =
- { &ClassFactoryVtbl, SecManagerImpl_Construct};
-static const ClassFactory ZoneManagerCF =
- { &ClassFactoryVtbl, ZoneMgrImpl_Construct};
-static const ClassFactory StdURLMonikerCF =
- { &ClassFactoryVtbl, StdURLMoniker_Construct};
-static const ClassFactory MimeFilterCF =
- { &ClassFactoryVtbl, MimeFilter_Construct};
-
+static ClassFactory FileProtocolCF =
+ { { &ClassFactoryVtbl }, FileProtocol_Construct};
+static ClassFactory FtpProtocolCF =
+ { { &ClassFactoryVtbl }, FtpProtocol_Construct};
+static ClassFactory GopherProtocolCF =
+ { { &ClassFactoryVtbl }, GopherProtocol_Construct};
+static ClassFactory HttpProtocolCF =
+ { { &ClassFactoryVtbl }, HttpProtocol_Construct};
+static ClassFactory HttpSProtocolCF =
+ { { &ClassFactoryVtbl }, HttpSProtocol_Construct};
+static ClassFactory MkProtocolCF =
+ { { &ClassFactoryVtbl }, MkProtocol_Construct};
+static ClassFactory SecurityManagerCF =
+ { { &ClassFactoryVtbl }, SecManagerImpl_Construct};
+static ClassFactory ZoneManagerCF =
+ { { &ClassFactoryVtbl }, ZoneMgrImpl_Construct};
+static ClassFactory StdURLMonikerCF =
+ { { &ClassFactoryVtbl }, StdURLMoniker_Construct};
+static ClassFactory MimeFilterCF =
+ { { &ClassFactoryVtbl }, MimeFilter_Construct};
+
struct object_creation_info
{
const CLSID *clsid;
static const struct object_creation_info object_creation[] =
{
- { &CLSID_FileProtocol, CLASSFACTORY(&FileProtocolCF), wszFile },
- { &CLSID_FtpProtocol, CLASSFACTORY(&FtpProtocolCF), wszFtp },
- { &CLSID_GopherProtocol, CLASSFACTORY(&GopherProtocolCF), wszGopher },
- { &CLSID_HttpProtocol, CLASSFACTORY(&HttpProtocolCF), wszHttp },
- { &CLSID_HttpSProtocol, CLASSFACTORY(&HttpSProtocolCF), wszHttps },
- { &CLSID_MkProtocol, CLASSFACTORY(&MkProtocolCF), wszMk },
- { &CLSID_InternetSecurityManager, CLASSFACTORY(&SecurityManagerCF), NULL },
- { &CLSID_InternetZoneManager, CLASSFACTORY(&ZoneManagerCF), NULL },
- { &CLSID_StdURLMoniker, CLASSFACTORY(&StdURLMonikerCF), NULL },
- { &CLSID_DeCompMimeFilter, CLASSFACTORY(&MimeFilterCF), NULL }
+ { &CLSID_FileProtocol, &FileProtocolCF.IClassFactory_iface, wszFile },
+ { &CLSID_FtpProtocol, &FtpProtocolCF.IClassFactory_iface, wszFtp },
+ { &CLSID_GopherProtocol, &GopherProtocolCF.IClassFactory_iface, wszGopher },
+ { &CLSID_HttpProtocol, &HttpProtocolCF.IClassFactory_iface, wszHttp },
+ { &CLSID_HttpSProtocol, &HttpSProtocolCF.IClassFactory_iface, wszHttps },
+ { &CLSID_MkProtocol, &MkProtocolCF.IClassFactory_iface, wszMk },
+ { &CLSID_InternetSecurityManager, &SecurityManagerCF.IClassFactory_iface, NULL },
+ { &CLSID_InternetZoneManager, &ZoneManagerCF.IClassFactory_iface, NULL },
+ { &CLSID_StdURLMoniker, &StdURLMonikerCF.IClassFactory_iface, NULL },
+ { &CLSID_DeCompMimeFilter, &MimeFilterCF.IClassFactory_iface, NULL }
};
static void init_session(BOOL init)
return CLASS_E_CLASSNOTAVAILABLE;
}
+static HRESULT register_inf(BOOL doregister)
+{
+ HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
+ HMODULE hAdvpack;
+
+ static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
+
+ hAdvpack = LoadLibraryW(wszAdvpack);
+ pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
+
+ return pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", NULL);
+}
+
+/***********************************************************************
+ * DllRegisterServer (URLMON.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = URLMON_DllRegisterServer();
+ return SUCCEEDED(hr) ? register_inf(TRUE) : hr;
+}
+
+/***********************************************************************
+ * DllUnregisterServer (URLMON.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = URLMON_DllUnregisterServer();
+ return SUCCEEDED(hr) ? register_inf(FALSE) : hr;
+}
/***********************************************************************
* DllRegisterServerEx (URLMON.@)
* Determines if a specified string is a valid URL.
*
* PARAMS
- * pBC [I] ignored, must be NULL.
+ * pBC [I] ignored, should be NULL.
* szURL [I] string that represents the URL in question.
* dwReserved [I] reserved and must be zero.
*
{
FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved);
- if (pBC || dwReserved || !szURL)
+ if (dwReserved || !szURL)
return E_INVALIDARG;
return S_OK;
FIXME("(%s)\n", debugstr_w(url));
return FALSE;
}
+
+/***********************************************************************
+ * URLMON_410 (URLMON.410)
+ * Undocumented, added in IE8
+ */
+BOOL WINAPI URLMON_410(DWORD unknown1, DWORD unknown2)
+{
+ FIXME("stub: %d %d\n", unknown1, unknown2);
+ return FALSE;
+}
+
+/***********************************************************************
+ * URLMON_423 (URLMON.423)
+ * Undocumented, added in IE8
+ */
+BOOL WINAPI URLMON_423(DWORD unknown1, DWORD unknown2, DWORD unknown3, DWORD unknown4)
+{
+ FIXME("stub: %d %d %d %d\n", unknown1, unknown2, unknown3, unknown4);
+ return FALSE;
+}
#include "wine/list.h"
extern HINSTANCE hProxyDll DECLSPEC_HIDDEN;
-extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT StdURLMoniker_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT HttpSProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
-extern HRESULT MimeFilter_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
+extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT StdURLMoniker_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT HttpSProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
+extern HRESULT MimeFilter_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) DECLSPEC_HIDDEN;
extern BOOL WINAPI URLMON_DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DECLSPEC_HIDDEN;
extern HRESULT WINAPI URLMON_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN;
/**********************************************************************
* Dll lifetime tracking declaration for urlmon.dll
*/
-extern LONG URLMON_refCount;
+extern LONG URLMON_refCount DECLSPEC_HIDDEN;
static inline void URLMON_LockModule(void) { InterlockedIncrement( &URLMON_refCount ); }
static inline void URLMON_UnlockModule(void) { InterlockedDecrement( &URLMON_refCount ); }
-#define DEFINE_THIS2(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,ifc)))
-#define DEFINE_THIS(cls,ifc,iface) DEFINE_THIS2(cls,lp ## ifc ## Vtbl,iface)
+IInternetProtocolInfo *get_protocol_info(LPCWSTR) DECLSPEC_HIDDEN;
+HRESULT get_protocol_handler(IUri*,CLSID*,BOOL*,IClassFactory**) DECLSPEC_HIDDEN;
+IInternetProtocol *get_mime_filter(LPCWSTR) DECLSPEC_HIDDEN;
+BOOL is_registered_protocol(LPCWSTR) DECLSPEC_HIDDEN;
+void register_urlmon_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL) DECLSPEC_HIDDEN;
+HINTERNET get_internet_session(IInternetBindInfo*) DECLSPEC_HIDDEN;
+LPWSTR get_useragent(void) DECLSPEC_HIDDEN;
+void free_session(void) DECLSPEC_HIDDEN;
-IInternetProtocolInfo *get_protocol_info(LPCWSTR);
-HRESULT get_protocol_handler(IUri*,CLSID*,BOOL*,IClassFactory**);
-IInternetProtocol *get_mime_filter(LPCWSTR);
-BOOL is_registered_protocol(LPCWSTR);
-void register_urlmon_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL);
-HINTERNET get_internet_session(IInternetBindInfo*);
-LPWSTR get_useragent(void);
-void free_session(void);
+HRESULT bind_to_storage(IUri*,IBindCtx*,REFIID,void**) DECLSPEC_HIDDEN;
+HRESULT bind_to_object(IMoniker*,IUri*,IBindCtx*,REFIID,void**ppv) DECLSPEC_HIDDEN;
-HRESULT bind_to_storage(IUri*,IBindCtx*,REFIID,void**);
-HRESULT bind_to_object(IMoniker*,IUri*,IBindCtx*,REFIID,void**ppv);
-
-HRESULT create_binding_protocol(BOOL,IInternetProtocolEx**);
-void set_binding_sink(IInternetProtocolEx*,IInternetProtocolSink*,IInternetBindInfo*);
-IWinInetInfo *get_wininet_info(IInternetProtocolEx*);
-HRESULT create_default_callback(IBindStatusCallback**);
-HRESULT wrap_callback(IBindStatusCallback*,IBindStatusCallback**);
+HRESULT create_default_callback(IBindStatusCallback**) DECLSPEC_HIDDEN;
+HRESULT wrap_callback(IBindStatusCallback*,IBindStatusCallback**) DECLSPEC_HIDDEN;
typedef struct ProtocolVtbl ProtocolVtbl;
HRESULT (*end_request)(Protocol*);
HRESULT (*start_downloading)(Protocol*);
void (*close_connection)(Protocol*);
+ void (*on_error)(Protocol*,DWORD);
};
-HRESULT protocol_start(Protocol*,IInternetProtocol*,IUri*,IInternetProtocolSink*,IInternetBindInfo*);
-HRESULT protocol_continue(Protocol*,PROTOCOLDATA*);
-HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*);
-HRESULT protocol_lock_request(Protocol*);
-HRESULT protocol_unlock_request(Protocol*);
-HRESULT protocol_abort(Protocol*,HRESULT);
-void protocol_close_connection(Protocol*);
+/* 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 0x0001
+#define FLAG_FIRST_CONTINUE_COMPLETE 0x0002
+#define FLAG_FIRST_DATA_REPORTED 0x0004
+#define FLAG_ALL_DATA_READ 0x0008
+#define FLAG_LAST_DATA_REPORTED 0x0010
+#define FLAG_RESULT_REPORTED 0x0020
+#define FLAG_ERROR 0x0040
+
+HRESULT protocol_start(Protocol*,IInternetProtocol*,IUri*,IInternetProtocolSink*,IInternetBindInfo*) DECLSPEC_HIDDEN;
+HRESULT protocol_continue(Protocol*,PROTOCOLDATA*) DECLSPEC_HIDDEN;
+HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*) DECLSPEC_HIDDEN;
+HRESULT protocol_lock_request(Protocol*) DECLSPEC_HIDDEN;
+HRESULT protocol_unlock_request(Protocol*) DECLSPEC_HIDDEN;
+HRESULT protocol_abort(Protocol*,HRESULT) DECLSPEC_HIDDEN;
+void protocol_close_connection(Protocol*) DECLSPEC_HIDDEN;
+
+void find_domain_name(const WCHAR*,DWORD,INT*) DECLSPEC_HIDDEN;
typedef struct {
- const IInternetProtocolVtbl *lpIInternetProtocolVtbl;
- const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl;
+ IInternetProtocol IInternetProtocol_iface;
+ IInternetProtocolSink IInternetProtocolSink_iface;
LONG ref;
IInternetProtocol *protocol;
} ProtocolProxy;
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpIInternetProtocolVtbl)
-#define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpIInternetProtocolSinkVtbl)
+HRESULT create_protocol_proxy(IInternetProtocol*,IInternetProtocolSink*,ProtocolProxy**) DECLSPEC_HIDDEN;
+
+typedef struct _task_header_t task_header_t;
+
+typedef struct {
+ IInternetProtocolEx IInternetProtocolEx_iface;
+ IInternetBindInfo IInternetBindInfo_iface;
+ IInternetPriority IInternetPriority_iface;
+ IServiceProvider IServiceProvider_iface;
+ IInternetProtocolSink IInternetProtocolSink_iface;
+ IWinInetHttpInfo IWinInetHttpInfo_iface;
+
+ LONG ref;
+
+ IInternetProtocol *protocol;
+ IInternetBindInfo *bind_info;
+ IInternetProtocolSink *protocol_sink;
+ IServiceProvider *service_provider;
+ IWinInetInfo *wininet_info;
+ IWinInetHttpInfo *wininet_http_info;
+
+ struct {
+ IInternetProtocol IInternetProtocol_iface;
+ } default_protocol_handler;
+ IInternetProtocol *protocol_handler;
+
+ LONG priority;
+
+ BOOL reported_result;
+ BOOL reported_mime;
+ BOOL from_urlmon;
+ DWORD pi;
+
+ DWORD bscf;
+ ULONG progress;
+ ULONG progress_max;
+
+ DWORD apartment_thread;
+ HWND notif_hwnd;
+ DWORD continue_call;
+
+ CRITICAL_SECTION section;
+ task_header_t *task_queue_head, *task_queue_tail;
+
+ BYTE *buf;
+ DWORD buf_size;
+ LPWSTR mime;
+ IUri *uri;
+ ProtocolProxy *filter_proxy;
+} BindProtocol;
-HRESULT create_protocol_proxy(IInternetProtocol*,IInternetProtocolSink*,ProtocolProxy**);
+HRESULT create_binding_protocol(BOOL,BindProtocol**) DECLSPEC_HIDDEN;
+void set_binding_sink(BindProtocol*,IInternetProtocolSink*,IInternetBindInfo*) DECLSPEC_HIDDEN;
typedef struct {
HWND notif_hwnd;
struct list entry;
} tls_data_t;
-tls_data_t *get_tls_data(void);
+tls_data_t *get_tls_data(void) DECLSPEC_HIDDEN;
-HWND get_notif_hwnd(void);
-void release_notif_hwnd(HWND);
+HWND get_notif_hwnd(void) DECLSPEC_HIDDEN;
+void release_notif_hwnd(HWND) DECLSPEC_HIDDEN;
static inline void *heap_alloc(size_t len)
{
*/
#include "urlmon.idl"
+
+[
+ helpstring("URL Moniker"),
+ threading(apartment),
+ uuid(79eac9e0-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass StdURLMoniker { interface IMoniker; }
+
+[
+ helpstring("http: Asynchronous Pluggable Protocol Handler"),
+ threading(apartment),
+ uuid(79eac9e2-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass HttpProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
+
+[
+ helpstring("ftp: Asynchronous Pluggable Protocol Handler"),
+ threading(apartment),
+ uuid(79eac9e3-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass FtpProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
+
+[
+ helpstring("gopher: Asynchronous Pluggable Protocol Handler"),
+ threading(apartment),
+ uuid(79eac9e4-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass GopherProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
+
+[
+ helpstring("https: Asynchronous Pluggable Protocol Handler"),
+ threading(apartment),
+ uuid(79eac9e5-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass HttpsProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
+
+[
+ helpstring("mk: Asynchronous Pluggable Protocol Handler"),
+ threading(apartment),
+ uuid(79eac9e6-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass MkProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
+
+[
+ helpstring("file:, local: Asynchronous Pluggable Protocol Handler"),
+ threading(apartment),
+ uuid(79eac9e7-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass FileProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
+
+[
+ helpstring("CDL: Asynchronous Pluggable Protocol Handler"),
+ threading(apartment),
+ uuid(3dd53d40-7b8b-11d0-b013-00aa0059ce02)
+]
+coclass CdlProtocol { interface IInternetProtocolEx; interface IInternetPriority; }
+
+[
+ helpstring("Security Manager"),
+ threading(both),
+ uuid(7b8a2d94-0ac9-11d1-896c-00c04fb6bfc4)
+]
+coclass InternetSecurityManager { interface IInternetSecurityManager; }
+
+[
+ helpstring("URL Zone Manager"),
+ threading(both),
+ uuid(7b8a2d95-0ac9-11d1-896c-00c04fb6bfc4)
+]
+coclass InternetZoneManager { interface IInternetZoneManagerEx2; }
+
+[
+ helpstring("URLMoniker ProxyStub Factory"),
+ threading(apartment),
+ uuid(79eac9f1-baf9-11ce-8c82-00aa004ba90b)
+]
+coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
+
+[
+ helpstring("AP lzdhtml encoding/decoding Filter"),
+ threading(apartment),
+ uuid(8f6b0360-b80d-11d0-a9b3-006097942311)
+]
+coclass DeCompMimeFilter { interface IInternetProtocol; interface IInternetProtocolSink; }
FEATURE_DISABLE_TELNET_PROTOCOL,
FEATURE_FEEDS,
FEATURE_BLOCK_INPUT_PROMPTS,
- FEATURE_DOMSTORAGE,
- FEATURE_XDOMAINREQUEST,
- FEATURE_DATAURI,
- FEATURE_AJAX_CONNECTIONSERVICES,
FEATURE_ENTRY_COUNT
} INTERNETFEATURELIST;
+cpp_quote("#define SET_FEATURE_ON_THREAD 0x00000001")
+cpp_quote("#define SET_FEATURE_ON_PROCESS 0x00000002")
+cpp_quote("#define SET_FEATURE_IN_REGISTRY 0x00000004")
+cpp_quote("#define SET_FEATURE_ON_THREAD_LOCALMACHINE 0x00000008")
+cpp_quote("#define SET_FEATURE_ON_THREAD_INTRANET 0x00000010")
+cpp_quote("#define SET_FEATURE_ON_THREAD_TRUSTED 0x00000020")
+cpp_quote("#define SET_FEATURE_ON_THREAD_INTERNET 0x00000040")
+cpp_quote("#define SET_FEATURE_ON_THREAD_RESTRICTED 0x00000080")
+
+cpp_quote("#define GET_FEATURE_FROM_THREAD 0x00000001")
+cpp_quote("#define GET_FEATURE_FROM_PROCESS 0x00000002")
+cpp_quote("#define GET_FEATURE_FROM_REGISTRY 0x00000004")
+cpp_quote("#define GET_FEATURE_FROM_THREAD_LOCALMACHINE 0x00000008")
+cpp_quote("#define GET_FEATURE_FROM_THREAD_INTRANET 0x00000010")
+cpp_quote("#define GET_FEATURE_FROM_THREAD_TRUSTED 0x00000020")
+cpp_quote("#define GET_FEATURE_FROM_THREAD_INTERNET 0x00000040")
+cpp_quote("#define GET_FEATURE_FROM_THREAD_RESTRICTED 0x00000080")
+
typedef struct _tagPROTOCOLFILTERDATA {
DWORD cbSize;
IInternetProtocolSink *pProtocolSink;
]
interface IUriBuilderFactory : IUnknown
{
- HRESULT CreateInitializedIUriBuilder(
+ HRESULT CreateIUriBuilder(
[in] DWORD dwFlags,
[in] DWORD_PTR dwReserved,
[out] IUriBuilder **ppIUriBuilder);
- HRESULT CreateIUriBuilder(
+ HRESULT CreateInitializedIUriBuilder(
[in] DWORD dwFlags,
[in] DWORD_PTR dwReserved,
[out] IUriBuilder **ppIUriBuilder);
-};
+}
/*****************************************************************************
* IInternetProtocolEx interface
cpp_quote("HRESULT WINAPI CoInternetQueryInfo(LPCWSTR,QUERYOPTION,DWORD,LPVOID,DWORD,DWORD*,DWORD);")
cpp_quote("HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST,DWORD,BOOL);")
cpp_quote("HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR,LPWSTR*,PSUACTION,DWORD);")
+cpp_quote("HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri*,IUri**,PSUACTION,DWORD_PTR);")
cpp_quote("HRESULT WINAPI CreateFormatEnumerator(UINT,FORMATETC*,IEnumFORMATETC**);")
cpp_quote("HRESULT WINAPI GetSoftwareUpdateInfo( LPCWSTR szDistUnit, LPSOFTDISTINFO psdi);")
cpp_quote("HRESULT WINAPI FaultInIEFeature(HWND,uCLSSPEC*,QUERYCONTEXT*,DWORD);")