Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbindctx.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
1.7.6.1
|