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
));