1 /***************************************************************************************
2 * BindCtx implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
10 #include "wine/obj_moniker.h"
14 /* represent the first size table and it's increment block size */
15 #define BLOCK_TAB_SIZE 10
16 #define MAX_TAB_SIZE 0xFFFFFFFF
18 /* data structure of the BindCtx table elements */
19 typedef struct BindCtxObject
{
21 IUnknown
* pObj
; /* point on a bound object */
23 LPOLESTR pkeyObj
; /* key associated to this bound object */
25 BYTE regType
; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
29 /* BindCtx data strucrture */
30 typedef struct BindCtxImpl
{
32 ICOM_VTABLE(IBindCtx
)* lpvtbl
; /* VTable relative to the IBindCtx interface.*/
34 ULONG ref
; /* reference counter for this object */
36 BindCtxObject
* bindCtxTable
; /* this is a table in witch all bounded objects are stored*/
37 DWORD bindCtxTableLastIndex
; /* first free index in the table */
38 DWORD bindCtxTableSize
; /* size table */
40 BIND_OPTS2 bindOption2
; /* a structure witch contains the bind options*/
44 /* IBindCtx prototype functions : */
46 /* IUnknown functions*/
47 static HRESULT WINAPI
BindCtxImpl_QueryInterface(IBindCtx
* iface
,REFIID riid
,void** ppvObject
);
48 static ULONG WINAPI
BindCtxImpl_AddRef(IBindCtx
* iface
);
49 static ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
);
50 /* IBindCtx functions */
51 static HRESULT WINAPI
BindCtxImpl_RegisterObjectBound(IBindCtx
* iface
,IUnknown
* punk
);
52 static HRESULT WINAPI
BindCtxImpl_RevokeObjectBound(IBindCtx
* iface
, IUnknown
* punk
);
53 static HRESULT WINAPI
BindCtxImpl_ReleaseBoundObjects(IBindCtx
* iface
);
54 static HRESULT WINAPI
BindCtxImpl_SetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
);
55 static HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
);
56 static HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
);
57 static HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
);
58 static HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
);
59 static HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** ppenum
);
60 static HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
);
62 HRESULT WINAPI
BindCtxImpl_Construct(BindCtxImpl
* This
);
63 HRESULT WINAPI
BindCtxImpl_Destroy(BindCtxImpl
* This
);
64 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,IUnknown
* punk
,LPOLESTR pszkey
,DWORD
*index
);
66 /* Virtual function table for the BindCtx class. */
67 static ICOM_VTABLE(IBindCtx
) VT_BindCtxImpl
=
69 BindCtxImpl_QueryInterface
,
72 BindCtxImpl_RegisterObjectBound
,
73 BindCtxImpl_RevokeObjectBound
,
74 BindCtxImpl_ReleaseBoundObjects
,
75 BindCtxImpl_SetBindOptions
,
76 BindCtxImpl_GetBindOptions
,
77 BindCtxImpl_GetRunningObjectTable
,
78 BindCtxImpl_RegisterObjectParam
,
79 BindCtxImpl_GetObjectParam
,
80 BindCtxImpl_EnumObjectParam
,
81 BindCtxImpl_RevokeObjectParam
84 /*******************************************************************************
85 * BindCtx_QueryInterface
86 *******************************************************************************/
87 HRESULT WINAPI
BindCtxImpl_QueryInterface(IBindCtx
* iface
,REFIID riid
,void** ppvObject
)
89 ICOM_THIS(BindCtxImpl
,iface
);
91 TRACE(ole
,"(%p,%p,%p)\n",This
,riid
,ppvObject
);
93 /* Perform a sanity check on the parameters.*/
94 if ( (This
==0) || (ppvObject
==0) )
97 /* Initialize the return parameter.*/
100 /* Compare the riid with the interface IDs implemented by this object.*/
101 if (IsEqualIID(&IID_IUnknown
, riid
))
102 *ppvObject
= (IBindCtx
*)This
;
104 if (IsEqualIID(&IID_IBindCtx
, riid
))
105 *ppvObject
= (IBindCtx
*)This
;
107 /* Check that we obtained an interface.*/
109 return E_NOINTERFACE
;
111 /* Query Interface always increases the reference count by one when it is successful */
112 BindCtxImpl_AddRef(iface
);
117 /******************************************************************************
119 ******************************************************************************/
120 ULONG WINAPI
BindCtxImpl_AddRef(IBindCtx
* iface
)
122 ICOM_THIS(BindCtxImpl
,iface
);
124 TRACE(ole
,"(%p)\n",This
);
126 return ++(This
->ref
);
129 /******************************************************************************
131 ******************************************************************************/
132 ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
)
134 ICOM_THIS(BindCtxImpl
,iface
);
136 TRACE(ole
,"(%p)\n",This
);
142 /* release all registred objects */
143 BindCtxImpl_ReleaseBoundObjects((IBindCtx
*)This
);
145 BindCtxImpl_Destroy(This
);
153 /******************************************************************************
154 * BindCtx_Construct (local function)
155 *******************************************************************************/
156 HRESULT WINAPI
BindCtxImpl_Construct(BindCtxImpl
* This
)
158 TRACE(ole
,"(%p)\n",This
);
160 /* Initialize the virtual function table.*/
161 This
->lpvtbl
= &VT_BindCtxImpl
;
164 /* Initialize the BIND_OPTS2 structure */
165 This
->bindOption2
.cbStruct
= sizeof(BIND_OPTS2
);
166 This
->bindOption2
.grfFlags
= 0;
167 This
->bindOption2
.grfMode
= STGM_READWRITE
;
168 This
->bindOption2
.dwTickCountDeadline
= 0;
170 This
->bindOption2
.dwTrackFlags
= 0;
171 This
->bindOption2
.dwClassContext
= CLSCTX_SERVER
;
172 This
->bindOption2
.locale
= 1033;
173 This
->bindOption2
.pServerInfo
= 0;
175 /* Initialize the bindctx table */
176 This
->bindCtxTableSize
=BLOCK_TAB_SIZE
;
177 This
->bindCtxTableLastIndex
=0;
178 This
->bindCtxTable
= HeapAlloc(GetProcessHeap(), 0,This
->bindCtxTableSize
*sizeof(BindCtxObject
));
180 if (This
->bindCtxTable
==NULL
)
181 return E_OUTOFMEMORY
;
186 /******************************************************************************
187 * BindCtx_Destroy (local function)
188 *******************************************************************************/
189 HRESULT WINAPI
BindCtxImpl_Destroy(BindCtxImpl
* This
)
191 TRACE(ole
,"(%p)\n",This
);
193 /* free the table space memory */
194 HeapFree(GetProcessHeap(),0,This
->bindCtxTable
);
196 /* free the bindctx structure */
197 HeapFree(GetProcessHeap(),0,This
);
203 /******************************************************************************
204 * BindCtx_RegisterObjectBound
205 ******************************************************************************/
206 HRESULT WINAPI
BindCtxImpl_RegisterObjectBound(IBindCtx
* iface
,IUnknown
* punk
)
209 ICOM_THIS(BindCtxImpl
,iface
);
210 DWORD lastIndex
=This
->bindCtxTableLastIndex
;
213 TRACE(ole
,"(%p,%p)\n",This
,punk
);
218 IUnknown_AddRef(punk
);
220 /* put the object in the first free element in the table */
221 This
->bindCtxTable
[lastIndex
].pObj
= punk
;
222 This
->bindCtxTable
[lastIndex
].pkeyObj
= NULL
;
223 This
->bindCtxTable
[lastIndex
].regType
= 0;
224 cell
=This
->bindCtxTable
[lastIndex
];
225 lastIndex
= ++This
->bindCtxTableLastIndex
;
227 if (lastIndex
== This
->bindCtxTableSize
){ /* the table is full so it must be resized */
229 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
230 FIXME(ole
,"This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
234 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
236 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
237 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
238 if (!This
->bindCtxTable
)
239 return E_OUTOFMEMORY
;
244 /******************************************************************************
245 * BindCtx_RevokeObjectBound
246 ******************************************************************************/
247 HRESULT WINAPI
BindCtxImpl_RevokeObjectBound(IBindCtx
* iface
, IUnknown
* punk
)
251 ICOM_THIS(BindCtxImpl
,iface
);
253 TRACE(ole
,"(%p,%p)\n",This
,punk
);
255 /* check if the object was registred or not */
256 if (BindCtxImpl_GetObjectIndex(This
,punk
,NULL
,&index
)==S_FALSE
)
258 return MK_E_NOTBOUND
;
260 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
262 /* left-shift all elements in the rigth side of the curent revoked object */
263 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
264 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
266 This
->bindCtxTableLastIndex
--;
271 /******************************************************************************
272 * BindCtx_ReleaseBoundObjects
273 ******************************************************************************/
274 HRESULT WINAPI
BindCtxImpl_ReleaseBoundObjects(IBindCtx
* iface
)
278 ICOM_THIS(BindCtxImpl
,iface
);
280 TRACE(ole
,"(%p)\n",This
);
282 for(i
=0;i
<This
->bindCtxTableLastIndex
;i
++)
283 IUnknown_Release(This
->bindCtxTable
[i
].pObj
);
285 This
->bindCtxTableLastIndex
= 0;
290 /******************************************************************************
291 * BindCtx_SetBindOptions
292 ******************************************************************************/
293 HRESULT WINAPI
BindCtxImpl_SetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
295 ICOM_THIS(BindCtxImpl
,iface
);
297 TRACE(ole
,"(%p,%p)\n",This
,pbindopts
);
302 This
->bindOption2
=*pbindopts
;
307 /******************************************************************************
308 * BindCtx_GetBindOptions
309 ******************************************************************************/
310 HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
312 ICOM_THIS(BindCtxImpl
,iface
);
314 TRACE(ole
,"(%p,%p)\n",This
,pbindopts
);
319 *pbindopts
=This
->bindOption2
;
324 /******************************************************************************
325 * BindCtx_GetRunningObjectTable
326 ******************************************************************************/
327 HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
)
331 ICOM_THIS(BindCtxImpl
,iface
);
333 TRACE(ole
,"(%p,%p)\n",This
,pprot
);
338 res
=GetRunningObjectTable(0,(LPVOID
*)pprot
);
343 /******************************************************************************
344 * BindCtx_RegisterObjectParam
345 ******************************************************************************/
346 HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
)
348 ICOM_THIS(BindCtxImpl
,iface
);
350 TRACE(ole
,"(%p,%p,%p)\n",This
,pszkey
,punk
);
355 IUnknown_AddRef(punk
);
357 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pObj
= punk
;
358 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].regType
= 1;
362 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=NULL
;
366 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=
367 HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR
)*(1+lstrlenW(pszkey
))));
369 if (This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
==NULL
)
370 return E_OUTOFMEMORY
;
371 lstrcpyW(This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
,pszkey
);
374 This
->bindCtxTableLastIndex
++;
376 if (This
->bindCtxTableLastIndex
== This
->bindCtxTableSize
){ /* table is full ! must be resized */
378 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
380 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
381 FIXME(ole
,"This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
384 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
385 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
386 if (!This
->bindCtxTable
)
387 return E_OUTOFMEMORY
;
391 /******************************************************************************
392 * BindCtx_GetObjectParam
393 ******************************************************************************/
394 HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
)
397 ICOM_THIS(BindCtxImpl
,iface
);
399 TRACE(ole
,"(%p,%p,%p)\n",This
,pszkey
,punk
);
406 if (BindCtxImpl_GetObjectIndex(This
,NULL
,pszkey
,&index
)==S_FALSE
)
409 IUnknown_AddRef(This
->bindCtxTable
[index
].pObj
);
411 *punk
= This
->bindCtxTable
[index
].pObj
;
416 /******************************************************************************
417 * BindCtx_RevokeObjectParam
418 ******************************************************************************/
419 HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR ppenum
)
423 ICOM_THIS(BindCtxImpl
,iface
);
425 TRACE(ole
,"(%p,%p)\n",This
,ppenum
);
427 if (BindCtxImpl_GetObjectIndex(This
,NULL
,ppenum
,&index
)==S_FALSE
)
430 /* release the object if it's found */
431 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
433 /* remove the object from the table with a left-shifting of all objects in the right side */
434 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
435 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
437 This
->bindCtxTableLastIndex
--;
442 /******************************************************************************
443 * BindCtx_EnumObjectParam
444 ******************************************************************************/
445 HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** pszkey
)
447 FIXME(ole
,"(%p,%p),stub!\n",iface
,pszkey
);
451 /********************************************************************************
452 * GetObjectIndex (local function)
453 ********************************************************************************/
454 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,
463 TRACE(ole
,"(%p,%p,%p,%p)\n",This
,punk
,pszkey
,index
);
466 /* search object identified by a register key */
467 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++){
469 if(This
->bindCtxTable
[i
].regType
==1){
471 if ( ( (This
->bindCtxTable
[i
].pkeyObj
==NULL
) && (pszkey
==NULL
) ) ||
472 ( (This
->bindCtxTable
[i
].pkeyObj
!=NULL
) &&
474 (lstrcmpW(This
->bindCtxTable
[i
].pkeyObj
,pszkey
)==0)
482 /* search object identified by a moniker*/
483 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++)
484 if(This
->bindCtxTable
[i
].pObj
==punk
)
496 /******************************************************************************
498 ******************************************************************************/
499 HRESULT WINAPI
CreateBindCtx16(DWORD reserved
, LPBC
* ppbc
)
501 FIXME(ole
,"(%ld,%p),stub!\n",reserved
,ppbc
);
505 /******************************************************************************
507 ******************************************************************************/
508 HRESULT WINAPI
CreateBindCtx(DWORD reserved
, LPBC
* ppbc
)
510 BindCtxImpl
* newBindCtx
= 0;
512 IID riid
=IID_IBindCtx
;
514 TRACE(ole
,"(%ld,%p)\n",reserved
,ppbc
);
516 newBindCtx
= HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl
));
519 return E_OUTOFMEMORY
;
521 hr
= BindCtxImpl_Construct(newBindCtx
);
525 HeapFree(GetProcessHeap(),0,newBindCtx
);
529 hr
= BindCtxImpl_QueryInterface((IBindCtx
*)newBindCtx
,&riid
,(void**)ppbc
);