blob: ed6269d3e97701b47be36c5a6fe52cd5248a43f2 [file] [log] [blame]
Jonathan Ernst360a3f92006-05-18 14:49:52 +02001/*
Noomen Hamza3fb3da21999-01-28 17:56:14 +00002 * BindCtx implementation
3 *
4 * Copyright 1999 Noomen Hamza
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
Jonathan Ernst360a3f92006-05-18 14:49:52 +020018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
Noomen Hamza3fb3da21999-01-28 17:56:14 +000020
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000021#include <stdarg.h>
Noomen Hamza3fb3da21999-01-28 17:56:14 +000022#include <string.h>
Francois Gouget486d0202004-10-07 03:06:48 +000023
24#define COBJMACROS
25
Noomen Hamza3fb3da21999-01-28 17:56:14 +000026#include "winerror.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000027#include "windef.h"
Alexandre Julliard74af67e2000-09-26 00:00:55 +000028#include "winbase.h"
Rob Shearmanbdefb462007-03-08 11:00:21 +000029#include "winnls.h"
Ove Kaaven1f5315c2002-12-05 20:33:07 +000030#include "objbase.h"
Rob Shearmanbdefb462007-03-08 11:00:21 +000031
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000032#include "wine/debug.h"
Noomen Hamza3fb3da21999-01-28 17:56:14 +000033
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000034WINE_DEFAULT_DEBUG_CHANNEL(ole);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000035
Rob Shearman2815cd82007-03-13 12:38:03 +000036#define BINDCTX_FIRST_TABLE_SIZE 4
Noomen Hamzaed494ec1999-03-23 13:48:56 +000037
38/* data structure of the BindCtx table elements */
39typedef struct BindCtxObject{
40
41 IUnknown* pObj; /* point on a bound object */
42
43 LPOLESTR pkeyObj; /* key associated to this bound object */
44
45 BYTE regType; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
46
47} BindCtxObject;
48
Austin English1b24da32008-04-09 14:33:37 -050049/* BindCtx data structure */
Noomen Hamza3fb3da21999-01-28 17:56:14 +000050typedef struct BindCtxImpl{
51
Michael Stefaniuce362c672010-12-08 22:59:43 +010052 IBindCtx IBindCtx_iface;
Vincent Béron9a624912002-05-31 23:06:46 +000053
Mike McCormackc7fdb452005-07-05 11:02:54 +000054 LONG ref; /* reference counter for this object */
Noomen Hamzaed494ec1999-03-23 13:48:56 +000055
Francois Gouget282f7272001-02-28 05:31:02 +000056 BindCtxObject* bindCtxTable; /* this is a table in which all bounded objects are stored*/
Noomen Hamzaed494ec1999-03-23 13:48:56 +000057 DWORD bindCtxTableLastIndex; /* first free index in the table */
58 DWORD bindCtxTableSize; /* size table */
59
Francois Gouget282f7272001-02-28 05:31:02 +000060 BIND_OPTS2 bindOption2; /* a structure which contains the bind options*/
Noomen Hamza3fb3da21999-01-28 17:56:14 +000061
62} BindCtxImpl;
63
Noomen Hamzaed494ec1999-03-23 13:48:56 +000064/* IBindCtx prototype functions : */
Mike McCormack1ff3bf82005-03-27 18:16:25 +000065static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx*);
66static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl*, IUnknown*, LPOLESTR, DWORD *);
Rob Shearman2815cd82007-03-13 12:38:03 +000067static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *);
Noomen Hamza3fb3da21999-01-28 17:56:14 +000068
Michael Stefaniuce362c672010-12-08 22:59:43 +010069static inline BindCtxImpl *impl_from_IBindCtx(IBindCtx *iface)
70{
71return CONTAINING_RECORD(iface, BindCtxImpl, IBindCtx_iface);
72}
73
Noomen Hamza3fb3da21999-01-28 17:56:14 +000074/*******************************************************************************
75 * BindCtx_QueryInterface
76 *******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +000077static HRESULT WINAPI
78BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
Francois Gougetb0c61291999-02-18 13:26:22 +000079{
Michael Stefaniuce362c672010-12-08 22:59:43 +010080 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamzaed494ec1999-03-23 13:48:56 +000081
Jacek Caban2c6cbea2007-12-30 17:44:32 +010082 TRACE("(%p %s %p)\n",This, debugstr_guid(riid), ppvObject);
Noomen Hamzaed494ec1999-03-23 13:48:56 +000083
Mike McCormack1ff3bf82005-03-27 18:16:25 +000084 /* Perform a sanity check on the parameters.*/
Jacek Caban2c6cbea2007-12-30 17:44:32 +010085 if (!ppvObject)
86 return E_POINTER;
Vincent Béron9a624912002-05-31 23:06:46 +000087
Mike McCormack1ff3bf82005-03-27 18:16:25 +000088 /* Initialize the return parameter.*/
89 *ppvObject = 0;
Noomen Hamza3fb3da21999-01-28 17:56:14 +000090
Mike McCormack1ff3bf82005-03-27 18:16:25 +000091 /* Compare the riid with the interface IDs implemented by this object.*/
92 if (IsEqualIID(&IID_IUnknown, riid) ||
93 IsEqualIID(&IID_IBindCtx, riid))
94 {
Michael Stefaniuc04497012009-02-11 10:48:38 +010095 *ppvObject = This;
Mike McCormack1ff3bf82005-03-27 18:16:25 +000096 IBindCtx_AddRef(iface);
97 return S_OK;
98 }
Noomen Hamza3fb3da21999-01-28 17:56:14 +000099
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000100 return E_NOINTERFACE;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000101}
102
103/******************************************************************************
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000104 * BindCtx_AddRef
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000105 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000106static ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface)
Francois Gougetb0c61291999-02-18 13:26:22 +0000107{
Michael Stefaniuce362c672010-12-08 22:59:43 +0100108 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000109
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000110 TRACE("(%p)\n",This);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000111
Joris Huizer34cffce2004-09-24 01:16:53 +0000112 return InterlockedIncrement(&This->ref);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000113}
114
115/******************************************************************************
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000116 * BindCtx_Destroy (local function)
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000117 *******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000118static HRESULT BindCtxImpl_Destroy(BindCtxImpl* This)
Francois Gougetb0c61291999-02-18 13:26:22 +0000119{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000120 TRACE("(%p)\n",This);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000121
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000122 /* free the table space memory */
123 HeapFree(GetProcessHeap(),0,This->bindCtxTable);
124
125 /* free the bindctx structure */
126 HeapFree(GetProcessHeap(),0,This);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000127
128 return S_OK;
129}
130
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000131/******************************************************************************
132 * BindCtx_Release
133 ******************************************************************************/
134static ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface)
135{
Michael Stefaniuce362c672010-12-08 22:59:43 +0100136 BindCtxImpl *This = impl_from_IBindCtx(iface);
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000137 ULONG ref;
138
139 TRACE("(%p)\n",This);
140
141 ref = InterlockedDecrement(&This->ref);
142 if (ref == 0)
143 {
144 /* release all registered objects */
Michael Stefaniuce362c672010-12-08 22:59:43 +0100145 BindCtxImpl_ReleaseBoundObjects(&This->IBindCtx_iface);
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000146
147 BindCtxImpl_Destroy(This);
148 }
149 return ref;
150}
151
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000152
153/******************************************************************************
154 * BindCtx_RegisterObjectBound
155 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000156static HRESULT WINAPI
157BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
Francois Gougetb0c61291999-02-18 13:26:22 +0000158{
Michael Stefaniuce362c672010-12-08 22:59:43 +0100159 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000160 DWORD lastIndex=This->bindCtxTableLastIndex;
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000161
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000162 TRACE("(%p,%p)\n",This,punk);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000163
164 if (punk==NULL)
Rob Shearmanc4727fd2007-03-09 09:48:26 +0000165 return S_OK;
Vincent Béron9a624912002-05-31 23:06:46 +0000166
Rob Shearman2815cd82007-03-13 12:38:03 +0000167 if (lastIndex == This->bindCtxTableSize)
168 {
169 HRESULT hr = BindCtxImpl_ExpandTable(This);
170 if (FAILED(hr))
171 return hr;
172 }
173
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000174 IUnknown_AddRef(punk);
Vincent Béron9a624912002-05-31 23:06:46 +0000175
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000176 /* put the object in the first free element in the table */
177 This->bindCtxTable[lastIndex].pObj = punk;
178 This->bindCtxTable[lastIndex].pkeyObj = NULL;
179 This->bindCtxTable[lastIndex].regType = 0;
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000180 lastIndex= ++This->bindCtxTableLastIndex;
181
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000182 return S_OK;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000183}
184
185/******************************************************************************
186 * BindCtx_RevokeObjectBound
187 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000188static HRESULT WINAPI
189BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
Francois Gougetb0c61291999-02-18 13:26:22 +0000190{
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000191 DWORD index,j;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000192
Michael Stefaniuce362c672010-12-08 22:59:43 +0100193 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000194
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000195 TRACE("(%p,%p)\n",This,punk);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000196
Rob Shearmanc4727fd2007-03-09 09:48:26 +0000197 if (!punk)
198 return E_INVALIDARG;
199
Francois Gougetf8e01ef2004-07-23 23:02:09 +0000200 /* check if the object was registered or not */
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000201 if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000202 return MK_E_NOTBOUND;
203
Alberto Massarifc47be52003-04-05 05:10:37 +0000204 if(This->bindCtxTable[index].pObj)
205 IUnknown_Release(This->bindCtxTable[index].pObj);
Michael Stefaniuc5ad7d852004-12-23 17:06:43 +0000206 HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
Alberto Massarifc47be52003-04-05 05:10:37 +0000207
Andreas Mohrf32f9182001-04-20 18:36:05 +0000208 /* left-shift all elements in the right side of the current revoked object */
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000209 for(j=index; j<This->bindCtxTableLastIndex-1; j++)
210 This->bindCtxTable[j]= This->bindCtxTable[j+1];
Vincent Béron9a624912002-05-31 23:06:46 +0000211
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000212 This->bindCtxTableLastIndex--;
213
214 return S_OK;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000215}
216
217/******************************************************************************
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000218 * BindCtx_ReleaseBoundObjects
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000219 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000220static HRESULT WINAPI
221BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface)
Francois Gougetb0c61291999-02-18 13:26:22 +0000222{
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000223 DWORD i;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000224
Michael Stefaniuce362c672010-12-08 22:59:43 +0100225 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000226
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000227 TRACE("(%p)\n",This);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000228
229 for(i=0;i<This->bindCtxTableLastIndex;i++)
Alberto Massarifc47be52003-04-05 05:10:37 +0000230 {
231 if(This->bindCtxTable[i].pObj)
232 IUnknown_Release(This->bindCtxTable[i].pObj);
Michael Stefaniuc15a308a2005-01-03 14:56:42 +0000233 HeapFree(GetProcessHeap(),0,This->bindCtxTable[i].pkeyObj);
Alberto Massarifc47be52003-04-05 05:10:37 +0000234 }
235
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000236 This->bindCtxTableLastIndex = 0;
237
238 return S_OK;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000239}
240
241/******************************************************************************
242 * BindCtx_SetBindOptions
243 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000244static HRESULT WINAPI
245BindCtxImpl_SetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
Francois Gougetb0c61291999-02-18 13:26:22 +0000246{
Michael Stefaniuce362c672010-12-08 22:59:43 +0100247 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000248
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000249 TRACE("(%p,%p)\n",This,pbindopts);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000250
251 if (pbindopts==NULL)
252 return E_POINTER;
Vincent Béron9a624912002-05-31 23:06:46 +0000253
Gerard Patelf44c1f71999-12-10 03:23:35 +0000254 if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
255 {
Francois Gougete76218d2001-05-09 17:31:31 +0000256 WARN("invalid size\n");
Gerard Patelf44c1f71999-12-10 03:23:35 +0000257 return E_INVALIDARG; /* FIXME : not verified */
258 }
259 memcpy(&This->bindOption2, pbindopts, pbindopts->cbStruct);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000260 return S_OK;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000261}
262
263/******************************************************************************
264 * BindCtx_GetBindOptions
265 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000266static HRESULT WINAPI
267BindCtxImpl_GetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
Francois Gougetb0c61291999-02-18 13:26:22 +0000268{
Michael Stefaniuce362c672010-12-08 22:59:43 +0100269 BindCtxImpl *This = impl_from_IBindCtx(iface);
Rob Shearmanba3ceaa2007-03-09 09:47:43 +0000270 ULONG cbStruct;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000271
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000272 TRACE("(%p,%p)\n",This,pbindopts);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000273
274 if (pbindopts==NULL)
275 return E_POINTER;
276
Rob Shearmanba3ceaa2007-03-09 09:47:43 +0000277 cbStruct = pbindopts->cbStruct;
278 if (cbStruct > sizeof(BIND_OPTS2))
279 cbStruct = sizeof(BIND_OPTS2);
Rob Shearmanbdefb462007-03-08 11:00:21 +0000280
Rob Shearmanba3ceaa2007-03-09 09:47:43 +0000281 memcpy(pbindopts, &This->bindOption2, cbStruct);
282 pbindopts->cbStruct = cbStruct;
283
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000284 return S_OK;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000285}
286
287/******************************************************************************
288 * BindCtx_GetRunningObjectTable
289 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000290static HRESULT WINAPI
291BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot)
Francois Gougetb0c61291999-02-18 13:26:22 +0000292{
Michael Stefaniuce362c672010-12-08 22:59:43 +0100293 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000294
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000295 TRACE("(%p,%p)\n",This,pprot);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000296
297 if (pprot==NULL)
298 return E_POINTER;
Vincent Béron9a624912002-05-31 23:06:46 +0000299
Nikolay Sivov51854092010-07-21 14:03:35 +0400300 return GetRunningObjectTable(0, pprot);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000301}
302
303/******************************************************************************
304 * BindCtx_RegisterObjectParam
305 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000306static HRESULT WINAPI
307BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
Francois Gougetb0c61291999-02-18 13:26:22 +0000308{
Alberto Massaribb7e49a2003-01-02 17:51:34 +0000309 DWORD index=0;
Michael Stefaniuce362c672010-12-08 22:59:43 +0100310 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000311
Alberto Massaribb7e49a2003-01-02 17:51:34 +0000312 TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000313
314 if (punk==NULL)
315 return E_INVALIDARG;
Vincent Béron9a624912002-05-31 23:06:46 +0000316
Alberto Massaribb7e49a2003-01-02 17:51:34 +0000317 if (pszkey!=NULL && BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_OK)
318 {
319 TRACE("Overwriting existing key\n");
320 if(This->bindCtxTable[index].pObj!=NULL)
321 IUnknown_Release(This->bindCtxTable[index].pObj);
322 This->bindCtxTable[index].pObj=punk;
Rolf Kalbermatter919bd782003-08-29 22:10:01 +0000323 IUnknown_AddRef(punk);
Alberto Massaribb7e49a2003-01-02 17:51:34 +0000324 return S_OK;
325 }
Rob Shearman2815cd82007-03-13 12:38:03 +0000326
327 if (This->bindCtxTableLastIndex == This->bindCtxTableSize)
328 {
329 HRESULT hr = BindCtxImpl_ExpandTable(This);
330 if (FAILED(hr))
331 return hr;
332 }
333
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000334 This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
335 This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
336
337 if (pszkey==NULL)
338
339 This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=NULL;
340
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000341 else
342 {
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000343
344 This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=
345 HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR)*(1+lstrlenW(pszkey))));
346
347 if (This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj==NULL)
348 return E_OUTOFMEMORY;
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000349 lstrcpyW(This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj,pszkey);
Patrik Stridvall3c0211f2001-09-11 00:32:32 +0000350 }
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000351
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000352 This->bindCtxTableLastIndex++;
Vincent Béron9a624912002-05-31 23:06:46 +0000353
Rolf Kalbermatter919bd782003-08-29 22:10:01 +0000354 IUnknown_AddRef(punk);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000355 return S_OK;
356}
Rolf Kalbermatter919bd782003-08-29 22:10:01 +0000357
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000358/******************************************************************************
359 * BindCtx_GetObjectParam
360 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000361static HRESULT WINAPI
362BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk)
Francois Gougetb0c61291999-02-18 13:26:22 +0000363{
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000364 DWORD index;
Michael Stefaniuce362c672010-12-08 22:59:43 +0100365 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000366
Alberto Massaribb7e49a2003-01-02 17:51:34 +0000367 TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000368
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000369 if (punk==NULL)
370 return E_POINTER;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000371
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000372 *punk=0;
Vincent Béron9a624912002-05-31 23:06:46 +0000373
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000374 if (BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_FALSE)
375 return E_FAIL;
376
377 IUnknown_AddRef(This->bindCtxTable[index].pObj);
Vincent Béron9a624912002-05-31 23:06:46 +0000378
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000379 *punk = This->bindCtxTable[index].pObj;
380
381 return S_OK;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000382}
383
384/******************************************************************************
385 * BindCtx_RevokeObjectParam
386 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000387static HRESULT WINAPI
388BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
Francois Gougetb0c61291999-02-18 13:26:22 +0000389{
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000390 DWORD index,j;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000391
Michael Stefaniuce362c672010-12-08 22:59:43 +0100392 BindCtxImpl *This = impl_from_IBindCtx(iface);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000393
Alberto Massaribb7e49a2003-01-02 17:51:34 +0000394 TRACE("(%p,%s)\n",This,debugstr_w(ppenum));
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000395
396 if (BindCtxImpl_GetObjectIndex(This,NULL,ppenum,&index)==S_FALSE)
397 return E_FAIL;
398
399 /* release the object if it's found */
Alberto Massarifc47be52003-04-05 05:10:37 +0000400 if(This->bindCtxTable[index].pObj)
401 IUnknown_Release(This->bindCtxTable[index].pObj);
Michael Stefaniuc5ad7d852004-12-23 17:06:43 +0000402 HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
Alberto Massarifc47be52003-04-05 05:10:37 +0000403
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000404 /* remove the object from the table with a left-shifting of all objects in the right side */
405 for(j=index; j<This->bindCtxTableLastIndex-1; j++)
406 This->bindCtxTable[j]= This->bindCtxTable[j+1];
Vincent Béron9a624912002-05-31 23:06:46 +0000407
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000408 This->bindCtxTableLastIndex--;
409
410 return S_OK;
411}
412
413/******************************************************************************
414 * BindCtx_EnumObjectParam
415 ******************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000416static HRESULT WINAPI
417BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000418{
Rob Shearman3d6070a2007-03-08 11:01:06 +0000419 TRACE("(%p,%p)\n",iface,pszkey);
420
421 *pszkey = NULL;
422
423 /* not implemented in native either */
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000424 return E_NOTIMPL;
425}
426
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000427/********************************************************************************
428 * GetObjectIndex (local function)
429 ********************************************************************************/
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000430static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000431 IUnknown* punk,
432 LPOLESTR pszkey,
433 DWORD *index)
434{
435
436 DWORD i;
437 BYTE found=0;
Vincent Béron9a624912002-05-31 23:06:46 +0000438
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000439 TRACE("(%p,%p,%p,%p)\n",This,punk,pszkey,index);
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000440
441 if (punk==NULL)
442 /* search object identified by a register key */
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000443 for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
444 {
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000445 if(This->bindCtxTable[i].regType==1){
446
447 if ( ( (This->bindCtxTable[i].pkeyObj==NULL) && (pszkey==NULL) ) ||
448 ( (This->bindCtxTable[i].pkeyObj!=NULL) &&
449 (pszkey!=NULL) &&
450 (lstrcmpW(This->bindCtxTable[i].pkeyObj,pszkey)==0)
451 )
452 )
453
454 found=1;
455 }
456 }
457 else
458 /* search object identified by a moniker*/
459 for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
460 if(This->bindCtxTable[i].pObj==punk)
461 found=1;
462
463 if (index != NULL)
464 *index=i-1;
465
466 if (found)
467 return S_OK;
Alberto Massaribb7e49a2003-01-02 17:51:34 +0000468 TRACE("key not found\n");
469 return S_FALSE;
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000470}
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000471
Rob Shearman2815cd82007-03-13 12:38:03 +0000472static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *This)
473{
474 if (!This->bindCtxTableSize)
475 {
476 This->bindCtxTableSize = BINDCTX_FIRST_TABLE_SIZE;
477 This->bindCtxTable = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
478 This->bindCtxTableSize * sizeof(BindCtxObject));
479 }
480 else
481 {
482 This->bindCtxTableSize *= 2;
483
484 This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
485 This->bindCtxTableSize * sizeof(BindCtxObject));
486 }
487
488 if (!This->bindCtxTable)
489 return E_OUTOFMEMORY;
490
491 return S_OK;
492}
493
494
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000495/* Virtual function table for the BindCtx class. */
Dmitry Timoshkoveba47f12005-06-06 19:50:35 +0000496static const IBindCtxVtbl VT_BindCtxImpl =
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000497{
498 BindCtxImpl_QueryInterface,
499 BindCtxImpl_AddRef,
500 BindCtxImpl_Release,
501 BindCtxImpl_RegisterObjectBound,
502 BindCtxImpl_RevokeObjectBound,
503 BindCtxImpl_ReleaseBoundObjects,
504 BindCtxImpl_SetBindOptions,
505 BindCtxImpl_GetBindOptions,
506 BindCtxImpl_GetRunningObjectTable,
507 BindCtxImpl_RegisterObjectParam,
508 BindCtxImpl_GetObjectParam,
509 BindCtxImpl_EnumObjectParam,
510 BindCtxImpl_RevokeObjectParam
511};
512
513/******************************************************************************
514 * BindCtx_Construct (local function)
515 *******************************************************************************/
516static HRESULT BindCtxImpl_Construct(BindCtxImpl* This)
517{
518 TRACE("(%p)\n",This);
519
520 /* Initialize the virtual function table.*/
Michael Stefaniuce362c672010-12-08 22:59:43 +0100521 This->IBindCtx_iface.lpVtbl = &VT_BindCtxImpl;
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000522 This->ref = 0;
523
524 /* Initialize the BIND_OPTS2 structure */
525 This->bindOption2.cbStruct = sizeof(BIND_OPTS2);
526 This->bindOption2.grfFlags = 0;
527 This->bindOption2.grfMode = STGM_READWRITE;
528 This->bindOption2.dwTickCountDeadline = 0;
529
530 This->bindOption2.dwTrackFlags = 0;
531 This->bindOption2.dwClassContext = CLSCTX_SERVER;
Rob Shearmanbdefb462007-03-08 11:00:21 +0000532 This->bindOption2.locale = GetThreadLocale();
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000533 This->bindOption2.pServerInfo = 0;
534
535 /* Initialize the bindctx table */
Rob Shearman2815cd82007-03-13 12:38:03 +0000536 This->bindCtxTableSize=0;
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000537 This->bindCtxTableLastIndex=0;
Rob Shearman2815cd82007-03-13 12:38:03 +0000538 This->bindCtxTable = NULL;
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000539
540 return S_OK;
541}
542
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000543/******************************************************************************
Dave Miller47fb9382003-09-11 03:06:25 +0000544 * CreateBindCtx (OLE32.@)
Rob Shearmancdc93672007-03-26 18:23:51 +0100545 *
546 * Creates a bind context. A bind context encompasses information and options
547 * used when binding to a moniker.
548 *
549 * PARAMS
550 * reserved [I] Reserved. Set to 0.
551 * ppbc [O] Address that receives the bind context object.
552 *
553 * RETURNS
554 * Success: S_OK.
555 * Failure: Any HRESULT code.
556 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000557HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
Francois Gougetb0c61291999-02-18 13:26:22 +0000558{
Nikolay Sivov51854092010-07-21 14:03:35 +0400559 BindCtxImpl* newBindCtx;
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000560 HRESULT hr;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000561
Michael Stefaniuc21ff87b2006-10-15 12:28:08 +0200562 TRACE("(%d,%p)\n",reserved,ppbc);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000563
Rob Shearmane14e4642007-03-09 09:46:58 +0000564 if (!ppbc) return E_INVALIDARG;
565
Rob Shearmanbf4b5182007-03-08 10:59:38 +0000566 *ppbc = NULL;
567
568 if (reserved != 0)
569 {
570 ERR("reserved should be 0, not 0x%x\n", reserved);
571 return E_INVALIDARG;
572 }
573
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000574 newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000575 if (newBindCtx == 0)
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000576 return E_OUTOFMEMORY;
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000577
578 hr = BindCtxImpl_Construct(newBindCtx);
Mike McCormack1ff3bf82005-03-27 18:16:25 +0000579 if (FAILED(hr))
580 {
Noomen Hamzaed494ec1999-03-23 13:48:56 +0000581 HeapFree(GetProcessHeap(),0,newBindCtx);
582 return hr;
583 }
584
Michael Stefaniuce362c672010-12-08 22:59:43 +0100585 return BindCtxImpl_QueryInterface(&newBindCtx->IBindCtx_iface,&IID_IBindCtx,(void**)ppbc);
Noomen Hamza3fb3da21999-01-28 17:56:14 +0000586}
Robert Shearman26781ac2002-12-12 02:17:39 +0000587
Rob Shearmancdc93672007-03-26 18:23:51 +0100588/******************************************************************************
589 * BindMoniker [OLE32.@]
590 *
591 * Binds to a moniker.
592 *
593 * PARAMS
594 * pmk [I] Moniker to bind to.
595 * grfOpt [I] Reserved option flags. Set to 0.
596 * riid [I] ID of the interface to bind to.
597 * pvResult [O] Address that receives the interface of the object that was bound to.
598 *
599 * RETURNS
600 * Success: S_OK.
601 * Failure: Any HRESULT code.
602 */
Robert Shearman26781ac2002-12-12 02:17:39 +0000603HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID riid, LPVOID * ppvResult)
604{
605 HRESULT res;
606 IBindCtx * pbc;
607
Michael Stefaniuc21ff87b2006-10-15 12:28:08 +0200608 TRACE("(%p, %x, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult);
Robert Shearman26781ac2002-12-12 02:17:39 +0000609
610 res = CreateBindCtx(grfOpt, &pbc);
611 if (SUCCEEDED(res))
Rob Shearman14f7a592008-02-13 12:34:44 +0000612 {
Robert Shearman26781ac2002-12-12 02:17:39 +0000613 res = IMoniker_BindToObject(pmk, pbc, NULL, riid, ppvResult);
Rob Shearman14f7a592008-02-13 12:34:44 +0000614 IBindCtx_Release(pbc);
615 }
Robert Shearman26781ac2002-12-12 02:17:39 +0000616 return res;
617}