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;
32 const IExtensionServicesVtbl *lpIExtensionServicesVtbl;
43 #define EXTSERVUNK(x) ((IUnknown*) &(x)->lpIUnknownVtbl)
44 #define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpIAuthenticateVtbl)
45 #define HTTPNEGOTIATE(x) ((IHttpNegotiate*) &(x)->lpIHttpNegotiateVtbl)
46 #define EXTENSIONSERVICES(x) ((IExtensionServices*) &(x)->lpIExtensionServicesVtbl)
48 #define EXTSERVUNK_THIS(iface) DEFINE_THIS(ExtensionService, IUnknown, iface)
50 static HRESULT WINAPI ExtServUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
52 ExtensionService *This = EXTSERVUNK_THIS(iface);
56 if(IsEqualGUID(&IID_IUnknown, riid)) {
57 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
58 *ppv = EXTSERVUNK(This);
59 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
60 TRACE("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
61 *ppv = AUTHENTICATE(This);
62 }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
63 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
64 *ppv = HTTPNEGOTIATE(This);
65 }else if(IsEqualGUID(&IID_IExtensionServices, riid)) {
66 TRACE("(%p)->(IID_IExtensionServices %p)\n", This, ppv);
67 *ppv = EXTENSIONSERVICES(This);
71 IUnknown_AddRef((IUnknown*)*ppv);
75 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
79 static ULONG WINAPI ExtServUnk_AddRef(IUnknown *iface)
81 ExtensionService *This = EXTSERVUNK_THIS(iface);
82 LONG ref = InterlockedIncrement(&This->ref);
84 TRACE("(%p) ref=%d\n", This, ref);
89 static ULONG WINAPI ExtServUnk_Release(IUnknown *iface)
91 ExtensionService *This = EXTSERVUNK_THIS(iface);
92 LONG ref = InterlockedDecrement(&This->ref);
94 TRACE("(%p) ref=%d\n", This, ref);
97 heap_free(This->username);
98 heap_free(This->password);
99 heap_free(This->headers);
106 #undef EXTSERVUNK_THIS
108 static const IUnknownVtbl ExtServUnkVtbl = {
109 ExtServUnk_QueryInterface,
114 #define AUTHENTICATE_THIS(iface) DEFINE_THIS(ExtensionService, IAuthenticate, iface)
116 static HRESULT WINAPI Authenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
118 ExtensionService *This = AUTHENTICATE_THIS(iface);
119 return IUnknown_QueryInterface(This->outer, riid, ppv);
122 static ULONG WINAPI Authenticate_AddRef(IAuthenticate *iface)
124 ExtensionService *This = AUTHENTICATE_THIS(iface);
125 return IUnknown_AddRef(This->outer);
128 static ULONG WINAPI Authenticate_Release(IAuthenticate *iface)
130 ExtensionService *This = AUTHENTICATE_THIS(iface);
131 return IUnknown_Release(This->outer);
134 static HRESULT WINAPI Authenticate_Authenticate(IAuthenticate *iface,
135 HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
137 ExtensionService *This = AUTHENTICATE_THIS(iface);
139 TRACE("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
141 if(!phwnd || !pszUsername || !pszPassword)
145 *pszUsername = hlink_co_strdupW(This->username);
146 *pszPassword = hlink_co_strdupW(This->password);
151 #undef AUTHENTICATE_THIS
153 static const IAuthenticateVtbl AuthenticateVtbl = {
154 Authenticate_QueryInterface,
156 Authenticate_Release,
157 Authenticate_Authenticate
160 #define HTTPNEGOTIATE_THIS(iface) DEFINE_THIS(ExtensionService, IHttpNegotiate, iface)
162 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv)
164 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
165 return IUnknown_QueryInterface(This->outer, riid, ppv);
168 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
170 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
171 return IUnknown_AddRef(This->outer);
174 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
176 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
177 return IUnknown_Release(This->outer);
180 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
181 LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
183 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
185 TRACE("(%p)->(%s %s %x %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
186 pszAdditionalHeaders);
188 if(!pszAdditionalHeaders)
191 *pszAdditionalHeaders = hlink_co_strdupW(This->headers);
195 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface, DWORD dwResponseCode,
196 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
198 ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
200 TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
201 debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
203 *pszAdditionalRequestHeaders = NULL;
207 #undef HTTPNEGOTIATE_THIS
209 static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
210 HttpNegotiate_QueryInterface,
211 HttpNegotiate_AddRef,
212 HttpNegotiate_Release,
213 HttpNegotiate_BeginningTransaction,
214 HttpNegotiate_OnResponse
217 #define EXTENSIONSERVICES_THIS(iface) DEFINE_THIS(ExtensionService, IExtensionServices, iface)
219 static HRESULT WINAPI ExtServ_QueryInterface(IExtensionServices *iface, REFIID riid, void **ppv)
221 ExtensionService *This = EXTENSIONSERVICES_THIS(iface);
222 return IUnknown_QueryInterface(This->outer, riid, ppv);
225 static ULONG WINAPI ExtServ_AddRef(IExtensionServices *iface)
227 ExtensionService *This = EXTENSIONSERVICES_THIS(iface);
228 return IUnknown_AddRef(This->outer);
231 static ULONG WINAPI ExtServ_Release(IExtensionServices *iface)
233 ExtensionService *This = EXTENSIONSERVICES_THIS(iface);
234 return IUnknown_Release(This->outer);
237 static HRESULT ExtServ_ImplSetAdditionalHeaders(ExtensionService* This, LPCWSTR pwzAdditionalHeaders)
241 heap_free(This->headers);
242 This->headers = NULL;
244 if (!pwzAdditionalHeaders)
247 len = strlenW(pwzAdditionalHeaders);
249 if(len && pwzAdditionalHeaders[len-1] != '\n' && pwzAdditionalHeaders[len-1] != '\r') {
250 static const WCHAR endlW[] = {'\r','\n',0};
251 This->headers = heap_alloc(len*sizeof(WCHAR) + sizeof(endlW));
252 memcpy(This->headers, pwzAdditionalHeaders, len*sizeof(WCHAR));
253 memcpy(This->headers+len, endlW, sizeof(endlW));
255 This->headers = hlink_strdupW(pwzAdditionalHeaders);
261 static HRESULT WINAPI ExtServ_SetAdditionalHeaders(IExtensionServices* iface, LPCWSTR pwzAdditionalHeaders)
263 ExtensionService *This = EXTENSIONSERVICES_THIS(iface);
265 TRACE("(%p)->(%s)\n", This, debugstr_w(pwzAdditionalHeaders));
267 return ExtServ_ImplSetAdditionalHeaders(This,pwzAdditionalHeaders);
270 static HRESULT ExtServ_ImplSetAuthenticateData(ExtensionService* This, HWND phwnd, LPCWSTR pwzUsername, LPCWSTR pwzPassword)
272 heap_free(This->username);
273 heap_free(This->password);
276 This->username = hlink_strdupW(pwzUsername);
277 This->password = hlink_strdupW(pwzPassword);
282 static HRESULT WINAPI ExtServ_SetAuthenticateData(IExtensionServices* iface, HWND phwnd, LPCWSTR pwzUsername, LPCWSTR pwzPassword)
284 ExtensionService *This = EXTENSIONSERVICES_THIS(iface);
286 TRACE("(%p)->(%p %s %s)\n", This, phwnd, debugstr_w(pwzUsername), debugstr_w(pwzPassword));
288 return ExtServ_ImplSetAuthenticateData(This, phwnd, pwzUsername, pwzPassword);
291 #undef EXTENSIONSERVICES_THIS
293 static const IExtensionServicesVtbl ExtServVtbl = {
294 ExtServ_QueryInterface,
297 ExtServ_SetAdditionalHeaders,
298 ExtServ_SetAuthenticateData
301 /***********************************************************************
302 * HlinkCreateExtensionServices (HLINK.@)
304 HRESULT WINAPI HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders,
305 HWND phwnd, LPCWSTR pszUsername, LPCWSTR pszPassword,
306 IUnknown *punkOuter, REFIID riid, void** ppv)
308 ExtensionService *ret;
311 TRACE("%s %p %s %s %p %s %p\n",debugstr_w(pwzAdditionalHeaders),
312 phwnd, debugstr_w(pszUsername), debugstr_w(pszPassword),
313 punkOuter, debugstr_guid(riid), ppv);
315 ret = heap_alloc(sizeof(*ret));
317 ret->lpIUnknownVtbl = &ExtServUnkVtbl;
318 ret->lpIAuthenticateVtbl = &AuthenticateVtbl;
319 ret->lpIHttpNegotiateVtbl = &HttpNegotiateVtbl;
320 ret->lpIExtensionServicesVtbl= &ExtServVtbl;
324 ret->username = NULL;
325 ret->password = NULL;
327 ExtServ_ImplSetAuthenticateData(ret, phwnd, pszUsername, pszPassword);
328 ExtServ_ImplSetAdditionalHeaders(ret, pwzAdditionalHeaders);
331 ret->outer = EXTSERVUNK(ret);
332 hres = IUnknown_QueryInterface(EXTSERVUNK(ret), riid, ppv);
333 IUnknown_Release(EXTSERVUNK(ret));
334 }else if(IsEqualGUID(&IID_IUnknown, riid)) {
335 ret->outer = punkOuter;
336 *ppv = EXTSERVUNK(ret);
338 IUnknown_Release(EXTSERVUNK(ret));