2 * Copyright 2007 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "hlink_private.h"
21 #include "wine/debug.h"
22 #include "wine/unicode.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(hlink);
26 #define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))
29 const IUnknownVtbl *lpIUnknownVtbl;
30 const IAuthenticateVtbl *lpIAuthenticateVtbl;
31 const IHttpNegotiateVtbl *lpIHttpNegotiateVtbl;
42 #define EXTSERVUNK(x) ((IUnknown*) &(x)->lpIUnknownVtbl)
43 #define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpIAuthenticateVtbl)
44 #define HTTPNEGOTIATE(x) ((IHttpNegotiate*) &(x)->lpIHttpNegotiateVtbl)
46 #define EXTSERVUNK_THIS(iface) DEFINE_THIS(ExtensionService, IUnknown, iface)
48 static HRESULT WINAPI ExtServUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
50 ExtensionService *This = EXTSERVUNK_THIS(iface);
54 if(IsEqualGUID(&IID_IUnknown, riid)) {
55 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
56 *ppv = EXTSERVUNK(This);
57 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
58 TRACE("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
59 *ppv = AUTHENTICATE(This);
60 }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
61 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
62 *ppv = HTTPNEGOTIATE(This);
66 IUnknown_AddRef(EXTSERVUNK(This));
70 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
74 static ULONG WINAPI ExtServUnk_AddRef(IUnknown *iface)
76 ExtensionService *This = EXTSERVUNK_THIS(iface);
77 LONG ref = InterlockedIncrement(&This->ref);
79 TRACE("(%p) ref=%d\n", This, ref);
84 static ULONG WINAPI ExtServUnk_Release(IUnknown *iface)
86 ExtensionService *This = EXTSERVUNK_THIS(iface);
87 LONG ref = InterlockedDecrement(&This->ref);
89 TRACE("(%p) ref=%d\n", This, ref);
92 hlink_free(This->username);
93 hlink_free(This->password);
100 #undef EXTSERVUNK_THIS
102 static const IUnknownVtbl ExtServUnkVtbl = {
103 ExtServUnk_QueryInterface,
108 #define AUTHENTICATE_THIS(iface) DEFINE_THIS(ExtensionService, IAuthenticate, iface)
110 static HRESULT WINAPI Authenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
112 ExtensionService *This = AUTHENTICATE_THIS(iface);
113 return IUnknown_QueryInterface(This->outer, riid, ppv);
116 static ULONG WINAPI Authenticate_AddRef(IAuthenticate *iface)
118 ExtensionService *This = AUTHENTICATE_THIS(iface);
119 return IUnknown_AddRef(This->outer);
122 static ULONG WINAPI Authenticate_Release(IAuthenticate *iface)
124 ExtensionService *This = AUTHENTICATE_THIS(iface);
125 return IUnknown_Release(This->outer);
128 static HRESULT WINAPI Authenticate_Authenticate(IAuthenticate *iface,
129 HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
131 ExtensionService *This = AUTHENTICATE_THIS(iface);
133 TRACE("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
135 if(!phwnd || !pszUsername || !pszPassword)
139 *pszUsername = hlink_co_strdupW(This->username);
140 *pszPassword = hlink_co_strdupW(This->password);
145 #undef AUTHENTICATE_THIS
147 static const IAuthenticateVtbl AuthenticateVtbl = {
148 Authenticate_QueryInterface,
150 Authenticate_Release,
151 Authenticate_Authenticate
154 #define HTTPNEGOTIATE_THIS(iface) DEFINE_THIS(ExtensionService, IHttpNegotiate, iface)
156 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv)
158 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
159 return IUnknown_QueryInterface(This->outer, riid, ppv);
162 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
164 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
165 return IUnknown_AddRef(This->outer);
168 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
170 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
171 return IUnknown_Release(This->outer);
174 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
175 LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
177 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
179 TRACE("(%p)->(%s %s %x %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
180 pszAdditionalHeaders);
182 if(!pszAdditionalHeaders)
185 *pszAdditionalHeaders = hlink_co_strdupW(This->headers);
189 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface, DWORD dwResponseCode,
190 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
192 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
194 TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
195 debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
197 *pszAdditionalRequestHeaders = NULL;
201 #undef HTTPNEGOTIATE_THIS
203 static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
204 HttpNegotiate_QueryInterface,
205 HttpNegotiate_AddRef,
206 HttpNegotiate_Release,
207 HttpNegotiate_BeginningTransaction,
208 HttpNegotiate_OnResponse
211 HRESULT WINAPI HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders,
212 HWND phwnd, LPCWSTR pszUsername, LPCWSTR pszPassword,
213 IUnknown *punkOuter, REFIID riid, void** ppv)
215 ExtensionService *ret;
219 TRACE("%s %p %s %s %p %s %p\n",debugstr_w(pwzAdditionalHeaders),
220 phwnd, debugstr_w(pszUsername), debugstr_w(pszPassword),
221 punkOuter, debugstr_guid(riid), ppv);
223 ret = hlink_alloc(sizeof(*ret));
225 ret->lpIUnknownVtbl = &ExtServUnkVtbl;
226 ret->lpIAuthenticateVtbl = &AuthenticateVtbl;
227 ret->lpIHttpNegotiateVtbl = &HttpNegotiateVtbl;
230 ret->username = hlink_strdupW(pszUsername);
231 ret->password = hlink_strdupW(pszPassword);
233 if(pwzAdditionalHeaders)
234 len = strlenW(pwzAdditionalHeaders);
236 if(len && pwzAdditionalHeaders[len-1] != '\n' && pwzAdditionalHeaders[len-1] != '\r') {
237 static const WCHAR endlW[] = {'\r','\n',0};
238 ret->headers = hlink_alloc(len*sizeof(WCHAR) + sizeof(endlW));
239 memcpy(ret->headers, pwzAdditionalHeaders, len*sizeof(WCHAR));
240 memcpy(ret->headers+len, endlW, sizeof(endlW));
242 ret->headers = hlink_strdupW(pwzAdditionalHeaders);
246 ret->outer = EXTSERVUNK(ret);
247 hres = IUnknown_QueryInterface(EXTSERVUNK(ret), riid, ppv);
248 IUnknown_Release(EXTSERVUNK(ret));
249 }else if(IsEqualGUID(&IID_IUnknown, riid)) {
250 ret->outer = punkOuter;
251 *ppv = EXTSERVUNK(ret);
253 IUnknown_Release(EXTSERVUNK(ret));