1 /***************************************************************************************
2 * BindCtx implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
10 #include "wine/obj_moniker.h"
14 DEFAULT_DEBUG_CHANNEL(ole
)
16 /* represent the first size table and it's increment block size */
17 #define BLOCK_TAB_SIZE 10
18 #define MAX_TAB_SIZE 0xFFFFFFFF
20 /* data structure of the BindCtx table elements */
21 typedef struct BindCtxObject
{
23 IUnknown
* pObj
; /* point on a bound object */
25 LPOLESTR pkeyObj
; /* key associated to this bound object */
27 BYTE regType
; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
31 /* BindCtx data strucrture */
32 typedef struct BindCtxImpl
{
34 ICOM_VTABLE(IBindCtx
)* lpvtbl
; /* VTable relative to the IBindCtx interface.*/
36 ULONG ref
; /* reference counter for this object */
38 BindCtxObject
* bindCtxTable
; /* this is a table in witch all bounded objects are stored*/
39 DWORD bindCtxTableLastIndex
; /* first free index in the table */
40 DWORD bindCtxTableSize
; /* size table */
42 BIND_OPTS2 bindOption2
; /* a structure witch contains the bind options*/
46 /* IBindCtx prototype functions : */
48 /* IUnknown functions*/
49 static HRESULT WINAPI
BindCtxImpl_QueryInterface(IBindCtx
* iface
,REFIID riid
,void** ppvObject
);
50 static ULONG WINAPI
BindCtxImpl_AddRef(IBindCtx
* iface
);
51 static ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
);
52 /* IBindCtx functions */
53 static HRESULT WINAPI
BindCtxImpl_RegisterObjectBound(IBindCtx
* iface
,IUnknown
* punk
);
54 static HRESULT WINAPI
BindCtxImpl_RevokeObjectBound(IBindCtx
* iface
, IUnknown
* punk
);
55 static HRESULT WINAPI
BindCtxImpl_ReleaseBoundObjects(IBindCtx
* iface
);
56 static HRESULT WINAPI
BindCtxImpl_SetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
);
57 static HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
);
58 static HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
);
59 static HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
);
60 static HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
);
61 static HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** ppenum
);
62 static HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
);
64 HRESULT WINAPI
BindCtxImpl_Construct(BindCtxImpl
* This
);
65 HRESULT WINAPI
BindCtxImpl_Destroy(BindCtxImpl
* This
);
66 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,IUnknown
* punk
,LPOLESTR pszkey
,DWORD
*index
);
68 /* Virtual function table for the BindCtx class. */
69 static ICOM_VTABLE(IBindCtx
) VT_BindCtxImpl
=
71 BindCtxImpl_QueryInterface
,
74 BindCtxImpl_RegisterObjectBound
,
75 BindCtxImpl_RevokeObjectBound
,
76 BindCtxImpl_ReleaseBoundObjects
,
77 BindCtxImpl_SetBindOptions
,
78 BindCtxImpl_GetBindOptions
,
79 BindCtxImpl_GetRunningObjectTable
,
80 BindCtxImpl_RegisterObjectParam
,
81 BindCtxImpl_GetObjectParam
,
82 BindCtxImpl_EnumObjectParam
,
83 BindCtxImpl_RevokeObjectParam
86 /*******************************************************************************
87 * BindCtx_QueryInterface
88 *******************************************************************************/
89 HRESULT WINAPI
BindCtxImpl_QueryInterface(IBindCtx
* iface
,REFIID riid
,void** ppvObject
)
91 ICOM_THIS(BindCtxImpl
,iface
);
93 TRACE(ole
,"(%p,%p,%p)\n",This
,riid
,ppvObject
);
95 /* Perform a sanity check on the parameters.*/
96 if ( (This
==0) || (ppvObject
==0) )
99 /* Initialize the return parameter.*/
102 /* Compare the riid with the interface IDs implemented by this object.*/
103 if (IsEqualIID(&IID_IUnknown
, riid
))
104 *ppvObject
= (IBindCtx
*)This
;
106 if (IsEqualIID(&IID_IBindCtx
, riid
))
107 *ppvObject
= (IBindCtx
*)This
;
109 /* Check that we obtained an interface.*/
111 return E_NOINTERFACE
;
113 /* Query Interface always increases the reference count by one when it is successful */
114 BindCtxImpl_AddRef(iface
);
119 /******************************************************************************
121 ******************************************************************************/
122 ULONG WINAPI
BindCtxImpl_AddRef(IBindCtx
* iface
)
124 ICOM_THIS(BindCtxImpl
,iface
);
126 TRACE(ole
,"(%p)\n",This
);
128 return ++(This
->ref
);
131 /******************************************************************************
133 ******************************************************************************/
134 ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
)
136 ICOM_THIS(BindCtxImpl
,iface
);
138 TRACE(ole
,"(%p)\n",This
);
144 /* release all registred objects */
145 BindCtxImpl_ReleaseBoundObjects((IBindCtx
*)This
);
147 BindCtxImpl_Destroy(This
);
155 /******************************************************************************
156 * BindCtx_Construct (local function)
157 *******************************************************************************/
158 HRESULT WINAPI
BindCtxImpl_Construct(BindCtxImpl
* This
)
160 TRACE(ole
,"(%p)\n",This
);
162 /* Initialize the virtual function table.*/
163 This
->lpvtbl
= &VT_BindCtxImpl
;
166 /* Initialize the BIND_OPTS2 structure */
167 This
->bindOption2
.cbStruct
= sizeof(BIND_OPTS2
);
168 This
->bindOption2
.grfFlags
= 0;
169 This
->bindOption2
.grfMode
= STGM_READWRITE
;
170 This
->bindOption2
.dwTickCountDeadline
= 0;
172 This
->bindOption2
.dwTrackFlags
= 0;
173 This
->bindOption2
.dwClassContext
= CLSCTX_SERVER
;
174 This
->bindOption2
.locale
= 1033;
175 This
->bindOption2
.pServerInfo
= 0;
177 /* Initialize the bindctx table */
178 This
->bindCtxTableSize
=BLOCK_TAB_SIZE
;
179 This
->bindCtxTableLastIndex
=0;
180 This
->bindCtxTable
= HeapAlloc(GetProcessHeap(), 0,This
->bindCtxTableSize
*sizeof(BindCtxObject
));
182 if (This
->bindCtxTable
==NULL
)
183 return E_OUTOFMEMORY
;
188 /******************************************************************************
189 * BindCtx_Destroy (local function)
190 *******************************************************************************/
191 HRESULT WINAPI
BindCtxImpl_Destroy(BindCtxImpl
* This
)
193 TRACE(ole
,"(%p)\n",This
);
195 /* free the table space memory */
196 HeapFree(GetProcessHeap(),0,This
->bindCtxTable
);
198 /* free the bindctx structure */
199 HeapFree(GetProcessHeap(),0,This
);
205 /******************************************************************************
206 * BindCtx_RegisterObjectBound
207 ******************************************************************************/
208 HRESULT WINAPI
BindCtxImpl_RegisterObjectBound(IBindCtx
* iface
,IUnknown
* punk
)
211 ICOM_THIS(BindCtxImpl
,iface
);
212 DWORD lastIndex
=This
->bindCtxTableLastIndex
;
215 TRACE(ole
,"(%p,%p)\n",This
,punk
);
220 IUnknown_AddRef(punk
);
222 /* put the object in the first free element in the table */
223 This
->bindCtxTable
[lastIndex
].pObj
= punk
;
224 This
->bindCtxTable
[lastIndex
].pkeyObj
= NULL
;
225 This
->bindCtxTable
[lastIndex
].regType
= 0;
226 cell
=This
->bindCtxTable
[lastIndex
];
227 lastIndex
= ++This
->bindCtxTableLastIndex
;
229 if (lastIndex
== This
->bindCtxTableSize
){ /* the table is full so it must be resized */
231 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
232 FIXME(ole
,"This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
236 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
238 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
239 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
240 if (!This
->bindCtxTable
)
241 return E_OUTOFMEMORY
;
246 /******************************************************************************
247 * BindCtx_RevokeObjectBound
248 ******************************************************************************/
249 HRESULT WINAPI
BindCtxImpl_RevokeObjectBound(IBindCtx
* iface
, IUnknown
* punk
)
253 ICOM_THIS(BindCtxImpl
,iface
);
255 TRACE(ole
,"(%p,%p)\n",This
,punk
);
257 /* check if the object was registred or not */
258 if (BindCtxImpl_GetObjectIndex(This
,punk
,NULL
,&index
)==S_FALSE
)
260 return MK_E_NOTBOUND
;
262 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
264 /* left-shift all elements in the rigth side of the curent revoked object */
265 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
266 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
268 This
->bindCtxTableLastIndex
--;
273 /******************************************************************************
274 * BindCtx_ReleaseBoundObjects
275 ******************************************************************************/
276 HRESULT WINAPI
BindCtxImpl_ReleaseBoundObjects(IBindCtx
* iface
)
280 ICOM_THIS(BindCtxImpl
,iface
);
282 TRACE(ole
,"(%p)\n",This
);
284 for(i
=0;i
<This
->bindCtxTableLastIndex
;i
++)
285 IUnknown_Release(This
->bindCtxTable
[i
].pObj
);
287 This
->bindCtxTableLastIndex
= 0;
292 /******************************************************************************
293 * BindCtx_SetBindOptions
294 ******************************************************************************/
295 HRESULT WINAPI
BindCtxImpl_SetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
297 ICOM_THIS(BindCtxImpl
,iface
);
299 TRACE(ole
,"(%p,%p)\n",This
,pbindopts
);
304 This
->bindOption2
=*pbindopts
;
309 /******************************************************************************
310 * BindCtx_GetBindOptions
311 ******************************************************************************/
312 HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
314 ICOM_THIS(BindCtxImpl
,iface
);
316 TRACE(ole
,"(%p,%p)\n",This
,pbindopts
);
321 *pbindopts
=This
->bindOption2
;
326 /******************************************************************************
327 * BindCtx_GetRunningObjectTable
328 ******************************************************************************/
329 HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
)
333 ICOM_THIS(BindCtxImpl
,iface
);
335 TRACE(ole
,"(%p,%p)\n",This
,pprot
);
340 res
=GetRunningObjectTable(0,(LPVOID
*)pprot
);
345 /******************************************************************************
346 * BindCtx_RegisterObjectParam
347 ******************************************************************************/
348 HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
)
350 ICOM_THIS(BindCtxImpl
,iface
);
352 TRACE(ole
,"(%p,%p,%p)\n",This
,pszkey
,punk
);
357 IUnknown_AddRef(punk
);
359 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pObj
= punk
;
360 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].regType
= 1;
364 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=NULL
;
368 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=
369 HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR
)*(1+lstrlenW(pszkey
))));
371 if (This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
==NULL
)
372 return E_OUTOFMEMORY
;
373 lstrcpyW(This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
,pszkey
);
376 This
->bindCtxTableLastIndex
++;
378 if (This
->bindCtxTableLastIndex
== This
->bindCtxTableSize
){ /* table is full ! must be resized */
380 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
382 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
383 FIXME(ole
,"This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
386 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
387 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
388 if (!This
->bindCtxTable
)
389 return E_OUTOFMEMORY
;
393 /******************************************************************************
394 * BindCtx_GetObjectParam
395 ******************************************************************************/
396 HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
)
399 ICOM_THIS(BindCtxImpl
,iface
);
401 TRACE(ole
,"(%p,%p,%p)\n",This
,pszkey
,punk
);
408 if (BindCtxImpl_GetObjectIndex(This
,NULL
,pszkey
,&index
)==S_FALSE
)
411 IUnknown_AddRef(This
->bindCtxTable
[index
].pObj
);
413 *punk
= This
->bindCtxTable
[index
].pObj
;
418 /******************************************************************************
419 * BindCtx_RevokeObjectParam
420 ******************************************************************************/
421 HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR ppenum
)
425 ICOM_THIS(BindCtxImpl
,iface
);
427 TRACE(ole
,"(%p,%p)\n",This
,ppenum
);
429 if (BindCtxImpl_GetObjectIndex(This
,NULL
,ppenum
,&index
)==S_FALSE
)
432 /* release the object if it's found */
433 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
435 /* remove the object from the table with a left-shifting of all objects in the right side */
436 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
437 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
439 This
->bindCtxTableLastIndex
--;
444 /******************************************************************************
445 * BindCtx_EnumObjectParam
446 ******************************************************************************/
447 HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** pszkey
)
449 FIXME(ole
,"(%p,%p),stub!\n",iface
,pszkey
);
453 /********************************************************************************
454 * GetObjectIndex (local function)
455 ********************************************************************************/
456 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,
465 TRACE(ole
,"(%p,%p,%p,%p)\n",This
,punk
,pszkey
,index
);
468 /* search object identified by a register key */
469 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++){
471 if(This
->bindCtxTable
[i
].regType
==1){
473 if ( ( (This
->bindCtxTable
[i
].pkeyObj
==NULL
) && (pszkey
==NULL
) ) ||
474 ( (This
->bindCtxTable
[i
].pkeyObj
!=NULL
) &&
476 (lstrcmpW(This
->bindCtxTable
[i
].pkeyObj
,pszkey
)==0)
484 /* search object identified by a moniker*/
485 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++)
486 if(This
->bindCtxTable
[i
].pObj
==punk
)
498 /******************************************************************************
500 ******************************************************************************/
501 HRESULT WINAPI
CreateBindCtx16(DWORD reserved
, LPBC
* ppbc
)
503 FIXME(ole
,"(%ld,%p),stub!\n",reserved
,ppbc
);
507 /******************************************************************************
509 ******************************************************************************/
510 HRESULT WINAPI
CreateBindCtx(DWORD reserved
, LPBC
* ppbc
)
512 BindCtxImpl
* newBindCtx
= 0;
514 IID riid
=IID_IBindCtx
;
516 TRACE(ole
,"(%ld,%p)\n",reserved
,ppbc
);
518 newBindCtx
= HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl
));
521 return E_OUTOFMEMORY
;
523 hr
= BindCtxImpl_Construct(newBindCtx
);
527 HeapFree(GetProcessHeap(),0,newBindCtx
);
531 hr
= BindCtxImpl_QueryInterface((IBindCtx
*)newBindCtx
,&riid
,(void**)ppbc
);