source: trunk/src/ole32/bindctx.c@ 6666

Last change on this file since 6666 was 6648, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 17.2 KB
Line 
1/* $Id: bindctx.c,v 1.2 2001-09-05 13:17:07 bird Exp $ */
2/***************************************************************************************
3 * BindCtx implementation
4 *
5 * Copyright 1999 Noomen Hamza
6 ***************************************************************************************/
7
8#include <string.h>
9#include <assert.h>
10#include "winerror.h"
11#include "winbase.h"
12#include "wine/unicode.h"
13#include "wine/obj_base.h"
14#include "wine/obj_misc.h"
15#include "wine/obj_storage.h"
16#include "wine/obj_moniker.h"
17#include "debugtools.h"
18#include "heap.h"
19
20DEFAULT_DEBUG_CHANNEL(ole);
21
22/* represent the first size table and it's increment block size */
23#define BLOCK_TAB_SIZE 10
24#define MAX_TAB_SIZE 0xFFFFFFFF
25
26/* data structure of the BindCtx table elements */
27typedef struct BindCtxObject{
28
29 IUnknown* pObj; /* point on a bound object */
30
31 LPOLESTR pkeyObj; /* key associated to this bound object */
32
33 BYTE regType; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
34
35} BindCtxObject;
36
37/* BindCtx data strucrture */
38typedef struct BindCtxImpl{
39
40 ICOM_VFIELD(IBindCtx); /* VTable relative to the IBindCtx interface.*/
41
42 ULONG ref; /* reference counter for this object */
43
44 BindCtxObject* bindCtxTable; /* this is a table in which all bounded objects are stored*/
45 DWORD bindCtxTableLastIndex; /* first free index in the table */
46 DWORD bindCtxTableSize; /* size table */
47
48 BIND_OPTS2 bindOption2; /* a structure which contains the bind options*/
49
50} BindCtxImpl;
51
52/* IBindCtx prototype functions : */
53
54/* IUnknown functions*/
55static HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject);
56static ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface);
57static ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface);
58/* IBindCtx functions */
59static HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk);
60static HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk);
61static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface);
62static HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts);
63static HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts);
64static HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot);
65static HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk);
66static HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk);
67static HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** ppenum);
68static HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR pszkey);
69/* Local functions*/
70HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This);
71HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This);
72HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,IUnknown* punk,LPOLESTR pszkey,DWORD *index);
73
74/* Virtual function table for the BindCtx class. */
75static ICOM_VTABLE(IBindCtx) VT_BindCtxImpl =
76 {
77 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
78 BindCtxImpl_QueryInterface,
79 BindCtxImpl_AddRef,
80 BindCtxImpl_Release,
81 BindCtxImpl_RegisterObjectBound,
82 BindCtxImpl_RevokeObjectBound,
83 BindCtxImpl_ReleaseBoundObjects,
84 BindCtxImpl_SetBindOptions,
85 BindCtxImpl_GetBindOptions,
86 BindCtxImpl_GetRunningObjectTable,
87 BindCtxImpl_RegisterObjectParam,
88 BindCtxImpl_GetObjectParam,
89 BindCtxImpl_EnumObjectParam,
90 BindCtxImpl_RevokeObjectParam
91};
92
93/*******************************************************************************
94 * BindCtx_QueryInterface
95 *******************************************************************************/
96HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
97{
98 ICOM_THIS(BindCtxImpl,iface);
99
100 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
101
102 /* Perform a sanity check on the parameters.*/
103 if ( (This==0) || (ppvObject==0) )
104 return E_INVALIDARG;
105
106 /* Initialize the return parameter.*/
107 *ppvObject = 0;
108
109 /* Compare the riid with the interface IDs implemented by this object.*/
110 if (IsEqualIID(&IID_IUnknown, riid))
111 *ppvObject = (IBindCtx*)This;
112 else
113 if (IsEqualIID(&IID_IBindCtx, riid))
114 *ppvObject = (IBindCtx*)This;
115
116 /* Check that we obtained an interface.*/
117 if ((*ppvObject)==0)
118 return E_NOINTERFACE;
119
120 /* Query Interface always increases the reference count by one when it is successful */
121 BindCtxImpl_AddRef(iface);
122
123 return S_OK;
124}
125
126/******************************************************************************
127 * BindCtx_AddRef
128 ******************************************************************************/
129ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface)
130{
131 ICOM_THIS(BindCtxImpl,iface);
132
133 TRACE("(%p)\n",This);
134
135 return ++(This->ref);
136}
137
138/******************************************************************************
139 * BindCtx_Release
140 ******************************************************************************/
141ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface)
142{
143 ICOM_THIS(BindCtxImpl,iface);
144
145 TRACE("(%p)\n",This);
146
147 This->ref--;
148
149 if (This->ref==0){
150
151 /* release all registered objects */
152 BindCtxImpl_ReleaseBoundObjects((IBindCtx*)This);
153
154 BindCtxImpl_Destroy(This);
155
156 return 0;
157 }
158 return This->ref;;
159}
160
161
162/******************************************************************************
163 * BindCtx_Construct (local function)
164 *******************************************************************************/
165HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This)
166{
167 TRACE("(%p)\n",This);
168
169 /* Initialize the virtual function table.*/
170 ICOM_VTBL(This) = &VT_BindCtxImpl;
171 This->ref = 0;
172
173 /* Initialize the BIND_OPTS2 structure */
174 This->bindOption2.cbStruct = sizeof(BIND_OPTS2);
175 This->bindOption2.grfFlags = 0;
176 This->bindOption2.grfMode = STGM_READWRITE;
177 This->bindOption2.dwTickCountDeadline = 0;
178
179 This->bindOption2.dwTrackFlags = 0;
180 This->bindOption2.dwClassContext = CLSCTX_SERVER;
181 This->bindOption2.locale = 1033;
182 This->bindOption2.pServerInfo = 0;
183
184 /* Initialize the bindctx table */
185 This->bindCtxTableSize=BLOCK_TAB_SIZE;
186 This->bindCtxTableLastIndex=0;
187 This->bindCtxTable= HeapAlloc(GetProcessHeap(), 0,This->bindCtxTableSize*sizeof(BindCtxObject));
188
189 if (This->bindCtxTable==NULL)
190 return E_OUTOFMEMORY;
191
192 return S_OK;
193}
194
195/******************************************************************************
196 * BindCtx_Destroy (local function)
197 *******************************************************************************/
198HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This)
199{
200 TRACE("(%p)\n",This);
201
202 /* free the table space memory */
203 HeapFree(GetProcessHeap(),0,This->bindCtxTable);
204
205 /* free the bindctx structure */
206 HeapFree(GetProcessHeap(),0,This);
207
208 return S_OK;
209}
210
211
212/******************************************************************************
213 * BindCtx_RegisterObjectBound
214 ******************************************************************************/
215HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
216{
217
218 ICOM_THIS(BindCtxImpl,iface);
219 DWORD lastIndex=This->bindCtxTableLastIndex;
220 BindCtxObject cell;
221
222 TRACE("(%p,%p)\n",This,punk);
223
224 if (punk==NULL)
225 return E_POINTER;
226
227 IUnknown_AddRef(punk);
228
229 /* put the object in the first free element in the table */
230 This->bindCtxTable[lastIndex].pObj = punk;
231 This->bindCtxTable[lastIndex].pkeyObj = NULL;
232 This->bindCtxTable[lastIndex].regType = 0;
233 cell=This->bindCtxTable[lastIndex];
234 lastIndex= ++This->bindCtxTableLastIndex;
235
236 if (lastIndex == This->bindCtxTableSize){ /* the table is full so it must be resized */
237
238 if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
239 FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
240 return E_FAIL;
241}
242
243 This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
244
245 This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
246 This->bindCtxTableSize * sizeof(BindCtxObject));
247 if (!This->bindCtxTable)
248 return E_OUTOFMEMORY;
249 }
250 return S_OK;
251}
252
253/******************************************************************************
254 * BindCtx_RevokeObjectBound
255 ******************************************************************************/
256HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
257{
258 DWORD index,j;
259
260 ICOM_THIS(BindCtxImpl,iface);
261
262 TRACE("(%p,%p)\n",This,punk);
263
264 /* check if the object was registred or not */
265 if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
266
267 return MK_E_NOTBOUND;
268
269 IUnknown_Release(This->bindCtxTable[index].pObj);
270
271 /* left-shift all elements in the right side of the current revoked object */
272 for(j=index; j<This->bindCtxTableLastIndex-1; j++)
273 This->bindCtxTable[j]= This->bindCtxTable[j+1];
274
275 This->bindCtxTableLastIndex--;
276
277 return S_OK;
278}
279
280/******************************************************************************
281 * BindCtx_ReleaseBoundObjects
282 ******************************************************************************/
283HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface)
284{
285 DWORD i;
286
287 ICOM_THIS(BindCtxImpl,iface);
288
289 TRACE("(%p)\n",This);
290
291 for(i=0;i<This->bindCtxTableLastIndex;i++)
292 IUnknown_Release(This->bindCtxTable[i].pObj);
293
294 This->bindCtxTableLastIndex = 0;
295
296 return S_OK;
297}
298
299/******************************************************************************
300 * BindCtx_SetBindOptions
301 ******************************************************************************/
302HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts)
303{
304 ICOM_THIS(BindCtxImpl,iface);
305
306 TRACE("(%p,%p)\n",This,pbindopts);
307
308 if (pbindopts==NULL)
309 return E_POINTER;
310
311 if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
312 {
313 WARN("invalid size");
314 return E_INVALIDARG; /* FIXME : not verified */
315 }
316 memcpy(&This->bindOption2, pbindopts, pbindopts->cbStruct);
317 return S_OK;
318}
319
320/******************************************************************************
321 * BindCtx_GetBindOptions
322 ******************************************************************************/
323HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts)
324{
325 ICOM_THIS(BindCtxImpl,iface);
326
327 TRACE("(%p,%p)\n",This,pbindopts);
328
329 if (pbindopts==NULL)
330 return E_POINTER;
331
332 if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
333 {
334 WARN("invalid size");
335 return E_INVALIDARG; /* FIXME : not verified */
336 }
337 memcpy(pbindopts, &This->bindOption2, pbindopts->cbStruct);
338 return S_OK;
339}
340
341/******************************************************************************
342 * BindCtx_GetRunningObjectTable
343 ******************************************************************************/
344HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot)
345{
346 HRESULT res;
347
348 ICOM_THIS(BindCtxImpl,iface);
349
350 TRACE("(%p,%p)\n",This,pprot);
351
352 if (pprot==NULL)
353 return E_POINTER;
354
355 res=GetRunningObjectTable(0, pprot);
356
357 return res;
358}
359
360/******************************************************************************
361 * BindCtx_RegisterObjectParam
362 ******************************************************************************/
363HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
364{
365 ICOM_THIS(BindCtxImpl,iface);
366
367 TRACE("(%p,%p,%p)\n",This,pszkey,punk);
368
369 if (punk==NULL)
370 return E_INVALIDARG;
371
372 IUnknown_AddRef(punk);
373
374 This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
375 This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
376
377 if (pszkey==NULL)
378
379 This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=NULL;
380
381 else{
382
383 This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=
384 HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR)*(1+lstrlenW(pszkey))));
385
386 if (This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj==NULL)
387 return E_OUTOFMEMORY;
388 strcpyW(This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj,pszkey);
389}
390
391 This->bindCtxTableLastIndex++;
392
393 if (This->bindCtxTableLastIndex == This->bindCtxTableSize){ /* table is full ! must be resized */
394
395 This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
396
397 if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
398 FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
399 return E_FAIL;
400 }
401 This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
402 This->bindCtxTableSize * sizeof(BindCtxObject));
403 if (!This->bindCtxTable)
404 return E_OUTOFMEMORY;
405 }
406 return S_OK;
407}
408/******************************************************************************
409 * BindCtx_GetObjectParam
410 ******************************************************************************/
411HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk)
412{
413 DWORD index;
414 ICOM_THIS(BindCtxImpl,iface);
415
416 TRACE("(%p,%p,%p)\n",This,pszkey,punk);
417
418 if (punk==NULL)
419 return E_POINTER;
420
421 *punk=0;
422
423 if (BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_FALSE)
424 return E_FAIL;
425
426 IUnknown_AddRef(This->bindCtxTable[index].pObj);
427
428 *punk = This->bindCtxTable[index].pObj;
429
430 return S_OK;
431}
432
433/******************************************************************************
434 * BindCtx_RevokeObjectParam
435 ******************************************************************************/
436HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
437{
438 DWORD index,j;
439
440 ICOM_THIS(BindCtxImpl,iface);
441
442 TRACE("(%p,%p)\n",This,ppenum);
443
444 if (BindCtxImpl_GetObjectIndex(This,NULL,ppenum,&index)==S_FALSE)
445 return E_FAIL;
446
447 /* release the object if it's found */
448 IUnknown_Release(This->bindCtxTable[index].pObj);
449
450 /* remove the object from the table with a left-shifting of all objects in the right side */
451 for(j=index; j<This->bindCtxTableLastIndex-1; j++)
452 This->bindCtxTable[j]= This->bindCtxTable[j+1];
453
454 This->bindCtxTableLastIndex--;
455
456 return S_OK;
457}
458
459/******************************************************************************
460 * BindCtx_EnumObjectParam
461 ******************************************************************************/
462HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
463{
464 FIXME("(%p,%p),stub!\n",iface,pszkey);
465 return E_NOTIMPL;
466}
467
468/********************************************************************************
469 * GetObjectIndex (local function)
470 ********************************************************************************/
471HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
472 IUnknown* punk,
473 LPOLESTR pszkey,
474 DWORD *index)
475{
476
477 DWORD i;
478 BYTE found=0;
479
480 TRACE("(%p,%p,%p,%p)\n",This,punk,pszkey,index);
481
482 if (punk==NULL)
483 /* search object identified by a register key */
484 for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++){
485
486 if(This->bindCtxTable[i].regType==1){
487
488 if ( ( (This->bindCtxTable[i].pkeyObj==NULL) && (pszkey==NULL) ) ||
489 ( (This->bindCtxTable[i].pkeyObj!=NULL) &&
490 (pszkey!=NULL) &&
491 (lstrcmpW(This->bindCtxTable[i].pkeyObj,pszkey)==0)
492 )
493 )
494
495 found=1;
496 }
497 }
498 else
499 /* search object identified by a moniker*/
500 for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
501 if(This->bindCtxTable[i].pObj==punk)
502 found=1;
503
504 if (index != NULL)
505 *index=i-1;
506
507 if (found)
508 return S_OK;
509 else
510 return S_FALSE;
511}
512
513/******************************************************************************
514 * CreateBindCtx16
515 ******************************************************************************/
516HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC * ppbc)
517{
518 FIXME("(%ld,%p),stub!\n",reserved,ppbc);
519 return E_NOTIMPL;
520}
521
522/******************************************************************************
523 * CreateBindCtx
524 ******************************************************************************/
525HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
526{
527 BindCtxImpl* newBindCtx = 0;
528 HRESULT hr;
529 IID riid=IID_IBindCtx;
530
531 TRACE("(%ld,%p)\n",reserved,ppbc);
532
533 newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
534
535 if (newBindCtx == 0)
536 return E_OUTOFMEMORY;
537
538 hr = BindCtxImpl_Construct(newBindCtx);
539
540 if (FAILED(hr)){
541
542 HeapFree(GetProcessHeap(),0,newBindCtx);
543 return hr;
544 }
545
546 hr = BindCtxImpl_QueryInterface((IBindCtx*)newBindCtx,&riid,(void**)ppbc);
547
548 return hr;
549}
Note: See TracBrowser for help on using the repository browser.