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

classmoniker.c
Go to the documentation of this file.
00001 /*
00002  *                        Class Monikers
00003  *
00004  *           Copyright 1999  Noomen Hamza
00005  *           Copyright 2005-2007  Robert Shearman
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include <assert.h>
00023 #include <stdarg.h>
00024 #include <string.h>
00025 
00026 #define COBJMACROS
00027 #define NONAMELESSUNION
00028 #define NONAMELESSSTRUCT
00029 
00030 #include "winerror.h"
00031 #include "windef.h"
00032 #include "winbase.h"
00033 #include "winuser.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 #define CHARS_IN_GUID 39
00042 
00043 /* ClassMoniker data structure */
00044 typedef struct ClassMoniker
00045 {
00046     IMoniker IMoniker_iface;
00047     IROTData IROTData_iface;
00048     LONG ref;
00049     CLSID clsid; /* clsid identified by this moniker */
00050     IUnknown *pMarshal; /* custom marshaler */
00051 } ClassMoniker;
00052 
00053 static inline ClassMoniker *impl_from_IMoniker(IMoniker *iface)
00054 {
00055     return CONTAINING_RECORD(iface, ClassMoniker, IMoniker_iface);
00056 }
00057 
00058 static inline ClassMoniker *impl_from_IROTData(IROTData *iface)
00059 {
00060     return CONTAINING_RECORD(iface, ClassMoniker, IROTData_iface);
00061 }
00062 
00063 /*******************************************************************************
00064  *        ClassMoniker_QueryInterface
00065  *******************************************************************************/
00066 static HRESULT WINAPI ClassMoniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
00067 {
00068     ClassMoniker *This = impl_from_IMoniker(iface);
00069 
00070     TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
00071 
00072     /* Perform a sanity check on the parameters.*/
00073     if (!ppvObject)
00074         return E_POINTER;
00075 
00076     /* Initialize the return parameter */
00077     *ppvObject = 0;
00078 
00079     /* Compare the riid with the interface IDs implemented by this object.*/
00080     if (IsEqualIID(&IID_IUnknown, riid) ||
00081         IsEqualIID(&IID_IPersist, riid) ||
00082         IsEqualIID(&IID_IPersistStream, riid) ||
00083         IsEqualIID(&IID_IMoniker, riid))
00084     {
00085         *ppvObject = iface;
00086     }
00087     else if (IsEqualIID(&IID_IROTData, riid))
00088         *ppvObject = &This->IROTData_iface;
00089     else if (IsEqualIID(&IID_IMarshal, riid))
00090     {
00091         HRESULT hr = S_OK;
00092         if (!This->pMarshal)
00093             hr = MonikerMarshal_Create(iface, &This->pMarshal);
00094         if (hr != S_OK)
00095             return hr;
00096         return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
00097     }
00098 
00099     /* Check that we obtained an interface.*/
00100     if (!*ppvObject)
00101         return E_NOINTERFACE;
00102 
00103     /* Query Interface always increases the reference count by one when it is successful */
00104     IMoniker_AddRef(iface);
00105 
00106     return S_OK;
00107 }
00108 
00109 /******************************************************************************
00110  *        ClassMoniker_AddRef
00111  ******************************************************************************/
00112 static ULONG WINAPI ClassMoniker_AddRef(IMoniker* iface)
00113 {
00114     ClassMoniker *This = impl_from_IMoniker(iface);
00115 
00116     TRACE("(%p)\n",This);
00117 
00118     return InterlockedIncrement(&This->ref);
00119 }
00120 
00121 /******************************************************************************
00122  *        ClassMoniker_Destroy (local function)
00123  *******************************************************************************/
00124 static HRESULT ClassMoniker_Destroy(ClassMoniker* This)
00125 {
00126     TRACE("(%p)\n",This);
00127 
00128     if (This->pMarshal) IUnknown_Release(This->pMarshal);
00129 
00130     HeapFree(GetProcessHeap(),0,This);
00131 
00132     return S_OK;
00133 }
00134 
00135 /******************************************************************************
00136  *        ClassMoniker_Release
00137  ******************************************************************************/
00138 static ULONG WINAPI ClassMoniker_Release(IMoniker* iface)
00139 {
00140     ClassMoniker *This = impl_from_IMoniker(iface);
00141     ULONG ref;
00142 
00143     TRACE("(%p)\n",This);
00144 
00145     ref = InterlockedDecrement(&This->ref);
00146 
00147     /* destroy the object if there's no more reference on it */
00148     if (ref == 0) ClassMoniker_Destroy(This);
00149 
00150     return ref;
00151 }
00152 
00153 /******************************************************************************
00154  *        ClassMoniker_GetClassID
00155  ******************************************************************************/
00156 static HRESULT WINAPI ClassMoniker_GetClassID(IMoniker* iface,CLSID *pClassID)
00157 {
00158     TRACE("(%p,%p),stub!\n",iface,pClassID);
00159 
00160     if (pClassID==NULL)
00161         return E_POINTER;
00162 
00163     *pClassID = CLSID_ClassMoniker;
00164 
00165     return S_OK;
00166 }
00167 
00168 /******************************************************************************
00169  *        ClassMoniker_IsDirty
00170  ******************************************************************************/
00171 static HRESULT WINAPI ClassMoniker_IsDirty(IMoniker* iface)
00172 {
00173     /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
00174        method in the OLE-provided moniker interfaces always return S_FALSE because
00175        their internal state never changes. */
00176 
00177     TRACE("(%p)\n",iface);
00178 
00179     return S_FALSE;
00180 }
00181 
00182 /******************************************************************************
00183  *        ClassMoniker_Load
00184  ******************************************************************************/
00185 static HRESULT WINAPI ClassMoniker_Load(IMoniker* iface,IStream* pStm)
00186 {
00187     ClassMoniker *This = impl_from_IMoniker(iface);
00188     HRESULT hr;
00189     DWORD zero;
00190 
00191     TRACE("(%p)\n", pStm);
00192 
00193     hr = IStream_Read(pStm, &This->clsid, sizeof(This->clsid), NULL);
00194     if (hr != S_OK) return STG_E_READFAULT;
00195 
00196     hr = IStream_Read(pStm, &zero, sizeof(zero), NULL);
00197     if ((hr != S_OK) || (zero != 0)) return STG_E_READFAULT;
00198 
00199     return S_OK;
00200 }
00201 
00202 /******************************************************************************
00203  *        ClassMoniker_Save
00204  ******************************************************************************/
00205 static HRESULT WINAPI ClassMoniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
00206 {
00207     ClassMoniker *This = impl_from_IMoniker(iface);
00208     HRESULT hr;
00209     DWORD zero = 0;
00210 
00211     TRACE("(%p, %s)\n", pStm, fClearDirty ? "TRUE" : "FALSE");
00212 
00213     hr = IStream_Write(pStm, &This->clsid, sizeof(This->clsid), NULL);
00214     if (FAILED(hr)) return hr;
00215 
00216     return IStream_Write(pStm, &zero, sizeof(zero), NULL);
00217 }
00218 
00219 /******************************************************************************
00220  *        ClassMoniker_GetSizeMax
00221  ******************************************************************************/
00222 static HRESULT WINAPI ClassMoniker_GetSizeMax(IMoniker* iface,
00223                                           ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
00224 {
00225     TRACE("(%p)\n", pcbSize);
00226 
00227     pcbSize->QuadPart = sizeof(CLSID) + sizeof(DWORD);
00228 
00229     return S_OK;
00230 }
00231 
00232 /******************************************************************************
00233  *                  ClassMoniker_BindToObject
00234  ******************************************************************************/
00235 static HRESULT WINAPI ClassMoniker_BindToObject(IMoniker* iface,
00236                                             IBindCtx* pbc,
00237                                             IMoniker* pmkToLeft,
00238                                             REFIID riid,
00239                                             VOID** ppvResult)
00240 {
00241     ClassMoniker *This = impl_from_IMoniker(iface);
00242     BIND_OPTS2 bindopts;
00243     IClassActivator *pActivator;
00244     HRESULT hr;
00245 
00246     TRACE("(%p,%p,%p,%p)\n", pbc, pmkToLeft, riid, ppvResult);
00247 
00248     bindopts.cbStruct = sizeof(bindopts);
00249     IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts);
00250 
00251     if (!pmkToLeft)
00252         return CoGetClassObject(&This->clsid, bindopts.dwClassContext, NULL,
00253                                 riid, ppvResult);
00254     else
00255     {
00256         hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator,
00257                                    (void **)&pActivator);
00258         if (FAILED(hr)) return hr;
00259 
00260         hr = IClassActivator_GetClassObject(pActivator, &This->clsid,
00261                                             bindopts.dwClassContext,
00262                                             bindopts.locale, riid, ppvResult);
00263 
00264         IClassActivator_Release(pActivator);
00265 
00266         return hr;
00267     }
00268 }
00269 
00270 /******************************************************************************
00271  *        ClassMoniker_BindToStorage
00272  ******************************************************************************/
00273 static HRESULT WINAPI ClassMoniker_BindToStorage(IMoniker* iface,
00274                                              IBindCtx* pbc,
00275                                              IMoniker* pmkToLeft,
00276                                              REFIID riid,
00277                                              VOID** ppvResult)
00278 {
00279     TRACE("(%p,%p,%p,%p)\n",pbc, pmkToLeft, riid, ppvResult);
00280     return ClassMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult);
00281 }
00282 
00283 /******************************************************************************
00284  *        ClassMoniker_Reduce
00285  ******************************************************************************/
00286 static HRESULT WINAPI ClassMoniker_Reduce(IMoniker* iface,
00287                                       IBindCtx* pbc,
00288                                       DWORD dwReduceHowFar,
00289                                       IMoniker** ppmkToLeft,
00290                                       IMoniker** ppmkReduced)
00291 {
00292     TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
00293 
00294     if (!ppmkReduced)
00295         return E_POINTER;
00296 
00297     ClassMoniker_AddRef(iface);
00298 
00299     *ppmkReduced = iface;
00300 
00301     return MK_S_REDUCED_TO_SELF;
00302 }
00303 /******************************************************************************
00304  *        ClassMoniker_ComposeWith
00305  ******************************************************************************/
00306 static HRESULT WINAPI ClassMoniker_ComposeWith(IMoniker* iface,
00307                                            IMoniker* pmkRight,
00308                                            BOOL fOnlyIfNotGeneric,
00309                                            IMoniker** ppmkComposite)
00310 {
00311     HRESULT res=S_OK;
00312     DWORD mkSys,mkSys2;
00313     IEnumMoniker* penumMk=0;
00314     IMoniker *pmostLeftMk=0;
00315     IMoniker* tempMkComposite=0;
00316 
00317     TRACE("(%p,%d,%p)\n", pmkRight, fOnlyIfNotGeneric, ppmkComposite);
00318 
00319     if ((ppmkComposite==NULL)||(pmkRight==NULL))
00320     return E_POINTER;
00321 
00322     *ppmkComposite=0;
00323 
00324     IMoniker_IsSystemMoniker(pmkRight,&mkSys);
00325 
00326     /* If pmkRight is an anti-moniker, the returned moniker is NULL */
00327     if(mkSys==MKSYS_ANTIMONIKER)
00328         return res;
00329 
00330     else
00331         /* if pmkRight is a composite whose leftmost component is an anti-moniker,           */
00332         /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
00333 
00334          if(mkSys==MKSYS_GENERICCOMPOSITE){
00335 
00336             res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
00337 
00338             if (FAILED(res))
00339                 return res;
00340 
00341             res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
00342 
00343             IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
00344 
00345             if(mkSys2==MKSYS_ANTIMONIKER){
00346 
00347                 IMoniker_Release(pmostLeftMk);
00348 
00349                 tempMkComposite=iface;
00350                 IMoniker_AddRef(iface);
00351 
00352                 while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
00353 
00354                     res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
00355 
00356                     IMoniker_Release(tempMkComposite);
00357                     IMoniker_Release(pmostLeftMk);
00358 
00359                     tempMkComposite=*ppmkComposite;
00360                     IMoniker_AddRef(tempMkComposite);
00361                 }
00362                 return res;
00363             }
00364             else
00365                 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
00366          }
00367          /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
00368           composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
00369           a NULL moniker and a return value of MK_E_NEEDGENERIC */
00370           else
00371             if (!fOnlyIfNotGeneric)
00372                 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
00373 
00374             else
00375                 return MK_E_NEEDGENERIC;
00376 }
00377 
00378 /******************************************************************************
00379  *        ClassMoniker_Enum
00380  ******************************************************************************/
00381 static HRESULT WINAPI ClassMoniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
00382 {
00383     TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
00384 
00385     if (ppenumMoniker == NULL)
00386         return E_POINTER;
00387 
00388     *ppenumMoniker = NULL;
00389 
00390     return S_OK;
00391 }
00392 
00393 /******************************************************************************
00394  *        ClassMoniker_IsEqual
00395  ******************************************************************************/
00396 static HRESULT WINAPI ClassMoniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
00397 {
00398 
00399     CLSID clsid;
00400     LPOLESTR dispName1,dispName2;
00401     IBindCtx* bind;
00402     HRESULT res = S_FALSE;
00403 
00404     TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
00405 
00406     if (!pmkOtherMoniker) return S_FALSE;
00407 
00408 
00409     /* check if both are ClassMoniker */
00410     if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
00411     if(!IsEqualCLSID(&clsid,&CLSID_ClassMoniker)) return S_FALSE;
00412 
00413     /* check if both displaynames are the same */
00414     if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
00415         if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
00416         if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
00417                 if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;
00418                 CoTaskMemFree(dispName2);
00419             }
00420             CoTaskMemFree(dispName1);
00421     }
00422     }
00423     return res;
00424 }
00425 
00426 /******************************************************************************
00427  *        ClassMoniker_Hash
00428  ******************************************************************************/
00429 static HRESULT WINAPI ClassMoniker_Hash(IMoniker* iface,DWORD* pdwHash)
00430 {
00431     ClassMoniker *This = impl_from_IMoniker(iface);
00432 
00433     TRACE("(%p)\n", pdwHash);
00434 
00435     *pdwHash = This->clsid.Data1;
00436 
00437     return S_OK;
00438 }
00439 
00440 /******************************************************************************
00441  *        ClassMoniker_IsRunning
00442  ******************************************************************************/
00443 static HRESULT WINAPI ClassMoniker_IsRunning(IMoniker* iface,
00444                                          IBindCtx* pbc,
00445                                          IMoniker* pmkToLeft,
00446                                          IMoniker* pmkNewlyRunning)
00447 {
00448     TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pmkNewlyRunning);
00449 
00450     /* as in native */
00451     return E_NOTIMPL;
00452 }
00453 
00454 /******************************************************************************
00455  *        ClassMoniker_GetTimeOfLastChange
00456  ******************************************************************************/
00457 static HRESULT WINAPI ClassMoniker_GetTimeOfLastChange(IMoniker* iface,
00458                                                    IBindCtx* pbc,
00459                                                    IMoniker* pmkToLeft,
00460                                                    FILETIME* pItemTime)
00461 {
00462     TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pItemTime);
00463 
00464     return MK_E_UNAVAILABLE;
00465 }
00466 
00467 /******************************************************************************
00468  *        ClassMoniker_Inverse
00469  ******************************************************************************/
00470 static HRESULT WINAPI ClassMoniker_Inverse(IMoniker* iface,IMoniker** ppmk)
00471 {
00472     TRACE("(%p)\n",ppmk);
00473 
00474     if (!ppmk)
00475         return E_POINTER;
00476 
00477     return CreateAntiMoniker(ppmk);
00478 }
00479 
00480 /******************************************************************************
00481  *        ClassMoniker_CommonPrefixWith
00482  ******************************************************************************/
00483 static HRESULT WINAPI ClassMoniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
00484 {
00485     DWORD mkSys;
00486     
00487     TRACE("(%p, %p)\n", pmkOther, ppmkPrefix);
00488 
00489     *ppmkPrefix = NULL;
00490 
00491     IMoniker_IsSystemMoniker(pmkOther, &mkSys);
00492 
00493     /* If the other moniker is an class moniker that is equal to this moniker, this method sets *ppmkPrefix */
00494     /* to this moniker and returns MK_S_US */
00495 
00496     if (mkSys == MKSYS_CLASSMONIKER)
00497     {
00498         if (IMoniker_IsEqual(iface, pmkOther) == S_OK)
00499         {
00500             *ppmkPrefix = iface;
00501 
00502             IMoniker_AddRef(iface);
00503 
00504             return MK_S_US;
00505         }
00506         else
00507             return MK_E_NOPREFIX;
00508     }
00509     else
00510         /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
00511         /* the case where the other moniker is a generic composite. */
00512         return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix);
00513 }
00514 
00515 /******************************************************************************
00516  *        ClassMoniker_RelativePathTo
00517  ******************************************************************************/
00518 static HRESULT WINAPI ClassMoniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
00519 {
00520     TRACE("(%p, %p)\n",pmOther,ppmkRelPath);
00521 
00522     if (!ppmkRelPath)
00523         return E_POINTER;
00524 
00525     *ppmkRelPath = NULL;
00526 
00527     return MK_E_NOTBINDABLE;
00528 }
00529 
00530 /******************************************************************************
00531  *        ClassMoniker_GetDisplayName
00532  ******************************************************************************/
00533 static HRESULT WINAPI ClassMoniker_GetDisplayName(IMoniker* iface,
00534                                               IBindCtx* pbc,
00535                                               IMoniker* pmkToLeft,
00536                                               LPOLESTR *ppszDisplayName)
00537 {
00538     ClassMoniker *This = impl_from_IMoniker(iface);
00539     static const WCHAR wszClsidPrefix[] = {'c','l','s','i','d',':',0};
00540 
00541     TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, ppszDisplayName);
00542 
00543     if (!ppszDisplayName)
00544         return E_POINTER;
00545 
00546     if (pmkToLeft)
00547         return E_INVALIDARG;
00548 
00549     *ppszDisplayName = CoTaskMemAlloc(sizeof(wszClsidPrefix) + (CHARS_IN_GUID-2) * sizeof(WCHAR));
00550 
00551     StringFromGUID2(&This->clsid, *ppszDisplayName+sizeof(wszClsidPrefix)/sizeof(WCHAR)-2, CHARS_IN_GUID);
00552 
00553     /* note: this overwrites the opening curly bracket of the CLSID string generated above */
00554     memcpy(*ppszDisplayName, wszClsidPrefix, sizeof(wszClsidPrefix)-sizeof(WCHAR));
00555 
00556     /* note: this overwrites the closing curly bracket of the CLSID string generated above */
00557     (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-2] = ':';
00558     (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-1] = '\0';
00559 
00560     TRACE("string is %s\n", debugstr_w(*ppszDisplayName));
00561     return S_OK;
00562 }
00563 
00564 /******************************************************************************
00565  *        ClassMoniker_ParseDisplayName
00566  ******************************************************************************/
00567 static HRESULT WINAPI ClassMoniker_ParseDisplayName(IMoniker* iface,
00568                                                 IBindCtx* pbc,
00569                                                 IMoniker* pmkToLeft,
00570                                                 LPOLESTR pszDisplayName,
00571                                                 ULONG* pchEaten,
00572                                                 IMoniker** ppmkOut)
00573 {
00574     FIXME("(%p, %p, %s, %p, %p)\n", pbc, pmkToLeft, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
00575     return E_NOTIMPL;
00576 }
00577 
00578 /******************************************************************************
00579  *        ClassMoniker_IsSystemMoniker
00580  ******************************************************************************/
00581 static HRESULT WINAPI ClassMoniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
00582 {
00583     TRACE("(%p,%p)\n",iface,pwdMksys);
00584 
00585     if (!pwdMksys)
00586         return E_POINTER;
00587 
00588     *pwdMksys = MKSYS_CLASSMONIKER;
00589 
00590     return S_OK;
00591 }
00592 
00593 /*******************************************************************************
00594  *        ClassMonikerIROTData_QueryInterface
00595  *******************************************************************************/
00596 static HRESULT WINAPI ClassMonikerROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
00597 {
00598 
00599     ClassMoniker *This = impl_from_IROTData(iface);
00600 
00601     TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
00602 
00603     return ClassMoniker_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
00604 }
00605 
00606 /***********************************************************************
00607  *        ClassMonikerIROTData_AddRef
00608  */
00609 static ULONG WINAPI ClassMonikerROTData_AddRef(IROTData *iface)
00610 {
00611     ClassMoniker *This = impl_from_IROTData(iface);
00612 
00613     TRACE("(%p)\n",iface);
00614 
00615     return ClassMoniker_AddRef(&This->IMoniker_iface);
00616 }
00617 
00618 /***********************************************************************
00619  *        ClassMonikerIROTData_Release
00620  */
00621 static ULONG WINAPI ClassMonikerROTData_Release(IROTData* iface)
00622 {
00623     ClassMoniker *This = impl_from_IROTData(iface);
00624 
00625     TRACE("(%p)\n",iface);
00626 
00627     return ClassMoniker_Release(&This->IMoniker_iface);
00628 }
00629 
00630 /******************************************************************************
00631  *        ClassMonikerIROTData_GetComparisonData
00632  ******************************************************************************/
00633 static HRESULT WINAPI ClassMonikerROTData_GetComparisonData(IROTData* iface,
00634                                                          BYTE* pbData,
00635                                                          ULONG cbMax,
00636                                                          ULONG* pcbData)
00637 {
00638     ClassMoniker *This = impl_from_IROTData(iface);
00639 
00640     TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
00641 
00642     *pcbData = 2*sizeof(CLSID);
00643     if (cbMax < *pcbData)
00644         return E_OUTOFMEMORY;
00645 
00646     /* write CLSID of the moniker */
00647     memcpy(pbData, &CLSID_ClassMoniker, sizeof(CLSID));
00648     /* write CLSID the moniker represents */
00649     memcpy(pbData+sizeof(CLSID), &This->clsid, sizeof(CLSID));
00650 
00651     return S_OK;
00652 }
00653 
00654 /********************************************************************************/
00655 /* Virtual function table for the ClassMoniker class which  include IPersist,*/
00656 /* IPersistStream and IMoniker functions.                                       */
00657 static const IMonikerVtbl ClassMonikerVtbl =
00658 {
00659     ClassMoniker_QueryInterface,
00660     ClassMoniker_AddRef,
00661     ClassMoniker_Release,
00662     ClassMoniker_GetClassID,
00663     ClassMoniker_IsDirty,
00664     ClassMoniker_Load,
00665     ClassMoniker_Save,
00666     ClassMoniker_GetSizeMax,
00667     ClassMoniker_BindToObject,
00668     ClassMoniker_BindToStorage,
00669     ClassMoniker_Reduce,
00670     ClassMoniker_ComposeWith,
00671     ClassMoniker_Enum,
00672     ClassMoniker_IsEqual,
00673     ClassMoniker_Hash,
00674     ClassMoniker_IsRunning,
00675     ClassMoniker_GetTimeOfLastChange,
00676     ClassMoniker_Inverse,
00677     ClassMoniker_CommonPrefixWith,
00678     ClassMoniker_RelativePathTo,
00679     ClassMoniker_GetDisplayName,
00680     ClassMoniker_ParseDisplayName,
00681     ClassMoniker_IsSystemMoniker
00682 };
00683 
00684 /********************************************************************************/
00685 /* Virtual function table for the IROTData class.                               */
00686 static const IROTDataVtbl ROTDataVtbl =
00687 {
00688     ClassMonikerROTData_QueryInterface,
00689     ClassMonikerROTData_AddRef,
00690     ClassMonikerROTData_Release,
00691     ClassMonikerROTData_GetComparisonData
00692 };
00693 
00694 /******************************************************************************
00695  *         ClassMoniker_Construct (local function)
00696  *******************************************************************************/
00697 static HRESULT ClassMoniker_Construct(ClassMoniker* This, REFCLSID rclsid)
00698 {
00699     TRACE("(%p,%s)\n",This,debugstr_guid(rclsid));
00700 
00701     /* Initialize the virtual function table. */
00702     This->IMoniker_iface.lpVtbl = &ClassMonikerVtbl;
00703     This->IROTData_iface.lpVtbl = &ROTDataVtbl;
00704     This->ref           = 0;
00705     This->clsid         = *rclsid;
00706     This->pMarshal      = NULL;
00707 
00708     return S_OK;
00709 }
00710 
00711 /******************************************************************************
00712  *        CreateClassMoniker    [OLE32.@]
00713  ******************************************************************************/
00714 HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker **ppmk)
00715 {
00716     ClassMoniker* newClassMoniker;
00717     HRESULT       hr;
00718 
00719     TRACE("(%s,%p)\n", debugstr_guid(rclsid), ppmk);
00720 
00721     newClassMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassMoniker));
00722 
00723     if (!newClassMoniker)
00724         return STG_E_INSUFFICIENTMEMORY;
00725 
00726     hr = ClassMoniker_Construct(newClassMoniker, rclsid);
00727 
00728     if (FAILED(hr))
00729     {
00730         HeapFree(GetProcessHeap(), 0, newClassMoniker);
00731         return hr;
00732     }
00733 
00734     return ClassMoniker_QueryInterface(&newClassMoniker->IMoniker_iface, &IID_IMoniker,
00735                                        (void**)ppmk);
00736 }
00737 
00738 HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten,
00739                                            IMoniker **ppmk)
00740 {
00741     HRESULT hr;
00742     LPCWSTR s = strchrW(szDisplayName, ':');
00743     LPCWSTR end;
00744     CLSID clsid;
00745     BYTE table[256];
00746     int i;
00747 
00748     if (!s)
00749         return MK_E_SYNTAX;
00750 
00751     s++;
00752 
00753     for (end = s; *end && (*end != ':'); end++)
00754         ;
00755 
00756     TRACE("parsing %s\n", debugstr_wn(s, end - s));
00757 
00758     /* validate the CLSID string */
00759     if (s[0] == '{')
00760     {
00761         if ((end - s != 38) || (s[37] != '}'))
00762             return MK_E_SYNTAX;
00763         s++;
00764     }
00765     else
00766     {
00767         if (end - s != 36)
00768             return MK_E_SYNTAX;
00769     }
00770 
00771     for (i=0; i<36; i++)
00772     {
00773         if ((i == 8)||(i == 13)||(i == 18)||(i == 23))
00774         {
00775             if (s[i] != '-')
00776                 return MK_E_SYNTAX;
00777             continue;
00778         }
00779         if (!(((s[i] >= '0') && (s[i] <= '9'))  ||
00780               ((s[i] >= 'a') && (s[i] <= 'f'))  ||
00781               ((s[i] >= 'A') && (s[i] <= 'F'))))
00782             return MK_E_SYNTAX;
00783     }
00784 
00785     /* quick lookup table */
00786     memset(table, 0, 256);
00787 
00788     for (i = 0; i < 10; i++)
00789         table['0' + i] = i;
00790     for (i = 0; i < 6; i++)
00791     {
00792         table['A' + i] = i+10;
00793         table['a' + i] = i+10;
00794     }
00795 
00796     /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
00797 
00798     clsid.Data1 = (table[s[0]] << 28 | table[s[1]] << 24 | table[s[2]] << 20 | table[s[3]] << 16 |
00799                    table[s[4]] << 12 | table[s[5]] << 8  | table[s[6]] << 4  | table[s[7]]);
00800     clsid.Data2 = table[s[9]] << 12  | table[s[10]] << 8 | table[s[11]] << 4 | table[s[12]];
00801     clsid.Data3 = table[s[14]] << 12 | table[s[15]] << 8 | table[s[16]] << 4 | table[s[17]];
00802 
00803     /* these are just sequential bytes */
00804     clsid.Data4[0] = table[s[19]] << 4 | table[s[20]];
00805     clsid.Data4[1] = table[s[21]] << 4 | table[s[22]];
00806     clsid.Data4[2] = table[s[24]] << 4 | table[s[25]];
00807     clsid.Data4[3] = table[s[26]] << 4 | table[s[27]];
00808     clsid.Data4[4] = table[s[28]] << 4 | table[s[29]];
00809     clsid.Data4[5] = table[s[30]] << 4 | table[s[31]];
00810     clsid.Data4[6] = table[s[32]] << 4 | table[s[33]];
00811     clsid.Data4[7] = table[s[34]] << 4 | table[s[35]];
00812 
00813     hr = CreateClassMoniker(&clsid, ppmk);
00814     if (SUCCEEDED(hr))
00815         *pchEaten = (*end == ':' ? end + 1 : end) - szDisplayName;
00816     return hr;
00817 }
00818 
00819 static HRESULT WINAPI ClassMonikerCF_QueryInterface(LPCLASSFACTORY iface,
00820                                                   REFIID riid, LPVOID *ppv)
00821 {
00822     *ppv = NULL;
00823     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
00824     {
00825         *ppv = iface;
00826         IUnknown_AddRef(iface);
00827         return S_OK;
00828     }
00829     return E_NOINTERFACE;
00830 }
00831 
00832 static ULONG WINAPI ClassMonikerCF_AddRef(LPCLASSFACTORY iface)
00833 {
00834     return 2; /* non-heap based object */
00835 }
00836 
00837 static ULONG WINAPI ClassMonikerCF_Release(LPCLASSFACTORY iface)
00838 {
00839     return 1; /* non-heap based object */
00840 }
00841 
00842 static HRESULT WINAPI ClassMonikerCF_CreateInstance(LPCLASSFACTORY iface,
00843     LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
00844 {
00845     HRESULT hr;
00846     IMoniker *pmk;
00847 
00848     TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
00849 
00850     *ppv = NULL;
00851 
00852     if (pUnk)
00853         return CLASS_E_NOAGGREGATION;
00854 
00855     hr = CreateClassMoniker(&CLSID_NULL, &pmk);
00856     if (FAILED(hr)) return hr;
00857 
00858     hr = IMoniker_QueryInterface(pmk, riid, ppv);
00859     IMoniker_Release(pmk);
00860 
00861     return hr;
00862 }
00863 
00864 static HRESULT WINAPI ClassMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
00865 {
00866     FIXME("(%d), stub!\n",fLock);
00867     return S_OK;
00868 }
00869 
00870 static const IClassFactoryVtbl ClassMonikerCFVtbl =
00871 {
00872     ClassMonikerCF_QueryInterface,
00873     ClassMonikerCF_AddRef,
00874     ClassMonikerCF_Release,
00875     ClassMonikerCF_CreateInstance,
00876     ClassMonikerCF_LockServer
00877 };
00878 static const IClassFactoryVtbl *ClassMonikerCF = &ClassMonikerCFVtbl;
00879 
00880 HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv)
00881 {
00882     return IClassFactory_QueryInterface((IClassFactory *)&ClassMonikerCF, riid, ppv);
00883 }

Generated on Sun May 27 2012 04:25:33 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.