1 /***************************************************************************************
2 * BindCtx implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
10 #include "wine/unicode.h"
11 #include "wine/obj_moniker.h"
12 #include "debugtools.h"
15 DEFAULT_DEBUG_CHANNEL(ole
);
17 /* represent the first size table and it's increment block size */
18 #define BLOCK_TAB_SIZE 10
19 #define MAX_TAB_SIZE 0xFFFFFFFF
21 /* data structure of the BindCtx table elements */
22 typedef struct BindCtxObject
{
24 IUnknown
* pObj
; /* point on a bound object */
26 LPOLESTR pkeyObj
; /* key associated to this bound object */
28 BYTE regType
; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
32 /* BindCtx data strucrture */
33 typedef struct BindCtxImpl
{
35 ICOM_VFIELD(IBindCtx
); /* VTable relative to the IBindCtx interface.*/
37 ULONG ref
; /* reference counter for this object */
39 BindCtxObject
* bindCtxTable
; /* this is a table in witch all bounded objects are stored*/
40 DWORD bindCtxTableLastIndex
; /* first free index in the table */
41 DWORD bindCtxTableSize
; /* size table */
43 BIND_OPTS2 bindOption2
; /* a structure witch contains the bind options*/
47 /* IBindCtx prototype functions : */
49 /* IUnknown functions*/
50 static HRESULT WINAPI
BindCtxImpl_QueryInterface(IBindCtx
* iface
,REFIID riid
,void** ppvObject
);
51 static ULONG WINAPI
BindCtxImpl_AddRef(IBindCtx
* iface
);
52 static ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
);
53 /* IBindCtx functions */
54 static HRESULT WINAPI
BindCtxImpl_RegisterObjectBound(IBindCtx
* iface
,IUnknown
* punk
);
55 static HRESULT WINAPI
BindCtxImpl_RevokeObjectBound(IBindCtx
* iface
, IUnknown
* punk
);
56 static HRESULT WINAPI
BindCtxImpl_ReleaseBoundObjects(IBindCtx
* iface
);
57 static HRESULT WINAPI
BindCtxImpl_SetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
);
58 static HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
);
59 static HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
);
60 static HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
);
61 static HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
);
62 static HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** ppenum
);
63 static HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
);
65 HRESULT WINAPI
BindCtxImpl_Construct(BindCtxImpl
* This
);
66 HRESULT WINAPI
BindCtxImpl_Destroy(BindCtxImpl
* This
);
67 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,IUnknown
* punk
,LPOLESTR pszkey
,DWORD
*index
);
69 /* Virtual function table for the BindCtx class. */
70 static ICOM_VTABLE(IBindCtx
) VT_BindCtxImpl
=
72 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
73 BindCtxImpl_QueryInterface
,
76 BindCtxImpl_RegisterObjectBound
,
77 BindCtxImpl_RevokeObjectBound
,
78 BindCtxImpl_ReleaseBoundObjects
,
79 BindCtxImpl_SetBindOptions
,
80 BindCtxImpl_GetBindOptions
,
81 BindCtxImpl_GetRunningObjectTable
,
82 BindCtxImpl_RegisterObjectParam
,
83 BindCtxImpl_GetObjectParam
,
84 BindCtxImpl_EnumObjectParam
,
85 BindCtxImpl_RevokeObjectParam
88 /*******************************************************************************
89 * BindCtx_QueryInterface
90 *******************************************************************************/
91 HRESULT WINAPI
BindCtxImpl_QueryInterface(IBindCtx
* iface
,REFIID riid
,void** ppvObject
)
93 ICOM_THIS(BindCtxImpl
,iface
);
95 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
97 /* Perform a sanity check on the parameters.*/
98 if ( (This
==0) || (ppvObject
==0) )
101 /* Initialize the return parameter.*/
104 /* Compare the riid with the interface IDs implemented by this object.*/
105 if (IsEqualIID(&IID_IUnknown
, riid
))
106 *ppvObject
= (IBindCtx
*)This
;
108 if (IsEqualIID(&IID_IBindCtx
, riid
))
109 *ppvObject
= (IBindCtx
*)This
;
111 /* Check that we obtained an interface.*/
113 return E_NOINTERFACE
;
115 /* Query Interface always increases the reference count by one when it is successful */
116 BindCtxImpl_AddRef(iface
);
121 /******************************************************************************
123 ******************************************************************************/
124 ULONG WINAPI
BindCtxImpl_AddRef(IBindCtx
* iface
)
126 ICOM_THIS(BindCtxImpl
,iface
);
128 TRACE("(%p)\n",This
);
130 return ++(This
->ref
);
133 /******************************************************************************
135 ******************************************************************************/
136 ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
)
138 ICOM_THIS(BindCtxImpl
,iface
);
140 TRACE("(%p)\n",This
);
146 /* release all registered objects */
147 BindCtxImpl_ReleaseBoundObjects((IBindCtx
*)This
);
149 BindCtxImpl_Destroy(This
);
157 /******************************************************************************
158 * BindCtx_Construct (local function)
159 *******************************************************************************/
160 HRESULT WINAPI
BindCtxImpl_Construct(BindCtxImpl
* This
)
162 TRACE("(%p)\n",This
);
164 /* Initialize the virtual function table.*/
165 ICOM_VTBL(This
) = &VT_BindCtxImpl
;
168 /* Initialize the BIND_OPTS2 structure */
169 This
->bindOption2
.cbStruct
= sizeof(BIND_OPTS2
);
170 This
->bindOption2
.grfFlags
= 0;
171 This
->bindOption2
.grfMode
= STGM_READWRITE
;
172 This
->bindOption2
.dwTickCountDeadline
= 0;
174 This
->bindOption2
.dwTrackFlags
= 0;
175 This
->bindOption2
.dwClassContext
= CLSCTX_SERVER
;
176 This
->bindOption2
.locale
= 1033;
177 This
->bindOption2
.pServerInfo
= 0;
179 /* Initialize the bindctx table */
180 This
->bindCtxTableSize
=BLOCK_TAB_SIZE
;
181 This
->bindCtxTableLastIndex
=0;
182 This
->bindCtxTable
= HeapAlloc(GetProcessHeap(), 0,This
->bindCtxTableSize
*sizeof(BindCtxObject
));
184 if (This
->bindCtxTable
==NULL
)
185 return E_OUTOFMEMORY
;
190 /******************************************************************************
191 * BindCtx_Destroy (local function)
192 *******************************************************************************/
193 HRESULT WINAPI
BindCtxImpl_Destroy(BindCtxImpl
* This
)
195 TRACE("(%p)\n",This
);
197 /* free the table space memory */
198 HeapFree(GetProcessHeap(),0,This
->bindCtxTable
);
200 /* free the bindctx structure */
201 HeapFree(GetProcessHeap(),0,This
);
207 /******************************************************************************
208 * BindCtx_RegisterObjectBound
209 ******************************************************************************/
210 HRESULT WINAPI
BindCtxImpl_RegisterObjectBound(IBindCtx
* iface
,IUnknown
* punk
)
213 ICOM_THIS(BindCtxImpl
,iface
);
214 DWORD lastIndex
=This
->bindCtxTableLastIndex
;
217 TRACE("(%p,%p)\n",This
,punk
);
222 IUnknown_AddRef(punk
);
224 /* put the object in the first free element in the table */
225 This
->bindCtxTable
[lastIndex
].pObj
= punk
;
226 This
->bindCtxTable
[lastIndex
].pkeyObj
= NULL
;
227 This
->bindCtxTable
[lastIndex
].regType
= 0;
228 cell
=This
->bindCtxTable
[lastIndex
];
229 lastIndex
= ++This
->bindCtxTableLastIndex
;
231 if (lastIndex
== This
->bindCtxTableSize
){ /* the table is full so it must be resized */
233 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
234 FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
238 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
240 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
241 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
242 if (!This
->bindCtxTable
)
243 return E_OUTOFMEMORY
;
248 /******************************************************************************
249 * BindCtx_RevokeObjectBound
250 ******************************************************************************/
251 HRESULT WINAPI
BindCtxImpl_RevokeObjectBound(IBindCtx
* iface
, IUnknown
* punk
)
255 ICOM_THIS(BindCtxImpl
,iface
);
257 TRACE("(%p,%p)\n",This
,punk
);
259 /* check if the object was registred or not */
260 if (BindCtxImpl_GetObjectIndex(This
,punk
,NULL
,&index
)==S_FALSE
)
262 return MK_E_NOTBOUND
;
264 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
266 /* left-shift all elements in the rigth side of the curent revoked object */
267 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
268 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
270 This
->bindCtxTableLastIndex
--;
275 /******************************************************************************
276 * BindCtx_ReleaseBoundObjects
277 ******************************************************************************/
278 HRESULT WINAPI
BindCtxImpl_ReleaseBoundObjects(IBindCtx
* iface
)
282 ICOM_THIS(BindCtxImpl
,iface
);
284 TRACE("(%p)\n",This
);
286 for(i
=0;i
<This
->bindCtxTableLastIndex
;i
++)
287 IUnknown_Release(This
->bindCtxTable
[i
].pObj
);
289 This
->bindCtxTableLastIndex
= 0;
294 /******************************************************************************
295 * BindCtx_SetBindOptions
296 ******************************************************************************/
297 HRESULT WINAPI
BindCtxImpl_SetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
299 ICOM_THIS(BindCtxImpl
,iface
);
301 TRACE("(%p,%p)\n",This
,pbindopts
);
306 if (pbindopts
->cbStruct
> sizeof(BIND_OPTS2
))
308 WARN("invalid size");
309 return E_INVALIDARG
; /* FIXME : not verified */
311 memcpy(&This
->bindOption2
, pbindopts
, pbindopts
->cbStruct
);
315 /******************************************************************************
316 * BindCtx_GetBindOptions
317 ******************************************************************************/
318 HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
320 ICOM_THIS(BindCtxImpl
,iface
);
322 TRACE("(%p,%p)\n",This
,pbindopts
);
327 if (pbindopts
->cbStruct
> sizeof(BIND_OPTS2
))
329 WARN("invalid size");
330 return E_INVALIDARG
; /* FIXME : not verified */
332 memcpy(pbindopts
, &This
->bindOption2
, pbindopts
->cbStruct
);
336 /******************************************************************************
337 * BindCtx_GetRunningObjectTable
338 ******************************************************************************/
339 HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
)
343 ICOM_THIS(BindCtxImpl
,iface
);
345 TRACE("(%p,%p)\n",This
,pprot
);
350 res
=GetRunningObjectTable(0, pprot
);
355 /******************************************************************************
356 * BindCtx_RegisterObjectParam
357 ******************************************************************************/
358 HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
)
360 ICOM_THIS(BindCtxImpl
,iface
);
362 TRACE("(%p,%p,%p)\n",This
,pszkey
,punk
);
367 IUnknown_AddRef(punk
);
369 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pObj
= punk
;
370 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].regType
= 1;
374 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=NULL
;
378 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=
379 HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR
)*(1+lstrlenW(pszkey
))));
381 if (This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
==NULL
)
382 return E_OUTOFMEMORY
;
383 strcpyW(This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
,pszkey
);
386 This
->bindCtxTableLastIndex
++;
388 if (This
->bindCtxTableLastIndex
== This
->bindCtxTableSize
){ /* table is full ! must be resized */
390 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
392 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
393 FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
396 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
397 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
398 if (!This
->bindCtxTable
)
399 return E_OUTOFMEMORY
;
403 /******************************************************************************
404 * BindCtx_GetObjectParam
405 ******************************************************************************/
406 HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
)
409 ICOM_THIS(BindCtxImpl
,iface
);
411 TRACE("(%p,%p,%p)\n",This
,pszkey
,punk
);
418 if (BindCtxImpl_GetObjectIndex(This
,NULL
,pszkey
,&index
)==S_FALSE
)
421 IUnknown_AddRef(This
->bindCtxTable
[index
].pObj
);
423 *punk
= This
->bindCtxTable
[index
].pObj
;
428 /******************************************************************************
429 * BindCtx_RevokeObjectParam
430 ******************************************************************************/
431 HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR ppenum
)
435 ICOM_THIS(BindCtxImpl
,iface
);
437 TRACE("(%p,%p)\n",This
,ppenum
);
439 if (BindCtxImpl_GetObjectIndex(This
,NULL
,ppenum
,&index
)==S_FALSE
)
442 /* release the object if it's found */
443 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
445 /* remove the object from the table with a left-shifting of all objects in the right side */
446 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
447 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
449 This
->bindCtxTableLastIndex
--;
454 /******************************************************************************
455 * BindCtx_EnumObjectParam
456 ******************************************************************************/
457 HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** pszkey
)
459 FIXME("(%p,%p),stub!\n",iface
,pszkey
);
463 /********************************************************************************
464 * GetObjectIndex (local function)
465 ********************************************************************************/
466 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,
475 TRACE("(%p,%p,%p,%p)\n",This
,punk
,pszkey
,index
);
478 /* search object identified by a register key */
479 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++){
481 if(This
->bindCtxTable
[i
].regType
==1){
483 if ( ( (This
->bindCtxTable
[i
].pkeyObj
==NULL
) && (pszkey
==NULL
) ) ||
484 ( (This
->bindCtxTable
[i
].pkeyObj
!=NULL
) &&
486 (lstrcmpW(This
->bindCtxTable
[i
].pkeyObj
,pszkey
)==0)
494 /* search object identified by a moniker*/
495 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++)
496 if(This
->bindCtxTable
[i
].pObj
==punk
)
508 /******************************************************************************
510 ******************************************************************************/
511 HRESULT WINAPI
CreateBindCtx16(DWORD reserved
, LPBC
* ppbc
)
513 FIXME("(%ld,%p),stub!\n",reserved
,ppbc
);
517 /******************************************************************************
519 ******************************************************************************/
520 HRESULT WINAPI
CreateBindCtx(DWORD reserved
, LPBC
* ppbc
)
522 BindCtxImpl
* newBindCtx
= 0;
524 IID riid
=IID_IBindCtx
;
526 TRACE("(%ld,%p)\n",reserved
,ppbc
);
528 newBindCtx
= HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl
));
531 return E_OUTOFMEMORY
;
533 hr
= BindCtxImpl_Construct(newBindCtx
);
537 HeapFree(GetProcessHeap(),0,newBindCtx
);
541 hr
= BindCtxImpl_QueryInterface((IBindCtx
*)newBindCtx
,&riid
,(void**)ppbc
);