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

itemmoniker.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 doxygen 1.7.6.1

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