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
);
27 IUnknown IUnknown_inner
;
28 IAuthenticate IAuthenticate_iface
;
29 IHttpNegotiate IHttpNegotiate_iface
;
30 IExtensionServices IExtensionServices_iface
;
41 static inline ExtensionService
*impl_from_IUnknown(IUnknown
*iface
)
43 return CONTAINING_RECORD(iface
, ExtensionService
, IUnknown_inner
);
46 static HRESULT WINAPI
ExtServUnk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
48 ExtensionService
*This
= impl_from_IUnknown(iface
);
52 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
53 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
54 *ppv
= &This
->IUnknown_inner
;
55 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
56 TRACE("(%p)->(IID_IAuthenticate %p)\n", This
, ppv
);
57 *ppv
= &This
->IAuthenticate_iface
;
58 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
59 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This
, ppv
);
60 *ppv
= &This
->IHttpNegotiate_iface
;
61 }else if(IsEqualGUID(&IID_IExtensionServices
, riid
)) {
62 TRACE("(%p)->(IID_IExtensionServices %p)\n", This
, ppv
);
63 *ppv
= &This
->IExtensionServices_iface
;
67 IUnknown_AddRef((IUnknown
*)*ppv
);
71 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
75 static ULONG WINAPI
ExtServUnk_AddRef(IUnknown
*iface
)
77 ExtensionService
*This
= impl_from_IUnknown(iface
);
78 LONG ref
= InterlockedIncrement(&This
->ref
);
80 TRACE("(%p) ref=%d\n", This
, ref
);
85 static ULONG WINAPI
ExtServUnk_Release(IUnknown
*iface
)
87 ExtensionService
*This
= impl_from_IUnknown(iface
);
88 LONG ref
= InterlockedDecrement(&This
->ref
);
90 TRACE("(%p) ref=%d\n", This
, ref
);
93 heap_free(This
->username
);
94 heap_free(This
->password
);
95 heap_free(This
->headers
);
102 static const IUnknownVtbl ExtServUnkVtbl
= {
103 ExtServUnk_QueryInterface
,
108 static inline ExtensionService
*impl_from_IAuthenticate(IAuthenticate
*iface
)
110 return CONTAINING_RECORD(iface
, ExtensionService
, IAuthenticate_iface
);
113 static HRESULT WINAPI
Authenticate_QueryInterface(IAuthenticate
*iface
, REFIID riid
, void **ppv
)
115 ExtensionService
*This
= impl_from_IAuthenticate(iface
);
116 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
119 static ULONG WINAPI
Authenticate_AddRef(IAuthenticate
*iface
)
121 ExtensionService
*This
= impl_from_IAuthenticate(iface
);
122 return IUnknown_AddRef(This
->outer_unk
);
125 static ULONG WINAPI
Authenticate_Release(IAuthenticate
*iface
)
127 ExtensionService
*This
= impl_from_IAuthenticate(iface
);
128 return IUnknown_Release(This
->outer_unk
);
131 static HRESULT WINAPI
Authenticate_Authenticate(IAuthenticate
*iface
,
132 HWND
*phwnd
, LPWSTR
*pszUsername
, LPWSTR
*pszPassword
)
134 ExtensionService
*This
= impl_from_IAuthenticate(iface
);
136 TRACE("(%p)->(%p %p %p)\n", This
, phwnd
, pszUsername
, pszPassword
);
138 if(!phwnd
|| !pszUsername
|| !pszPassword
)
142 *pszUsername
= hlink_co_strdupW(This
->username
);
143 *pszPassword
= hlink_co_strdupW(This
->password
);
148 static const IAuthenticateVtbl AuthenticateVtbl
= {
149 Authenticate_QueryInterface
,
151 Authenticate_Release
,
152 Authenticate_Authenticate
155 static inline ExtensionService
*impl_from_IHttpNegotiate(IHttpNegotiate
*iface
)
157 return CONTAINING_RECORD(iface
, ExtensionService
, IHttpNegotiate_iface
);
160 static HRESULT WINAPI
HttpNegotiate_QueryInterface(IHttpNegotiate
*iface
, REFIID riid
, void **ppv
)
162 ExtensionService
*This
= impl_from_IHttpNegotiate(iface
);
163 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
166 static ULONG WINAPI
HttpNegotiate_AddRef(IHttpNegotiate
*iface
)
168 ExtensionService
*This
= impl_from_IHttpNegotiate(iface
);
169 return IUnknown_AddRef(This
->outer_unk
);
172 static ULONG WINAPI
HttpNegotiate_Release(IHttpNegotiate
*iface
)
174 ExtensionService
*This
= impl_from_IHttpNegotiate(iface
);
175 return IUnknown_Release(This
->outer_unk
);
178 static HRESULT WINAPI
HttpNegotiate_BeginningTransaction(IHttpNegotiate
*iface
,
179 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
181 ExtensionService
*This
= impl_from_IHttpNegotiate(iface
);
183 TRACE("(%p)->(%s %s %x %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
), dwReserved
,
184 pszAdditionalHeaders
);
186 if(!pszAdditionalHeaders
)
189 *pszAdditionalHeaders
= hlink_co_strdupW(This
->headers
);
193 static HRESULT WINAPI
HttpNegotiate_OnResponse(IHttpNegotiate
*iface
, DWORD dwResponseCode
,
194 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
, LPWSTR
*pszAdditionalRequestHeaders
)
196 ExtensionService
*This
= impl_from_IHttpNegotiate(iface
);
198 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
199 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
201 *pszAdditionalRequestHeaders
= NULL
;
205 static const IHttpNegotiateVtbl HttpNegotiateVtbl
= {
206 HttpNegotiate_QueryInterface
,
207 HttpNegotiate_AddRef
,
208 HttpNegotiate_Release
,
209 HttpNegotiate_BeginningTransaction
,
210 HttpNegotiate_OnResponse
213 static inline ExtensionService
*impl_from_IExtensionServices(IExtensionServices
*iface
)
215 return CONTAINING_RECORD(iface
, ExtensionService
, IExtensionServices_iface
);
218 static HRESULT WINAPI
ExtServ_QueryInterface(IExtensionServices
*iface
, REFIID riid
, void **ppv
)
220 ExtensionService
*This
= impl_from_IExtensionServices(iface
);
221 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
224 static ULONG WINAPI
ExtServ_AddRef(IExtensionServices
*iface
)
226 ExtensionService
*This
= impl_from_IExtensionServices(iface
);
227 return IUnknown_AddRef(This
->outer_unk
);
230 static ULONG WINAPI
ExtServ_Release(IExtensionServices
*iface
)
232 ExtensionService
*This
= impl_from_IExtensionServices(iface
);
233 return IUnknown_Release(This
->outer_unk
);
236 static HRESULT
ExtServ_ImplSetAdditionalHeaders(ExtensionService
* This
, LPCWSTR pwzAdditionalHeaders
)
240 heap_free(This
->headers
);
241 This
->headers
= NULL
;
243 if (!pwzAdditionalHeaders
)
246 len
= strlenW(pwzAdditionalHeaders
);
248 if(len
&& pwzAdditionalHeaders
[len
-1] != '\n' && pwzAdditionalHeaders
[len
-1] != '\r') {
249 static const WCHAR endlW
[] = {'\r','\n',0};
250 This
->headers
= heap_alloc(len
*sizeof(WCHAR
) + sizeof(endlW
));
251 memcpy(This
->headers
, pwzAdditionalHeaders
, len
*sizeof(WCHAR
));
252 memcpy(This
->headers
+len
, endlW
, sizeof(endlW
));
254 This
->headers
= hlink_strdupW(pwzAdditionalHeaders
);
260 static HRESULT WINAPI
ExtServ_SetAdditionalHeaders(IExtensionServices
* iface
, LPCWSTR pwzAdditionalHeaders
)
262 ExtensionService
*This
= impl_from_IExtensionServices(iface
);
264 TRACE("(%p)->(%s)\n", This
, debugstr_w(pwzAdditionalHeaders
));
266 return ExtServ_ImplSetAdditionalHeaders(This
,pwzAdditionalHeaders
);
269 static HRESULT
ExtServ_ImplSetAuthenticateData(ExtensionService
* This
, HWND phwnd
, LPCWSTR pwzUsername
, LPCWSTR pwzPassword
)
271 heap_free(This
->username
);
272 heap_free(This
->password
);
275 This
->username
= hlink_strdupW(pwzUsername
);
276 This
->password
= hlink_strdupW(pwzPassword
);
281 static HRESULT WINAPI
ExtServ_SetAuthenticateData(IExtensionServices
* iface
, HWND phwnd
, LPCWSTR pwzUsername
, LPCWSTR pwzPassword
)
283 ExtensionService
*This
= impl_from_IExtensionServices(iface
);
285 TRACE("(%p)->(%p %s %s)\n", This
, phwnd
, debugstr_w(pwzUsername
), debugstr_w(pwzPassword
));
287 return ExtServ_ImplSetAuthenticateData(This
, phwnd
, pwzUsername
, pwzPassword
);
290 static const IExtensionServicesVtbl ExtServVtbl
= {
291 ExtServ_QueryInterface
,
294 ExtServ_SetAdditionalHeaders
,
295 ExtServ_SetAuthenticateData
298 /***********************************************************************
299 * HlinkCreateExtensionServices (HLINK.@)
301 HRESULT WINAPI
HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders
,
302 HWND phwnd
, LPCWSTR pszUsername
, LPCWSTR pszPassword
,
303 IUnknown
*punkOuter
, REFIID riid
, void** ppv
)
305 ExtensionService
*ret
;
308 TRACE("%s %p %s %s %p %s %p\n",debugstr_w(pwzAdditionalHeaders
),
309 phwnd
, debugstr_w(pszUsername
), debugstr_w(pszPassword
),
310 punkOuter
, debugstr_guid(riid
), ppv
);
312 ret
= heap_alloc(sizeof(*ret
));
314 ret
->IUnknown_inner
.lpVtbl
= &ExtServUnkVtbl
;
315 ret
->IAuthenticate_iface
.lpVtbl
= &AuthenticateVtbl
;
316 ret
->IHttpNegotiate_iface
.lpVtbl
= &HttpNegotiateVtbl
;
317 ret
->IExtensionServices_iface
.lpVtbl
= &ExtServVtbl
;
321 ret
->username
= NULL
;
322 ret
->password
= NULL
;
324 ExtServ_ImplSetAuthenticateData(ret
, phwnd
, pszUsername
, pszPassword
);
325 ExtServ_ImplSetAdditionalHeaders(ret
, pwzAdditionalHeaders
);
328 ret
->outer_unk
= &ret
->IUnknown_inner
;
329 hres
= IUnknown_QueryInterface(&ret
->IUnknown_inner
, riid
, ppv
);
330 IUnknown_Release(&ret
->IUnknown_inner
);
331 }else if(IsEqualGUID(&IID_IUnknown
, riid
)) {
332 ret
->outer_unk
= punkOuter
;
333 *ppv
= &ret
->IUnknown_inner
;
335 IUnknown_Release(&ret
->IUnknown_inner
);