comctl32: We can now store binary files in the repository.
[wine] / dlls / urlmon / bindctx.c
1 /*
2  * Copyright 2007 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include <stdarg.h>
20 #include <stdio.h>
21
22 #define COBJMACROS
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "objbase.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "urlmon.h"
32 #include "urlmon_main.h"
33
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
38
39 typedef struct {
40     const IBindCtxVtbl *lpBindCtxVtbl;
41
42     LONG ref;
43
44     IBindCtx *bindctx;
45 } AsyncBindCtx;
46
47 #define BINDCTX(x)  ((IBindCtx*)  &(x)->lpBindCtxVtbl)
48
49 #define BINDCTX_THIS(iface) DEFINE_THIS(AsyncBindCtx, BindCtx, iface)
50
51 static HRESULT WINAPI AsyncBindCtx_QueryInterface(IBindCtx *iface, REFIID riid, void **ppv)
52 {
53     AsyncBindCtx *This = BINDCTX_THIS(iface);
54
55     *ppv = NULL;
56
57     if(IsEqualGUID(riid, &IID_IUnknown)) {
58         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
59         *ppv = BINDCTX(This);
60     }else if(IsEqualGUID(riid, &IID_IBindCtx)) {
61         TRACE("(%p)->(IID_IBindCtx %p)\n", This, ppv);
62         *ppv = BINDCTX(This);
63     }else if(IsEqualGUID(riid, &IID_IAsyncBindCtx)) {
64         TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This, ppv);
65         *ppv = BINDCTX(This);
66     }
67
68     if(*ppv) {
69         IUnknown_AddRef((IUnknown*)*ppv);
70         return S_OK;
71     }
72
73     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
74     return E_NOINTERFACE;
75 }
76
77 static ULONG WINAPI AsyncBindCtx_AddRef(IBindCtx *iface)
78 {
79     AsyncBindCtx *This = BINDCTX_THIS(iface);
80     LONG ref = InterlockedIncrement(&This->ref);
81
82     TRACE("(%p) ref=%d\n", This, ref);
83
84     return ref;
85 }
86
87 static ULONG WINAPI AsyncBindCtx_Release(IBindCtx *iface)
88 {
89     AsyncBindCtx *This = BINDCTX_THIS(iface);
90     LONG ref = InterlockedDecrement(&This->ref);
91
92     TRACE("(%p) ref=%d\n", This, ref);
93
94     if(!ref) {
95         IBindCtx_Release(This->bindctx);
96         HeapFree(GetProcessHeap(), 0, This);
97     }
98
99     return ref;
100 }
101
102 static HRESULT WINAPI AsyncBindCtx_RegisterObjectBound(IBindCtx *iface, IUnknown *punk)
103 {
104     AsyncBindCtx *This = BINDCTX_THIS(iface);
105
106     TRACE("(%p)->(%p)\n", This, punk);
107
108     return IBindCtx_RegisterObjectBound(This->bindctx, punk);
109 }
110
111 static HRESULT WINAPI AsyncBindCtx_RevokeObjectBound(IBindCtx *iface, IUnknown *punk)
112 {
113     AsyncBindCtx *This = BINDCTX_THIS(iface);
114
115     TRACE("(%p %p)\n", This, punk);
116
117     return IBindCtx_RevokeObjectBound(This->bindctx, punk);
118 }
119
120 static HRESULT WINAPI AsyncBindCtx_ReleaseBoundObjects(IBindCtx *iface)
121 {
122     AsyncBindCtx *This = BINDCTX_THIS(iface);
123
124     TRACE("(%p)\n", This);
125
126     return IBindCtx_ReleaseBoundObjects(This->bindctx);
127 }
128
129 static HRESULT WINAPI AsyncBindCtx_SetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
130 {
131     AsyncBindCtx *This = BINDCTX_THIS(iface);
132
133     TRACE("(%p)->(%p)\n", This, pbindopts);
134
135     return IBindCtx_SetBindOptions(This->bindctx, pbindopts);
136 }
137
138 static HRESULT WINAPI AsyncBindCtx_GetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
139 {
140     AsyncBindCtx *This = BINDCTX_THIS(iface);
141
142     TRACE("(%p)->(%p)\n", This, pbindopts);
143
144     return IBindCtx_GetBindOptions(This->bindctx, pbindopts);
145 }
146
147 static HRESULT WINAPI AsyncBindCtx_GetRunningObjectTable(IBindCtx *iface, IRunningObjectTable **pprot)
148 {
149     AsyncBindCtx *This = BINDCTX_THIS(iface);
150
151     TRACE("(%p)->(%p)\n", This, pprot);
152
153     return IBindCtx_GetRunningObjectTable(This->bindctx, pprot);
154 }
155
156 static HRESULT WINAPI AsyncBindCtx_RegisterObjectParam(IBindCtx *iface, LPOLESTR pszkey, IUnknown *punk)
157 {
158     AsyncBindCtx *This = BINDCTX_THIS(iface);
159
160     TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
161
162     return IBindCtx_RegisterObjectParam(This->bindctx, pszkey, punk);
163 }
164
165 static HRESULT WINAPI AsyncBindCtx_GetObjectParam(IBindCtx* iface, LPOLESTR pszkey, IUnknown **punk)
166 {
167     AsyncBindCtx *This = BINDCTX_THIS(iface);
168
169     TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
170
171     return IBindCtx_GetObjectParam(This->bindctx, pszkey, punk);
172 }
173
174 static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR ppenum)
175 {
176     AsyncBindCtx *This = BINDCTX_THIS(iface);
177
178     TRACE("(%p)->(%p)\n", This, ppenum);
179
180     return IBindCtx_RevokeObjectParam(This->bindctx, ppenum);
181 }
182
183 static HRESULT WINAPI AsyncBindCtx_EnumObjectParam(IBindCtx *iface, IEnumString **pszkey)
184 {
185     AsyncBindCtx *This = BINDCTX_THIS(iface);
186
187     TRACE("(%p)->(%p)\n", This, pszkey);
188
189     return IBindCtx_EnumObjectParam(This->bindctx, pszkey);
190 }
191
192 #undef BINDCTX_THIS
193
194 static const IBindCtxVtbl AsyncBindCtxVtbl =
195 {
196     AsyncBindCtx_QueryInterface,
197     AsyncBindCtx_AddRef,
198     AsyncBindCtx_Release,
199     AsyncBindCtx_RegisterObjectBound,
200     AsyncBindCtx_RevokeObjectBound,
201     AsyncBindCtx_ReleaseBoundObjects,
202     AsyncBindCtx_SetBindOptions,
203     AsyncBindCtx_GetBindOptions,
204     AsyncBindCtx_GetRunningObjectTable,
205     AsyncBindCtx_RegisterObjectParam,
206     AsyncBindCtx_GetObjectParam,
207     AsyncBindCtx_EnumObjectParam,
208     AsyncBindCtx_RevokeObjectParam
209 };
210
211 static HRESULT init_bindctx(IBindCtx *bindctx, DWORD options,
212        IBindStatusCallback *callback, IEnumFORMATETC *format)
213 {
214     BIND_OPTS bindopts;
215     HRESULT hres;
216
217     if(options)
218         FIXME("not supported options %08x\n", options);
219     if(format)
220         FIXME("format is not supported\n");
221
222     bindopts.cbStruct = sizeof(BIND_OPTS);
223     bindopts.grfFlags = BIND_MAYBOTHERUSER;
224     bindopts.grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
225     bindopts.dwTickCountDeadline = 0;
226
227     hres = IBindCtx_SetBindOptions(bindctx, &bindopts);
228     if(FAILED(hres))
229        return hres;
230
231     if(callback) {
232         hres = RegisterBindStatusCallback(bindctx, callback, NULL, 0);
233         if(FAILED(hres))
234             return hres;
235     }
236
237     return S_OK;
238 }
239
240 /***********************************************************************
241  *           CreateAsyncBindCtx (urlmon.@)
242  */
243 HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback,
244         IEnumFORMATETC *format, IBindCtx **pbind)
245 {
246     IBindCtx *bindctx;
247     HRESULT hres;
248
249     TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind);
250
251     if(!pbind || !callback)
252         return E_INVALIDARG;
253
254     hres = CreateBindCtx(0, &bindctx);
255     if(FAILED(hres))
256         return hres;
257
258     hres = init_bindctx(bindctx, 0, callback, format);
259     if(FAILED(hres)) {
260         IBindCtx_Release(bindctx);
261         return hres;
262     }
263
264     *pbind = bindctx;
265     return S_OK;
266 }
267
268 /***********************************************************************
269  *           CreateAsyncBindCtxEx (urlmon.@)
270  *
271  * Create an asynchronous bind context.
272  */
273 HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
274         IBindStatusCallback *callback, IEnumFORMATETC *format, IBindCtx** pbind,
275         DWORD reserved)
276 {
277     AsyncBindCtx *ret;
278     IBindCtx *bindctx;
279     HRESULT hres;
280
281     TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved);
282
283     if(!pbind)
284         return E_INVALIDARG;
285
286     if(reserved)
287         WARN("reserved=%d\n", reserved);
288
289     hres = CreateBindCtx(0, &bindctx);
290     if(FAILED(hres))
291         return hres;
292
293     ret = HeapAlloc(GetProcessHeap(), 0, sizeof(AsyncBindCtx));
294
295     ret->lpBindCtxVtbl = &AsyncBindCtxVtbl;
296     ret->ref = 1;
297     ret->bindctx = bindctx;
298
299     hres = init_bindctx(BINDCTX(ret), options, callback, format);
300     if(FAILED(hres)) {
301         IBindCtx_Release(BINDCTX(ret));
302         return hres;
303     }
304
305     *pbind = BINDCTX(ret);
306     return S_OK;
307 }