~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ole32/bindctx.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  *                            BindCtx implementation
  3  *
  4  *  Copyright 1999  Noomen Hamza
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include <stdarg.h>
 22 #include <string.h>
 23 
 24 #define COBJMACROS
 25 
 26 #include "winerror.h"
 27 #include "windef.h"
 28 #include "winbase.h"
 29 #include "winnls.h"
 30 #include "objbase.h"
 31 
 32 #include "wine/debug.h"
 33 
 34 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 35 
 36 #define  BINDCTX_FIRST_TABLE_SIZE 4
 37 
 38 /* data structure of the BindCtx table elements */
 39 typedef struct BindCtxObject{
 40 
 41     IUnknown*   pObj; /* point on a bound object */
 42 
 43     LPOLESTR  pkeyObj; /* key associated to this bound object */
 44 
 45     BYTE regType; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
 46 
 47 } BindCtxObject;
 48 
 49 /* BindCtx data structure */
 50 typedef struct BindCtxImpl{
 51 
 52     const IBindCtxVtbl *lpVtbl; /* VTable relative to the IBindCtx interface.*/
 53 
 54     LONG ref; /* reference counter for this object */
 55 
 56     BindCtxObject* bindCtxTable; /* this is a table in which all bounded objects are stored*/
 57     DWORD          bindCtxTableLastIndex;  /* first free index in the table */
 58     DWORD          bindCtxTableSize;   /* size table */
 59 
 60     BIND_OPTS2 bindOption2; /* a structure which contains the bind options*/
 61 
 62 } BindCtxImpl;
 63 
 64 /* IBindCtx prototype functions : */
 65 static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx*);
 66 static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl*, IUnknown*, LPOLESTR, DWORD *);
 67 static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *);
 68 
 69 /*******************************************************************************
 70  *        BindCtx_QueryInterface
 71  *******************************************************************************/
 72 static HRESULT WINAPI
 73 BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
 74 {
 75     BindCtxImpl *This = (BindCtxImpl *)iface;
 76 
 77     TRACE("(%p %s %p)\n",This, debugstr_guid(riid), ppvObject);
 78 
 79     /* Perform a sanity check on the parameters.*/
 80     if (!ppvObject)
 81         return E_POINTER;
 82 
 83     /* Initialize the return parameter.*/
 84     *ppvObject = 0;
 85 
 86     /* Compare the riid with the interface IDs implemented by this object.*/
 87     if (IsEqualIID(&IID_IUnknown, riid) ||
 88         IsEqualIID(&IID_IBindCtx, riid))
 89     {
 90         *ppvObject = This;
 91         IBindCtx_AddRef(iface);
 92         return S_OK;
 93     }
 94 
 95     return E_NOINTERFACE;
 96 }
 97 
 98 /******************************************************************************
 99  *       BindCtx_AddRef
100  ******************************************************************************/
101 static ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface)
102 {
103     BindCtxImpl *This = (BindCtxImpl *)iface;
104 
105     TRACE("(%p)\n",This);
106 
107     return InterlockedIncrement(&This->ref);
108 }
109 
110 /******************************************************************************
111  *        BindCtx_Destroy    (local function)
112  *******************************************************************************/
113 static HRESULT BindCtxImpl_Destroy(BindCtxImpl* This)
114 {
115     TRACE("(%p)\n",This);
116 
117     /* free the table space memory */
118     HeapFree(GetProcessHeap(),0,This->bindCtxTable);
119 
120     /* free the bindctx structure */
121     HeapFree(GetProcessHeap(),0,This);
122 
123     return S_OK;
124 }
125 
126 /******************************************************************************
127  *        BindCtx_Release
128  ******************************************************************************/
129 static ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface)
130 {
131     BindCtxImpl *This = (BindCtxImpl *)iface;
132     ULONG ref;
133 
134     TRACE("(%p)\n",This);
135 
136     ref = InterlockedDecrement(&This->ref);
137     if (ref == 0)
138     {
139         /* release all registered objects */
140         BindCtxImpl_ReleaseBoundObjects((IBindCtx*)This);
141 
142         BindCtxImpl_Destroy(This);
143     }
144     return ref;
145 }
146 
147 
148 /******************************************************************************
149  *        BindCtx_RegisterObjectBound
150  ******************************************************************************/
151 static HRESULT WINAPI
152 BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
153 {
154     BindCtxImpl *This = (BindCtxImpl *)iface;
155     DWORD lastIndex=This->bindCtxTableLastIndex;
156 
157     TRACE("(%p,%p)\n",This,punk);
158 
159     if (punk==NULL)
160         return S_OK;
161 
162     if (lastIndex == This->bindCtxTableSize)
163     {
164         HRESULT hr = BindCtxImpl_ExpandTable(This);
165         if (FAILED(hr))
166             return hr;
167     }
168 
169     IUnknown_AddRef(punk);
170 
171     /* put the object in the first free element in the table */
172     This->bindCtxTable[lastIndex].pObj = punk;
173     This->bindCtxTable[lastIndex].pkeyObj = NULL;
174     This->bindCtxTable[lastIndex].regType = 0;
175     lastIndex= ++This->bindCtxTableLastIndex;
176 
177     return S_OK;
178 }
179 
180 /******************************************************************************
181  *        BindCtx_RevokeObjectBound
182  ******************************************************************************/
183 static HRESULT WINAPI
184 BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
185 {
186     DWORD index,j;
187 
188     BindCtxImpl *This = (BindCtxImpl *)iface;
189 
190     TRACE("(%p,%p)\n",This,punk);
191 
192     if (!punk)
193         return E_INVALIDARG;
194 
195     /* check if the object was registered or not */
196     if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
197         return MK_E_NOTBOUND;
198 
199     if(This->bindCtxTable[index].pObj)
200         IUnknown_Release(This->bindCtxTable[index].pObj);
201     HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
202     
203     /* left-shift all elements in the right side of the current revoked object */
204     for(j=index; j<This->bindCtxTableLastIndex-1; j++)
205         This->bindCtxTable[j]= This->bindCtxTable[j+1];
206 
207     This->bindCtxTableLastIndex--;
208 
209     return S_OK;
210 }
211 
212 /******************************************************************************
213  *        BindCtx_ReleaseBoundObjects
214  ******************************************************************************/
215 static HRESULT WINAPI
216 BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface)
217 {
218     DWORD i;
219 
220     BindCtxImpl *This = (BindCtxImpl *)iface;
221 
222     TRACE("(%p)\n",This);
223 
224     for(i=0;i<This->bindCtxTableLastIndex;i++)
225     {
226         if(This->bindCtxTable[i].pObj)
227             IUnknown_Release(This->bindCtxTable[i].pObj);
228         HeapFree(GetProcessHeap(),0,This->bindCtxTable[i].pkeyObj);
229     }
230     
231     This->bindCtxTableLastIndex = 0;
232 
233     return S_OK;
234 }
235 
236 /******************************************************************************
237  *        BindCtx_SetBindOptions
238  ******************************************************************************/
239 static HRESULT WINAPI
240 BindCtxImpl_SetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
241 {
242     BindCtxImpl *This = (BindCtxImpl *)iface;
243 
244     TRACE("(%p,%p)\n",This,pbindopts);
245 
246     if (pbindopts==NULL)
247         return E_POINTER;
248 
249     if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
250     {
251         WARN("invalid size\n");
252         return E_INVALIDARG; /* FIXME : not verified */
253     }
254     memcpy(&This->bindOption2, pbindopts, pbindopts->cbStruct);
255     return S_OK;
256 }
257 
258 /******************************************************************************
259  *        BindCtx_GetBindOptions
260  ******************************************************************************/
261 static HRESULT WINAPI
262 BindCtxImpl_GetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
263 {
264     BindCtxImpl *This = (BindCtxImpl *)iface;
265     ULONG cbStruct;
266 
267     TRACE("(%p,%p)\n",This,pbindopts);
268 
269     if (pbindopts==NULL)
270         return E_POINTER;
271 
272     cbStruct = pbindopts->cbStruct;
273     if (cbStruct > sizeof(BIND_OPTS2))
274         cbStruct = sizeof(BIND_OPTS2);
275 
276     memcpy(pbindopts, &This->bindOption2, cbStruct);
277     pbindopts->cbStruct = cbStruct;
278 
279     return S_OK;
280 }
281 
282 /******************************************************************************
283  *        BindCtx_GetRunningObjectTable
284  ******************************************************************************/
285 static HRESULT WINAPI
286 BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot)
287 {
288     HRESULT res;
289 
290     BindCtxImpl *This = (BindCtxImpl *)iface;
291 
292     TRACE("(%p,%p)\n",This,pprot);
293 
294     if (pprot==NULL)
295         return E_POINTER;
296 
297     res=GetRunningObjectTable(0, pprot);
298 
299     return res;
300 }
301 
302 /******************************************************************************
303  *        BindCtx_RegisterObjectParam
304  ******************************************************************************/
305 static HRESULT WINAPI
306 BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
307 {
308     DWORD index=0;
309     BindCtxImpl *This = (BindCtxImpl *)iface;
310 
311     TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
312 
313     if (punk==NULL)
314         return E_INVALIDARG;
315 
316     if (pszkey!=NULL && BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_OK)
317     {
318         TRACE("Overwriting existing key\n");
319         if(This->bindCtxTable[index].pObj!=NULL)
320             IUnknown_Release(This->bindCtxTable[index].pObj);
321         This->bindCtxTable[index].pObj=punk;
322         IUnknown_AddRef(punk);
323         return S_OK;
324     }
325 
326     if (This->bindCtxTableLastIndex == This->bindCtxTableSize)
327     {
328         HRESULT hr = BindCtxImpl_ExpandTable(This);
329         if (FAILED(hr))
330             return hr;
331     }
332 
333     This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
334     This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
335 
336     if (pszkey==NULL)
337 
338         This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=NULL;
339 
340     else
341     {
342 
343         This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=
344             HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR)*(1+lstrlenW(pszkey))));
345 
346         if (This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj==NULL)
347             return E_OUTOFMEMORY;
348         lstrcpyW(This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj,pszkey);
349     }
350 
351     This->bindCtxTableLastIndex++;
352 
353     IUnknown_AddRef(punk);
354     return S_OK;
355 }
356 
357 /******************************************************************************
358  *        BindCtx_GetObjectParam
359  ******************************************************************************/
360 static HRESULT WINAPI
361 BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk)
362 {
363     DWORD index;
364     BindCtxImpl *This = (BindCtxImpl *)iface;
365 
366     TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
367 
368     if (punk==NULL)
369         return E_POINTER;
370 
371     *punk=0;
372 
373     if (BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_FALSE)
374         return E_FAIL;
375 
376     IUnknown_AddRef(This->bindCtxTable[index].pObj);
377 
378     *punk = This->bindCtxTable[index].pObj;
379 
380     return S_OK;
381 }
382 
383 /******************************************************************************
384  *        BindCtx_RevokeObjectParam
385  ******************************************************************************/
386 static HRESULT WINAPI
387 BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
388 {
389     DWORD index,j;
390 
391     BindCtxImpl *This = (BindCtxImpl *)iface;
392 
393     TRACE("(%p,%s)\n",This,debugstr_w(ppenum));
394 
395     if (BindCtxImpl_GetObjectIndex(This,NULL,ppenum,&index)==S_FALSE)
396         return E_FAIL;
397 
398     /* release the object if it's found */
399     if(This->bindCtxTable[index].pObj)
400         IUnknown_Release(This->bindCtxTable[index].pObj);
401     HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
402     
403     /* remove the object from the table with a left-shifting of all objects in the right side */
404     for(j=index; j<This->bindCtxTableLastIndex-1; j++)
405         This->bindCtxTable[j]= This->bindCtxTable[j+1];
406 
407     This->bindCtxTableLastIndex--;
408 
409     return S_OK;
410 }
411 
412 /******************************************************************************
413  *        BindCtx_EnumObjectParam
414  ******************************************************************************/
415 static HRESULT WINAPI
416 BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
417 {
418     TRACE("(%p,%p)\n",iface,pszkey);
419 
420     *pszkey = NULL;
421 
422     /* not implemented in native either */
423     return E_NOTIMPL;
424 }
425 
426 /********************************************************************************
427  *        GetObjectIndex (local function)
428  ********************************************************************************/
429 static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
430                                           IUnknown* punk,
431                                           LPOLESTR pszkey,
432                                           DWORD *index)
433 {
434 
435     DWORD i;
436     BYTE found=0;
437 
438     TRACE("(%p,%p,%p,%p)\n",This,punk,pszkey,index);
439 
440     if (punk==NULL)
441         /* search object identified by a register key */
442         for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
443         {
444             if(This->bindCtxTable[i].regType==1){
445 
446                 if ( ( (This->bindCtxTable[i].pkeyObj==NULL) && (pszkey==NULL) ) ||
447                      ( (This->bindCtxTable[i].pkeyObj!=NULL) &&
448                        (pszkey!=NULL) &&
449                        (lstrcmpW(This->bindCtxTable[i].pkeyObj,pszkey)==0)
450                      )
451                    )
452 
453                     found=1;
454             }
455         }
456     else
457         /* search object identified by a moniker*/
458         for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
459             if(This->bindCtxTable[i].pObj==punk)
460                 found=1;
461 
462     if (index != NULL)
463         *index=i-1;
464 
465     if (found)
466         return S_OK;
467     TRACE("key not found\n");
468     return S_FALSE;
469 }
470 
471 static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *This)
472 {
473     if (!This->bindCtxTableSize)
474     {
475         This->bindCtxTableSize = BINDCTX_FIRST_TABLE_SIZE;
476         This->bindCtxTable = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
477                                        This->bindCtxTableSize * sizeof(BindCtxObject));
478     }
479     else
480     {
481         This->bindCtxTableSize *= 2;
482 
483         This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
484                                          This->bindCtxTableSize * sizeof(BindCtxObject));
485     }
486 
487     if (!This->bindCtxTable)
488         return E_OUTOFMEMORY;
489 
490     return S_OK;
491 }
492 
493 
494 /* Virtual function table for the BindCtx class. */
495 static const IBindCtxVtbl VT_BindCtxImpl =
496 {
497     BindCtxImpl_QueryInterface,
498     BindCtxImpl_AddRef,
499     BindCtxImpl_Release,
500     BindCtxImpl_RegisterObjectBound,
501     BindCtxImpl_RevokeObjectBound,
502     BindCtxImpl_ReleaseBoundObjects,
503     BindCtxImpl_SetBindOptions,
504     BindCtxImpl_GetBindOptions,
505     BindCtxImpl_GetRunningObjectTable,
506     BindCtxImpl_RegisterObjectParam,
507     BindCtxImpl_GetObjectParam,
508     BindCtxImpl_EnumObjectParam,
509     BindCtxImpl_RevokeObjectParam
510 };
511 
512 /******************************************************************************
513  *         BindCtx_Construct (local function)
514  *******************************************************************************/
515 static HRESULT BindCtxImpl_Construct(BindCtxImpl* This)
516 {
517     TRACE("(%p)\n",This);
518 
519     /* Initialize the virtual function table.*/
520     This->lpVtbl       = &VT_BindCtxImpl;
521     This->ref          = 0;
522 
523     /* Initialize the BIND_OPTS2 structure */
524     This->bindOption2.cbStruct  = sizeof(BIND_OPTS2);
525     This->bindOption2.grfFlags = 0;
526     This->bindOption2.grfMode = STGM_READWRITE;
527     This->bindOption2.dwTickCountDeadline = 0;
528 
529     This->bindOption2.dwTrackFlags = 0;
530     This->bindOption2.dwClassContext = CLSCTX_SERVER;
531     This->bindOption2.locale = GetThreadLocale();
532     This->bindOption2.pServerInfo = 0;
533 
534     /* Initialize the bindctx table */
535     This->bindCtxTableSize=0;
536     This->bindCtxTableLastIndex=0;
537     This->bindCtxTable = NULL;
538 
539     return S_OK;
540 }
541 
542 /******************************************************************************
543  *        CreateBindCtx (OLE32.@)
544  *
545  * Creates a bind context. A bind context encompasses information and options
546  * used when binding to a moniker.
547  *
548  * PARAMS
549  *  reserved [I] Reserved. Set to 0.
550  *  ppbc     [O] Address that receives the bind context object.
551  *
552  * RETURNS
553  *  Success: S_OK.
554  *  Failure: Any HRESULT code.
555  */
556 HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
557 {
558     BindCtxImpl* newBindCtx = 0;
559     HRESULT hr;
560     IID riid=IID_IBindCtx;
561 
562     TRACE("(%d,%p)\n",reserved,ppbc);
563 
564     if (!ppbc) return E_INVALIDARG;
565 
566     *ppbc = NULL;
567 
568     if (reserved != 0)
569     {
570         ERR("reserved should be 0, not 0x%x\n", reserved);
571         return E_INVALIDARG;
572     }
573 
574     newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
575     if (newBindCtx == 0)
576         return E_OUTOFMEMORY;
577 
578     hr = BindCtxImpl_Construct(newBindCtx);
579     if (FAILED(hr))
580     {
581         HeapFree(GetProcessHeap(),0,newBindCtx);
582         return hr;
583     }
584 
585     hr = BindCtxImpl_QueryInterface((IBindCtx*)newBindCtx,&riid,(void**)ppbc);
586 
587     return hr;
588 }
589 
590 /******************************************************************************
591  *              BindMoniker        [OLE32.@]
592  *
593  * Binds to a moniker.
594  *
595  * PARAMS
596  *  pmk      [I] Moniker to bind to.
597  *  grfOpt   [I] Reserved option flags. Set to 0.
598  *  riid     [I] ID of the interface to bind to.
599  *  pvResult [O] Address that receives the interface of the object that was bound to.
600  *
601  * RETURNS
602  *  Success: S_OK.
603  *  Failure: Any HRESULT code.
604  */
605 HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID riid, LPVOID * ppvResult)
606 {
607     HRESULT res;
608     IBindCtx * pbc;
609 
610     TRACE("(%p, %x, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult);
611 
612     res = CreateBindCtx(grfOpt, &pbc);
613     if (SUCCEEDED(res))
614     {
615         res = IMoniker_BindToObject(pmk, pbc, NULL, riid, ppvResult);
616         IBindCtx_Release(pbc);
617     }
618     return res;
619 }
620 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.