1 /***************************************************************************************
2 * BindCtx implementation
4 * Copyright 1999 Noomen Hamza
5 ***************************************************************************************/
10 #include "wine/obj_moniker.h"
11 #include "debugtools.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_VFIELD(IBindCtx
); /* 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("(%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("(%p)\n",This
);
129 return ++(This
->ref
);
132 /******************************************************************************
134 ******************************************************************************/
135 ULONG WINAPI
BindCtxImpl_Release(IBindCtx
* iface
)
137 ICOM_THIS(BindCtxImpl
,iface
);
139 TRACE("(%p)\n",This
);
145 /* release all registered 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("(%p)\n",This
);
163 /* Initialize the virtual function table.*/
164 ICOM_VTBL(This
) = &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("(%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("(%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("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("(%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("(%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("(%p,%p)\n",This
,pbindopts
);
305 if (pbindopts
->cbStruct
> sizeof(BIND_OPTS2
))
307 WARN("invalid size");
308 return E_INVALIDARG
; /* FIXME : not verified */
310 memcpy(&This
->bindOption2
, pbindopts
, pbindopts
->cbStruct
);
314 /******************************************************************************
315 * BindCtx_GetBindOptions
316 ******************************************************************************/
317 HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx
* iface
,LPBIND_OPTS2 pbindopts
)
319 ICOM_THIS(BindCtxImpl
,iface
);
321 TRACE("(%p,%p)\n",This
,pbindopts
);
326 if (pbindopts
->cbStruct
> sizeof(BIND_OPTS2
))
328 WARN("invalid size");
329 return E_INVALIDARG
; /* FIXME : not verified */
331 memcpy(pbindopts
, &This
->bindOption2
, pbindopts
->cbStruct
);
335 /******************************************************************************
336 * BindCtx_GetRunningObjectTable
337 ******************************************************************************/
338 HRESULT WINAPI
BindCtxImpl_GetRunningObjectTable(IBindCtx
* iface
,IRunningObjectTable
** pprot
)
342 ICOM_THIS(BindCtxImpl
,iface
);
344 TRACE("(%p,%p)\n",This
,pprot
);
349 res
=GetRunningObjectTable(0, pprot
);
354 /******************************************************************************
355 * BindCtx_RegisterObjectParam
356 ******************************************************************************/
357 HRESULT WINAPI
BindCtxImpl_RegisterObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
* punk
)
359 ICOM_THIS(BindCtxImpl
,iface
);
361 TRACE("(%p,%p,%p)\n",This
,pszkey
,punk
);
366 IUnknown_AddRef(punk
);
368 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pObj
= punk
;
369 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].regType
= 1;
373 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=NULL
;
377 This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
=
378 HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR
)*(1+lstrlenW(pszkey
))));
380 if (This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
==NULL
)
381 return E_OUTOFMEMORY
;
382 lstrcpyW(This
->bindCtxTable
[This
->bindCtxTableLastIndex
].pkeyObj
,pszkey
);
385 This
->bindCtxTableLastIndex
++;
387 if (This
->bindCtxTableLastIndex
== This
->bindCtxTableSize
){ /* table is full ! must be resized */
389 This
->bindCtxTableSize
+=BLOCK_TAB_SIZE
; /* new table size */
391 if (This
->bindCtxTableSize
> (MAX_TAB_SIZE
-BLOCK_TAB_SIZE
)){
392 FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This
->bindCtxTableSize
);
395 This
->bindCtxTable
= HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->bindCtxTable
,
396 This
->bindCtxTableSize
* sizeof(BindCtxObject
));
397 if (!This
->bindCtxTable
)
398 return E_OUTOFMEMORY
;
402 /******************************************************************************
403 * BindCtx_GetObjectParam
404 ******************************************************************************/
405 HRESULT WINAPI
BindCtxImpl_GetObjectParam(IBindCtx
* iface
,LPOLESTR pszkey
, IUnknown
** punk
)
408 ICOM_THIS(BindCtxImpl
,iface
);
410 TRACE("(%p,%p,%p)\n",This
,pszkey
,punk
);
417 if (BindCtxImpl_GetObjectIndex(This
,NULL
,pszkey
,&index
)==S_FALSE
)
420 IUnknown_AddRef(This
->bindCtxTable
[index
].pObj
);
422 *punk
= This
->bindCtxTable
[index
].pObj
;
427 /******************************************************************************
428 * BindCtx_RevokeObjectParam
429 ******************************************************************************/
430 HRESULT WINAPI
BindCtxImpl_RevokeObjectParam(IBindCtx
* iface
,LPOLESTR ppenum
)
434 ICOM_THIS(BindCtxImpl
,iface
);
436 TRACE("(%p,%p)\n",This
,ppenum
);
438 if (BindCtxImpl_GetObjectIndex(This
,NULL
,ppenum
,&index
)==S_FALSE
)
441 /* release the object if it's found */
442 IUnknown_Release(This
->bindCtxTable
[index
].pObj
);
444 /* remove the object from the table with a left-shifting of all objects in the right side */
445 for(j
=index
; j
<This
->bindCtxTableLastIndex
-1; j
++)
446 This
->bindCtxTable
[j
]= This
->bindCtxTable
[j
+1];
448 This
->bindCtxTableLastIndex
--;
453 /******************************************************************************
454 * BindCtx_EnumObjectParam
455 ******************************************************************************/
456 HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx
* iface
,IEnumString
** pszkey
)
458 FIXME("(%p,%p),stub!\n",iface
,pszkey
);
462 /********************************************************************************
463 * GetObjectIndex (local function)
464 ********************************************************************************/
465 HRESULT WINAPI
BindCtxImpl_GetObjectIndex(BindCtxImpl
* This
,
474 TRACE("(%p,%p,%p,%p)\n",This
,punk
,pszkey
,index
);
477 /* search object identified by a register key */
478 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++){
480 if(This
->bindCtxTable
[i
].regType
==1){
482 if ( ( (This
->bindCtxTable
[i
].pkeyObj
==NULL
) && (pszkey
==NULL
) ) ||
483 ( (This
->bindCtxTable
[i
].pkeyObj
!=NULL
) &&
485 (lstrcmpW(This
->bindCtxTable
[i
].pkeyObj
,pszkey
)==0)
493 /* search object identified by a moniker*/
494 for(i
=0; ( (i
<This
->bindCtxTableLastIndex
) && (!found
));i
++)
495 if(This
->bindCtxTable
[i
].pObj
==punk
)
507 /******************************************************************************
509 ******************************************************************************/
510 HRESULT WINAPI
CreateBindCtx16(DWORD reserved
, LPBC
* ppbc
)
512 FIXME("(%ld,%p),stub!\n",reserved
,ppbc
);
516 /******************************************************************************
518 ******************************************************************************/
519 HRESULT WINAPI
CreateBindCtx(DWORD reserved
, LPBC
* ppbc
)
521 BindCtxImpl
* newBindCtx
= 0;
523 IID riid
=IID_IBindCtx
;
525 TRACE("(%ld,%p)\n",reserved
,ppbc
);
527 newBindCtx
= HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl
));
530 return E_OUTOFMEMORY
;
532 hr
= BindCtxImpl_Construct(newBindCtx
);
536 HeapFree(GetProcessHeap(),0,newBindCtx
);
540 hr
= BindCtxImpl_QueryInterface((IBindCtx
*)newBindCtx
,&riid
,(void**)ppbc
);