gdi32: Fix leak in GdiDeleteSpoolFileHandle.
[wine.git] / dlls / hlink / extserv.c
blobd6587ce9e799f655a513c2f03675e5b1978238e6
1 /*
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"
23 WINE_DEFAULT_DEBUG_CHANNEL(hlink);
25 typedef struct {
26 IUnknown IUnknown_inner;
27 IAuthenticate IAuthenticate_iface;
28 IHttpNegotiate IHttpNegotiate_iface;
29 IExtensionServices IExtensionServices_iface;
31 IUnknown *outer_unk;
32 LONG ref;
34 HWND hwnd;
35 LPWSTR username;
36 LPWSTR password;
37 LPWSTR headers;
38 } ExtensionService;
40 static inline ExtensionService *impl_from_IUnknown(IUnknown *iface)
42 return CONTAINING_RECORD(iface, ExtensionService, IUnknown_inner);
45 static HRESULT WINAPI ExtServUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
47 ExtensionService *This = impl_from_IUnknown(iface);
49 *ppv = NULL;
51 if(IsEqualGUID(&IID_IUnknown, riid)) {
52 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
53 *ppv = &This->IUnknown_inner;
54 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
55 TRACE("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
56 *ppv = &This->IAuthenticate_iface;
57 }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
58 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
59 *ppv = &This->IHttpNegotiate_iface;
60 }else if(IsEqualGUID(&IID_IExtensionServices, riid)) {
61 TRACE("(%p)->(IID_IExtensionServices %p)\n", This, ppv);
62 *ppv = &This->IExtensionServices_iface;
65 if(*ppv) {
66 IUnknown_AddRef((IUnknown*)*ppv);
67 return S_OK;
70 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
71 return E_NOINTERFACE;
74 static ULONG WINAPI ExtServUnk_AddRef(IUnknown *iface)
76 ExtensionService *This = impl_from_IUnknown(iface);
77 LONG ref = InterlockedIncrement(&This->ref);
79 TRACE("(%p) ref=%ld\n", This, ref);
81 return ref;
84 static ULONG WINAPI ExtServUnk_Release(IUnknown *iface)
86 ExtensionService *This = impl_from_IUnknown(iface);
87 LONG ref = InterlockedDecrement(&This->ref);
89 TRACE("(%p) ref=%ld\n", This, ref);
91 if(!ref) {
92 free(This->username);
93 free(This->password);
94 free(This->headers);
95 free(This);
98 return ref;
101 static const IUnknownVtbl ExtServUnkVtbl = {
102 ExtServUnk_QueryInterface,
103 ExtServUnk_AddRef,
104 ExtServUnk_Release
107 static inline ExtensionService *impl_from_IAuthenticate(IAuthenticate *iface)
109 return CONTAINING_RECORD(iface, ExtensionService, IAuthenticate_iface);
112 static HRESULT WINAPI Authenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
114 ExtensionService *This = impl_from_IAuthenticate(iface);
115 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
118 static ULONG WINAPI Authenticate_AddRef(IAuthenticate *iface)
120 ExtensionService *This = impl_from_IAuthenticate(iface);
121 return IUnknown_AddRef(This->outer_unk);
124 static ULONG WINAPI Authenticate_Release(IAuthenticate *iface)
126 ExtensionService *This = impl_from_IAuthenticate(iface);
127 return IUnknown_Release(This->outer_unk);
130 static HRESULT WINAPI Authenticate_Authenticate(IAuthenticate *iface,
131 HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
133 ExtensionService *This = impl_from_IAuthenticate(iface);
135 TRACE("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
137 if(!phwnd || !pszUsername || !pszPassword)
138 return E_INVALIDARG;
140 *phwnd = This->hwnd;
141 *pszUsername = hlink_co_strdupW(This->username);
142 *pszPassword = hlink_co_strdupW(This->password);
144 return S_OK;
147 static const IAuthenticateVtbl AuthenticateVtbl = {
148 Authenticate_QueryInterface,
149 Authenticate_AddRef,
150 Authenticate_Release,
151 Authenticate_Authenticate
154 static inline ExtensionService *impl_from_IHttpNegotiate(IHttpNegotiate *iface)
156 return CONTAINING_RECORD(iface, ExtensionService, IHttpNegotiate_iface);
159 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv)
161 ExtensionService *This = impl_from_IHttpNegotiate(iface);
162 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
165 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
167 ExtensionService *This = impl_from_IHttpNegotiate(iface);
168 return IUnknown_AddRef(This->outer_unk);
171 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
173 ExtensionService *This = impl_from_IHttpNegotiate(iface);
174 return IUnknown_Release(This->outer_unk);
177 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
178 LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
180 ExtensionService *This = impl_from_IHttpNegotiate(iface);
182 TRACE("(%p)->(%s %s %lx %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
183 pszAdditionalHeaders);
185 if(!pszAdditionalHeaders)
186 return E_INVALIDARG;
188 *pszAdditionalHeaders = hlink_co_strdupW(This->headers);
189 return S_OK;
192 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface, DWORD dwResponseCode,
193 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
195 ExtensionService *This = impl_from_IHttpNegotiate(iface);
197 TRACE("(%p)->(%ld %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
198 debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
200 *pszAdditionalRequestHeaders = NULL;
201 return S_OK;
204 static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
205 HttpNegotiate_QueryInterface,
206 HttpNegotiate_AddRef,
207 HttpNegotiate_Release,
208 HttpNegotiate_BeginningTransaction,
209 HttpNegotiate_OnResponse
212 static inline ExtensionService *impl_from_IExtensionServices(IExtensionServices *iface)
214 return CONTAINING_RECORD(iface, ExtensionService, IExtensionServices_iface);
217 static HRESULT WINAPI ExtServ_QueryInterface(IExtensionServices *iface, REFIID riid, void **ppv)
219 ExtensionService *This = impl_from_IExtensionServices(iface);
220 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
223 static ULONG WINAPI ExtServ_AddRef(IExtensionServices *iface)
225 ExtensionService *This = impl_from_IExtensionServices(iface);
226 return IUnknown_AddRef(This->outer_unk);
229 static ULONG WINAPI ExtServ_Release(IExtensionServices *iface)
231 ExtensionService *This = impl_from_IExtensionServices(iface);
232 return IUnknown_Release(This->outer_unk);
235 static HRESULT ExtServ_ImplSetAdditionalHeaders(ExtensionService* This, LPCWSTR pwzAdditionalHeaders)
237 int len;
239 free(This->headers);
240 This->headers = NULL;
242 if (!pwzAdditionalHeaders)
243 return S_OK;
245 len = lstrlenW(pwzAdditionalHeaders);
247 if(len && pwzAdditionalHeaders[len-1] != '\n' && pwzAdditionalHeaders[len-1] != '\r') {
248 This->headers = malloc(len*sizeof(WCHAR) + sizeof(L"\r\n"));
249 memcpy(This->headers, pwzAdditionalHeaders, len*sizeof(WCHAR));
250 memcpy(This->headers+len, L"\r\n", sizeof(L"\r\n"));
251 }else {
252 This->headers = wcsdup(pwzAdditionalHeaders);
255 return S_OK;
258 static HRESULT WINAPI ExtServ_SetAdditionalHeaders(IExtensionServices* iface, LPCWSTR pwzAdditionalHeaders)
260 ExtensionService *This = impl_from_IExtensionServices(iface);
262 TRACE("(%p)->(%s)\n", This, debugstr_w(pwzAdditionalHeaders));
264 return ExtServ_ImplSetAdditionalHeaders(This,pwzAdditionalHeaders);
267 static HRESULT ExtServ_ImplSetAuthenticateData(ExtensionService* This, HWND phwnd, LPCWSTR pwzUsername, LPCWSTR pwzPassword)
269 free(This->username);
270 free(This->password);
272 This->hwnd = phwnd;
273 This->username = wcsdup(pwzUsername);
274 This->password = wcsdup(pwzPassword);
276 return S_OK;
279 static HRESULT WINAPI ExtServ_SetAuthenticateData(IExtensionServices* iface, HWND phwnd, LPCWSTR pwzUsername, LPCWSTR pwzPassword)
281 ExtensionService *This = impl_from_IExtensionServices(iface);
283 TRACE("(%p)->(%p %s %s)\n", This, phwnd, debugstr_w(pwzUsername), debugstr_w(pwzPassword));
285 return ExtServ_ImplSetAuthenticateData(This, phwnd, pwzUsername, pwzPassword);
288 static const IExtensionServicesVtbl ExtServVtbl = {
289 ExtServ_QueryInterface,
290 ExtServ_AddRef,
291 ExtServ_Release,
292 ExtServ_SetAdditionalHeaders,
293 ExtServ_SetAuthenticateData
296 /***********************************************************************
297 * HlinkCreateExtensionServices (HLINK.@)
299 HRESULT WINAPI HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders,
300 HWND phwnd, LPCWSTR pszUsername, LPCWSTR pszPassword,
301 IUnknown *punkOuter, REFIID riid, void** ppv)
303 ExtensionService *ret;
304 HRESULT hres = S_OK;
306 TRACE("%s %p %s %s %p %s %p\n",debugstr_w(pwzAdditionalHeaders),
307 phwnd, debugstr_w(pszUsername), debugstr_w(pszPassword),
308 punkOuter, debugstr_guid(riid), ppv);
310 if (!(ret = calloc(1, sizeof(*ret))))
311 return E_OUTOFMEMORY;
313 ret->IUnknown_inner.lpVtbl = &ExtServUnkVtbl;
314 ret->IAuthenticate_iface.lpVtbl = &AuthenticateVtbl;
315 ret->IHttpNegotiate_iface.lpVtbl = &HttpNegotiateVtbl;
316 ret->IExtensionServices_iface.lpVtbl = &ExtServVtbl;
317 ret->ref = 1;
319 ExtServ_ImplSetAuthenticateData(ret, phwnd, pszUsername, pszPassword);
320 ExtServ_ImplSetAdditionalHeaders(ret, pwzAdditionalHeaders);
322 if(!punkOuter) {
323 ret->outer_unk = &ret->IUnknown_inner;
324 hres = IUnknown_QueryInterface(&ret->IUnknown_inner, riid, ppv);
325 IUnknown_Release(&ret->IUnknown_inner);
326 }else if(IsEqualGUID(&IID_IUnknown, riid)) {
327 ret->outer_unk = punkOuter;
328 *ppv = &ret->IUnknown_inner;
329 }else {
330 IUnknown_Release(&ret->IUnknown_inner);
331 hres = E_INVALIDARG;
334 return hres;