-/***************************************************************************************
+/*
* ItemMonikers implementation
*
* Copyright 1999 Noomen Hamza
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- ***************************************************************************************/
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
#include <assert.h>
+#include <stdarg.h>
#include <string.h>
+#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
+
#include "winerror.h"
+#include "windef.h"
#include "winbase.h"
+#include "winuser.h"
#include "winnls.h"
#include "wine/debug.h"
#include "ole2.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-const CLSID CLSID_ItemMoniker = {
- 0x304, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
-};
-
/* ItemMoniker data structure */
typedef struct ItemMonikerImpl{
- ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
+ const IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/
/* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
* two monikers are equal. That's whay IROTData interface is implemented by monikers.
*/
- ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/
+ const IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/
- ULONG ref; /* reference counter for this object */
+ LONG ref; /* reference counter for this object */
LPOLESTR itemName; /* item name identified by this ItemMoniker */
LPOLESTR itemDelimiter; /* Delimiter string */
+ IUnknown *pMarshal; /* custom marshaler */
} ItemMonikerImpl;
+static inline IMoniker *impl_from_IROTData( IROTData *iface )
+{
+ return (IMoniker *)((char*)iface - FIELD_OFFSET(ItemMonikerImpl, lpvtbl2));
+}
+
/********************************************************************************/
/* ItemMoniker prototype functions : */
static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
/* Local function used by ItemMoniker implementation */
-HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
-HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
+static HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
+static HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
/********************************************************************************/
/* IROTData prototype functions */
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
/* IROTData prototype function */
-static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
+static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
/********************************************************************************/
/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
/* IPersistStream and IMoniker functions. */
-static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl =
+static const IMonikerVtbl VT_ItemMonikerImpl =
{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
ItemMonikerImpl_QueryInterface,
ItemMonikerImpl_AddRef,
ItemMonikerImpl_Release,
/********************************************************************************/
/* Virtual function table for the IROTData class. */
-static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
+static const IROTDataVtbl VT_ROTDataImpl =
{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
ItemMonikerROTDataImpl_QueryInterface,
ItemMonikerROTDataImpl_AddRef,
ItemMonikerROTDataImpl_Release,
- ItemMonikerROTDataImpl_GetComparaisonData
+ ItemMonikerROTDataImpl_GetComparisonData
};
/*******************************************************************************
*******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
- TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
/* Perform a sanity check on the parameters.*/
if ( (This==0) || (ppvObject==0) )
else if (IsEqualIID(&IID_IROTData, riid))
*ppvObject = (IROTData*)&(This->lpvtbl2);
+ else if (IsEqualIID(&IID_IMarshal, riid))
+ {
+ HRESULT hr = S_OK;
+ if (!This->pMarshal)
+ hr = MonikerMarshal_Create(iface, &This->pMarshal);
+ if (hr != S_OK)
+ return hr;
+ return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
+ }
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
******************************************************************************/
ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
TRACE("(%p)\n",This);
- return ++(This->ref);
+ return InterlockedIncrement(&This->ref);
}
/******************************************************************************
******************************************************************************/
ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+ ULONG ref;
TRACE("(%p)\n",This);
- This->ref--;
+ ref = InterlockedDecrement(&This->ref);
/* destroy the object if there's no more reference on it */
- if (This->ref==0){
-
- ItemMonikerImpl_Destroy(This);
+ if (ref == 0) ItemMonikerImpl_Destroy(This);
- return 0;
- }
- return This->ref;
+ return ref;
}
/******************************************************************************
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
- TRACE("(%p,%p),stub!\n",iface,pClassID);
+ TRACE("(%p,%p)\n",iface,pClassID);
if (pClassID==NULL)
return E_POINTER;
HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
HRESULT res;
DWORD delimiterLength,nameLength,lenW;
CHAR *itemNameA,*itemDelimiterA;
ULONG bread;
+ TRACE("\n");
+
/* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
/* read item delimiter string length + 1 */
IStream* pStm,/* pointer to the stream where the object is to be saved */
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
HRESULT res;
CHAR *itemNameA,*itemDelimiterA;
WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
+ TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE");
+
res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
DWORD nameLength=lstrlenW(This->itemName)+1;
TRACE("(%p,%p)\n",iface,pcbSize);
- if (pcbSize!=NULL)
+ if (!pcbSize)
return E_POINTER;
/* for more details see ItemMonikerImpl_Save coments */
- pcbSize->s.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
- delimiterLength + /* item delimiter string */
+ pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
+ delimiterLength*4 + /* item delimiter string */
sizeof(DWORD) + /* DWORD which contains item name length */
- nameLength + /* item name string */
- 34; /* this constant was added ! because when I tested this function it usually */
- /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
- pcbSize->s.HighPart=0;
+ nameLength*4 + /* item name string */
+ 18; /* strange, but true */
+ pcbSize->u.HighPart=0;
return S_OK;
}
/******************************************************************************
* ItemMoniker_Construct (local function)
*******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
+static HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
{
int sizeStr1=lstrlenW(lpszItem), sizeStr2;
static const OLECHAR emptystr[1];
LPCOLESTR delim;
- TRACE("(%p,%p)\n",This,lpszItem);
+ TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));
/* Initialize the virtual fgunction table. */
This->lpvtbl1 = &VT_ItemMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
+ This->pMarshal = NULL;
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
if (!This->itemName)
/******************************************************************************
* ItemMoniker_Destroy (local function)
*******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
+static HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
{
TRACE("(%p)\n",This);
- if (This->itemName)
- HeapFree(GetProcessHeap(),0,This->itemName);
-
- if (This->itemDelimiter)
- HeapFree(GetProcessHeap(),0,This->itemDelimiter);
-
+ if (This->pMarshal) IUnknown_Release(This->pMarshal);
+ HeapFree(GetProcessHeap(),0,This->itemName);
+ HeapFree(GetProcessHeap(),0,This->itemDelimiter);
HeapFree(GetProcessHeap(),0,This);
return S_OK;
REFIID riid,
VOID** ppvResult)
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
HRESULT res;
IID refid=IID_IOleItemContainer;
IOleItemContainer *poic=0;
- TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+ TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
if(ppvResult ==NULL)
return E_POINTER;
REFIID riid,
VOID** ppvResult)
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
HRESULT res;
IOleItemContainer *poic=0;
- TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+ TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
*ppvResult=0;
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
{
- TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
+ TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
- ICOM_THIS(ItemMonikerImpl,iface);
-
- int h = 0,i,skip,len;
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+ DWORD h = 0;
+ int i,len;
int off = 0;
LPOLESTR val;
val = This->itemName;
len = lstrlenW(val);
- if (len < 16) {
- for (i = len ; i > 0; i--) {
- h = (h * 37) + val[off++];
- }
- } else {
- /* only sample some characters */
- skip = len / 8;
- for (i = len ; i > 0; i -= skip, off += skip) {
- h = (h * 39) + val[off];
- }
- }
+ for (i = len ; i > 0; i--)
+ h = (h * 3) ^ toupperW(val[off++]);
*pdwHash=h;
IRunningObjectTable* rot;
HRESULT res;
IOleItemContainer *poic=0;
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
DWORD mkSys;
+
+ TRACE("(%p,%p)\n", pmkOther, ppmkPrefix);
+
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
/* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
/* to this moniker and returns MK_S_US */
IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
{
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
lstrcpyW(*ppszDisplayName,This->itemDelimiter);
lstrcatW(*ppszDisplayName,This->itemName);
+ TRACE("-- %s\n", debugstr_w(*ppszDisplayName));
+
return S_OK;
}
IParseDisplayName* ppdn=0;
LPOLESTR displayName;
HRESULT res;
- ICOM_THIS(ItemMonikerImpl,iface);
+ ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
+
+ TRACE("%s\n", debugstr_w(pszDisplayName));
/* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
if (pmkToLeft==NULL)
HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
{
- ICOM_THIS_From_IROTData(IMoniker, iface);
+ IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
*/
ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
{
- ICOM_THIS_From_IROTData(IMoniker, iface);
+ IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p)\n",iface);
*/
ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
{
- ICOM_THIS_From_IROTData(IMoniker, iface);
+ IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p)\n",iface);
/******************************************************************************
* ItemMonikerIROTData_GetComparaisonData
******************************************************************************/
-HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
+HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData,
ULONG cbMax,
ULONG* pcbData)
{
- FIXME("(),stub!\n");
- return E_NOTIMPL;
-}
+ IMoniker *This = impl_from_IROTData(iface);
+ ItemMonikerImpl *This1 = (ItemMonikerImpl *)This;
+ int len = (strlenW(This1->itemName)+1);
+ int i;
+ LPWSTR pszItemName;
+ LPWSTR pszItemDelimiter;
-/******************************************************************************
- * CreateItemMoniker16 [OLE2.28]
- ******************************************************************************/
-HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk)
-{
+ TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
+
+ *pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);
+ if (cbMax < *pcbData)
+ return E_OUTOFMEMORY;
+
+ /* write CLSID */
+ memcpy(pbData, &CLSID_ItemMoniker, sizeof(CLSID));
+ /* write delimiter */
+ pszItemDelimiter = (LPWSTR)(pbData+sizeof(CLSID));
+ *pszItemDelimiter = *This1->itemDelimiter;
+ /* write name */
+ pszItemName = pszItemDelimiter + 1;
+ for (i = 0; i < len; i++)
+ pszItemName[i] = toupperW(This1->itemName[i]);
- FIXME("(%s,%p),stub!\n",lpszDelim,ppmk);
- *ppmk = NULL;
- return E_NOTIMPL;
+ return S_OK;
}
/******************************************************************************
- * CreateItemMoniker [OLE32.58]
+ * CreateItemMoniker [OLE32.@]
******************************************************************************/
HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
{
- ItemMonikerImpl* newItemMoniker = 0;
- HRESULT hr = S_OK;
- IID riid=IID_IMoniker;
+ ItemMonikerImpl* newItemMoniker;
+ HRESULT hr;
- TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
+ TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk);
newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
- if (newItemMoniker == 0)
+ if (!newItemMoniker)
return STG_E_INSUFFICIENTMEMORY;
hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
return hr;
}
- return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);
+ return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);
+}
+
+static HRESULT WINAPI ItemMonikerCF_QueryInterface(LPCLASSFACTORY iface,
+ REFIID riid, LPVOID *ppv)
+{
+ *ppv = NULL;
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
+ {
+ *ppv = iface;
+ IUnknown_AddRef(iface);
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ItemMonikerCF_AddRef(LPCLASSFACTORY iface)
+{
+ return 2; /* non-heap based object */
+}
+
+static ULONG WINAPI ItemMonikerCF_Release(LPCLASSFACTORY iface)
+{
+ return 1; /* non-heap based object */
+}
+
+static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface,
+ LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
+{
+ ItemMonikerImpl* newItemMoniker;
+ HRESULT hr;
+ static const WCHAR wszEmpty[] = { 0 };
+
+ TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
+
+ *ppv = NULL;
+
+ if (pUnk)
+ return CLASS_E_NOAGGREGATION;
+
+ newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
+ if (!newItemMoniker)
+ return E_OUTOFMEMORY;
+
+ hr = ItemMonikerImpl_Construct(newItemMoniker, wszEmpty, wszEmpty);
+
+ if (SUCCEEDED(hr))
+ hr = ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker, riid, ppv);
+ if (FAILED(hr))
+ HeapFree(GetProcessHeap(),0,newItemMoniker);
+
+ return hr;
+}
+
+static HRESULT WINAPI ItemMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
+{
+ FIXME("(%d), stub!\n",fLock);
+ return S_OK;
+}
+
+static const IClassFactoryVtbl ItemMonikerCFVtbl =
+{
+ ItemMonikerCF_QueryInterface,
+ ItemMonikerCF_AddRef,
+ ItemMonikerCF_Release,
+ ItemMonikerCF_CreateInstance,
+ ItemMonikerCF_LockServer
+};
+static const IClassFactoryVtbl *ItemMonikerCF = &ItemMonikerCFVtbl;
+
+HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv)
+{
+ return IClassFactory_QueryInterface((IClassFactory *)&ItemMonikerCF, riid, ppv);
}