From d371b8b5f0436f430cfed3ff19222630e35fe077 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 6 Dec 2007 13:17:30 +0100 Subject: [PATCH] hlink: Added IHttpNegotiate interface to ExtensionService. --- dlls/hlink/extserv.c | 79 ++++++++++++++++++++++++++++++++++++++-- dlls/hlink/tests/hlink.c | 51 +++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/dlls/hlink/extserv.c b/dlls/hlink/extserv.c index d2abf2e872a..b306d352a38 100644 --- a/dlls/hlink/extserv.c +++ b/dlls/hlink/extserv.c @@ -28,6 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(hlink); typedef struct { const IUnknownVtbl *lpIUnknownVtbl; const IAuthenticateVtbl *lpIAuthenticateVtbl; + const IHttpNegotiateVtbl *lpIHttpNegotiateVtbl; LONG ref; IUnknown *outer; @@ -35,10 +36,12 @@ typedef struct { HWND hwnd; LPWSTR username; LPWSTR password; + LPWSTR headers; } ExtensionService; #define EXTSERVUNK(x) ((IUnknown*) &(x)->lpIUnknownVtbl) #define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpIAuthenticateVtbl) +#define HTTPNEGOTIATE(x) ((IHttpNegotiate*) &(x)->lpIHttpNegotiateVtbl) #define EXTSERVUNK_THIS(iface) DEFINE_THIS(ExtensionService, IUnknown, iface) @@ -54,6 +57,9 @@ static HRESULT WINAPI ExtServUnk_QueryInterface(IUnknown *iface, REFIID riid, vo }else if(IsEqualGUID(&IID_IAuthenticate, riid)) { TRACE("(%p)->(IID_IAuthenticate %p)\n", This, ppv); *ppv = AUTHENTICATE(This); + }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) { + TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv); + *ppv = HTTPNEGOTIATE(This); } if(*ppv) { @@ -145,29 +151,96 @@ static const IAuthenticateVtbl AuthenticateVtbl = { Authenticate_Authenticate }; +#define HTTPNEGOTIATE_THIS(iface) DEFINE_THIS(ExtensionService, IHttpNegotiate, iface) + +static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv) +{ + ExtensionService *This = HTTPNEGOTIATE_THIS(iface); + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface) +{ + ExtensionService *This = HTTPNEGOTIATE_THIS(iface); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface) +{ + ExtensionService *This = HTTPNEGOTIATE_THIS(iface); + return IUnknown_Release(This->outer); +} + +static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface, + LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) +{ + ExtensionService *This = HTTPNEGOTIATE_THIS(iface); + + TRACE("(%p)->(%s %s %x %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved, + pszAdditionalHeaders); + + if(!pszAdditionalHeaders) + return E_INVALIDARG; + + *pszAdditionalHeaders = hlink_co_strdupW(This->headers); + return S_OK; +} + +static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface, DWORD dwResponseCode, + LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders) +{ + ExtensionService *This = HTTPNEGOTIATE_THIS(iface); + + TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders), + debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders); + + *pszAdditionalRequestHeaders = NULL; + return S_OK; +} + +#undef HTTPNEGOTIATE_THIS + +static const IHttpNegotiateVtbl HttpNegotiateVtbl = { + HttpNegotiate_QueryInterface, + HttpNegotiate_AddRef, + HttpNegotiate_Release, + HttpNegotiate_BeginningTransaction, + HttpNegotiate_OnResponse +}; + HRESULT WINAPI HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders, HWND phwnd, LPCWSTR pszUsername, LPCWSTR pszPassword, IUnknown *punkOuter, REFIID riid, void** ppv) { ExtensionService *ret; + int len = 0; HRESULT hres = S_OK; TRACE("%s %p %s %s %p %s %p\n",debugstr_w(pwzAdditionalHeaders), phwnd, debugstr_w(pszUsername), debugstr_w(pszPassword), punkOuter, debugstr_guid(riid), ppv); - if(pwzAdditionalHeaders) - FIXME("Unsupported pwzAdditionalHeaders\n"); - ret = hlink_alloc(sizeof(*ret)); ret->lpIUnknownVtbl = &ExtServUnkVtbl; ret->lpIAuthenticateVtbl = &AuthenticateVtbl; + ret->lpIHttpNegotiateVtbl = &HttpNegotiateVtbl; ret->ref = 1; ret->hwnd = phwnd; ret->username = hlink_strdupW(pszUsername); ret->password = hlink_strdupW(pszPassword); + if(pwzAdditionalHeaders) + len = strlenW(pwzAdditionalHeaders); + + if(len && pwzAdditionalHeaders[len-1] != '\n' && pwzAdditionalHeaders[len-1] != '\r') { + static const WCHAR endlW[] = {'\r','\n',0}; + ret->headers = hlink_alloc(len*sizeof(WCHAR) + sizeof(endlW)); + memcpy(ret->headers, pwzAdditionalHeaders, len*sizeof(WCHAR)); + memcpy(ret->headers+len, endlW, sizeof(endlW)); + }else { + ret->headers = hlink_strdupW(pwzAdditionalHeaders); + } if(!punkOuter) { ret->outer = EXTSERVUNK(ret); diff --git a/dlls/hlink/tests/hlink.c b/dlls/hlink/tests/hlink.c index 4a59f63f322..06d1ee82081 100644 --- a/dlls/hlink/tests/hlink.c +++ b/dlls/hlink/tests/hlink.c @@ -28,6 +28,15 @@ #include "wine/test.h" +static const char *debugstr_w(LPCWSTR str) +{ + static char buf[1024]; + if(!str) + return "(null)"; + WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); + return buf; +} + static void test_HlinkIsShortcut(void) { int i; @@ -346,12 +355,15 @@ static void test_special_reference(void) static void test_HlinkCreateExtensionServices(void) { IAuthenticate *authenticate; - LPWSTR password, username; + IHttpNegotiate *http_negotiate; + LPWSTR password, username, headers; HWND hwnd; HRESULT hres; static const WCHAR usernameW[] = {'u','s','e','r',0}; static const WCHAR passwordW[] = {'p','a','s','s',0}; + static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0}; + static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0}; hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL, NULL, &IID_IAuthenticate, (void**)&authenticate); @@ -366,10 +378,29 @@ static void test_HlinkCreateExtensionServices(void) ok(!username, "username != NULL\n"); ok(!password, "password != NULL\n"); + hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate); + ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres); + + headers = (void*)0xdeadbeef; + hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef, + 0, &headers); + ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres); + ok(headers == NULL, "headers != NULL\n"); + + hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef, + 0, NULL); + ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres); + + headers = (void*)0xdeadbeef; + hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers); + ok(hres == S_OK, "OnResponse failed: %08x\n", hres); + ok(headers == NULL, "headers != NULL\n"); + + IHttpNegotiate_Release(http_negotiate); IAuthenticate_Release(authenticate); - hres = HlinkCreateExtensionServices(NULL, (HWND)0xfefefefe, usernameW, passwordW, + hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW, NULL, &IID_IAuthenticate, (void**)&authenticate); ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres); ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n"); @@ -391,6 +422,22 @@ static void test_HlinkCreateExtensionServices(void) ok(password == (void*)0xdeadbeef, "password = %p\n", password); ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd); + hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate); + ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres); + + headers = (void*)0xdeadbeef; + hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef, + 0, &headers); + ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres); + ok(!lstrcmpW(headers, headersexW), "unexpected headers \"%s\"\n", debugstr_w(headers)); + CoTaskMemFree(headers); + + headers = (void*)0xdeadbeef; + hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers); + ok(hres == S_OK, "OnResponse failed: %08x\n", hres); + ok(headers == NULL, "unexpected headers \"%s\"\n", debugstr_w(headers)); + + IHttpNegotiate_Release(http_negotiate); IAuthenticate_Release(authenticate); }