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 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
72 BindCtxImpl_QueryInterface
,
75 BindCtxImpl_RegisterObjectBound
,
76 BindCtxImpl_RevokeObjectBound
,
77 BindCtxImpl_ReleaseBoundObjects
,
78 BindCtxImpl_SetBindOptions
,
79 BindCtxImpl_GetBindOptions
,
80 BindCtxImpl_GetRunningObjectTable
,
81 BindCtxImpl_RegisterObjectParam
,
82 BindCtxImpl_GetObjectParam
,
83 BindCtxImpl_EnumObjectParam
,
84 BindCtxImpl_RevokeObjectParam
87 /*******************************************************************************
88 * BindCtx_QueryInterface
89 *******************************************************************************/
90 HRESULT WINAPI
BindCtxImpl_QueryInterface(IBindCtx
* iface
,REFIID riid
,void** ppvObject
)
92 ICOM_THIS(BindCtxImpl
,iface
);
94 TRACE(ole
,"(%p,%p,%p)\n",This
,riid
,ppvObject
);
96 /* Perform a sanity check on the parameters.*/
97 if ( (This
==0) || (ppvObject
==0) )
100 /* Initialize the return parameter.*/
103 /* Compare the riid with the interface IDs implemented by this object.*/
104 if (IsEqualIID(&IID_IUnknown
, riid
))
105 *ppvObject
= (IBindCtx
*)This
;
107 if (IsEqualIID(&IID_IBindCtx
, riid
))
108 *ppvObject
= (IBindCtx
*)This
;
110 /* Check that we obtained an interface.*/
112 return E_NOINTERFACE
;
114 /* Query Interface always increases the reference count by one when it is successful */
115 BindCtxImpl_AddRef(iface
);
120 /******************************************************************************
122 ******************************************************************************/
123 ULONG WINAPI
BindCtxImpl_AddRef(IBindCtx
* iface
)
125 ICOM_THIS(BindCtxImpl
,iface
);
127 TRACE(ole
,"(%p)\n",This
);
129 return ++(This
->ref
);
132 /******************************************************************************
134 ******************************************************************************/
135 ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
)
137 ICOM_THIS(BindCtxImpl
,iface
);
139 TRACE(ole
,"(%p)\n",This
);
145 /* release all registred objects */
146 BindCtxImpl_ReleaseBoundObjects((IBindCtx
*)This
);
148 BindCtxImpl_Destroy(This
);
156 /******************************************************************************
157 * BindCtx_Construct (local function)
158 *******************************************************************************/
159 HRESULT WINAPI
BindCtxImpl_Construct(BindCtxImpl
* This
)
161 TRACE(ole
,"(%p)\n",This
);
163 /* Initialize the virtual function table.*/
164 This
->lpvtbl
= &VT_BindCtxImpl
;
167 /* Initialize the BIND_OPTS2 structure */
168 This
->bindOption2
.cbStruct
= sizeof(BIND_OPTS2
);
169 This
->bindOption2
.grfFlags
= 0;
170 This
->bindOption2
.grfMode
= STGM_READWRITE
;
171 This
->bindOption2
.dwTickCountDeadline
= 0;
173 This
->bindOption2
.dwTrackFlags
= 0;
174 This
->bindOption2
.dwClassContext
= CLSCTX_SERVER
;
175 This
->bindOption2
.locale
= 1033;
176 This
->bindOption2
.pServerInfo
= 0;
178 /* Initialize the bindctx table */
179 This
->bindCtxTableSize
=BLOCK_TAB_SIZE
;
180 This
->bindCtxTableLastIndex
=0;
181 This
->bindCtxTable
= HeapAlloc(GetProcessHeap(), 0,This
->bindCtxTableSize
*sizeof(BindCtxObject
));
183 if (This
->bindCtxTable
==NULL
)
184 return E_OUTOFMEMORY
;
189 /******************************************************************************
190 * BindCtx_Destroy (local function)
191 *******************************************************************************/
192 HRESULT WINAPI
BindCtxImpl_Destroy(BindCtxImpl
* This
)
194 TRACE(ole
,"(%p)\n",This
);
196 /* free the table space memory */
197 HeapFree(GetProcessHeap(),0,This
->bindCtxTable
);
199 /* free the bindctx structure */
200 HeapFree(GetProcessHeap(),0,This
);
206 /******************************************************************************
207 * BindCtx_RegisterObjectBound
208 ******************************************************************************/
209 HRESULT WINAPI
BindCtxImpl_RegisterObjectBound(IBindCtx
* iface
,IUnknown
* punk
)
212 ICOM_THIS(BindCtxImpl
,iface
);
213 DWORD lastIndex
=This
->bindCtxTableLastIndex
;
216 TRACE(ole
,"(%p,%p)\n",This
,punk
);
221 IUnknown_AddRef(punk
);
223 /* put the object in the first free element in the table */
224 This
->bindCtxTable
[lastIndex
].pObj
= punk
;
225 This
->bindCtxTable
[lastIndex
].pkeyObj
= NULL
;
226 This
->bindCtxTable
[lastIndex
].regType
= 0;
227 cell
=This
->bindCtxTable
[lastIndex
];
228 lastIndex
= ++This
->bindCtxTableLastIndex
;
230 if (lastIndex
== This
->bindCtxTableSize
){ /* the table is full so it must be resized */
232 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
233 FIXME(ole
,"This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
237 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
239 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
240 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
241 if (!This
->bindCtxTable
)
242 return E_OUTOFMEMORY
;
247 /******************************************************************************
248 * BindCtx_RevokeObjectBound
249 ******************************************************************************/
250 HRESULT WINAPI
BindCtxImpl_RevokeObjectBound(IBindCtx
* iface
, IUnknown
* punk
)
254 ICOM_THIS(BindCtxImpl
,iface
);
256 TRACE(ole
,"(%p,%p)\n",This
,punk
);
258 /* check if the object was registred or not */
259 if (BindCtxImpl_GetObjectIndex(This
,punk
,NULL
,&index
)==S_FALSE
)
261 return MK_E_NOTBOUND
;
263 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
265 /* left-shift all elements in the rigth side of the curent revoked object */
266 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
267 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
269 This
->bindCtxTableLastIndex
--;
274 /******************************************************************************
275 * BindCtx_ReleaseBoundObjects
276 ******************************************************************************/
277 HRESULT WINAPI
BindCtxImpl_ReleaseBoundObjects(IBindCtx
* iface
)
281 ICOM_THIS(BindCtxImpl
,iface
);
283 TRACE(ole
,"(%p)\n",This
);
285 for(i
=0;i
<This
->bindCtxTableLastIndex
;i
++)
286 IUnknown_Release(This
->bindCtxTable
[i
].pObj
);
288 This
->bindCtxTableLastIndex
= 0;
293 /******************************************************************************
294 * BindCtx_SetBindOptions
295 ******************************************************************************/
296 HRESULT WINAPI
BindCtxImpl_SetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
298 ICOM_THIS(BindCtxImpl
,iface
);
300 TRACE(ole
,"(%p,%p)\n",This
,pbindopts
);
305 This
->bindOption2
=*pbindopts
;
310 /******************************************************************************
311 * BindCtx_GetBindOptions
312 ******************************************************************************/
313 HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
315 ICOM_THIS(BindCtxImpl
,iface
);
317 TRACE(ole
,"(%p,%p)\n",This
,pbindopts
);
322 *pbindopts
=This
->bindOption2
;
327 /******************************************************************************
328 * BindCtx_GetRunningObjectTable
329 ******************************************************************************/
330 HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
)
334 ICOM_THIS(BindCtxImpl
,iface
);
336 TRACE(ole
,"(%p,%p)\n",This
,pprot
);
341 res
=GetRunningObjectTable(0,(LPVOID
*)pprot
);
346 /******************************************************************************
347 * BindCtx_RegisterObjectParam
348 ******************************************************************************/
349 HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
)
351 ICOM_THIS(BindCtxImpl
,iface
);
353 TRACE(ole
,"(%p,%p,%p)\n",This
,pszkey
,punk
);
358 IUnknown_AddRef(punk
);
360 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pObj
= punk
;
361 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].regType
= 1;
365 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=NULL
;
369 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=
370 HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR
)*(1+lstrlenW(pszkey
))));
372 if (This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
==NULL
)
373 return E_OUTOFMEMORY
;
374 lstrcpyW(This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
,pszkey
);
377 This
->bindCtxTableLastIndex
++;
379 if (This
->bindCtxTableLastIndex
== This
->bindCtxTableSize
){ /* table is full ! must be resized */
381 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
383 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
384 FIXME(ole
,"This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
387 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
388 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
389 if (!This
->bindCtxTable
)
390 return E_OUTOFMEMORY
;
394 /******************************************************************************
395 * BindCtx_GetObjectParam
396 ******************************************************************************/
397 HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
)
400 ICOM_THIS(BindCtxImpl
,iface
);
402 TRACE(ole
,"(%p,%p,%p)\n",This
,pszkey
,punk
);
409 if (BindCtxImpl_GetObjectIndex(This
,NULL
,pszkey
,&index
)==S_FALSE
)
412 IUnknown_AddRef(This
->bindCtxTable
[index
].pObj
);
414 *punk
= This
->bindCtxTable
[index
].pObj
;
419 /******************************************************************************
420 * BindCtx_RevokeObjectParam
421 ******************************************************************************/
422 HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR ppenum
)
426 ICOM_THIS(BindCtxImpl
,iface
);
428 TRACE(ole
,"(%p,%p)\n",This
,ppenum
);
430 if (BindCtxImpl_GetObjectIndex(This
,NULL
,ppenum
,&index
)==S_FALSE
)
433 /* release the object if it's found */
434 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
436 /* remove the object from the table with a left-shifting of all objects in the right side */
437 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
438 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
440 This
->bindCtxTableLastIndex
--;
445 /******************************************************************************
446 * BindCtx_EnumObjectParam
447 ******************************************************************************/
448 HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** pszkey
)
450 FIXME(ole
,"(%p,%p),stub!\n",iface
,pszkey
);
454 /********************************************************************************
455 * GetObjectIndex (local function)
456 ********************************************************************************/
457 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,
466 TRACE(ole
,"(%p,%p,%p,%p)\n",This
,punk
,pszkey
,index
);
469 /* search object identified by a register key */
470 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++){
472 if(This
->bindCtxTable
[i
].regType
==1){
474 if ( ( (This
->bindCtxTable
[i
].pkeyObj
==NULL
) && (pszkey
==NULL
) ) ||
475 ( (This
->bindCtxTable
[i
].pkeyObj
!=NULL
) &&
477 (lstrcmpW(This
->bindCtxTable
[i
].pkeyObj
,pszkey
)==0)
485 /* search object identified by a moniker*/
486 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++)
487 if(This
->bindCtxTable
[i
].pObj
==punk
)
499 /******************************************************************************
501 ******************************************************************************/
502 HRESULT WINAPI
CreateBindCtx16(DWORD reserved
, LPBC
* ppbc
)
504 FIXME(ole
,"(%ld,%p),stub!\n",reserved
,ppbc
);
508 /******************************************************************************
510 ******************************************************************************/
511 HRESULT WINAPI
CreateBindCtx(DWORD reserved
, LPBC
* ppbc
)
513 BindCtxImpl
* newBindCtx
= 0;
515 IID riid
=IID_IBindCtx
;
517 TRACE(ole
,"(%ld,%p)\n",reserved
,ppbc
);
519 newBindCtx
= HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl
));
522 return E_OUTOFMEMORY
;
524 hr
= BindCtxImpl_Construct(newBindCtx
);
528 HeapFree(GetProcessHeap(),0,newBindCtx
);
532 hr
= BindCtxImpl_QueryInterface((IBindCtx
*)newBindCtx
,&riid
,(void**)ppbc
);