extern IID IID_IBindStatusCallbackHolder;
typedef struct {
- const IBindStatusCallbackVtbl *lpBindStatusCallbackVtbl;
- const IServiceProviderVtbl *lpServiceProviderVtbl;
- const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl;
- const IAuthenticateVtbl *lpAuthenticateVtbl;
+ const IBindStatusCallbackExVtbl *lpBindStatusCallbackExVtbl;
+ const IServiceProviderVtbl *lpServiceProviderVtbl;
+ const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl;
+ const IAuthenticateVtbl *lpAuthenticateVtbl;
LONG ref;
IBindStatusCallback *callback;
IServiceProvider *serv_prov;
-
- IHttpNegotiate *http_negotiate;
- BOOL init_http_negotiate;
- IHttpNegotiate2 *http_negotiate2;
- BOOL init_http_negotiate2;
- IAuthenticate *authenticate;
- BOOL init_authenticate;
} BindStatusCallback;
-#define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl)
+#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)
-#define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
+static void *get_callback_iface(BindStatusCallback *This, REFIID riid)
+{
+ void *ret;
+ HRESULT hres;
+
+ hres = IBindStatusCallback_QueryInterface(This->callback, riid, (void**)&ret);
+ if(FAILED(hres) && This->serv_prov)
+ hres = IServiceProvider_QueryService(This->serv_prov, riid, riid, &ret);
-static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface,
+ return SUCCEEDED(hres) ? ret : NULL;
+}
+
+#define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallbackEx, iface)
+
+static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface,
REFIID riid, void **ppv)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
}else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
*ppv = STATUSCLB(This);
+ }else if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)) {
+ TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
+ *ppv = STATUSCLBEX(This);
}else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) {
TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv);
*ppv = This;
return E_NOINTERFACE;
}
-static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
+static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallbackEx *iface)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
LONG ref = InterlockedIncrement(&This->ref);
return ref;
}
-static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
+static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallbackEx *iface)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
LONG ref = InterlockedDecrement(&This->ref);
if(!ref) {
if(This->serv_prov)
IServiceProvider_Release(This->serv_prov);
- if(This->http_negotiate)
- IHttpNegotiate_Release(This->http_negotiate);
- if(This->http_negotiate2)
- IHttpNegotiate2_Release(This->http_negotiate2);
- if(This->authenticate)
- IAuthenticate_Release(This->authenticate);
IBindStatusCallback_Release(This->callback);
heap_free(This);
}
return ref;
}
-static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
+static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface,
DWORD dwReserved, IBinding *pbind)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
return IBindStatusCallback_OnStartBinding(This->callback, 0xff, pbind);
}
-static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
+static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
return IBindStatusCallback_GetPriority(This->callback, pnPriority);
}
-static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
+static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
return IBindStatusCallback_OnLowResource(This->callback, reserved);
}
-static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
+static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
ulProgressMax, ulStatusCode, szStatusText);
}
-static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface,
+static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallbackEx *iface,
HRESULT hresult, LPCWSTR szError)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
return IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
}
-static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
+static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface,
DWORD *grfBINDF, BINDINFO *pbindinfo)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
+ IBindStatusCallbackEx *bscex;
+ HRESULT hres;
TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
- return IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
+ hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
+ if(SUCCEEDED(hres)) {
+ DWORD bindf2 = 0, reserv = 0;
+
+ hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, &bindf2, &reserv);
+ IBindStatusCallbackEx_Release(bscex);
+ }else {
+ hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
+ }
+
+ return hres;
}
-static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface,
+static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx *iface,
DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
return IBindStatusCallback_OnDataAvailable(This->callback, grfBSCF, dwSize, pformatetc, pstgmed);
}
-static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface,
+static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface,
REFIID riid, IUnknown *punk)
{
BindStatusCallback *This = STATUSCLB_THIS(iface);
return IBindStatusCallback_OnObjectAvailable(This->callback, riid, punk);
}
+static HRESULT WINAPI BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF,
+ BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
+{
+ BindStatusCallback *This = STATUSCLB_THIS(iface);
+ IBindStatusCallbackEx *bscex;
+ HRESULT hres;
+
+ TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
+
+ hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
+ if(SUCCEEDED(hres)) {
+ hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
+ IBindStatusCallbackEx_Release(bscex);
+ }else {
+ hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
+ }
+
+ return hres;
+}
+
#undef STATUSCLB_THIS
-static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
+static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
BindStatusCallback_QueryInterface,
BindStatusCallback_AddRef,
BindStatusCallback_Release,
BindStatusCallback_OnStopBinding,
BindStatusCallback_GetBindInfo,
BindStatusCallback_OnDataAvailable,
- BindStatusCallback_OnObjectAvailable
+ BindStatusCallback_OnObjectAvailable,
+ BindStatusCallback_GetBindInfoEx
};
#define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface)
if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) {
TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv);
-
- if(!This->init_http_negotiate) {
- This->init_http_negotiate = TRUE;
- hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate,
- (void**)&This->http_negotiate);
- if(FAILED(hres) && This->serv_prov)
- IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate,
- &IID_IHttpNegotiate, (void**)&This->http_negotiate);
- }
-
return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
}
if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) {
TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv);
-
- if(!This->init_http_negotiate2) {
- This->init_http_negotiate2 = TRUE;
- hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate2,
- (void**)&This->http_negotiate2);
- if(FAILED(hres) && This->serv_prov)
- IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate2,
- &IID_IHttpNegotiate2, (void**)&This->http_negotiate2);
- }
-
return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
}
if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv);
-
- if(!This->init_authenticate) {
- This->init_authenticate = TRUE;
- hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IAuthenticate,
- (void**)&This->authenticate);
- if(FAILED(hres) && This->serv_prov)
- IServiceProvider_QueryService(This->serv_prov, &IID_IAuthenticate,
- &IID_IAuthenticate, (void**)&This->authenticate);
- }
-
return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
}
LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
{
BindStatusCallback *This = HTTPNEG2_THIS(iface);
+ IHttpNegotiate *http_negotiate;
+ HRESULT hres = S_OK;
TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
pszAdditionalHeaders);
*pszAdditionalHeaders = NULL;
- if(!This->http_negotiate)
- return S_OK;
+ http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
+ if(http_negotiate) {
+ hres = IHttpNegotiate_BeginningTransaction(http_negotiate, szURL, szHeaders,
+ dwReserved, pszAdditionalHeaders);
+ IHttpNegotiate_Release(http_negotiate);
+ }
- return IHttpNegotiate_BeginningTransaction(This->http_negotiate, szURL, szHeaders,
- dwReserved, pszAdditionalHeaders);
+ return hres;
}
static HRESULT WINAPI BSCHttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
{
BindStatusCallback *This = HTTPNEG2_THIS(iface);
LPWSTR additional_headers = NULL;
+ IHttpNegotiate *http_negotiate;
HRESULT hres = S_OK;
TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
- if(This->http_negotiate)
- hres = IHttpNegotiate_OnResponse(This->http_negotiate, dwResponseCode, szResponseHeaders,
- szRequestHeaders, &additional_headers);
+ http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
+ if(http_negotiate) {
+ hres = IHttpNegotiate_OnResponse(http_negotiate, dwResponseCode, szResponseHeaders,
+ szRequestHeaders, &additional_headers);
+ IHttpNegotiate_Release(http_negotiate);
+ }
if(pszAdditionalRequestHeaders)
*pszAdditionalRequestHeaders = additional_headers;
BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
{
BindStatusCallback *This = HTTPNEG2_THIS(iface);
+ IHttpNegotiate2 *http_negotiate2;
+ HRESULT hres = E_FAIL;
TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved);
- if(!This->http_negotiate2)
- return E_NOTIMPL;
+ http_negotiate2 = get_callback_iface(This, &IID_IHttpNegotiate2);
+ if(http_negotiate2) {
+ hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, pbSecurityId,
+ pcbSecurityId, dwReserved);
+ IHttpNegotiate2_Release(http_negotiate2);
+ }
- return IHttpNegotiate2_GetRootSecurityId(This->http_negotiate2, pbSecurityId,
- pcbSecurityId, dwReserved);
+ return hres;
}
#undef HTTPNEG2_THIS
{
BindStatusCallback *ret = heap_alloc_zero(sizeof(BindStatusCallback));
- ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl;
+ ret->lpBindStatusCallbackExVtbl = &BindStatusCallbackExVtbl;
ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl;
ret->lpHttpNegotiate2Vtbl = &BSCHttpNegotiateVtbl;
ret->lpAuthenticateVtbl = &BSCAuthenticateVtbl;
TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
- IInternetProtocol_Terminate(This->protocol, 0);
stop_binding(This, hrResult, szResult);
+ IInternetProtocol_Terminate(This->protocol, 0);
return S_OK;
}
const IInternetPriorityVtbl *lpInternetPriorityVtbl;
const IServiceProviderVtbl *lpServiceProviderVtbl;
const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl;
+ const IWinInetHttpInfoVtbl *lpIWinInetHttpInfoVtbl;
const IInternetProtocolVtbl *lpIInternetProtocolHandlerVtbl;
#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 PROTOCOLHANDLER(x) ((IInternetProtocol*) &(x)->lpIInternetProtocolHandlerVtbl)
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
*ppv = PROTSINK(This);
- }
+ }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
+ TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv);
- if(*ppv) {
- IInternetProtocol_AddRef(iface);
- return S_OK;
+ if(This->protocol) {
+ IWinInetInfo *inet_info;
+ HRESULT hres;
+
+ hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetInfo, (void**)&inet_info);
+ if(SUCCEEDED(hres)) {
+ *ppv = HTTPINFO(This);
+ IWinInetInfo_Release(inet_info);
+ }
+ }
+ }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
+ TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv);
+
+ if(This->protocol) {
+ IWinInetHttpInfo *http_info;
+ HRESULT hres;
+
+ hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
+ if(SUCCEEDED(hres)) {
+ *ppv = HTTPINFO(This);
+ IWinInetHttpInfo_Release(http_info);
+ }
+ }
+ }else {
+ WARN("not supported interface %s\n", debugstr_guid(riid));
}
- WARN("not supported interface %s\n", debugstr_guid(riid));
- return E_NOINTERFACE;
+ if(!*ppv)
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
}
static ULONG WINAPI BindProtocol_AddRef(IInternetProtocol *iface)
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
- if(This->buf) {
+ if(This->buf_size) {
read = min(cb, This->buf_size);
memcpy(pv, This->buf, read);
return S_OK;
if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) {
+ BYTE buf[BUFFER_SIZE];
DWORD read = 0;
LPWSTR mime;
HRESULT hres;
- if(!This->buf) {
- This->buf = heap_alloc(BUFFER_SIZE);
- if(!This->buf)
- return E_OUTOFMEMORY;
- }
-
do {
read = 0;
- hres = IInternetProtocol_Read(This->protocol, This->buf+This->buf_size,
- BUFFER_SIZE-This->buf_size, &read);
+ hres = IInternetProtocol_Read(This->protocol, buf,
+ sizeof(buf)-This->buf_size, &read);
if(FAILED(hres) && hres != E_PENDING)
return hres;
+
+ if(!This->buf) {
+ This->buf = heap_alloc(BUFFER_SIZE);
+ if(!This->buf)
+ return E_OUTOFMEMORY;
+ }else if(read + This->buf_size > BUFFER_SIZE) {
+ BYTE *tmp;
+
+ tmp = heap_realloc(This->buf, read+This->buf_size);
+ if(!tmp)
+ return E_OUTOFMEMORY;
+ This->buf = tmp;
+ }
+
+ memcpy(This->buf+This->buf_size, buf, read);
This->buf_size += read;
}while(This->buf_size < MIME_TEST_SIZE && hres == S_OK);
if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE)
return S_OK;
- hres = FindMimeFromData(NULL, This->url, This->buf, min(This->buf_size, MIME_TEST_SIZE),
- This->mime, 0, &mime, 0);
- if(FAILED(hres))
- return hres;
+ bscf = BSCF_FIRSTDATANOTIFICATION;
+ if(hres == S_FALSE)
+ bscf |= BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE;
+
+ if(!This->reported_mime) {
+ hres = FindMimeFromData(NULL, This->url, This->buf, min(This->buf_size, MIME_TEST_SIZE),
+ This->mime, 0, &mime, 0);
+ if(FAILED(hres))
+ return hres;
- mime_available(This, mime, TRUE);
- CoTaskMemFree(mime);
+ mime_available(This, mime, TRUE);
+ CoTaskMemFree(mime);
+ }
}
+ if(!This->protocol_sink)
+ return S_OK;
+
return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max);
}
BPInternetProtocolSink_ReportResult
};
+#define INETINFO_THIS(iface) DEFINE_THIS(BindProtocol, IWinInetHttpInfo, iface)
+
+static HRESULT WINAPI WinInetHttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv)
+{
+ BindProtocol *This = INETINFO_THIS(iface);
+ return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
+}
+
+static ULONG WINAPI WinInetHttpInfo_AddRef(IWinInetHttpInfo *iface)
+{
+ BindProtocol *This = INETINFO_THIS(iface);
+ return IInternetProtocol_AddRef(PROTOCOL(This));
+}
+
+static ULONG WINAPI WinInetHttpInfo_Release(IWinInetHttpInfo *iface)
+{
+ BindProtocol *This = INETINFO_THIS(iface);
+ return IInternetProtocol_Release(PROTOCOL(This));
+}
+
+static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption,
+ void *pBuffer, DWORD *pcbBuffer)
+{
+ BindProtocol *This = INETINFO_THIS(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);
+ 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_Release,
+ WinInetHttpInfo_QueryOption,
+ WinInetHttpInfo_QueryInfo
+};
+
#define SERVPROV_THIS(iface) DEFINE_THIS(BindProtocol, ServiceProvider, iface)
static HRESULT WINAPI BPServiceProvider_QueryInterface(IServiceProvider *iface,
ret->lpServiceProviderVtbl = &ServiceProviderVtbl;
ret->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
ret->lpIInternetProtocolHandlerVtbl = &InternetProtocolHandlerVtbl;
+ ret->lpIWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl;
ret->ref = 1;
ret->from_urlmon = from_urlmon;
#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(FtpProtocol, base, iface)
static HRESULT FtpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
- IInternetBindInfo *bind_info)
+ HINTERNET internet_session, IInternetBindInfo *bind_info)
{
FtpProtocol *This = ASYNCPROTOCOL_THIS(prot);
- This->base.request = InternetOpenUrlW(This->base.internet, url, NULL, 0,
+ This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0,
request_flags|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_PASSIVE,
(DWORD_PTR)&This->base);
if (!This->base.request && GetLastError() != ERROR_IO_PENDING) {
#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(GopherProtocol, base, iface)
static HRESULT GopherProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
- IInternetBindInfo *bind_info)
+ HINTERNET internet_session, IInternetBindInfo *bind_info)
{
GopherProtocol *This = ASYNCPROTOCOL_THIS(prot);
- This->base.request = InternetOpenUrlW(This->base.internet, url, NULL, 0,
+ This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0,
request_flags, (DWORD_PTR)&This->base);
if (!This->base.request && GetLastError() != ERROR_IO_PENDING) {
WARN("InternetOpenUrl failed: %d\n", GetLastError());
#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(HttpProtocol, base, iface)
static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
- IInternetBindInfo *bind_info)
+ HINTERNET internet_session, IInternetBindInfo *bind_info)
{
HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
LPWSTR addl_header = NULL, post_cookie = NULL, optional = NULL;
host = heap_strndupW(url_comp.lpszHostName, url_comp.dwHostNameLength);
user = heap_strndupW(url_comp.lpszUserName, url_comp.dwUserNameLength);
pass = heap_strndupW(url_comp.lpszPassword, url_comp.dwPasswordLength);
- This->base.connection = InternetConnectW(This->base.internet, host, url_comp.nPort, user, pass,
+ This->base.connection = InternetConnectW(internet_session, host, url_comp.nPort, user, pass,
INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base);
heap_free(pass);
heap_free(user);
}
}
+static HINTERNET create_internet_session(IInternetBindInfo *bind_info)
+{
+ LPWSTR global_user_agent = NULL;
+ LPOLESTR user_agent = NULL;
+ ULONG size = 0;
+ HINTERNET ret;
+ HRESULT hres;
+
+ hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_USER_AGENT, &user_agent, 1, &size);
+ if(hres != S_OK || !size)
+ global_user_agent = get_useragent();
+
+ ret = InternetOpenW(user_agent ? user_agent : global_user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
+ heap_free(global_user_agent);
+ CoTaskMemFree(user_agent);
+ if(!ret) {
+ WARN("InternetOpen failed: %d\n", GetLastError());
+ return NULL;
+ }
+
+ InternetSetStatusCallbackW(ret, internet_status_callback);
+ return ret;
+}
+
+static HINTERNET internet_session;
+
+HINTERNET get_internet_session(IInternetBindInfo *bind_info)
+{
+ HINTERNET new_session;
+
+ if(internet_session)
+ return internet_session;
+
+ if(!bind_info)
+ return NULL;
+
+ new_session = create_internet_session(bind_info);
+ if(new_session && InterlockedCompareExchangePointer((void**)&internet_session, new_session, NULL))
+ InternetCloseHandle(new_session);
+
+ return internet_session;
+}
+
HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, LPCWSTR url,
IInternetProtocolSink *protocol_sink, IInternetBindInfo *bind_info)
{
- LPOLESTR user_agent = NULL;
DWORD request_flags;
- ULONG size = 0;
HRESULT hres;
protocol->protocol = prot;
if(!(protocol->bindf & BINDF_FROMURLMON))
report_progress(protocol, BINDSTATUS_DIRECTBIND, NULL);
- hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_USER_AGENT, &user_agent, 1, &size);
- if (hres != S_OK || !size) {
- DWORD len;
- CHAR null_char = 0;
- LPSTR user_agenta = NULL;
-
- len = 0;
- if ((hres = ObtainUserAgentString(0, &null_char, &len)) != E_OUTOFMEMORY) {
- WARN("ObtainUserAgentString failed: %08x\n", hres);
- }else if (!(user_agenta = heap_alloc(len*sizeof(CHAR)))) {
- WARN("Out of memory\n");
- }else if ((hres = ObtainUserAgentString(0, user_agenta, &len)) != S_OK) {
- WARN("ObtainUserAgentString failed: %08x\n", hres);
- }else {
- if(!(user_agent = CoTaskMemAlloc((len)*sizeof(WCHAR))))
- WARN("Out of memory\n");
- else
- MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len);
- }
- heap_free(user_agenta);
- }
-
- protocol->internet = InternetOpenW(user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
- CoTaskMemFree(user_agent);
- if(!protocol->internet) {
- WARN("InternetOpen failed: %d\n", GetLastError());
+ if(!get_internet_session(bind_info))
return report_result(protocol, INET_E_NO_SESSION);
- }
-
- /* Native does not check for success of next call, so we won't either */
- InternetSetStatusCallbackW(protocol->internet, internet_status_callback);
request_flags = INTERNET_FLAG_KEEP_CONNECTION;
if(protocol->bindf & BINDF_NOWRITECACHE)
if(protocol->bindf & BINDF_NEEDFILE)
request_flags |= INTERNET_FLAG_NEED_FILE;
- hres = protocol->vtbl->open_request(protocol, url, request_flags, bind_info);
+ hres = protocol->vtbl->open_request(protocol, url, request_flags, internet_session, bind_info);
if(FAILED(hres)) {
protocol_close_connection(protocol);
return report_result(protocol, hres);
BOOL res;
HRESULT hres = S_FALSE;
- if(!(protocol->flags & FLAG_REQUEST_COMPLETE)) {
+ if(protocol->flags & FLAG_ALL_DATA_READ) {
*read_ret = 0;
- return E_PENDING;
+ return S_FALSE;
}
- if(protocol->flags & FLAG_ALL_DATA_READ) {
+ if(!(protocol->flags & FLAG_REQUEST_COMPLETE)) {
*read_ret = 0;
- return S_FALSE;
+ return E_PENDING;
}
while(read < size) {
if(protocol->connection)
InternetCloseHandle(protocol->connection);
- if(protocol->internet) {
- InternetCloseHandle(protocol->internet);
- protocol->internet = 0;
- }
-
protocol->flags = 0;
}
/* @makedep: urlmon.inf */
REGINST REGINST urlmon.inf
-#include "version.rc"
+#define WINE_FILENAME_STR "urlmon.dll"
+#define WINE_FILEVERSION 6,0,2800,1485
+#define WINE_FILEVERSION_STR "6.0.2800.1485"
+#define WINE_PRODUCTVERSION 6,0,2800,1485
+#define WINE_PRODUCTVERSION_STR "6.0.2800.1485"
+
+#include "wine/wine_common_ver.rc"
*
* Copyright (c) 2004 Huw D M Davies
* Copyright 2004 Jacek Caban
+ * Copyright 2009 Detlef Riekenberg
*
* 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 currentlevelW[] = {'C','u','r','r','e','n','t','L','e','v','e','l',0};
+static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
+static const WCHAR displaynameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
static const WCHAR fileW[] = {'f','i','l','e',0};
+static const WCHAR flagsW[] = {'F','l','a','g','s',0};
+static const WCHAR iconW[] = {'I','c','o','n',0};
+static const WCHAR minlevelW[] = {'M','i','n','L','e','v','e','l',0};
+static const WCHAR recommendedlevelW[] = {'R','e','c','o','m','m','e','n','d','e','d',
+ 'L','e','v','e','l',0};
+static const WCHAR wszZonesKey[] = {'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','s','\\',0};
+
+/********************************************************************
+ * get_string_from_reg [internal]
+ *
+ * helper to get a string from the reg.
+ *
+ */
+static void get_string_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPWSTR out, DWORD maxlen)
+{
+ DWORD type = REG_SZ;
+ DWORD len = maxlen * sizeof(WCHAR);
+ DWORD res;
+
+ res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);
+
+ if (res && hklm) {
+ len = maxlen * sizeof(WCHAR);
+ type = REG_SZ;
+ res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
+ }
+
+ if (res) {
+ TRACE("%s failed: %d\n", debugstr_w(name), res);
+ *out = '\0';
+ }
+}
+
+/********************************************************************
+ * get_dword_from_reg [internal]
+ *
+ * helper to get a dword from the reg.
+ *
+ */
+static void get_dword_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPDWORD out)
+{
+ DWORD type = REG_DWORD;
+ DWORD len = sizeof(DWORD);
+ DWORD res;
+
+ res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len);
+
+ if (res && hklm) {
+ len = sizeof(DWORD);
+ type = REG_DWORD;
+ res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len);
+ }
+
+ if (res) {
+ TRACE("%s failed: %d\n", debugstr_w(name), res);
+ *out = 0;
+ }
+}
static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone)
{
static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey)
{
- static const WCHAR wszZonesKey[] =
- {'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','s','\\',0};
static const WCHAR wszFormat[] = {'%','s','%','l','d',0};
WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+8];
switch(action) {
case URLACTION_SCRIPT_OVERRIDE_SAFETY:
+ case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY:
*(DWORD*)policy = URLPOLICY_DISALLOW;
return S_OK;
}
return hres;
}
- if(pContext || cbContext || dwFlags || dwReserved)
+ if(dwFlags || dwReserved)
FIXME("Unsupported arguments\n");
if(!pwszUrl)
return hres;
TRACE("policy %x\n", policy);
+ if(cbPolicy >= sizeof(DWORD))
+ *(DWORD*)pPolicy = policy;
switch(GetUrlPolicyPermissions(policy)) {
case URLPOLICY_ALLOW:
return hres;
}
- FIXME("Default action is not implemented\n");
- return E_NOTIMPL;
+ WARN("Unknown guidKey %s\n", debugstr_guid(guidKey));
+ return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManager *iface,
*
*/
typedef struct {
- const IInternetZoneManagerVtbl* lpVtbl;
+ const IInternetZoneManagerEx2Vtbl* lpVtbl;
LONG ref;
+ LPDWORD *zonemaps;
+ DWORD zonemap_count;
} ZoneMgrImpl;
+
+/***********************************************************************
+ * build_zonemap_from_reg [internal]
+ *
+ * Enumerate the Zones in the Registry and return the Zones in a DWORD-array
+ * The number of the Zones is returned in data[0]
+ */
+static LPDWORD build_zonemap_from_reg(void)
+{
+ WCHAR name[32];
+ HKEY hkey;
+ LPDWORD data = NULL;
+ DWORD allocated = 6; /* space for the zonecount and Zone "0" up to Zone "4" */
+ DWORD used = 0;
+ DWORD res;
+ DWORD len;
+
+
+ res = RegOpenKeyW(HKEY_CURRENT_USER, wszZonesKey, &hkey);
+ if (res)
+ return NULL;
+
+ data = heap_alloc(allocated * sizeof(DWORD));
+ if (!data)
+ goto cleanup;
+
+ while (!res) {
+ name[0] = '\0';
+ len = sizeof(name) / sizeof(name[0]);
+ res = RegEnumKeyExW(hkey, used, name, &len, NULL, NULL, NULL, NULL);
+
+ if (!res) {
+ used++;
+ if (used == allocated) {
+ LPDWORD new_data;
+
+ allocated *= 2;
+ new_data = heap_realloc_zero(data, allocated * sizeof(DWORD));
+ if (!new_data)
+ goto cleanup;
+
+ data = new_data;
+ }
+ data[used] = atoiW(name);
+ }
+ }
+ if (used) {
+ RegCloseKey(hkey);
+ data[0] = used;
+ return data;
+ }
+
+cleanup:
+ /* something failed */
+ RegCloseKey(hkey);
+ heap_free(data);
+ return NULL;
+}
+
/********************************************************************
* IInternetZoneManager_QueryInterface
*/
-static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManager* iface, REFIID riid, void** ppvObject)
+static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManagerEx2* iface, REFIID riid, void** ppvObject)
{
ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
if(!This || !ppvObject)
return E_INVALIDARG;
- if(!IsEqualIID(&IID_IUnknown, riid) && !IsEqualIID(&IID_IInternetZoneManager, riid)) {
+ if(IsEqualIID(&IID_IUnknown, riid)) {
+ TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObject);
+ }else if(IsEqualIID(&IID_IInternetZoneManager, riid)) {
+ TRACE("(%p)->(IID_InternetZoneManager %p)\n", This, ppvObject);
+ }else if(IsEqualIID(&IID_IInternetZoneManagerEx, riid)) {
+ TRACE("(%p)->(IID_InternetZoneManagerEx %p)\n", This, ppvObject);
+ }else if(IsEqualIID(&IID_IInternetZoneManagerEx2, riid)) {
+ TRACE("(%p)->(IID_InternetZoneManagerEx2 %p)\n", This, ppvObject);
+ }
+ else
+ {
FIXME("Unknown interface: %s\n", debugstr_guid(riid));
*ppvObject = NULL;
return E_NOINTERFACE;
*ppvObject = iface;
IInternetZoneManager_AddRef(iface);
-
return S_OK;
}
/********************************************************************
* IInternetZoneManager_AddRef
*/
-static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManager* iface)
+static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManagerEx2* iface)
{
ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
/********************************************************************
* IInternetZoneManager_Release
*/
-static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManager* iface)
+static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManagerEx2* iface)
{
ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
if(!refCount) {
+ while (This->zonemap_count) heap_free(This->zonemaps[--This->zonemap_count]);
+ heap_free(This->zonemaps);
heap_free(This);
URLMON_UnlockModule();
}
/********************************************************************
* IInternetZoneManager_GetZoneAttributes
*/
-static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManagerEx2* iface,
DWORD dwZone,
ZONEATTRIBUTES* pZoneAttributes)
{
- FIXME("(%p)->(%d %p) stub\n", iface, dwZone, pZoneAttributes);
- return E_NOTIMPL;
+ ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
+ HRESULT hr;
+ HKEY hcu;
+ HKEY hklm = NULL;
+
+ 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 and older returned E_FAIL here */
+
+ hr = open_zone_key(HKEY_LOCAL_MACHINE, dwZone, &hklm);
+ if (FAILED(hr))
+ TRACE("Zone %d not in HKLM\n", dwZone);
+
+ get_string_from_reg(hcu, hklm, displaynameW, pZoneAttributes->szDisplayName, MAX_ZONE_PATH);
+ get_string_from_reg(hcu, hklm, descriptionW, pZoneAttributes->szDescription, MAX_ZONE_DESCRIPTION);
+ get_string_from_reg(hcu, hklm, iconW, pZoneAttributes->szIconPath, MAX_ZONE_PATH);
+ get_dword_from_reg(hcu, hklm, minlevelW, &pZoneAttributes->dwTemplateMinLevel);
+ get_dword_from_reg(hcu, hklm, currentlevelW, &pZoneAttributes->dwTemplateCurrentLevel);
+ get_dword_from_reg(hcu, hklm, recommendedlevelW, &pZoneAttributes->dwTemplateRecommended);
+ get_dword_from_reg(hcu, hklm, flagsW, &pZoneAttributes->dwFlags);
+
+ RegCloseKey(hklm);
+ RegCloseKey(hcu);
+ return S_OK;
}
/********************************************************************
* IInternetZoneManager_SetZoneAttributes
*/
-static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManagerEx2* iface,
DWORD dwZone,
ZONEATTRIBUTES* pZoneAttributes)
{
/********************************************************************
* IInternetZoneManager_GetZoneCustomPolicy
*/
-static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
DWORD dwZone,
REFGUID guidKey,
BYTE** ppPolicy,
/********************************************************************
* IInternetZoneManager_SetZoneCustomPolicy
*/
-static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManagerEx2* iface,
DWORD dwZone,
REFGUID guidKey,
BYTE* ppPolicy,
/********************************************************************
* IInternetZoneManager_GetZoneActionPolicy
*/
-static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManagerEx2* iface,
DWORD dwZone, DWORD dwAction, BYTE* pPolicy, DWORD cbPolicy, URLZONEREG urlZoneReg)
{
TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy,
/********************************************************************
* IInternetZoneManager_SetZoneActionPolicy
*/
-static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManagerEx2* iface,
DWORD dwZone,
DWORD dwAction,
BYTE* pPolicy,
/********************************************************************
* IInternetZoneManager_PromptAction
*/
-static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManagerEx2* iface,
DWORD dwAction,
HWND hwndParent,
LPCWSTR pwszUrl,
/********************************************************************
* IInternetZoneManager_LogAction
*/
-static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManagerEx2* iface,
DWORD dwAction,
LPCWSTR pwszUrl,
LPCWSTR pwszText,
/********************************************************************
* IInternetZoneManager_CreateZoneEnumerator
*/
-static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManagerEx2* iface,
DWORD* pdwEnum,
DWORD* pdwCount,
DWORD dwFlags)
{
- FIXME("(%p)->(%p %p %08x) stub\n", iface, pdwEnum, pdwCount, dwFlags);
- return E_NOTIMPL;
+ ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
+ LPDWORD * new_maps;
+ LPDWORD data;
+ DWORD i;
+
+ TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pdwEnum, pdwCount, dwFlags);
+ if (!pdwEnum || !pdwCount || (dwFlags != 0))
+ return E_INVALIDARG;
+
+ data = build_zonemap_from_reg();
+ TRACE("found %d zones\n", data ? data[0] : -1);
+
+ if (!data)
+ return E_FAIL;
+
+ for (i = 0; i < This->zonemap_count; i++) {
+ if (This->zonemaps && !This->zonemaps[i]) {
+ This->zonemaps[i] = data;
+ *pdwEnum = i;
+ *pdwCount = data[0];
+ return S_OK;
+ }
+ }
+
+ if (This->zonemaps) {
+ /* try to double the nr. of pointers in the array */
+ new_maps = heap_realloc_zero(This->zonemaps, This->zonemap_count * 2 * sizeof(LPDWORD));
+ if (new_maps)
+ This->zonemap_count *= 2;
+ }
+ else
+ {
+ This->zonemap_count = 2;
+ new_maps = heap_alloc_zero(This->zonemap_count * sizeof(LPDWORD));
+ }
+
+ if (!new_maps) {
+ heap_free(data);
+ return E_FAIL;
+ }
+ This->zonemaps = new_maps;
+ This->zonemaps[i] = data;
+ *pdwEnum = i;
+ *pdwCount = data[0];
+ return S_OK;
}
/********************************************************************
* IInternetZoneManager_GetZoneAt
*/
-static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManagerEx2* iface,
DWORD dwEnum,
DWORD dwIndex,
DWORD* pdwZone)
{
- FIXME("(%p)->(%08x %08x %p) stub\n", iface, dwEnum, dwIndex, pdwZone);
- return E_NOTIMPL;
+ ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
+ LPDWORD data;
+
+ TRACE("(%p)->(0x%08x, %d, %p)\n", This, dwEnum, dwIndex, pdwZone);
+
+ /* make sure, that dwEnum and dwIndex are in the valid range */
+ if (dwEnum < This->zonemap_count) {
+ if ((data = This->zonemaps[dwEnum])) {
+ if (dwIndex < data[0]) {
+ *pdwZone = data[dwIndex + 1];
+ return S_OK;
+ }
+ }
+ }
+ return E_INVALIDARG;
}
/********************************************************************
* IInternetZoneManager_DestroyZoneEnumerator
*/
-static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManagerEx2* iface,
DWORD dwEnum)
{
- FIXME("(%p)->(%08x) stub\n", iface, dwEnum);
- return E_NOTIMPL;
+ ZoneMgrImpl* This = (ZoneMgrImpl*)iface;
+ LPDWORD data;
+
+ TRACE("(%p)->(0x%08x)\n", This, dwEnum);
+ /* make sure, that dwEnum is valid */
+ if (dwEnum < This->zonemap_count) {
+ if ((data = This->zonemaps[dwEnum])) {
+ This->zonemaps[dwEnum] = NULL;
+ heap_free(data);
+ return S_OK;
+ }
+ }
+ return E_INVALIDARG;
}
/********************************************************************
* IInternetZoneManager_CopyTemplatePoliciesToZone
*/
-static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManager* iface,
+static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManagerEx2* iface,
DWORD dwTemplate,
DWORD dwZone,
DWORD dwReserved)
return E_NOTIMPL;
}
+/********************************************************************
+ * IInternetZoneManagerEx_GetZoneActionPolicyEx
+ */
+static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicyEx(IInternetZoneManagerEx2* iface,
+ DWORD dwZone,
+ DWORD dwAction,
+ BYTE* pPolicy,
+ DWORD cbPolicy,
+ URLZONEREG urlZoneReg,
+ DWORD dwFlags)
+{
+ TRACE("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x)\n", iface, dwZone,
+ dwAction, pPolicy, cbPolicy, urlZoneReg, dwFlags);
+
+ if(!pPolicy)
+ return E_INVALIDARG;
+
+ if (dwFlags)
+ FIXME("dwFlags 0x%x ignored\n", dwFlags);
+
+ return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg);
+}
+
+/********************************************************************
+ * IInternetZoneManagerEx_SetZoneActionPolicyEx
+ */
+static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicyEx(IInternetZoneManagerEx2* iface,
+ DWORD dwZone,
+ DWORD dwAction,
+ BYTE* pPolicy,
+ DWORD cbPolicy,
+ URLZONEREG urlZoneReg,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x) stub\n", iface, dwZone, dwAction, pPolicy,
+ cbPolicy, urlZoneReg, dwFlags);
+ return E_NOTIMPL;
+}
+
+/********************************************************************
+ * IInternetZoneManagerEx2_GetZoneAttributesEx
+ */
+static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributesEx(IInternetZoneManagerEx2* iface,
+ DWORD dwZone,
+ ZONEATTRIBUTES* pZoneAttributes,
+ DWORD dwFlags)
+{
+ TRACE("(%p)->(%d, %p, 0x%x)\n", iface, dwZone, pZoneAttributes, dwFlags);
+
+ if (dwFlags)
+ FIXME("dwFlags 0x%x ignored\n", dwFlags);
+
+ return IInternetZoneManager_GetZoneAttributes(iface, dwZone, pZoneAttributes);
+}
+
+
+/********************************************************************
+ * IInternetZoneManagerEx2_GetZoneSecurityState
+ */
+static HRESULT WINAPI ZoneMgrImpl_GetZoneSecurityState(IInternetZoneManagerEx2* iface,
+ DWORD dwZoneIndex,
+ BOOL fRespectPolicy,
+ LPDWORD pdwState,
+ BOOL *pfPolicyEncountered)
+{
+ FIXME("(%p)->(%d, %d, %p, %p) stub\n", iface, dwZoneIndex, fRespectPolicy,
+ pdwState, pfPolicyEncountered);
+
+ *pdwState = SECURITY_IE_STATE_GREEN;
+
+ if (pfPolicyEncountered)
+ *pfPolicyEncountered = FALSE;
+
+ return S_OK;
+}
+
+/********************************************************************
+ * IInternetZoneManagerEx2_GetIESecurityState
+ */
+static HRESULT WINAPI ZoneMgrImpl_GetIESecurityState(IInternetZoneManagerEx2* iface,
+ BOOL fRespectPolicy,
+ LPDWORD pdwState,
+ BOOL *pfPolicyEncountered,
+ BOOL fNoCache)
+{
+ FIXME("(%p)->(%d, %p, %p, %d) stub\n", iface, fRespectPolicy, pdwState,
+ pfPolicyEncountered, fNoCache);
+
+ *pdwState = SECURITY_IE_STATE_GREEN;
+
+ if (pfPolicyEncountered)
+ *pfPolicyEncountered = FALSE;
+
+ return S_OK;
+}
+
+/********************************************************************
+ * IInternetZoneManagerEx2_FixInsecureSettings
+ */
+static HRESULT WINAPI ZoneMgrImpl_FixInsecureSettings(IInternetZoneManagerEx2* iface)
+{
+ FIXME("(%p) stub\n", iface);
+ return S_OK;
+}
+
/********************************************************************
* IInternetZoneManager_Construct
*/
-static const IInternetZoneManagerVtbl ZoneMgrImplVtbl = {
+static const IInternetZoneManagerEx2Vtbl ZoneMgrImplVtbl = {
ZoneMgrImpl_QueryInterface,
ZoneMgrImpl_AddRef,
ZoneMgrImpl_Release,
+ /* IInternetZoneManager */
ZoneMgrImpl_GetZoneAttributes,
ZoneMgrImpl_SetZoneAttributes,
ZoneMgrImpl_GetZoneCustomPolicy,
ZoneMgrImpl_GetZoneAt,
ZoneMgrImpl_DestroyZoneEnumerator,
ZoneMgrImpl_CopyTemplatePoliciesToZone,
+ /* IInternetZoneManagerEx */
+ ZoneMgrImpl_GetZoneActionPolicyEx,
+ ZoneMgrImpl_SetZoneActionPolicyEx,
+ /* IInternetZoneManagerEx2 */
+ ZoneMgrImpl_GetZoneAttributesEx,
+ ZoneMgrImpl_GetZoneSecurityState,
+ ZoneMgrImpl_GetIESecurityState,
+ ZoneMgrImpl_FixInsecureSettings,
};
HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
- ZoneMgrImpl* ret = heap_alloc(sizeof(ZoneMgrImpl));
+ ZoneMgrImpl* ret = heap_alloc_zero(sizeof(ZoneMgrImpl));
TRACE("(%p %p)\n", pUnkOuter, ppobj);
ret->lpVtbl = &ZoneMgrImplVtbl;
ret->ref = 1;
- *ppobj = (IInternetZoneManager*)ret;
+ *ppobj = (IInternetZoneManagerEx*)ret;
URLMON_LockModule();
};
static CRITICAL_SECTION session_cs = { &session_cs_dbg, -1, 0, 0, 0, 0 };
+static const WCHAR internet_settings_keyW[] =
+ {'S','O','F','T','W','A','R','E',
+ '\\','M','i','c','r','o','s','o','f','t',
+ '\\','W','i','n','d','o','w','s',
+ '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',
+ '\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0};
+
static name_space *find_name_space(LPCWSTR protocol)
{
name_space *iter;
DWORD size = sizeof(DWORD), res, type;
HKEY hkey;
- static const WCHAR wszKeyName[] =
- {'S','O','F','T','W','A','R','E',
- '\\','M','i','c','r','o','s','o','f','t',
- '\\','W','i','n','d','o','w','s',
- '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',
- '\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0};
static const WCHAR wszUrlEncoding[] = {'U','r','l','E','n','c','o','d','i','n','g',0};
- res = RegOpenKeyW(root, wszKeyName, &hkey);
+ res = RegOpenKeyW(root, internet_settings_keyW, &hkey);
if(res != ERROR_SUCCESS)
return FALSE;
return res == ERROR_SUCCESS;
}
+static LPWSTR user_agent;
+
+static void ensure_useragent(void)
+{
+ DWORD size = sizeof(DWORD), res, type;
+ HKEY hkey;
+
+ static const WCHAR user_agentW[] = {'U','s','e','r',' ','A','g','e','n','t',0};
+
+ if(user_agent)
+ return;
+
+ res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings_keyW, &hkey);
+ if(res != ERROR_SUCCESS)
+ return;
+
+ res = RegQueryValueExW(hkey, user_agentW, NULL, &type, NULL, &size);
+ if(res == ERROR_SUCCESS && type == REG_SZ) {
+ user_agent = heap_alloc(size);
+ res = RegQueryValueExW(hkey, user_agentW, NULL, &type, (LPBYTE)user_agent, &size);
+ if(res != ERROR_SUCCESS) {
+ heap_free(user_agent);
+ user_agent = NULL;
+ }
+ }else {
+ WARN("Could not find User Agent value: %u\n", res);
+ }
+
+ RegCloseKey(hkey);
+}
+
+LPWSTR get_useragent(void)
+{
+ LPWSTR ret;
+
+ ensure_useragent();
+
+ EnterCriticalSection(&session_cs);
+ ret = heap_strdupW(user_agent);
+ LeaveCriticalSection(&session_cs);
+
+ return ret;
+}
+
HRESULT WINAPI UrlMkGetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
DWORD* pdwBufferLength, DWORD dwReserved)
{
WARN("dwReserved = %d\n", dwReserved);
switch(dwOption) {
+ case URLMON_OPTION_USERAGENT: {
+ HRESULT hres = E_OUTOFMEMORY;
+ DWORD size;
+
+ if(!pdwBufferLength)
+ return E_INVALIDARG;
+
+ EnterCriticalSection(&session_cs);
+
+ ensure_useragent();
+ if(user_agent) {
+ size = WideCharToMultiByte(CP_ACP, 0, user_agent, -1, NULL, 0, NULL, NULL);
+ *pdwBufferLength = size;
+ if(size <= dwBufferLength) {
+ if(pBuffer)
+ WideCharToMultiByte(CP_ACP, 0, user_agent, -1, pBuffer, size, NULL, NULL);
+ else
+ hres = E_INVALIDARG;
+ }
+ }
+
+ LeaveCriticalSection(&session_cs);
+
+ /* Tests prove that we have to return E_OUTOFMEMORY on success. */
+ return hres;
+ }
case URLMON_OPTION_URL_ENCODING: {
DWORD encoding = 0;
return E_INVALIDARG;
}
+
+/**************************************************************************
+ * UrlMkSetSessionOption (URLMON.@)
+ */
+HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
+ DWORD Reserved)
+{
+ TRACE("(%x %p %x)\n", dwOption, pBuffer, dwBufferLength);
+
+ switch(dwOption) {
+ case URLMON_OPTION_USERAGENT: {
+ LPWSTR new_user_agent;
+ char *buf = pBuffer;
+ DWORD len, size;
+
+ if(!pBuffer || !dwBufferLength)
+ return E_INVALIDARG;
+
+ for(len=0; len<dwBufferLength && buf[len]; len++);
+
+ TRACE("Setting user agent %s\n", debugstr_an(buf, len));
+
+ size = MultiByteToWideChar(CP_ACP, 0, buf, len, NULL, 0);
+ new_user_agent = heap_alloc((size+1)*sizeof(WCHAR));
+ if(!new_user_agent)
+ return E_OUTOFMEMORY;
+ MultiByteToWideChar(CP_ACP, 0, buf, len, new_user_agent, size);
+ new_user_agent[size] = 0;
+
+ EnterCriticalSection(&session_cs);
+
+ heap_free(user_agent);
+ user_agent = new_user_agent;
+
+ LeaveCriticalSection(&session_cs);
+ break;
+ }
+ default:
+ FIXME("Unknown option %x\n", dwOption);
+ return E_INVALIDARG;
+ }
+
+ return S_OK;
+}
+
+/**************************************************************************
+ * ObtainUserAgentString (URLMON.@)
+ */
+HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbSize)
+{
+ DWORD size;
+ HRESULT hres = E_FAIL;
+
+ TRACE("(%d %p %p)\n", dwOption, pcszUAOut, cbSize);
+
+ if(!pcszUAOut || !cbSize)
+ return E_INVALIDARG;
+
+ EnterCriticalSection(&session_cs);
+
+ ensure_useragent();
+ if(user_agent) {
+ size = WideCharToMultiByte(CP_ACP, 0, user_agent, -1, NULL, 0, NULL, NULL);
+
+ if(size <= *cbSize) {
+ WideCharToMultiByte(CP_ACP, 0, user_agent, -1, pcszUAOut, *cbSize, NULL, NULL);
+ hres = S_OK;
+ }else {
+ hres = E_OUTOFMEMORY;
+ }
+
+ *cbSize = size;
+ }
+
+ LeaveCriticalSection(&session_cs);
+ return hres;
+}
+
+void free_session(void)
+{
+ heap_free(user_agent);
+}
[RegisterDll]
-AddReg=Classes.Reg, Protocols.Reg, ZoneMap.Reg, Zones.Reg
+AddReg=Classes.Reg, Protocols.Reg, ZoneMap.Reg, Zones.Reg, Misc.Reg
[UnregisterDll]
-DelReg=Classes.Reg, Protocols.Reg, ZoneMap.Reg, Zones.Reg
+DelReg=Classes.Reg, Protocols.Reg, ZoneMap.Reg, Zones.Reg, Misc.Reg
[Classes.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"
heap_free(data);
}
+static void process_detach(void)
+{
+ HINTERNET internet_session;
+
+ internet_session = get_internet_session(NULL);
+ if(internet_session)
+ InternetCloseHandle(internet_session);
+
+ if (hCabinet)
+ FreeLibrary(hCabinet);
+
+ init_session(FALSE);
+ free_session();
+ free_tls_list();
+}
+
/***********************************************************************
* DllMain (URLMON.init)
*/
case DLL_PROCESS_ATTACH:
URLMON_hInstance = hinstDLL;
init_session(TRUE);
- break;
+ break;
case DLL_PROCESS_DETACH:
- if (hCabinet)
- FreeLibrary(hCabinet);
- hCabinet = NULL;
- init_session(FALSE);
- free_tls_list();
- URLMON_hInstance = 0;
- break;
+ process_detach();
+ break;
case DLL_THREAD_DETACH:
detach_thread();
return E_FAIL;
}
-/**************************************************************************
- * UrlMkSetSessionOption (URLMON.@)
- */
-HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
- DWORD Reserved)
-{
- FIXME("(%#x, %p, %#x): stub\n", dwOption, pBuffer, dwBufferLength);
-
- return S_OK;
-}
-
-static const CHAR Agent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
-
-/**************************************************************************
- * ObtainUserAgentString (URLMON.@)
- */
-HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbSize)
-{
- FIXME("(%d, %p, %p): stub\n", dwOption, pcszUAOut, cbSize);
-
- if (pcszUAOut == NULL || cbSize == NULL)
- return E_INVALIDARG;
-
- if (*cbSize < sizeof(Agent))
- {
- *cbSize = sizeof(Agent);
- return E_OUTOFMEMORY;
- }
-
- if (sizeof(Agent) < *cbSize)
- *cbSize = sizeof(Agent);
- lstrcpynA(pcszUAOut, Agent, *cbSize);
-
- return S_OK;
-}
-
/**************************************************************************
* IsValidURL (URLMON.@)
*
HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
{
FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved);
-
- if (pBC != NULL || dwReserved != 0)
+
+ if (pBC || dwReserved || !szURL)
return E_INVALIDARG;
-
+
return S_OK;
}
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(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv);
HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv);
DWORD bindf;
BINDINFO bind_info;
- HINTERNET internet;
HINTERNET request;
HINTERNET connection;
DWORD flags;
} Protocol;
struct ProtocolVtbl {
- HRESULT (*open_request)(Protocol*,LPCWSTR,DWORD,IInternetBindInfo*);
+ HRESULT (*open_request)(Protocol*,LPCWSTR,DWORD,HINTERNET,IInternetBindInfo*);
HRESULT (*start_downloading)(Protocol*);
void (*close_connection)(Protocol*);
};
return HeapReAlloc(GetProcessHeap(), 0, mem, len);
}
+static inline void *heap_realloc_zero(void *mem, size_t len)
+{
+ return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);
+}
+
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);