ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bindctx.c
Go to the documentation of this file.
00001 /*
00002  *                        BindCtx implementation
00003  *
00004  *  Copyright 1999  Noomen Hamza
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include <stdarg.h>
00022 #include <string.h>
00023 
00024 #define COBJMACROS
00025 
00026 #include "winerror.h"
00027 #include "windef.h"
00028 #include "winbase.h"
00029 #include "winnls.h"
00030 #include "objbase.h"
00031 
00032 #include "wine/debug.h"
00033 
00034 WINE_DEFAULT_DEBUG_CHANNEL(ole);
00035 
00036 #define  BINDCTX_FIRST_TABLE_SIZE 4
00037 
00038 /* data structure of the BindCtx table elements */
00039 typedef struct BindCtxObject{
00040 
00041     IUnknown*   pObj; /* point on a bound object */
00042 
00043     LPOLESTR  pkeyObj; /* key associated to this bound object */
00044 
00045     BYTE regType; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
00046 
00047 } BindCtxObject;
00048 
00049 /* BindCtx data structure */
00050 typedef struct BindCtxImpl{
00051 
00052     IBindCtx IBindCtx_iface;
00053 
00054     LONG ref; /* reference counter for this object */
00055 
00056     BindCtxObject* bindCtxTable; /* this is a table in which all bounded objects are stored*/
00057     DWORD          bindCtxTableLastIndex;  /* first free index in the table */
00058     DWORD          bindCtxTableSize;   /* size table */
00059 
00060     BIND_OPTS2 bindOption2; /* a structure which contains the bind options*/
00061 
00062 } BindCtxImpl;
00063 
00064 /* IBindCtx prototype functions : */
00065 static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx*);
00066 static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl*, IUnknown*, LPOLESTR, DWORD *);
00067 static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *);
00068 
00069 static inline BindCtxImpl *impl_from_IBindCtx(IBindCtx *iface)
00070 {
00071 return CONTAINING_RECORD(iface, BindCtxImpl, IBindCtx_iface);
00072 }
00073 
00074 /*******************************************************************************
00075  *        BindCtx_QueryInterface
00076  *******************************************************************************/
00077 static HRESULT WINAPI
00078 BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
00079 {
00080     BindCtxImpl *This = impl_from_IBindCtx(iface);
00081 
00082     TRACE("(%p %s %p)\n",This, debugstr_guid(riid), ppvObject);
00083 
00084     /* Perform a sanity check on the parameters.*/
00085     if (!ppvObject)
00086         return E_POINTER;
00087 
00088     /* Initialize the return parameter.*/
00089     *ppvObject = 0;
00090 
00091     /* Compare the riid with the interface IDs implemented by this object.*/
00092     if (IsEqualIID(&IID_IUnknown, riid) ||
00093         IsEqualIID(&IID_IBindCtx, riid))
00094     {
00095         *ppvObject = This;
00096         IBindCtx_AddRef(iface);
00097         return S_OK;
00098     }
00099 
00100     return E_NOINTERFACE;
00101 }
00102 
00103 /******************************************************************************
00104  *       BindCtx_AddRef
00105  ******************************************************************************/
00106 static ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface)
00107 {
00108     BindCtxImpl *This = impl_from_IBindCtx(iface);
00109 
00110     TRACE("(%p)\n",This);
00111 
00112     return InterlockedIncrement(&This->ref);
00113 }
00114 
00115 /******************************************************************************
00116  *        BindCtx_Destroy    (local function)
00117  *******************************************************************************/
00118 static HRESULT BindCtxImpl_Destroy(BindCtxImpl* This)
00119 {
00120     TRACE("(%p)\n",This);
00121 
00122     /* free the table space memory */
00123     HeapFree(GetProcessHeap(),0,This->bindCtxTable);
00124 
00125     /* free the bindctx structure */
00126     HeapFree(GetProcessHeap(),0,This);
00127 
00128     return S_OK;
00129 }
00130 
00131 /******************************************************************************
00132  *        BindCtx_Release
00133  ******************************************************************************/
00134 static ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface)
00135 {
00136     BindCtxImpl *This = impl_from_IBindCtx(iface);
00137     ULONG ref;
00138 
00139     TRACE("(%p)\n",This);
00140 
00141     ref = InterlockedDecrement(&This->ref);
00142     if (ref == 0)
00143     {
00144         /* release all registered objects */
00145         BindCtxImpl_ReleaseBoundObjects(&This->IBindCtx_iface);
00146 
00147         BindCtxImpl_Destroy(This);
00148     }
00149     return ref;
00150 }
00151 
00152 
00153 /******************************************************************************
00154  *        BindCtx_RegisterObjectBound
00155  ******************************************************************************/
00156 static HRESULT WINAPI
00157 BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
00158 {
00159     BindCtxImpl *This = impl_from_IBindCtx(iface);
00160     DWORD lastIndex=This->bindCtxTableLastIndex;
00161 
00162     TRACE("(%p,%p)\n",This,punk);
00163 
00164     if (punk==NULL)
00165         return S_OK;
00166 
00167     if (lastIndex == This->bindCtxTableSize)
00168     {
00169         HRESULT hr = BindCtxImpl_ExpandTable(This);
00170         if (FAILED(hr))
00171             return hr;
00172     }
00173 
00174     IUnknown_AddRef(punk);
00175 
00176     /* put the object in the first free element in the table */
00177     This->bindCtxTable[lastIndex].pObj = punk;
00178     This->bindCtxTable[lastIndex].pkeyObj = NULL;
00179     This->bindCtxTable[lastIndex].regType = 0;
00180     lastIndex= ++This->bindCtxTableLastIndex;
00181 
00182     return S_OK;
00183 }
00184 
00185 /******************************************************************************
00186  *        BindCtx_RevokeObjectBound
00187  ******************************************************************************/
00188 static HRESULT WINAPI
00189 BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
00190 {
00191     DWORD index,j;
00192 
00193     BindCtxImpl *This = impl_from_IBindCtx(iface);
00194 
00195     TRACE("(%p,%p)\n",This,punk);
00196 
00197     if (!punk)
00198         return E_INVALIDARG;
00199 
00200     /* check if the object was registered or not */
00201     if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
00202         return MK_E_NOTBOUND;
00203 
00204     if(This->bindCtxTable[index].pObj)
00205         IUnknown_Release(This->bindCtxTable[index].pObj);
00206     HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
00207     
00208     /* left-shift all elements in the right side of the current revoked object */
00209     for(j=index; j<This->bindCtxTableLastIndex-1; j++)
00210         This->bindCtxTable[j]= This->bindCtxTable[j+1];
00211 
00212     This->bindCtxTableLastIndex--;
00213 
00214     return S_OK;
00215 }
00216 
00217 /******************************************************************************
00218  *        BindCtx_ReleaseBoundObjects
00219  ******************************************************************************/
00220 static HRESULT WINAPI
00221 BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface)
00222 {
00223     DWORD i;
00224 
00225     BindCtxImpl *This = impl_from_IBindCtx(iface);
00226 
00227     TRACE("(%p)\n",This);
00228 
00229     for(i=0;i<This->bindCtxTableLastIndex;i++)
00230     {
00231         if(This->bindCtxTable[i].pObj)
00232             IUnknown_Release(This->bindCtxTable[i].pObj);
00233         HeapFree(GetProcessHeap(),0,This->bindCtxTable[i].pkeyObj);
00234     }
00235     
00236     This->bindCtxTableLastIndex = 0;
00237 
00238     return S_OK;
00239 }
00240 
00241 /******************************************************************************
00242  *        BindCtx_SetBindOptions
00243  ******************************************************************************/
00244 static HRESULT WINAPI
00245 BindCtxImpl_SetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
00246 {
00247     BindCtxImpl *This = impl_from_IBindCtx(iface);
00248 
00249     TRACE("(%p,%p)\n",This,pbindopts);
00250 
00251     if (pbindopts==NULL)
00252         return E_POINTER;
00253 
00254     if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
00255     {
00256         WARN("invalid size\n");
00257         return E_INVALIDARG; /* FIXME : not verified */
00258     }
00259     memcpy(&This->bindOption2, pbindopts, pbindopts->cbStruct);
00260     return S_OK;
00261 }
00262 
00263 /******************************************************************************
00264  *        BindCtx_GetBindOptions
00265  ******************************************************************************/
00266 static HRESULT WINAPI
00267 BindCtxImpl_GetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
00268 {
00269     BindCtxImpl *This = impl_from_IBindCtx(iface);
00270     ULONG cbStruct;
00271 
00272     TRACE("(%p,%p)\n",This,pbindopts);
00273 
00274     if (pbindopts==NULL)
00275         return E_POINTER;
00276 
00277     cbStruct = pbindopts->cbStruct;
00278     if (cbStruct > sizeof(BIND_OPTS2))
00279         cbStruct = sizeof(BIND_OPTS2);
00280 
00281     memcpy(pbindopts, &This->bindOption2, cbStruct);
00282     pbindopts->cbStruct = cbStruct;
00283 
00284     return S_OK;
00285 }
00286 
00287 /******************************************************************************
00288  *        BindCtx_GetRunningObjectTable
00289  ******************************************************************************/
00290 static HRESULT WINAPI
00291 BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot)
00292 {
00293     BindCtxImpl *This = impl_from_IBindCtx(iface);
00294 
00295     TRACE("(%p,%p)\n",This,pprot);
00296 
00297     if (pprot==NULL)
00298         return E_POINTER;
00299 
00300     return GetRunningObjectTable(0, pprot);
00301 }
00302 
00303 /******************************************************************************
00304  *        BindCtx_RegisterObjectParam
00305  ******************************************************************************/
00306 static HRESULT WINAPI
00307 BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
00308 {
00309     DWORD index=0;
00310     BindCtxImpl *This = impl_from_IBindCtx(iface);
00311 
00312     TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
00313 
00314     if (punk==NULL)
00315         return E_INVALIDARG;
00316 
00317     if (pszkey!=NULL && BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_OK)
00318     {
00319     TRACE("Overwriting existing key\n");
00320     if(This->bindCtxTable[index].pObj!=NULL)
00321         IUnknown_Release(This->bindCtxTable[index].pObj);
00322     This->bindCtxTable[index].pObj=punk;
00323     IUnknown_AddRef(punk);
00324     return S_OK;
00325     }
00326 
00327     if (This->bindCtxTableLastIndex == This->bindCtxTableSize)
00328     {
00329         HRESULT hr = BindCtxImpl_ExpandTable(This);
00330         if (FAILED(hr))
00331             return hr;
00332     }
00333 
00334     This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
00335     This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
00336 
00337     if (pszkey==NULL)
00338 
00339         This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=NULL;
00340 
00341     else
00342     {
00343 
00344         This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=
00345             HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR)*(1+lstrlenW(pszkey))));
00346 
00347         if (This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj==NULL)
00348             return E_OUTOFMEMORY;
00349         lstrcpyW(This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj,pszkey);
00350     }
00351 
00352     This->bindCtxTableLastIndex++;
00353 
00354     IUnknown_AddRef(punk);
00355     return S_OK;
00356 }
00357 
00358 /******************************************************************************
00359  *        BindCtx_GetObjectParam
00360  ******************************************************************************/
00361 static HRESULT WINAPI
00362 BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk)
00363 {
00364     DWORD index;
00365     BindCtxImpl *This = impl_from_IBindCtx(iface);
00366 
00367     TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
00368 
00369     if (punk==NULL)
00370         return E_POINTER;
00371 
00372     *punk=0;
00373 
00374     if (BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_FALSE)
00375         return E_FAIL;
00376 
00377     IUnknown_AddRef(This->bindCtxTable[index].pObj);
00378 
00379     *punk = This->bindCtxTable[index].pObj;
00380 
00381     return S_OK;
00382 }
00383 
00384 /******************************************************************************
00385  *        BindCtx_RevokeObjectParam
00386  ******************************************************************************/
00387 static HRESULT WINAPI
00388 BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
00389 {
00390     DWORD index,j;
00391 
00392     BindCtxImpl *This = impl_from_IBindCtx(iface);
00393 
00394     TRACE("(%p,%s)\n",This,debugstr_w(ppenum));
00395 
00396     if (BindCtxImpl_GetObjectIndex(This,NULL,ppenum,&index)==S_FALSE)
00397         return E_FAIL;
00398 
00399     /* release the object if it's found */
00400     if(This->bindCtxTable[index].pObj)
00401         IUnknown_Release(This->bindCtxTable[index].pObj);
00402     HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
00403     
00404     /* remove the object from the table with a left-shifting of all objects in the right side */
00405     for(j=index; j<This->bindCtxTableLastIndex-1; j++)
00406         This->bindCtxTable[j]= This->bindCtxTable[j+1];
00407 
00408     This->bindCtxTableLastIndex--;
00409 
00410     return S_OK;
00411 }
00412 
00413 /******************************************************************************
00414  *        BindCtx_EnumObjectParam
00415  ******************************************************************************/
00416 static HRESULT WINAPI
00417 BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
00418 {
00419     TRACE("(%p,%p)\n",iface,pszkey);
00420 
00421     *pszkey = NULL;
00422 
00423     /* not implemented in native either */
00424     return E_NOTIMPL;
00425 }
00426 
00427 /********************************************************************************
00428  *        GetObjectIndex (local function)
00429  ********************************************************************************/
00430 static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
00431                                           IUnknown* punk,
00432                                           LPOLESTR pszkey,
00433                                           DWORD *index)
00434 {
00435 
00436     DWORD i;
00437     BYTE found=0;
00438 
00439     TRACE("(%p,%p,%p,%p)\n",This,punk,pszkey,index);
00440 
00441     if (punk==NULL)
00442         /* search object identified by a register key */
00443         for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
00444         {
00445             if(This->bindCtxTable[i].regType==1){
00446 
00447                 if ( ( (This->bindCtxTable[i].pkeyObj==NULL) && (pszkey==NULL) ) ||
00448                      ( (This->bindCtxTable[i].pkeyObj!=NULL) &&
00449                        (pszkey!=NULL) &&
00450                        (lstrcmpW(This->bindCtxTable[i].pkeyObj,pszkey)==0)
00451                      )
00452                    )
00453 
00454                     found=1;
00455             }
00456         }
00457     else
00458         /* search object identified by a moniker*/
00459         for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
00460             if(This->bindCtxTable[i].pObj==punk)
00461                 found=1;
00462 
00463     if (index != NULL)
00464         *index=i-1;
00465 
00466     if (found)
00467         return S_OK;
00468     TRACE("key not found\n");
00469     return S_FALSE;
00470 }
00471 
00472 static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *This)
00473 {
00474     if (!This->bindCtxTableSize)
00475     {
00476         This->bindCtxTableSize = BINDCTX_FIRST_TABLE_SIZE;
00477         This->bindCtxTable = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
00478                                        This->bindCtxTableSize * sizeof(BindCtxObject));
00479     }
00480     else
00481     {
00482         This->bindCtxTableSize *= 2;
00483 
00484         This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
00485                                          This->bindCtxTableSize * sizeof(BindCtxObject));
00486     }
00487 
00488     if (!This->bindCtxTable)
00489         return E_OUTOFMEMORY;
00490 
00491     return S_OK;
00492 }
00493 
00494 
00495 /* Virtual function table for the BindCtx class. */
00496 static const IBindCtxVtbl VT_BindCtxImpl =
00497 {
00498     BindCtxImpl_QueryInterface,
00499     BindCtxImpl_AddRef,
00500     BindCtxImpl_Release,
00501     BindCtxImpl_RegisterObjectBound,
00502     BindCtxImpl_RevokeObjectBound,
00503     BindCtxImpl_ReleaseBoundObjects,
00504     BindCtxImpl_SetBindOptions,
00505     BindCtxImpl_GetBindOptions,
00506     BindCtxImpl_GetRunningObjectTable,
00507     BindCtxImpl_RegisterObjectParam,
00508     BindCtxImpl_GetObjectParam,
00509     BindCtxImpl_EnumObjectParam,
00510     BindCtxImpl_RevokeObjectParam
00511 };
00512 
00513 /******************************************************************************
00514  *         BindCtx_Construct (local function)
00515  *******************************************************************************/
00516 static HRESULT BindCtxImpl_Construct(BindCtxImpl* This)
00517 {
00518     TRACE("(%p)\n",This);
00519 
00520     /* Initialize the virtual function table.*/
00521     This->IBindCtx_iface.lpVtbl = &VT_BindCtxImpl;
00522     This->ref          = 0;
00523 
00524     /* Initialize the BIND_OPTS2 structure */
00525     This->bindOption2.cbStruct  = sizeof(BIND_OPTS2);
00526     This->bindOption2.grfFlags = 0;
00527     This->bindOption2.grfMode = STGM_READWRITE;
00528     This->bindOption2.dwTickCountDeadline = 0;
00529 
00530     This->bindOption2.dwTrackFlags = 0;
00531     This->bindOption2.dwClassContext = CLSCTX_SERVER;
00532     This->bindOption2.locale = GetThreadLocale();
00533     This->bindOption2.pServerInfo = 0;
00534 
00535     /* Initialize the bindctx table */
00536     This->bindCtxTableSize=0;
00537     This->bindCtxTableLastIndex=0;
00538     This->bindCtxTable = NULL;
00539 
00540     return S_OK;
00541 }
00542 
00543 /******************************************************************************
00544  *        CreateBindCtx (OLE32.@)
00545  *
00546  * Creates a bind context. A bind context encompasses information and options
00547  * used when binding to a moniker.
00548  *
00549  * PARAMS
00550  *  reserved [I] Reserved. Set to 0.
00551  *  ppbc     [O] Address that receives the bind context object.
00552  *
00553  * RETURNS
00554  *  Success: S_OK.
00555  *  Failure: Any HRESULT code.
00556  */
00557 HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
00558 {
00559     BindCtxImpl* newBindCtx;
00560     HRESULT hr;
00561 
00562     TRACE("(%d,%p)\n",reserved,ppbc);
00563 
00564     if (!ppbc) return E_INVALIDARG;
00565 
00566     *ppbc = NULL;
00567 
00568     if (reserved != 0)
00569     {
00570         ERR("reserved should be 0, not 0x%x\n", reserved);
00571         return E_INVALIDARG;
00572     }
00573 
00574     newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
00575     if (newBindCtx == 0)
00576         return E_OUTOFMEMORY;
00577 
00578     hr = BindCtxImpl_Construct(newBindCtx);
00579     if (FAILED(hr))
00580     {
00581         HeapFree(GetProcessHeap(),0,newBindCtx);
00582         return hr;
00583     }
00584 
00585     return BindCtxImpl_QueryInterface(&newBindCtx->IBindCtx_iface,&IID_IBindCtx,(void**)ppbc);
00586 }
00587 
00588 /******************************************************************************
00589  *              BindMoniker        [OLE32.@]
00590  *
00591  * Binds to a moniker.
00592  *
00593  * PARAMS
00594  *  pmk      [I] Moniker to bind to.
00595  *  grfOpt   [I] Reserved option flags. Set to 0.
00596  *  riid     [I] ID of the interface to bind to.
00597  *  pvResult [O] Address that receives the interface of the object that was bound to.
00598  *
00599  * RETURNS
00600  *  Success: S_OK.
00601  *  Failure: Any HRESULT code.
00602  */
00603 HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID riid, LPVOID * ppvResult)
00604 {
00605     HRESULT res;
00606     IBindCtx * pbc;
00607 
00608     TRACE("(%p, %x, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult);
00609 
00610     res = CreateBindCtx(grfOpt, &pbc);
00611     if (SUCCEEDED(res))
00612     {
00613         res = IMoniker_BindToObject(pmk, pbc, NULL, riid, ppvResult);
00614         IBindCtx_Release(pbc);
00615     }
00616     return res;
00617 }

Generated on Sat May 26 2012 04:24:04 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.