Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenitemmoniker.c
Go to the documentation of this file.
00001 /* 00002 * ItemMonikers 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 <assert.h> 00022 #include <stdarg.h> 00023 #include <string.h> 00024 00025 #define COBJMACROS 00026 #define NONAMELESSUNION 00027 #define NONAMELESSSTRUCT 00028 00029 #include "winerror.h" 00030 #include "windef.h" 00031 #include "winbase.h" 00032 #include "winuser.h" 00033 #include "winnls.h" 00034 #include "wine/debug.h" 00035 #include "ole2.h" 00036 #include "wine/unicode.h" 00037 #include "moniker.h" 00038 00039 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00040 00041 /* ItemMoniker data structure */ 00042 typedef struct ItemMonikerImpl{ 00043 IMoniker IMoniker_iface; /* VTable relative to the IMoniker interface.*/ 00044 IROTData IROTData_iface; /* VTable relative to the IROTData interface.*/ 00045 LONG ref; 00046 LPOLESTR itemName; /* item name identified by this ItemMoniker */ 00047 LPOLESTR itemDelimiter; /* Delimiter string */ 00048 IUnknown *pMarshal; /* custom marshaler */ 00049 } ItemMonikerImpl; 00050 00051 static inline ItemMonikerImpl *impl_from_IMoniker(IMoniker *iface) 00052 { 00053 return CONTAINING_RECORD(iface, ItemMonikerImpl, IMoniker_iface); 00054 } 00055 00056 static inline ItemMonikerImpl *impl_from_IROTData(IROTData *iface) 00057 { 00058 return CONTAINING_RECORD(iface, ItemMonikerImpl, IROTData_iface); 00059 } 00060 00061 static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* iface); 00062 00063 /******************************************************************************* 00064 * ItemMoniker_QueryInterface 00065 *******************************************************************************/ 00066 static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject) 00067 { 00068 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00069 00070 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject); 00071 00072 if (!ppvObject) 00073 return E_INVALIDARG; 00074 00075 /* Compare the riid with the interface IDs implemented by this object.*/ 00076 if (IsEqualIID(&IID_IUnknown, riid) || 00077 IsEqualIID(&IID_IPersist, riid) || 00078 IsEqualIID(&IID_IPersistStream, riid) || 00079 IsEqualIID(&IID_IMoniker, riid)) 00080 *ppvObject = iface; 00081 else if (IsEqualIID(&IID_IROTData, riid)) 00082 *ppvObject = &This->IROTData_iface; 00083 else if (IsEqualIID(&IID_IMarshal, riid)) 00084 { 00085 HRESULT hr = S_OK; 00086 if (!This->pMarshal) 00087 hr = MonikerMarshal_Create(iface, &This->pMarshal); 00088 if (hr != S_OK) 00089 return hr; 00090 return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject); 00091 } 00092 else 00093 { 00094 *ppvObject = NULL; 00095 return E_NOINTERFACE; 00096 } 00097 00098 IMoniker_AddRef(iface); 00099 return S_OK; 00100 } 00101 00102 /****************************************************************************** 00103 * ItemMoniker_AddRef 00104 ******************************************************************************/ 00105 static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface) 00106 { 00107 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00108 00109 TRACE("(%p)\n",This); 00110 00111 return InterlockedIncrement(&This->ref); 00112 } 00113 00114 /****************************************************************************** 00115 * ItemMoniker_Release 00116 ******************************************************************************/ 00117 static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface) 00118 { 00119 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00120 ULONG ref; 00121 00122 TRACE("(%p)\n",This); 00123 00124 ref = InterlockedDecrement(&This->ref); 00125 00126 /* destroy the object if there's no more reference on it */ 00127 if (ref == 0) ItemMonikerImpl_Destroy(This); 00128 00129 return ref; 00130 } 00131 00132 /****************************************************************************** 00133 * ItemMoniker_GetClassID 00134 ******************************************************************************/ 00135 static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) 00136 { 00137 TRACE("(%p,%p)\n",iface,pClassID); 00138 00139 if (pClassID==NULL) 00140 return E_POINTER; 00141 00142 *pClassID = CLSID_ItemMoniker; 00143 00144 return S_OK; 00145 } 00146 00147 /****************************************************************************** 00148 * ItemMoniker_IsDirty 00149 ******************************************************************************/ 00150 static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface) 00151 { 00152 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty 00153 method in the OLE-provided moniker interfaces always return S_FALSE because 00154 their internal state never changes. */ 00155 00156 TRACE("(%p)\n",iface); 00157 00158 return S_FALSE; 00159 } 00160 00161 /****************************************************************************** 00162 * ItemMoniker_Load 00163 ******************************************************************************/ 00164 static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm) 00165 { 00166 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00167 HRESULT res; 00168 DWORD delimiterLength,nameLength,lenW; 00169 CHAR *itemNameA,*itemDelimiterA; 00170 ULONG bread; 00171 00172 TRACE("\n"); 00173 00174 /* for more details about data read by this function see comments of ItemMonikerImpl_Save function */ 00175 00176 /* read item delimiter string length + 1 */ 00177 res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread); 00178 if (bread != sizeof(DWORD)) 00179 return E_FAIL; 00180 00181 /* read item delimiter string */ 00182 if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength))) 00183 return E_OUTOFMEMORY; 00184 res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread); 00185 if (bread != delimiterLength) 00186 { 00187 HeapFree( GetProcessHeap(), 0, itemDelimiterA ); 00188 return E_FAIL; 00189 } 00190 00191 lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 ); 00192 This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR)); 00193 if (!This->itemDelimiter) 00194 { 00195 HeapFree( GetProcessHeap(), 0, itemDelimiterA ); 00196 return E_OUTOFMEMORY; 00197 } 00198 MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW ); 00199 HeapFree( GetProcessHeap(), 0, itemDelimiterA ); 00200 00201 /* read item name string length + 1*/ 00202 res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread); 00203 if (bread != sizeof(DWORD)) 00204 return E_FAIL; 00205 00206 /* read item name string */ 00207 if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength))) 00208 return E_OUTOFMEMORY; 00209 res=IStream_Read(pStm,itemNameA,nameLength,&bread); 00210 if (bread != nameLength) 00211 { 00212 HeapFree( GetProcessHeap(), 0, itemNameA ); 00213 return E_FAIL; 00214 } 00215 00216 lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 ); 00217 This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR)); 00218 if (!This->itemName) 00219 { 00220 HeapFree( GetProcessHeap(), 0, itemNameA ); 00221 return E_OUTOFMEMORY; 00222 } 00223 MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW ); 00224 HeapFree( GetProcessHeap(), 0, itemNameA ); 00225 00226 return res; 00227 } 00228 00229 /****************************************************************************** 00230 * ItemMoniker_Save 00231 ******************************************************************************/ 00232 static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty) 00233 { 00234 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00235 HRESULT res; 00236 CHAR *itemNameA,*itemDelimiterA; 00237 00238 /* data written by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */ 00239 /* 2) String (type A): item delimiter string ('\0' included) */ 00240 /* 3) DWORD : size of item name string ('\0' included) */ 00241 /* 4) String (type A): item name string ('\0' included) */ 00242 00243 DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL); 00244 DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL); 00245 itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength); 00246 itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength); 00247 WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL); 00248 WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL); 00249 00250 TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE"); 00251 00252 res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL); 00253 res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL); 00254 res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL); 00255 res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL); 00256 00257 HeapFree(GetProcessHeap(), 0, itemNameA); 00258 HeapFree(GetProcessHeap(), 0, itemDelimiterA); 00259 00260 return res; 00261 } 00262 00263 /****************************************************************************** 00264 * ItemMoniker_GetSizeMax 00265 ******************************************************************************/ 00266 static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize) 00267 { 00268 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00269 DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1; 00270 DWORD nameLength=lstrlenW(This->itemName)+1; 00271 00272 TRACE("(%p,%p)\n",iface,pcbSize); 00273 00274 if (!pcbSize) 00275 return E_POINTER; 00276 00277 /* for more details see ItemMonikerImpl_Save comments */ 00278 00279 pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */ 00280 delimiterLength*4 + /* item delimiter string */ 00281 sizeof(DWORD) + /* DWORD which contains item name length */ 00282 nameLength*4 + /* item name string */ 00283 18; /* strange, but true */ 00284 pcbSize->u.HighPart=0; 00285 00286 return S_OK; 00287 } 00288 00289 /****************************************************************************** 00290 * ItemMoniker_BindToObject 00291 ******************************************************************************/ 00292 static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface, 00293 IBindCtx* pbc, 00294 IMoniker* pmkToLeft, 00295 REFIID riid, 00296 VOID** ppvResult) 00297 { 00298 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00299 HRESULT res; 00300 IID refid=IID_IOleItemContainer; 00301 IOleItemContainer *poic=0; 00302 00303 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult); 00304 00305 if(ppvResult ==NULL) 00306 return E_POINTER; 00307 00308 if(pmkToLeft==NULL) 00309 return E_INVALIDARG; 00310 00311 *ppvResult=0; 00312 00313 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic); 00314 00315 if (SUCCEEDED(res)){ 00316 00317 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult); 00318 00319 IOleItemContainer_Release(poic); 00320 } 00321 00322 return res; 00323 } 00324 00325 /****************************************************************************** 00326 * ItemMoniker_BindToStorage 00327 ******************************************************************************/ 00328 static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface, 00329 IBindCtx* pbc, 00330 IMoniker* pmkToLeft, 00331 REFIID riid, 00332 VOID** ppvResult) 00333 { 00334 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00335 HRESULT res; 00336 IOleItemContainer *poic=0; 00337 00338 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult); 00339 00340 *ppvResult=0; 00341 00342 if(pmkToLeft==NULL) 00343 return E_INVALIDARG; 00344 00345 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); 00346 00347 if (SUCCEEDED(res)){ 00348 00349 res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult); 00350 00351 IOleItemContainer_Release(poic); 00352 } 00353 00354 return res; 00355 } 00356 00357 /****************************************************************************** 00358 * ItemMoniker_Reduce 00359 ******************************************************************************/ 00360 static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface, 00361 IBindCtx* pbc, 00362 DWORD dwReduceHowFar, 00363 IMoniker** ppmkToLeft, 00364 IMoniker** ppmkReduced) 00365 { 00366 TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced); 00367 00368 if (ppmkReduced==NULL) 00369 return E_POINTER; 00370 00371 ItemMonikerImpl_AddRef(iface); 00372 00373 *ppmkReduced=iface; 00374 00375 return MK_S_REDUCED_TO_SELF; 00376 } 00377 /****************************************************************************** 00378 * ItemMoniker_ComposeWith 00379 ******************************************************************************/ 00380 static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface, 00381 IMoniker* pmkRight, 00382 BOOL fOnlyIfNotGeneric, 00383 IMoniker** ppmkComposite) 00384 { 00385 HRESULT res=S_OK; 00386 DWORD mkSys,mkSys2; 00387 IEnumMoniker* penumMk=0; 00388 IMoniker *pmostLeftMk=0; 00389 IMoniker* tempMkComposite=0; 00390 00391 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite); 00392 00393 if ((ppmkComposite==NULL)||(pmkRight==NULL)) 00394 return E_POINTER; 00395 00396 *ppmkComposite=0; 00397 00398 IMoniker_IsSystemMoniker(pmkRight,&mkSys); 00399 00400 /* If pmkRight is an anti-moniker, the returned moniker is NULL */ 00401 if(mkSys==MKSYS_ANTIMONIKER) 00402 return res; 00403 00404 else 00405 /* if pmkRight is a composite whose leftmost component is an anti-moniker, */ 00406 /* the returned moniker is the composite after the leftmost anti-moniker is removed. */ 00407 00408 if(mkSys==MKSYS_GENERICCOMPOSITE){ 00409 00410 res=IMoniker_Enum(pmkRight,TRUE,&penumMk); 00411 00412 if (FAILED(res)) 00413 return res; 00414 00415 res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL); 00416 00417 IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2); 00418 00419 if(mkSys2==MKSYS_ANTIMONIKER){ 00420 00421 IMoniker_Release(pmostLeftMk); 00422 00423 tempMkComposite=iface; 00424 IMoniker_AddRef(iface); 00425 00426 while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){ 00427 00428 res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite); 00429 00430 IMoniker_Release(tempMkComposite); 00431 IMoniker_Release(pmostLeftMk); 00432 00433 tempMkComposite=*ppmkComposite; 00434 IMoniker_AddRef(tempMkComposite); 00435 } 00436 return res; 00437 } 00438 else 00439 return CreateGenericComposite(iface,pmkRight,ppmkComposite); 00440 } 00441 /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic 00442 composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns 00443 a NULL moniker and a return value of MK_E_NEEDGENERIC */ 00444 else 00445 if (!fOnlyIfNotGeneric) 00446 return CreateGenericComposite(iface,pmkRight,ppmkComposite); 00447 00448 else 00449 return MK_E_NEEDGENERIC; 00450 } 00451 00452 /****************************************************************************** 00453 * ItemMoniker_Enum 00454 ******************************************************************************/ 00455 static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) 00456 { 00457 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker); 00458 00459 if (ppenumMoniker == NULL) 00460 return E_POINTER; 00461 00462 *ppenumMoniker = NULL; 00463 00464 return S_OK; 00465 } 00466 00467 /****************************************************************************** 00468 * ItemMoniker_IsEqual 00469 ******************************************************************************/ 00470 static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) 00471 { 00472 00473 CLSID clsid; 00474 LPOLESTR dispName1,dispName2; 00475 IBindCtx* bind; 00476 HRESULT res = S_FALSE; 00477 00478 TRACE("(%p,%p)\n",iface,pmkOtherMoniker); 00479 00480 if (!pmkOtherMoniker) return S_FALSE; 00481 00482 00483 /* check if both are ItemMoniker */ 00484 if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE; 00485 if(!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) return S_FALSE; 00486 00487 /* check if both displaynames are the same */ 00488 if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) { 00489 if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) { 00490 if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) { 00491 if(lstrcmpW(dispName1,dispName2)==0) res = S_OK; 00492 CoTaskMemFree(dispName2); 00493 } 00494 CoTaskMemFree(dispName1); 00495 } 00496 } 00497 return res; 00498 } 00499 00500 /****************************************************************************** 00501 * ItemMoniker_Hash 00502 ******************************************************************************/ 00503 static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) 00504 { 00505 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00506 DWORD h = 0; 00507 int i,len; 00508 int off = 0; 00509 LPOLESTR val; 00510 00511 if (pdwHash==NULL) 00512 return E_POINTER; 00513 00514 val = This->itemName; 00515 len = lstrlenW(val); 00516 00517 for (i = len ; i > 0; i--) 00518 h = (h * 3) ^ toupperW(val[off++]); 00519 00520 *pdwHash=h; 00521 00522 return S_OK; 00523 } 00524 00525 /****************************************************************************** 00526 * ItemMoniker_IsRunning 00527 ******************************************************************************/ 00528 static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, 00529 IBindCtx* pbc, 00530 IMoniker* pmkToLeft, 00531 IMoniker* pmkNewlyRunning) 00532 { 00533 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00534 IRunningObjectTable* rot; 00535 HRESULT res; 00536 IOleItemContainer *poic=0; 00537 00538 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning); 00539 00540 /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */ 00541 /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */ 00542 if (pmkToLeft==NULL) 00543 if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK)) 00544 return S_OK; 00545 else { 00546 if (pbc==NULL) 00547 return E_INVALIDARG; 00548 00549 res=IBindCtx_GetRunningObjectTable(pbc,&rot); 00550 00551 if (FAILED(res)) 00552 return res; 00553 00554 res = IRunningObjectTable_IsRunning(rot,iface); 00555 00556 IRunningObjectTable_Release(rot); 00557 } 00558 else{ 00559 00560 /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */ 00561 /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/ 00562 /* passing the string contained within this moniker. */ 00563 00564 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); 00565 00566 if (SUCCEEDED(res)){ 00567 00568 res=IOleItemContainer_IsRunning(poic,This->itemName); 00569 00570 IOleItemContainer_Release(poic); 00571 } 00572 } 00573 00574 return res; 00575 } 00576 00577 /****************************************************************************** 00578 * ItemMoniker_GetTimeOfLastChange 00579 ******************************************************************************/ 00580 static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, 00581 IBindCtx* pbc, 00582 IMoniker* pmkToLeft, 00583 FILETIME* pItemTime) 00584 { 00585 IRunningObjectTable* rot; 00586 HRESULT res; 00587 IMoniker *compositeMk; 00588 00589 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime); 00590 00591 if (pItemTime==NULL) 00592 return E_INVALIDARG; 00593 00594 /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */ 00595 if (pmkToLeft==NULL) 00596 00597 return MK_E_NOTBINDABLE; 00598 else { 00599 00600 /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */ 00601 /* the time of last change. If the object is not in the ROT, the method calls */ 00602 /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */ 00603 00604 res=CreateGenericComposite(pmkToLeft,iface,&compositeMk); 00605 00606 res=IBindCtx_GetRunningObjectTable(pbc,&rot); 00607 00608 if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK) 00609 00610 res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime); 00611 00612 IMoniker_Release(compositeMk); 00613 } 00614 00615 return res; 00616 } 00617 00618 /****************************************************************************** 00619 * ItemMoniker_Inverse 00620 ******************************************************************************/ 00621 static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) 00622 { 00623 TRACE("(%p,%p)\n",iface,ppmk); 00624 00625 if (ppmk==NULL) 00626 return E_POINTER; 00627 00628 return CreateAntiMoniker(ppmk); 00629 } 00630 00631 /****************************************************************************** 00632 * ItemMoniker_CommonPrefixWith 00633 ******************************************************************************/ 00634 static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) 00635 { 00636 DWORD mkSys; 00637 00638 TRACE("(%p,%p)\n", pmkOther, ppmkPrefix); 00639 00640 IMoniker_IsSystemMoniker(pmkOther,&mkSys); 00641 /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */ 00642 /* to this moniker and returns MK_S_US */ 00643 00644 if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){ 00645 00646 *ppmkPrefix=iface; 00647 00648 IMoniker_AddRef(iface); 00649 00650 return MK_S_US; 00651 } 00652 else 00653 /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */ 00654 /* the case where the other moniker is a generic composite. */ 00655 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix); 00656 } 00657 00658 /****************************************************************************** 00659 * ItemMoniker_RelativePathTo 00660 ******************************************************************************/ 00661 static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) 00662 { 00663 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath); 00664 00665 if (ppmkRelPath==NULL) 00666 return E_POINTER; 00667 00668 *ppmkRelPath=0; 00669 00670 return MK_E_NOTBINDABLE; 00671 } 00672 00673 /****************************************************************************** 00674 * ItemMoniker_GetDisplayName 00675 ******************************************************************************/ 00676 static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface, 00677 IBindCtx* pbc, 00678 IMoniker* pmkToLeft, 00679 LPOLESTR *ppszDisplayName) 00680 { 00681 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00682 00683 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName); 00684 00685 if (ppszDisplayName==NULL) 00686 return E_POINTER; 00687 00688 if (pmkToLeft!=NULL){ 00689 return E_INVALIDARG; 00690 } 00691 00692 *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1)); 00693 00694 if (*ppszDisplayName==NULL) 00695 return E_OUTOFMEMORY; 00696 00697 lstrcpyW(*ppszDisplayName,This->itemDelimiter); 00698 lstrcatW(*ppszDisplayName,This->itemName); 00699 00700 TRACE("-- %s\n", debugstr_w(*ppszDisplayName)); 00701 00702 return S_OK; 00703 } 00704 00705 /****************************************************************************** 00706 * ItemMoniker_ParseDisplayName 00707 ******************************************************************************/ 00708 static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface, 00709 IBindCtx* pbc, 00710 IMoniker* pmkToLeft, 00711 LPOLESTR pszDisplayName, 00712 ULONG* pchEaten, 00713 IMoniker** ppmkOut) 00714 { 00715 ItemMonikerImpl *This = impl_from_IMoniker(iface); 00716 IOleItemContainer* poic=0; 00717 IParseDisplayName* ppdn=0; 00718 LPOLESTR displayName; 00719 HRESULT res; 00720 00721 TRACE("%s\n", debugstr_w(pszDisplayName)); 00722 00723 /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */ 00724 if (pmkToLeft==NULL) 00725 00726 return MK_E_SYNTAX; 00727 00728 else{ 00729 /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */ 00730 /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ 00731 /* name to IParseDisplayName::ParseDisplayName */ 00732 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); 00733 00734 if (SUCCEEDED(res)){ 00735 00736 res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn); 00737 00738 res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName); 00739 00740 res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut); 00741 00742 IOleItemContainer_Release(poic); 00743 IParseDisplayName_Release(ppdn); 00744 } 00745 } 00746 return res; 00747 } 00748 00749 /****************************************************************************** 00750 * ItemMoniker_IsSystemMoniker 00751 ******************************************************************************/ 00752 static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) 00753 { 00754 TRACE("(%p,%p)\n",iface,pwdMksys); 00755 00756 if (!pwdMksys) 00757 return E_POINTER; 00758 00759 (*pwdMksys)=MKSYS_ITEMMONIKER; 00760 00761 return S_OK; 00762 } 00763 00764 /******************************************************************************* 00765 * ItemMonikerIROTData_QueryInterface 00766 *******************************************************************************/ 00767 static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid, 00768 void **ppvObject) 00769 { 00770 00771 ItemMonikerImpl *This = impl_from_IROTData(iface); 00772 00773 TRACE("(%p,%p,%p)\n",iface,riid,ppvObject); 00774 00775 return ItemMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppvObject); 00776 } 00777 00778 /*********************************************************************** 00779 * ItemMonikerIROTData_AddRef 00780 */ 00781 static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface) 00782 { 00783 ItemMonikerImpl *This = impl_from_IROTData(iface); 00784 00785 TRACE("(%p)\n",iface); 00786 00787 return ItemMonikerImpl_AddRef(&This->IMoniker_iface); 00788 } 00789 00790 /*********************************************************************** 00791 * ItemMonikerIROTData_Release 00792 */ 00793 static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface) 00794 { 00795 ItemMonikerImpl *This = impl_from_IROTData(iface); 00796 00797 TRACE("(%p)\n",iface); 00798 00799 return ItemMonikerImpl_Release(&This->IMoniker_iface); 00800 } 00801 00802 /****************************************************************************** 00803 * ItemMonikerIROTData_GetComparisonData 00804 ******************************************************************************/ 00805 static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface, 00806 BYTE* pbData, 00807 ULONG cbMax, 00808 ULONG* pcbData) 00809 { 00810 ItemMonikerImpl *This = impl_from_IROTData(iface); 00811 int len = (strlenW(This->itemName)+1); 00812 int i; 00813 LPWSTR pszItemName; 00814 LPWSTR pszItemDelimiter; 00815 00816 TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData); 00817 00818 *pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR); 00819 if (cbMax < *pcbData) 00820 return E_OUTOFMEMORY; 00821 00822 /* write CLSID */ 00823 memcpy(pbData, &CLSID_ItemMoniker, sizeof(CLSID)); 00824 /* write delimiter */ 00825 pszItemDelimiter = (LPWSTR)(pbData+sizeof(CLSID)); 00826 *pszItemDelimiter = *This->itemDelimiter; 00827 /* write name */ 00828 pszItemName = pszItemDelimiter + 1; 00829 for (i = 0; i < len; i++) 00830 pszItemName[i] = toupperW(This->itemName[i]); 00831 00832 return S_OK; 00833 } 00834 00835 /********************************************************************************/ 00836 /* Virtual function table for the ItemMonikerImpl class which include IPersist,*/ 00837 /* IPersistStream and IMoniker functions. */ 00838 static const IMonikerVtbl VT_ItemMonikerImpl = 00839 { 00840 ItemMonikerImpl_QueryInterface, 00841 ItemMonikerImpl_AddRef, 00842 ItemMonikerImpl_Release, 00843 ItemMonikerImpl_GetClassID, 00844 ItemMonikerImpl_IsDirty, 00845 ItemMonikerImpl_Load, 00846 ItemMonikerImpl_Save, 00847 ItemMonikerImpl_GetSizeMax, 00848 ItemMonikerImpl_BindToObject, 00849 ItemMonikerImpl_BindToStorage, 00850 ItemMonikerImpl_Reduce, 00851 ItemMonikerImpl_ComposeWith, 00852 ItemMonikerImpl_Enum, 00853 ItemMonikerImpl_IsEqual, 00854 ItemMonikerImpl_Hash, 00855 ItemMonikerImpl_IsRunning, 00856 ItemMonikerImpl_GetTimeOfLastChange, 00857 ItemMonikerImpl_Inverse, 00858 ItemMonikerImpl_CommonPrefixWith, 00859 ItemMonikerImpl_RelativePathTo, 00860 ItemMonikerImpl_GetDisplayName, 00861 ItemMonikerImpl_ParseDisplayName, 00862 ItemMonikerImpl_IsSystemMoniker 00863 }; 00864 00865 /********************************************************************************/ 00866 /* Virtual function table for the IROTData class. */ 00867 static const IROTDataVtbl VT_ROTDataImpl = 00868 { 00869 ItemMonikerROTDataImpl_QueryInterface, 00870 ItemMonikerROTDataImpl_AddRef, 00871 ItemMonikerROTDataImpl_Release, 00872 ItemMonikerROTDataImpl_GetComparisonData 00873 }; 00874 00875 /****************************************************************************** 00876 * ItemMoniker_Construct (local function) 00877 *******************************************************************************/ 00878 static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem) 00879 { 00880 00881 int sizeStr1=lstrlenW(lpszItem), sizeStr2; 00882 static const OLECHAR emptystr[1]; 00883 LPCOLESTR delim; 00884 00885 TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem)); 00886 00887 /* Initialize the virtual function table. */ 00888 This->IMoniker_iface.lpVtbl = &VT_ItemMonikerImpl; 00889 This->IROTData_iface.lpVtbl = &VT_ROTDataImpl; 00890 This->ref = 0; 00891 This->pMarshal = NULL; 00892 00893 This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1)); 00894 if (!This->itemName) 00895 return E_OUTOFMEMORY; 00896 lstrcpyW(This->itemName,lpszItem); 00897 00898 if (!lpszDelim) 00899 FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n"); 00900 00901 delim = lpszDelim ? lpszDelim : emptystr; 00902 00903 sizeStr2=lstrlenW(delim); 00904 This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1)); 00905 if (!This->itemDelimiter) { 00906 HeapFree(GetProcessHeap(),0,This->itemName); 00907 return E_OUTOFMEMORY; 00908 } 00909 lstrcpyW(This->itemDelimiter,delim); 00910 return S_OK; 00911 } 00912 00913 /****************************************************************************** 00914 * ItemMoniker_Destroy (local function) 00915 *******************************************************************************/ 00916 static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* This) 00917 { 00918 TRACE("(%p)\n",This); 00919 00920 if (This->pMarshal) IUnknown_Release(This->pMarshal); 00921 HeapFree(GetProcessHeap(),0,This->itemName); 00922 HeapFree(GetProcessHeap(),0,This->itemDelimiter); 00923 HeapFree(GetProcessHeap(),0,This); 00924 00925 return S_OK; 00926 } 00927 00928 /****************************************************************************** 00929 * CreateItemMoniker [OLE32.@] 00930 ******************************************************************************/ 00931 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim, LPCOLESTR lpszItem, IMoniker **ppmk) 00932 { 00933 ItemMonikerImpl* newItemMoniker; 00934 HRESULT hr; 00935 00936 TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk); 00937 00938 newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl)); 00939 00940 if (!newItemMoniker) 00941 return STG_E_INSUFFICIENTMEMORY; 00942 00943 hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem); 00944 00945 if (FAILED(hr)){ 00946 00947 HeapFree(GetProcessHeap(),0,newItemMoniker); 00948 return hr; 00949 } 00950 00951 return ItemMonikerImpl_QueryInterface(&newItemMoniker->IMoniker_iface,&IID_IMoniker, 00952 (void**)ppmk); 00953 } 00954 00955 static HRESULT WINAPI ItemMonikerCF_QueryInterface(LPCLASSFACTORY iface, 00956 REFIID riid, LPVOID *ppv) 00957 { 00958 *ppv = NULL; 00959 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) 00960 { 00961 *ppv = iface; 00962 IUnknown_AddRef(iface); 00963 return S_OK; 00964 } 00965 return E_NOINTERFACE; 00966 } 00967 00968 static ULONG WINAPI ItemMonikerCF_AddRef(LPCLASSFACTORY iface) 00969 { 00970 return 2; /* non-heap based object */ 00971 } 00972 00973 static ULONG WINAPI ItemMonikerCF_Release(LPCLASSFACTORY iface) 00974 { 00975 return 1; /* non-heap based object */ 00976 } 00977 00978 static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface, 00979 LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) 00980 { 00981 ItemMonikerImpl* newItemMoniker; 00982 HRESULT hr; 00983 static const WCHAR wszEmpty[] = { 0 }; 00984 00985 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv); 00986 00987 *ppv = NULL; 00988 00989 if (pUnk) 00990 return CLASS_E_NOAGGREGATION; 00991 00992 newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl)); 00993 if (!newItemMoniker) 00994 return E_OUTOFMEMORY; 00995 00996 hr = ItemMonikerImpl_Construct(newItemMoniker, wszEmpty, wszEmpty); 00997 00998 if (SUCCEEDED(hr)) 00999 hr = ItemMonikerImpl_QueryInterface(&newItemMoniker->IMoniker_iface, riid, ppv); 01000 if (FAILED(hr)) 01001 HeapFree(GetProcessHeap(),0,newItemMoniker); 01002 01003 return hr; 01004 } 01005 01006 static HRESULT WINAPI ItemMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) 01007 { 01008 FIXME("(%d), stub!\n",fLock); 01009 return S_OK; 01010 } 01011 01012 static const IClassFactoryVtbl ItemMonikerCFVtbl = 01013 { 01014 ItemMonikerCF_QueryInterface, 01015 ItemMonikerCF_AddRef, 01016 ItemMonikerCF_Release, 01017 ItemMonikerCF_CreateInstance, 01018 ItemMonikerCF_LockServer 01019 }; 01020 static const IClassFactoryVtbl *ItemMonikerCF = &ItemMonikerCFVtbl; 01021 01022 HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv) 01023 { 01024 return IClassFactory_QueryInterface((IClassFactory *)&ItemMonikerCF, riid, ppv); 01025 } Generated on Fri May 25 2012 04:23:45 for ReactOS by
1.7.6.1
|