Implemented:
- IMoniker interface for FileMoniker,ItemMoniker,AntiMoniker and
GenericCompositeMoniker
- IRunningObjectTable interface, and
- IBindCtx interface.
diff --git a/include/compobj.h b/include/compobj.h
index e1b372b..2514fae 100644
--- a/include/compobj.h
+++ b/include/compobj.h
@@ -1,8 +1,17 @@
#ifndef __WINE_COMPOBJ_H
#define __WINE_COMPOBJ_H
-/* "compobj.h" is obsolete, you should include "objbase.h" instead */
+/* All private prototye functions used by OLE will be added to this header file */
#include "objbase.h"
+/* This function initialize the Running Object Table */
+HRESULT WINAPI RunningObjectTableImpl_Initialize();
+
+/* This function uninitialize the Running Object Table */
+HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
+
+/* This function decompose a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directoy" or "FileName") of the path */
+int WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** stringTable);
+
#endif /* __WINE_COMPOBJ_H */
diff --git a/include/objbase.h b/include/objbase.h
index f927b9e..0e15d8a 100644
--- a/include/objbase.h
+++ b/include/objbase.h
@@ -20,6 +20,8 @@
#include "wine/obj_dragdrop.h"
+HRESULT WINAPI GetClassFile(LPOLESTR filePathName,CLSID *pclsid);
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/include/ole2.h b/include/ole2.h
index b7da0a2..9966342 100644
--- a/include/ole2.h
+++ b/include/ole2.h
@@ -28,15 +28,15 @@
HRESULT WINAPI RevokeDragDrop(HWND);
HRESULT WINAPI DoDragDrop16(LPDATAOBJECT,LPDROPSOURCE,DWORD,DWORD*);
HRESULT WINAPI DoDragDrop(LPDATAOBJECT,LPDROPSOURCE,DWORD,DWORD*);
-
-HOLEMENU WINAPI OleCreateMenuDescriptor(HMENU hmenuCombined,
- LPOLEMENUGROUPWIDTHS lpMenuWidths);
+HRESULT WINAPI OleLoadFromStream(IStream *pStm,REFIID iidInterface,void** ppvObj);
+HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm);
+HOLEMENU WINAPI OleCreateMenuDescriptor(HMENU hmenuCombined,LPOLEMENUGROUPWIDTHS lpMenuWidths);
HRESULT WINAPI OleDestroyMenuDescriptor(HOLEMENU hmenuDescriptor);
-HRESULT WINAPI OleSetMenuDescriptor(HOLEMENU hmenuDescriptor,
- HWND hwndFrame,
- HWND hwndActiveObject,
- LPOLEINPLACEFRAME lpFrame,
- LPOLEINPLACEACTIVEOBJECT lpActiveObject);
+HRESULT WINAPI OleSetMenuDescriptor(HOLEMENU hmenuDescriptor,HWND hwndFrame,HWND hwndActiveObject,LPOLEINPLACEFRAME lpFrame,LPOLEINPLACEACTIVEOBJECT lpActiveObject);
+
+HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid);
+HRESULT WINAPI WriteClassStm(IStream *pStm,REFCLSID rclsid);
+HRESULT WINAPI ReadClassStm(IStream *pStm,REFCLSID pclsid);
#endif /* __WINE_OLE2_H */
diff --git a/include/wine/obj_base.h b/include/wine/obj_base.h
index 59f7da3..914c7cf 100644
--- a/include/wine/obj_base.h
+++ b/include/wine/obj_base.h
@@ -817,6 +817,10 @@
HRESULT WINAPI CoInitialize16(LPVOID lpReserved);
HRESULT WINAPI CoInitialize(LPVOID lpReserved);
+HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit);
+
+void WINAPI CoUninitialize16(void);
+void WINAPI CoUninitialize(void);
typedef enum tagCOINIT
{
@@ -826,7 +830,6 @@
COINIT_SPEED_OVER_MEMORY = 0x8 /* Trade memory for speed */
} COINIT;
-HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit);
/* FIXME: not implemented */
BOOL WINAPI CoIsOle1Class(REFCLSID rclsid);
@@ -850,10 +853,6 @@
HRESULT WINAPI CoRevokeClassObject(DWORD dwRegister);
-void WINAPI CoUninitialize16(void);
-void WINAPI CoUninitialize(void);
-
-
/*****************************************************************************
* Internal WINE API
*/
diff --git a/include/wine/obj_inplace.h b/include/wine/obj_inplace.h
index 98dec21..06a6478 100644
--- a/include/wine/obj_inplace.h
+++ b/include/wine/obj_inplace.h
@@ -384,7 +384,7 @@
#define IParseDisplayName_AddRef(p) ICOM_CALL (AddRef,p)
#define IParseDisplayName_Release(p) ICOM_CALL (Release,p)
/*** IParseDisplayName methods ***/
-#define IParseDisplayName_ParseDisplayName(p,a,b,c,d) ICOM_CALL4(ParseDisplayName,a,b,c,d)
+#define IParseDisplayName_ParseDisplayName(p,a,b,c,d) ICOM_CALL4(ParseDisplayName,p,a,b,c,d)
#endif
diff --git a/include/wine/obj_moniker.h b/include/wine/obj_moniker.h
index ddc65a8..9a90dfc 100644
--- a/include/wine/obj_moniker.h
+++ b/include/wine/obj_moniker.h
@@ -33,7 +33,13 @@
DEFINE_OLEGUID(IID_IRunningObjectTable, 0x00000010L, 0, 0);
typedef struct IRunningObjectTable IRunningObjectTable,*LPRUNNINGOBJECTTABLE;
+DEFINE_GUID( CLSID_FileMoniker,0x00000303,0,0,0xc0,0,0,0,0,0,0,0x46);
+DEFINE_GUID( CLSID_ItemMoniker,0x00000304,0,0,0xc0,0,0,0,0,0,0,0x46);
+
+DEFINE_GUID( CLSID_AntiMoniker,0x00000305,0,0,0xc0,0,0,0,0,0,0,0x46);
+
+DEFINE_GUID( CLSID_CompositeMoniker,0x00000309,0,0,0xc0,0,0,0,0,0,0,0x46);
/*********************************************************************************
* BIND_OPTS and BIND_OPTS2 structures definition
@@ -66,12 +72,12 @@
#define IBindCtx_METHODS \
ICOM_METHOD1 (HRESULT, RegisterObjectBound, IUnknown*,punk) \
ICOM_METHOD1 (HRESULT, RevokeObjectBound, IUnknown*,punk) \
- ICOM_METHOD (HRESULT, ReleaseObjects) \
+ ICOM_METHOD (HRESULT, ReleaseBoundObjects) \
ICOM_METHOD1 (HRESULT, SetBindOptions, LPBIND_OPTS2,pbindopts) \
ICOM_METHOD1 (HRESULT, GetBindOptions, LPBIND_OPTS2,pbindopts) \
ICOM_METHOD1 (HRESULT, GetRunningObjectTable,IRunningObjectTable**,pprot) \
ICOM_METHOD2 (HRESULT, RegisterObjectParam, LPOLESTR,pszkey, IUnknown*,punk) \
- ICOM_METHOD2 (HRESULT, GetObjectParam, LPOLESTR,pszkey, IUnknown*,punk) \
+ ICOM_METHOD2 (HRESULT, GetObjectParam, LPOLESTR,pszkey, IUnknown**,punk) \
ICOM_METHOD1 (HRESULT, EnumObjectParam, IEnumString**,ppenum) \
ICOM_METHOD1 (HRESULT, RevokeObjectParam, LPOLESTR,pszkey)
#define IBindCtx_IMETHODS \
@@ -88,7 +94,7 @@
/* IBindCtx methods*/
#define IBindCtx_RegisterObjectBound(p,a) ICOM_CALL1(RegisterObjectBound,p,a)
#define IBindCtx_RevokeObjectBound(p,a) ICOM_CALL1(RevokeObjectBound,p,a)
-#define IBindCtx_ReleaseObjects(p) ICOM_CALL (ReleaseObjects,p)
+#define IBindCtx_ReleaseBoundObjects(p) ICOM_CALL (ReleaseBoundObjects,p)
#define IBindCtx_SetBindOptions(p,a) ICOM_CALL1(SetBindOptions,p,a)
#define IBindCtx_GetBindOptions(p,a) ICOM_CALL1(GetBindOptions,p,a)
#define IBindCtx_GetRunningObjectTable(p,a) ICOM_CALL1(GetRunningObjectTable,p,a)
@@ -101,7 +107,6 @@
HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC* ppbc);
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC* ppbc);
-
/*****************************************************************************
* IClassActivator interface
*/
@@ -151,7 +156,6 @@
#define IEnumMoniker_Clone(p,a) ICOM_CALL1(Clone,p,a)
#endif
-
/*****************************************************************************
* IMoniker interface
*/
@@ -203,6 +207,7 @@
#define IMoniker_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IMoniker_AddRef(p) ICOM_CALL (AddRef,p)
#define IMoniker_Release(p) ICOM_CALL (Release,p)
+
/*** IPersist methods ***/
#define IMoniker_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a)
/*** IPersistStream methods ***/
@@ -211,45 +216,44 @@
#define IMoniker_Save(p,a,b) ICOM_CALL2(Save,p,a,b)
#define IMoniker_GetSizeMax(p,a) ICOM_CALL1(GetSizeMax,p,a)
/*** IMoniker methods ***/
-#define IMoniker_BindToObject(p,a,b,c,d) ICOM_CALL(BindToObject,p,a,b,c,d)
-#define IMoniker_BindToStorage(p,a,b,c,d) ICOM_CALL(BindToStorage,p,a,b,c,d)
-#define IMoniker_Reduce(p,a,b,c,d) ICOM_CALL(Reduce,p,a,b,c,d)
-#define IMoniker_ComposeWith(p,a,b,c) ICOM_CALL(ComposeWith,p,a,b,c)
-#define IMoniker_Enum(p,a,b) ICOM_CALL(Enum,p,a,b)
-#define IMoniker_IsEqual(p,a) ICOM_CALL(IsEqual,p,a)
-#define IMoniker_Hash(p,a) ICOM_CALL(Hash,p,a)
-#define IMoniker_IsRunning(p,a,b,c) ICOM_CALL(IsRunning,p,a,b,c)
-#define IMoniker_GetTimeOfLastChange(p,a,b,c) ICOM_CALL(GetTimeOfLastChange,p,a,b,c)
-#define IMoniker_Inverse(p,a) ICOM_CALL(Inverse,p,a)
-#define IMoniker_CommonPrefixWith(p,a,b) ICOM_CALL(CommonPrefixWith,p,a,b)
-#define IMoniker_RelativePathTo(p,a,b) ICOM_CALL(RelativePathTo,p,a,b)
-#define IMoniker_GetDisplayName(p,a,b,c) ICOM_CALL(GetDisplayName,p,a,b,c)
-#define IMoniker_ParseDisplayName(p,a,b,c,d,e) ICOM_CALL(ParseDisplayName,p,a,b,c,d,e)
-#define IMoniker_IsSystemMoniker(p,a) ICOM_CALL(IsSystemMoniker,p,a)
+#define IMoniker_BindToObject(p,a,b,c,d) ICOM_CALL4(BindToObject,p,a,b,c,d)
+#define IMoniker_BindToStorage(p,a,b,c,d) ICOM_CALL4(BindToStorage,p,a,b,c,d)
+#define IMoniker_Reduce(p,a,b,c,d) ICOM_CALL4(Reduce,p,a,b,c,d)
+#define IMoniker_ComposeWith(p,a,b,c) ICOM_CALL3(ComposeWith,p,a,b,c)
+#define IMoniker_Enum(p,a,b) ICOM_CALL2(Enum,p,a,b)
+#define IMoniker_IsEqual(p,a) ICOM_CALL1(IsEqual,p,a)
+#define IMoniker_Hash(p,a) ICOM_CALL1(Hash,p,a)
+#define IMoniker_IsRunning(p,a,b,c) ICOM_CALL3(IsRunning,p,a,b,c)
+#define IMoniker_GetTimeOfLastChange(p,a,b,c) ICOM_CALL3(GetTimeOfLastChange,p,a,b,c)
+#define IMoniker_Inverse(p,a) ICOM_CALL1(Inverse,p,a)
+#define IMoniker_CommonPrefixWith(p,a,b) ICOM_CALL2(CommonPrefixWith,p,a,b)
+#define IMoniker_RelativePathTo(p,a,b) ICOM_CALL2(RelativePathTo,p,a,b)
+#define IMoniker_GetDisplayName(p,a,b,c) ICOM_CALL3(GetDisplayName,p,a,b,c)
+#define IMoniker_ParseDisplayName(p,a,b,c,d,e) ICOM_CALL5(ParseDisplayName,p,a,b,c,d,e)
+#define IMoniker_IsSystemMoniker(p,a) ICOM_CALL1(IsSystemMoniker,p,a)
#endif
-/* FIXME: not implemented */
-HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID iidResult, LPVOID* ppvResult);
-
-/* FIXME: not implemented */
-HRESULT WINAPI CreateAntiMoniker(LPMONIKER* ppmk);
-
-/* FIXME: not implemented */
-HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, LPMONIKER* ppmk);
-
HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName, LPMONIKER* ppmk);
HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER* ppmk);
HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim, LPCOLESTR lpszItem, LPMONIKER* ppmk);
HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim, LPCOLESTR lpszItem, LPMONIKER* ppmk);
-/* FIXME: not implemented */
+HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk);
+
HRESULT WINAPI CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest, LPMONIKER* ppmkComposite);
/* FIXME: not implemented */
+HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID iidResult, LPVOID* ppvResult);
+
+/* FIXME: not implemented */
+HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, LPMONIKER* ppmk);
+
+/* FIXME: not implemented */
HRESULT WINAPI CreatePointerMoniker(LPUNKNOWN punk, LPMONIKER* ppmk);
-
+/* FIXME: not implemented */
+HRESULT WINAPI MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon);
/*****************************************************************************
* IROTData interface
*/
@@ -271,6 +275,7 @@
#define IROTData_GetComparisonData(p,a,b,c) ICOM_CALL3(GetComparisonData,p,a,b,c)
#endif
+#define ICOM_THIS_From_IROTData(class, name) class* This = (class*)(((void*)name)-sizeof(void*))
/*****************************************************************************
* IRunnableObject interface
@@ -335,6 +340,8 @@
#define IRunningObjectTable_EnumRunning(p,a) ICOM_CALL1(EnumRunning,p,a)
#endif
+HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPVOID *pprot);
+HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPVOID *pprot);
/*****************************************************************************
* Additional API
diff --git a/include/winerror.h b/include/winerror.h
index ae27c22..118e650 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -299,6 +299,7 @@
#define E_POINTER 0x80004003
#define E_ABORT 0x80004004
#define E_FAIL 0x80004005
+#define E_UNSPEC E_FAIL // must to be defined (used by FileMoniker, IOleLink and DoDragDrop as a return value)
/*#define CO_E_INIT_TLS 0x80004006
#define CO_E_INIT_SHARED_ALLOCATOR 0x80004007
@@ -313,9 +314,11 @@
#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010
#define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011
#define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012 */
-#define CO_E_ERRORINDLL 0x800401F9L
+#define CO_E_NOTINITIALIZED 0x800401F0
+#define CO_E_ERRORINDLL 0x800401F9
#define CO_E_OBJISREG 0x800401FB
+
#define OLE_E_ENUM_NOMORE 0x80040002
#define OLE_E_ADVISENOTSUPPORTED 0x80040003
#define OLE_E_NOCONNECTION 0x80040004
@@ -326,18 +329,46 @@
#define OLE_E_STATIC 0x8004000B
#define OLE_E_PROMPTSAVECANCELLED 0x8004000C
#define OLE_S_USEREG 0x00040000
+
#define DV_E_FORMATETC 0x80040064
#define DV_E_DVASPECT 0x8004006B
+
+#define CLASS_E_NOAGGREGATION 0x80040110
+#define CLASS_E_CLASSNOTAVAILABLE 0x80040111
+
#define DATA_S_SAMEFORMATETC 0x80040130
+
#define E_ACCESSDENIED 0x80070005
#define E_HANDLE 0x80070006
#define E_OUTOFMEMORY 0x8007000E
#define E_INVALIDARG 0x80070057
+
/*#define OLE_E_FIRST 0x80040000L */
/*#define OLE_E_LAST 0x800400FFL */
/*#define OLE_S_FIRST 0x00040000L */
/*#define OLE_S_LAST 0x000400FFL */
+#define MK_S_REDUCED_TO_SELF 0x000401E2
+#define MK_S_ME 0x000401E4
+#define MK_S_HIM 0x000401E5
+#define MK_S_US 0x000401E6
+#define MK_S_MONIKERALREADYREGISTERED 0x000401E7
+
+#define MK_E_EXCEEDEDDEADLINE 0x800401E1
+#define MK_E_NEEDGENERIC 0x800401E2
+#define MK_E_UNAVAILABLE 0x800401E3
+#define MK_E_SYNTAX 0x800401E4
+#define MK_E_NOOBJECT 0x800401E5
+#define MK_E_INVALIDEXTENSION 0x800401E6
+#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7
+#define MK_E_NOTBINDABLE 0x800401E8
+#define MK_E_NOTBOUND 0x800401E9
+#define MK_E_CANTOPENFILE 0x800401EA
+#define MK_E_MIUSTBOTHERUSER 0x800401EB
+#define MK_E_NOINVERSE 0x800401EC
+#define MK_E_NOSTORAGE 0x800401ED
+#define MK_E_NOPREFIX 0x800401EE
+
#define STG_E_INVALIDFUNCTION 0x80030001
#define STG_E_FILENOTFOUND 0x80030002
#define STG_E_PATHNOTFOUND 0x80030003
@@ -405,11 +436,6 @@
#define CLASS_E_NOAGGREGATION 0x80040110
#define CLASS_E_CLASSNOTAVAILABLE 0x80040111
-#define MK_E_EXCEEDEDDEADLINE 0x800401E1L
-#define MK_E_SYNTAX 0x800401E4L
-#define MK_E_NOOBJECT 0x800401E5L
-#define MK_E_INVALIDEXTENSION 0x800401E6L
-#define MK_E_NOSTORAGE 0x800401EDL
#define OLEOBJ_E_NOVERBS 0x00040180L
#define OLEOBJ_S_INVALIDVERB 0x00040180L
diff --git a/include/wtypes.h b/include/wtypes.h
index fd1949f..574cc5d 100644
--- a/include/wtypes.h
+++ b/include/wtypes.h
@@ -228,6 +228,12 @@
PACL Dacl;
} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR;
+#ifndef _ROTFLAGS_DEFINED
+#define _ROTFLAGS_DEFINED
+#define ROTFLAGS_REGISTRATIONKEEPSALIVE 0x1
+#define ROTFLAGS_ALLOWANYCLIENT 0x2
+#endif // !_ROTFLAGS_DEFINED
+
#endif /* _SECURITY_DEFINED */
diff --git a/ole/Makefile.in b/ole/Makefile.in
index df3ec8f..b957087 100644
--- a/ole/Makefile.in
+++ b/ole/Makefile.in
@@ -6,8 +6,10 @@
MODULE = ole
C_SRCS = \
+ antimoniker.c \
bindctx.c \
compobj.c \
+ compositemoniker.c \
filemoniker.c \
guid.c \
ifs.c \
@@ -23,10 +25,10 @@
olesvr.c \
parsedt.c \
safearray.c \
- storage.c \
- storage32.c \
stg_bigblockfile.c \
stg_stream.c \
+ storage.c \
+ storage32.c \
typelib.c \
variant.c
diff --git a/ole/antimoniker.c b/ole/antimoniker.c
new file mode 100644
index 0000000..9fd1833
--- /dev/null
+++ b/ole/antimoniker.c
@@ -0,0 +1,643 @@
+/***************************************************************************************
+ * AntiMonikers implementation
+ *
+ * Copyright 1999 Noomen Hamza
+ ***************************************************************************************/
+
+#include <assert.h>
+#include "winerror.h"
+#include "debug.h"
+#include "heap.h"
+#include "winuser.h"
+#include "file.h"
+#include "winreg.h"
+#include "objbase.h"
+#include "wine/obj_inplace.h"
+
+/* AntiMoniker data structure */
+typedef struct AntiMonikerImpl{
+
+ ICOM_VTABLE(IMoniker)* 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.*/
+
+ ULONG ref; /* reference counter for this object */
+
+} AntiMonikerImpl;
+
+/********************************************************************************/
+/* AntiMoniker prototype functions : */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
+static ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker* iface);
+static ULONG WINAPI AntiMonikerImpl_Release(IMoniker* iface);
+
+/* IPersist prototype functions */
+static HRESULT WINAPI AntiMonikerImpl_GetClassID(const IMoniker* iface, CLSID *pClassID);
+
+/* IPersistStream prototype functions */
+static HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface);
+static HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface, IStream* pStm);
+static HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
+static HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
+
+/* IMoniker prototype functions */
+static HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
+static HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
+static HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
+static HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
+static HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
+static HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
+static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
+static HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
+static HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pAntiTime);
+static HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
+static HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
+static HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
+static HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
+static HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
+static HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
+
+/********************************************************************************/
+/* IROTData prototype functions */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
+static ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData* iface);
+static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface);
+
+/* IROTData prototype function */
+static HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
+
+/* Local function used by AntiMoniker implementation */
+HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* iface);
+HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* iface);
+
+/********************************************************************************/
+/* Virtual function table for the AntiMonikerImpl class witch include Ipersist,*/
+/* IPersistStream and IMoniker functions. */
+static ICOM_VTABLE(IMoniker) VT_AntiMonikerImpl =
+{
+ AntiMonikerImpl_QueryInterface,
+ AntiMonikerImpl_AddRef,
+ AntiMonikerImpl_Release,
+ AntiMonikerImpl_GetClassID,
+ AntiMonikerImpl_IsDirty,
+ AntiMonikerImpl_Load,
+ AntiMonikerImpl_Save,
+ AntiMonikerImpl_GetSizeMax,
+ AntiMonikerImpl_BindToObject,
+ AntiMonikerImpl_BindToStorage,
+ AntiMonikerImpl_Reduce,
+ AntiMonikerImpl_ComposeWith,
+ AntiMonikerImpl_Enum,
+ AntiMonikerImpl_IsEqual,
+ AntiMonikerImpl_Hash,
+ AntiMonikerImpl_IsRunning,
+ AntiMonikerImpl_GetTimeOfLastChange,
+ AntiMonikerImpl_Inverse,
+ AntiMonikerImpl_CommonPrefixWith,
+ AntiMonikerImpl_RelativePathTo,
+ AntiMonikerImpl_GetDisplayName,
+ AntiMonikerImpl_ParseDisplayName,
+ AntiMonikerImpl_IsSystemMoniker
+};
+
+/********************************************************************************/
+/* Virtual function table for the IROTData class. */
+static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
+{
+ AntiMonikerROTDataImpl_QueryInterface,
+ AntiMonikerROTDataImpl_AddRef,
+ AntiMonikerROTDataImpl_Release,
+ AntiMonikerROTDataImpl_GetComparaisonData
+};
+
+/*******************************************************************************
+ * AntiMoniker_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
+{
+ ICOM_THIS(AntiMonikerImpl,iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
+
+ /* Perform a sanity check on the parameters.*/
+ if ( (This==0) || (ppvObject==0) )
+ return E_INVALIDARG;
+
+ /* Initialize the return parameter */
+ *ppvObject = 0;
+
+ /* Compare the riid with the interface IDs implemented by this object.*/
+ if (IsEqualIID(&IID_IUnknown, riid) ||
+ IsEqualIID(&IID_IPersist, riid) ||
+ IsEqualIID(&IID_IPersistStream, riid) ||
+ IsEqualIID(&IID_IMoniker, riid)
+ )
+ *ppvObject = iface;
+ else if (IsEqualIID(&IID_IROTData, riid))
+ *ppvObject = (IROTData*)&(This->lpvtbl2);
+
+ /* Check that we obtained an interface.*/
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ /* Query Interface always increases the reference count by one when it is successful */
+ AntiMonikerImpl_AddRef(iface);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * AntiMoniker_AddRef
+ ******************************************************************************/
+ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker* iface)
+{
+ ICOM_THIS(AntiMonikerImpl,iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ return ++(This->ref);
+}
+
+/******************************************************************************
+ * AntiMoniker_Release
+ ******************************************************************************/
+ULONG WINAPI AntiMonikerImpl_Release(IMoniker* iface)
+{
+ ICOM_THIS(AntiMonikerImpl,iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ This->ref--;
+
+ /* destroy the object if there's no more reference on it */
+ if (This->ref==0){
+
+ AntiMonikerImpl_Destroy(This);
+
+ return 0;
+ }
+ return This->ref;;
+}
+
+/******************************************************************************
+ * AntiMoniker_GetClassID
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_GetClassID(const IMoniker* iface,CLSID *pClassID)
+{
+ TRACE(ole,"(%p,%p),stub!\n",iface,pClassID);
+
+ if (pClassID==NULL)
+ return E_POINTER;
+
+ *pClassID = CLSID_AntiMoniker;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * AntiMoniker_IsDirty
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface)
+{
+ /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
+ method in the OLE-provided moniker interfaces always return S_FALSE because
+ their internal state never changes. */
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return S_FALSE;
+}
+
+/******************************************************************************
+ * AntiMoniker_Load
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface,IStream* pStm)
+{
+ DWORD constant=1,dwbuffer;
+ HRESULT res;
+
+ /* data read by this function is only a DWORD constant (must be 1) ! */
+ res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),NULL);
+
+ if (SUCCEEDED(res)&& dwbuffer!=constant)
+ return E_FAIL;
+
+ return res;
+}
+
+/******************************************************************************
+ * AntiMoniker_Save
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
+{
+ DWORD constant=1;
+ HRESULT res;
+
+ /* data writen by this function is only a DWORD constant seted to 1 ! */
+ res=IStream_Write(pStm,&constant,sizeof(constant),NULL);
+
+ return res;
+}
+
+/******************************************************************************
+ * AntiMoniker_GetSizeMax
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface,
+ ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
+{
+ TRACE(ole,"(%p,%p)\n",iface,pcbSize);
+
+ if (pcbSize!=NULL)
+ return E_POINTER;
+
+ /* for more details see AntiMonikerImpl_Save coments */
+
+ /* Normaly the sizemax must be the size of DWORD ! but I tested this function it ususlly return 16 bytes */
+ /* more than the number of bytes used by AntiMoniker::Save function */
+ pcbSize->LowPart = sizeof(DWORD)+16;
+
+ pcbSize->HighPart=0;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * AntiMoniker_Construct (local function)
+ *******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* This)
+{
+
+ TRACE(ole,"(%p)\n",This);
+
+ /* Initialize the virtual fgunction table. */
+ This->lpvtbl1 = &VT_AntiMonikerImpl;
+ This->lpvtbl2 = &VT_ROTDataImpl;
+ This->ref = 0;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * AntiMoniker_Destroy (local function)
+ *******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* This)
+{
+ TRACE(ole,"(%p)\n",This);
+
+ return HeapFree(GetProcessHeap(),0,This);
+}
+
+/******************************************************************************
+ * AntiMoniker_BindToObject
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvResult)
+{
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+ return E_NOTIMPL;
+}
+
+/******************************************************************************
+ * AntiMoniker_BindToStorage
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvResult)
+{
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+ return E_NOTIMPL;
+}
+
+/******************************************************************************
+ * AntiMoniker_Reduce
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface,
+ IBindCtx* pbc,
+ DWORD dwReduceHowFar,
+ IMoniker** ppmkToLeft,
+ IMoniker** ppmkReduced)
+{
+ TRACE(ole,"(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
+
+ if (ppmkReduced==NULL)
+ return E_POINTER;
+
+ AntiMonikerImpl_AddRef(iface);
+
+ *ppmkReduced=iface;
+
+ return MK_S_REDUCED_TO_SELF;
+}
+/******************************************************************************
+ * AntiMoniker_ComposeWith
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface,
+ IMoniker* pmkRight,
+ BOOL fOnlyIfNotGeneric,
+ IMoniker** ppmkComposite)
+{
+
+ TRACE(ole,"(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
+
+ if ((ppmkComposite==NULL)||(pmkRight==NULL))
+ return E_POINTER;
+
+ *ppmkComposite=0;
+
+ if (fOnlyIfNotGeneric)
+ return MK_E_NEEDGENERIC;
+ else
+ return CreateGenericComposite(iface,pmkRight,ppmkComposite);
+}
+
+/******************************************************************************
+ * AntiMoniker_Enum
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
+{
+ TRACE(ole,"(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
+
+ if (ppenumMoniker == NULL)
+ return E_POINTER;
+
+ *ppenumMoniker = NULL;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * AntiMoniker_IsEqual
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
+{
+ DWORD mkSys;
+
+ TRACE(ole,"(%p,%p)\n",iface,pmkOtherMoniker);
+
+ if (pmkOtherMoniker==NULL)
+ return S_FALSE;
+
+ IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys);
+
+ if (mkSys==MKSYS_ANTIMONIKER)
+ return S_OK;
+ else
+ return S_FALSE;
+}
+
+/******************************************************************************
+ * AntiMoniker_Hash
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
+{
+ if (pdwHash==NULL)
+ return E_POINTER;
+
+ *pdwHash=0;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * AntiMoniker_IsRunning
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ IMoniker* pmkNewlyRunning)
+{
+ IRunningObjectTable* rot;
+ HRESULT res;
+
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
+
+ if (pbc==NULL)
+ return E_INVALIDARG;
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+ if (FAILED(res))
+ return res;
+
+ res = IRunningObjectTable_IsRunning(rot,iface);
+
+ IRunningObjectTable_Release(rot);
+
+ return res;
+}
+
+/******************************************************************************
+ * AntiMoniker_GetTimeOfLastChange
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ FILETIME* pAntiTime)
+{
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
+ return E_NOTIMPL;
+}
+
+/******************************************************************************
+ * AntiMoniker_Inverse
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
+{
+ TRACE(ole,"(%p,%p)\n",iface,ppmk);
+
+ if (ppmk==NULL)
+ return E_POINTER;
+
+ *ppmk=0;
+
+ return MK_E_NOINVERSE;
+}
+
+/******************************************************************************
+ * AntiMoniker_CommonPrefixWith
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
+{
+ DWORD mkSys;
+
+ IMoniker_IsSystemMoniker(pmkOther,&mkSys);
+
+ if(mkSys==MKSYS_ITEMMONIKER){
+
+ IMoniker_AddRef(iface);
+
+ *ppmkPrefix=iface;
+
+ IMoniker_AddRef(iface);
+
+ return MK_S_US;
+ }
+ else
+ return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
+}
+
+/******************************************************************************
+ * AntiMoniker_RelativePathTo
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
+{
+ TRACE(ole,"(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
+
+ if (ppmkRelPath==NULL)
+ return E_POINTER;
+
+ IMoniker_AddRef(pmOther);
+
+ *ppmkRelPath=pmOther;
+
+ return MK_S_HIM;
+}
+
+/******************************************************************************
+ * AntiMoniker_GetDisplayName
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ LPOLESTR *ppszDisplayName)
+{
+ WCHAR back[]={'\\','.','.',0};
+
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
+
+ if (ppszDisplayName==NULL)
+ return E_POINTER;
+
+ if (pmkToLeft!=NULL){
+ FIXME(ole,"() pmkToLeft!=NULL not implemented \n");
+ return E_NOTIMPL;
+ }
+
+ *ppszDisplayName=CoTaskMemAlloc(sizeof(back));
+
+ if (*ppszDisplayName==NULL)
+ return E_OUTOFMEMORY;
+
+ lstrcpyW(*ppszDisplayName,back);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * AntiMoniker_ParseDisplayName
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ LPOLESTR pszDisplayName,
+ ULONG* pchEaten,
+ IMoniker** ppmkOut)
+{
+ TRACE(ole,"(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
+ return E_NOTIMPL;
+}
+
+/******************************************************************************
+ * AntiMoniker_IsSystemMonker
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
+{
+ TRACE(ole,"(%p,%p)\n",iface,pwdMksys);
+
+ if (!pwdMksys)
+ return E_POINTER;
+
+ (*pwdMksys)=MKSYS_ANTIMONIKER;
+
+ return S_OK;
+}
+
+/*******************************************************************************
+ * AntiMonikerIROTData_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
+{
+
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",iface,riid,ppvObject);
+
+ return AntiMonikerImpl_QueryInterface(This, riid, ppvObject);
+}
+
+/***********************************************************************
+ * AntiMonikerIROTData_AddRef
+ */
+ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData *iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return AntiMonikerImpl_AddRef(This);
+}
+
+/***********************************************************************
+ * AntiMonikerIROTData_Release
+ */
+ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return AntiMonikerImpl_Release(This);
+}
+
+/******************************************************************************
+ * AntiMonikerIROTData_GetComparaisonData
+ ******************************************************************************/
+HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
+ BYTE* pbData,
+ ULONG cbMax,
+ ULONG* pcbData)
+{
+ FIXME(ole,"(),stub!\n");
+ return E_NOTIMPL;
+}
+
+/******************************************************************************
+ * CreateAntiMoniker [OLE.55]
+ ******************************************************************************/
+HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk)
+{
+ AntiMonikerImpl* newAntiMoniker = 0;
+ HRESULT hr = S_OK;
+ IID riid=IID_IMoniker;
+
+ TRACE(ole,"(%p)\n",ppmk);
+
+ newAntiMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl));
+
+ if (newAntiMoniker == 0)
+ return STG_E_INSUFFICIENTMEMORY;
+
+ hr = AntiMonikerImpl_Construct(newAntiMoniker);
+
+ if (FAILED(hr)){
+
+ HeapFree(GetProcessHeap(),0,newAntiMoniker);
+ return hr;
+ }
+
+ hr = AntiMonikerImpl_QueryInterface((IMoniker*)newAntiMoniker,&riid,(void**)ppmk);
+
+ return hr;
+}
diff --git a/ole/bindctx.c b/ole/bindctx.c
index 68f3fc9..3057fd1 100644
--- a/ole/bindctx.c
+++ b/ole/bindctx.c
@@ -4,8 +4,6 @@
* Copyright 1999 Noomen Hamza
***************************************************************************************/
-#include <ctype.h>
-#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "winerror.h"
@@ -13,36 +11,59 @@
#include "debug.h"
#include "heap.h"
+/* represent the first size table and it's increment block size */
+#define BLOCK_TAB_SIZE 10
+#define MAX_TAB_SIZE 0xFFFFFFFF
+
+/* data structure of the BindCtx table elements */
+typedef struct BindCtxObject{
+
+ IUnknown* pObj; /* point on a bound object */
+
+ LPOLESTR pkeyObj; /* key associated to this bound object */
+
+ BYTE regType; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
+
+} BindCtxObject;
+
+/* BindCtx data strucrture */
typedef struct BindCtxImpl{
- ICOM_VTABLE(IBindCtx)* lpvtbl;
+ ICOM_VTABLE(IBindCtx)* lpvtbl; /* VTable relative to the IBindCtx interface.*/
- ULONG ref;
+ ULONG ref; /* reference counter for this object */
+
+ BindCtxObject* bindCtxTable; /* this is a table in witch all bounded objects are stored*/
+ DWORD bindCtxTableLastIndex; /* first free index in the table */
+ DWORD bindCtxTableSize; /* size table */
+
+ BIND_OPTS2 bindOption2; /* a structure witch contains the bind options*/
} BindCtxImpl;
+/* IBindCtx prototype functions : */
-HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject);
-ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface);
-ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface);
-HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk);
-HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk);
-HRESULT WINAPI BindCtxImpl_ReleaseObjects(IBindCtx* iface);
-HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts);
-HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts);
-HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot);
-HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk);
-HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk);
-HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** ppenum);
-HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR pszkey);
-
-HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC * ppbc);
-HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc);
-
+/* IUnknown functions*/
+static HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject);
+static ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface);
+static ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface);
+/* IBindCtx functions */
+static HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk);
+static HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk);
+static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface);
+static HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts);
+static HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts);
+static HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot);
+static HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk);
+static HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk);
+static HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** ppenum);
+static HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR pszkey);
+/* Local functions*/
HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This);
HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This);
+HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,IUnknown* punk,LPOLESTR pszkey,DWORD *index);
-// Virtual function table for the BindCtx class.
+/* Virtual function table for the BindCtx class. */
static ICOM_VTABLE(IBindCtx) VT_BindCtxImpl =
{
BindCtxImpl_QueryInterface,
@@ -50,7 +71,7 @@
BindCtxImpl_Release,
BindCtxImpl_RegisterObjectBound,
BindCtxImpl_RevokeObjectBound,
- BindCtxImpl_ReleaseObjects,
+ BindCtxImpl_ReleaseBoundObjects,
BindCtxImpl_SetBindOptions,
BindCtxImpl_GetBindOptions,
BindCtxImpl_GetRunningObjectTable,
@@ -66,35 +87,40 @@
HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
{
ICOM_THIS(BindCtxImpl,iface);
+
TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
- // Perform a sanity check on the parameters.
- if ( (This==0) || (ppvObject==0) ) return E_INVALIDARG;
+
+ /* Perform a sanity check on the parameters.*/
+ if ( (This==0) || (ppvObject==0) )
+ return E_INVALIDARG;
- // Initialize the return parameter.
+ /* Initialize the return parameter.*/
*ppvObject = 0;
- // Compare the riid with the interface IDs implemented by this object.
- if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
+ /* Compare the riid with the interface IDs implemented by this object.*/
+ if (IsEqualIID(&IID_IUnknown, riid))
*ppvObject = (IBindCtx*)This;
else
- if (memcmp(&IID_IBindCtx, riid, sizeof(IID_IBindCtx)) == 0)
+ if (IsEqualIID(&IID_IBindCtx, riid))
*ppvObject = (IBindCtx*)This;
- // Check that we obtained an interface.
- if ((*ppvObject)==0) return E_NOINTERFACE;
+ /* Check that we obtained an interface.*/
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
- // Query Interface always increases the reference count by one when it is successful
+ /* Query Interface always increases the reference count by one when it is successful */
BindCtxImpl_AddRef(iface);
return S_OK;
}
/******************************************************************************
- * BindCtx_ _AddRef
+ * BindCtx_AddRef
******************************************************************************/
ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface)
{
ICOM_THIS(BindCtxImpl,iface);
+
TRACE(ole,"(%p)\n",This);
return ++(This->ref);
@@ -106,12 +132,18 @@
ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface)
{
ICOM_THIS(BindCtxImpl,iface);
+
TRACE(ole,"(%p)\n",This);
This->ref--;
if (This->ref==0){
+
+ /* release all registred objects */
+ BindCtxImpl_ReleaseBoundObjects((IBindCtx*)This);
+
BindCtxImpl_Destroy(This);
+
return 0;
}
return This->ref;;
@@ -119,28 +151,50 @@
/******************************************************************************
- * BindCtx_Construct
+ * BindCtx_Construct (local function)
*******************************************************************************/
HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This)
{
- FIXME(ole,"(%p),stub!\n",This);
+ TRACE(ole,"(%p)\n",This);
- memset(This, 0, sizeof(BindCtxImpl));
-
- //Initialize the virtual fgunction table.
+ /* Initialize the virtual function table.*/
This->lpvtbl = &VT_BindCtxImpl;
+ This->ref = 0;
- return E_NOTIMPL;
+ /* Initialize the BIND_OPTS2 structure */
+ This->bindOption2.cbStruct = sizeof(BIND_OPTS2);
+ This->bindOption2.grfFlags = 0;
+ This->bindOption2.grfMode = STGM_READWRITE;
+ This->bindOption2.dwTickCountDeadline = 0;
+
+ This->bindOption2.dwTrackFlags = 0;
+ This->bindOption2.dwClassContext = CLSCTX_SERVER;
+ This->bindOption2.locale = 1033;
+ This->bindOption2.pServerInfo = 0;
+
+ /* Initialize the bindctx table */
+ This->bindCtxTableSize=BLOCK_TAB_SIZE;
+ This->bindCtxTableLastIndex=0;
+ This->bindCtxTable= HeapAlloc(GetProcessHeap(), 0,This->bindCtxTableSize*sizeof(BindCtxObject));
+
+ if (This->bindCtxTable==NULL)
+ return E_OUTOFMEMORY;
+
+ return S_OK;
}
/******************************************************************************
- * BindCtx_Destroy
+ * BindCtx_Destroy (local function)
*******************************************************************************/
HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This)
{
- FIXME(ole,"(%p),stub!\n",This);
+ TRACE(ole,"(%p)\n",This);
- SEGPTR_FREE(This);
+ /* free the table space memory */
+ HeapFree(GetProcessHeap(),0,This->bindCtxTable);
+
+ /* free the bindctx structure */
+ HeapFree(GetProcessHeap(),0,This);
return S_OK;
}
@@ -151,10 +205,40 @@
******************************************************************************/
HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
{
- ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,punk);
- return E_NOTIMPL;
+ ICOM_THIS(BindCtxImpl,iface);
+ DWORD lastIndex=This->bindCtxTableLastIndex;
+ BindCtxObject cell;
+
+ TRACE(ole,"(%p,%p)\n",This,punk);
+
+ if (punk==NULL)
+ return E_POINTER;
+
+ IUnknown_AddRef(punk);
+
+ /* put the object in the first free element in the table */
+ This->bindCtxTable[lastIndex].pObj = punk;
+ This->bindCtxTable[lastIndex].pkeyObj = NULL;
+ This->bindCtxTable[lastIndex].regType = 0;
+ cell=This->bindCtxTable[lastIndex];
+ lastIndex= ++This->bindCtxTableLastIndex;
+
+ if (lastIndex == This->bindCtxTableSize){ /* the table is full so it must be resized */
+
+ if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
+ FIXME(ole,"This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
+ return E_FAIL;
+}
+
+ This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
+
+ This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
+ This->bindCtxTableSize * sizeof(BindCtxObject));
+ if (!This->bindCtxTable)
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
}
/******************************************************************************
@@ -162,21 +246,45 @@
******************************************************************************/
HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
{
- ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,punk);
+ DWORD index,j;
- return E_NOTIMPL;
+ ICOM_THIS(BindCtxImpl,iface);
+
+ TRACE(ole,"(%p,%p)\n",This,punk);
+
+ /* check if the object was registred or not */
+ if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
+
+ return MK_E_NOTBOUND;
+
+ IUnknown_Release(This->bindCtxTable[index].pObj);
+
+ /* left-shift all elements in the rigth side of the curent revoked object */
+ for(j=index; j<This->bindCtxTableLastIndex-1; j++)
+ This->bindCtxTable[j]= This->bindCtxTable[j+1];
+
+ This->bindCtxTableLastIndex--;
+
+ return S_OK;
}
/******************************************************************************
- * BindCtx_ReleaseObjects
+ * BindCtx_ReleaseBoundObjects
******************************************************************************/
-HRESULT WINAPI BindCtxImpl_ReleaseObjects(IBindCtx* iface)
+HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface)
{
- ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p),stub!\n",This);
+ DWORD i;
- return E_NOTIMPL;
+ ICOM_THIS(BindCtxImpl,iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ for(i=0;i<This->bindCtxTableLastIndex;i++)
+ IUnknown_Release(This->bindCtxTable[i].pObj);
+
+ This->bindCtxTableLastIndex = 0;
+
+ return S_OK;
}
/******************************************************************************
@@ -185,9 +293,15 @@
HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts)
{
ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,pbindopts);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p)\n",This,pbindopts);
+
+ if (pbindopts==NULL)
+ return E_POINTER;
+
+ This->bindOption2=*pbindopts;
+
+ return S_OK;
}
/******************************************************************************
@@ -196,9 +310,15 @@
HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts)
{
ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,pbindopts);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p)\n",This,pbindopts);
+
+ if (pbindopts==NULL)
+ return E_POINTER;
+
+ *pbindopts=This->bindOption2;
+
+ return S_OK;
}
/******************************************************************************
@@ -206,10 +326,18 @@
******************************************************************************/
HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot)
{
- ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,pprot);
+ HRESULT res;
- return E_NOTIMPL;
+ ICOM_THIS(BindCtxImpl,iface);
+
+ TRACE(ole,"(%p,%p)\n",This,pprot);
+
+ if (pprot==NULL)
+ return E_POINTER;
+
+ res=GetRunningObjectTable(0,(LPVOID*)pprot);
+
+ return res;
}
/******************************************************************************
@@ -218,44 +346,152 @@
HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
{
ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p,%p),stub!\n",This,pszkey,punk);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p,%p)\n",This,pszkey,punk);
+
+ if (punk==NULL)
+ return E_INVALIDARG;
+
+ IUnknown_AddRef(punk);
+
+ This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
+ This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
+
+ if (pszkey==NULL)
+
+ This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=NULL;
+
+ else{
+
+ This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=
+ HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR)*(1+lstrlenW(pszkey))));
+
+ if (This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj==NULL)
+ return E_OUTOFMEMORY;
+ lstrcpyW(This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj,pszkey);
}
+ This->bindCtxTableLastIndex++;
+
+ if (This->bindCtxTableLastIndex == This->bindCtxTableSize){ /* table is full ! must be resized */
+
+ This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
+
+ if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
+ FIXME(ole,"This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
+ return E_FAIL;
+ }
+ This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
+ This->bindCtxTableSize * sizeof(BindCtxObject));
+ if (!This->bindCtxTable)
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
+}
/******************************************************************************
* BindCtx_GetObjectParam
******************************************************************************/
-HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
+HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk)
{
+ DWORD index;
ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p,%p),stub!\n",This,pszkey,punk);
- return E_NOTIMPL;
-}
+ TRACE(ole,"(%p,%p,%p)\n",This,pszkey,punk);
-/******************************************************************************
- * BindCtx_EnumObjectParam
- ******************************************************************************/
-HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** ppenum)
-{
- ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,ppenum);
+ if (punk==NULL)
+ return E_POINTER;
- return E_NOTIMPL;
+ *punk=0;
+
+ if (BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_FALSE)
+ return E_FAIL;
+
+ IUnknown_AddRef(This->bindCtxTable[index].pObj);
+
+ *punk = This->bindCtxTable[index].pObj;
+
+ return S_OK;
}
/******************************************************************************
* BindCtx_RevokeObjectParam
******************************************************************************/
-HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR pszkey)
+HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
{
- ICOM_THIS(BindCtxImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,pszkey);
+ DWORD index,j;
+ ICOM_THIS(BindCtxImpl,iface);
+
+ TRACE(ole,"(%p,%p)\n",This,ppenum);
+
+ if (BindCtxImpl_GetObjectIndex(This,NULL,ppenum,&index)==S_FALSE)
+ return E_FAIL;
+
+ /* release the object if it's found */
+ IUnknown_Release(This->bindCtxTable[index].pObj);
+
+ /* remove the object from the table with a left-shifting of all objects in the right side */
+ for(j=index; j<This->bindCtxTableLastIndex-1; j++)
+ This->bindCtxTable[j]= This->bindCtxTable[j+1];
+
+ This->bindCtxTableLastIndex--;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * BindCtx_EnumObjectParam
+ ******************************************************************************/
+HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
+{
+ FIXME(ole,"(%p,%p),stub!\n",iface,pszkey);
return E_NOTIMPL;
}
+/********************************************************************************
+ * GetObjectIndex (local function)
+ ********************************************************************************/
+HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
+ IUnknown* punk,
+ LPOLESTR pszkey,
+ DWORD *index)
+{
+
+ DWORD i;
+ BYTE found=0;
+
+ TRACE(ole,"(%p,%p,%p,%p)\n",This,punk,pszkey,index);
+
+ if (punk==NULL)
+ /* search object identified by a register key */
+ for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++){
+
+ if(This->bindCtxTable[i].regType==1){
+
+ if ( ( (This->bindCtxTable[i].pkeyObj==NULL) && (pszkey==NULL) ) ||
+ ( (This->bindCtxTable[i].pkeyObj!=NULL) &&
+ (pszkey!=NULL) &&
+ (lstrcmpW(This->bindCtxTable[i].pkeyObj,pszkey)==0)
+ )
+ )
+
+ found=1;
+ }
+ }
+ else
+ /* search object identified by a moniker*/
+ for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
+ if(This->bindCtxTable[i].pObj==punk)
+ found=1;
+
+ if (index != NULL)
+ *index=i-1;
+
+ if (found)
+ return S_OK;
+ else
+ return S_FALSE;
+}
/******************************************************************************
* CreateBindCtx16
@@ -263,31 +499,34 @@
HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC * ppbc)
{
FIXME(ole,"(%ld,%p),stub!\n",reserved,ppbc);
-
return E_NOTIMPL;
}
/******************************************************************************
- * CreateBindCtx32
+ * CreateBindCtx
******************************************************************************/
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
{
BindCtxImpl* newBindCtx = 0;
- HRESULT hr = S_OK;
+ HRESULT hr;
+ IID riid=IID_IBindCtx;
TRACE(ole,"(%ld,%p)\n",reserved,ppbc);
newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
if (newBindCtx == 0)
- return STG_E_INSUFFICIENTMEMORY;
+ return E_OUTOFMEMORY;
hr = BindCtxImpl_Construct(newBindCtx);
- if (FAILED(hr))
- return hr;
+ if (FAILED(hr)){
- hr = BindCtxImpl_QueryInterface((IBindCtx*)newBindCtx,&IID_IBindCtx,(void**)ppbc);
+ HeapFree(GetProcessHeap(),0,newBindCtx);
+ return hr;
+ }
+
+ hr = BindCtxImpl_QueryInterface((IBindCtx*)newBindCtx,&riid,(void**)ppbc);
return hr;
}
diff --git a/ole/compobj.c b/ole/compobj.c
index 30a0c47..cc7d50a 100644
--- a/ole/compobj.c
+++ b/ole/compobj.c
@@ -50,7 +50,7 @@
#include "wine/obj_clientserver.h"
#include "ifs.h"
-
+#include "compobj.h"
/****************************************************************************
* COM External Lock structures and methods declaration
*
@@ -270,6 +270,8 @@
*/
TRACE(ole, "() - Initializing the COM libraries\n");
+ RunningObjectTableImpl_Initialize();
+
hr = S_OK;
}
else
@@ -322,6 +324,7 @@
*/
TRACE(ole, "() - Releasing the COM libraries\n");
+ RunningObjectTableImpl_UnInitialize();
/*
* Release the references to the registered class objects.
*/
@@ -738,7 +741,7 @@
return E_FAIL;
}
- sprintf(idstr, "{%08lX-%04X-%04X-%02x%02X-",
+ sprintf(idstr, "{%08lX-%04X-%04X-%02X%02X-",
id->Data1, id->Data2, id->Data3,
id->Data4[0], id->Data4[1]);
s = &idstr[25];
@@ -894,6 +897,47 @@
return ret;
}
+/************************************************************************************************
+ * OleSaveToStream
+ *
+ * This function write a CLSID on stream
+ */
+HRESULT WINAPI WriteClassStm(IStream *pStm,REFCLSID rclsid)
+{
+ TRACE(ole,"(%p,%p)\n",pStm,rclsid);
+
+ if (rclsid==NULL)
+ return E_INVALIDARG;
+
+ return IStream_Write(pStm,rclsid,sizeof(CLSID),NULL);
+}
+
+/************************************************************************************************
+ * OleSaveToStream
+ *
+ * This function read a CLSID from a stream
+ */
+HRESULT WINAPI ReadClassStm(IStream *pStm,REFCLSID rclsid)
+{
+ ULONG nbByte;
+ HRESULT res;
+
+ TRACE(ole,"(%p,%p)\n",pStm,rclsid);
+
+ if (rclsid==NULL)
+ return E_INVALIDARG;
+
+ res = IStream_Read(pStm,(void*)rclsid,sizeof(CLSID),&nbByte);
+
+ if (FAILED(res))
+ return res;
+
+ if (nbByte != sizeof(CLSID))
+ return S_FALSE;
+ else
+ return S_OK;
+}
+
/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */
/***********************************************************************
* LookupETask (COMPOBJ.94)
@@ -1248,6 +1292,97 @@
return hres;
}
+/****************************************************************************************
+ * GetClassFile
+ *
+ * This function supplies the CLSID associated with the given filename.
+ */
+HRESULT WINAPI GetClassFile(LPOLESTR filePathName,CLSID *pclsid)
+{
+ IStorage *pstg=0;
+ HRESULT res;
+ int nbElm=0,length=0,i=0;
+ LONG sizeProgId=20;
+ LPOLESTR *pathDec=0,absFile=0,progId=0;
+ WCHAR extention[100]={0};
+
+ TRACE(ole,"()\n");
+
+ /* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method*/
+ if((StgIsStorageFile(filePathName))==S_OK){
+
+ res=StgOpenStorage(filePathName,NULL,STGM_READ | STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
+
+ if (SUCCEEDED(res))
+ res=ReadClassStg(pstg,pclsid);
+
+ IStorage_Release(pstg);
+
+ return res;
+ }
+ /* if the file is not a storage object then attemps to match various bits in the file against a
+ pattern in the registry. this case is not frequently used ! so I present only the psodocode for
+ this case
+
+ for(i=0;i<nFileTypes;i++)
+
+ for(i=0;j<nPatternsForType;j++){
+
+ PATTERN pat;
+ HANDLE hFile;
+
+ pat=ReadPatternFromRegistry(i,j);
+ hFile=CreateFileW(filePathName,,,,,,hFile);
+ SetFilePosition(hFile,pat.offset);
+ ReadFile(hFile,buf,pat.size,NULL,NULL);
+ if (memcmp(buf&pat.mask,pat.pattern.pat.size)==0){
+
+ *pclsid=ReadCLSIDFromRegistry(i);
+ return S_OK;
+ }
+ }
+ */
+
+ /* if the obove strategies fail then search for the extension key in the registry */
+
+ /* get the last element (absolute file) in the path name */
+ nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec);
+ absFile=pathDec[nbElm-1];
+
+ /* failed if the path represente a directory and not an absolute file name*/
+ if (lstrcmpW(absFile,(LPOLESTR)"\\"))
+ return MK_E_INVALIDEXTENSION;
+
+ /* get the extension of the file */
+ length=lstrlenW(absFile);
+ for(i=length-1; ( (i>=0) && (extention[i]=absFile[i]) );i--);
+
+ /* get the progId associated to the extension */
+ progId=CoTaskMemAlloc(sizeProgId);
+
+ res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId);
+
+ if (res==ERROR_MORE_DATA){
+
+ CoTaskMemRealloc(progId,sizeProgId);
+
+ res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId);
+ }
+ if (res==ERROR_SUCCESS)
+ /* return the clsid associated to the progId */
+ res= CLSIDFromProgID(progId,pclsid);
+
+ for(i=0; pathDec[i]!=NULL;i++)
+ CoTaskMemFree(pathDec[i]);
+ CoTaskMemFree(pathDec);
+
+ CoTaskMemFree(progId);
+
+ if (res==ERROR_SUCCESS)
+ return res;
+
+ return MK_E_INVALIDEXTENSION;
+}
/******************************************************************************
* CoRegisterMessageFilter16 [COMPOBJ.27]
*/
@@ -1413,7 +1548,6 @@
return IMalloc_Alloc(lpmalloc,size);
}
-
/***********************************************************************
* CoTaskMemFree (OLE32.44)
*/
diff --git a/ole/compositemoniker.c b/ole/compositemoniker.c
new file mode 100644
index 0000000..31c90fe
--- /dev/null
+++ b/ole/compositemoniker.c
@@ -0,0 +1,1695 @@
+/***************************************************************************************
+ * CompositeMonikers implementation
+ *
+ * Copyright 1999 Noomen Hamza
+ ***************************************************************************************/
+
+#include <assert.h>
+#include "winerror.h"
+#include "debug.h"
+#include "heap.h"
+#include "winuser.h"
+#include "file.h"
+#include "winreg.h"
+#include "objbase.h"
+#include "wine/obj_inplace.h"
+#include "ole2.h"
+
+#define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */
+
+/* CompositeMoniker data structure */
+typedef struct CompositeMonikerImpl{
+
+ ICOM_VTABLE(IMoniker)* 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.*/
+
+ ULONG ref; /* reference counter for this object */
+
+ IMoniker** tabMoniker; /* dynamaic table containing all components (monikers) of this composite moniker */
+
+ ULONG tabSize; /* size of tabMoniker */
+
+ ULONG tabLastIndex; /* first free index in tabMoniker */
+
+} CompositeMonikerImpl;
+
+
+/* EnumMoniker data structure */
+typedef struct EnumMonikerImpl{
+
+ ICOM_VTABLE(IEnumMoniker)* lpvtbl; /* VTable relative to the IEnumMoniker interface.*/
+
+ ULONG ref; /* reference counter for this object */
+
+ IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */
+
+ ULONG tabSize; /* size of tabMoniker */
+
+ ULONG currentPos; /* index pointer on the current moniker */
+
+} EnumMonikerImpl;
+
+
+/********************************************************************************/
+/* CompositeMoniker prototype functions : */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
+static ULONG WINAPI CompositeMonikerImpl_AddRef(IMoniker* iface);
+static ULONG WINAPI CompositeMonikerImpl_Release(IMoniker* iface);
+
+/* IPersist prototype functions */
+static HRESULT WINAPI CompositeMonikerImpl_GetClassID(const IMoniker* iface, CLSID *pClassID);
+
+/* IPersistStream prototype functions */
+static HRESULT WINAPI CompositeMonikerImpl_IsDirty(IMoniker* iface);
+static HRESULT WINAPI CompositeMonikerImpl_Load(IMoniker* iface, IStream* pStm);
+static HRESULT WINAPI CompositeMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
+static HRESULT WINAPI CompositeMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
+
+/* IMoniker prototype functions */
+static HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
+static HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
+static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
+static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
+static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
+static HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
+static HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
+static HRESULT WINAPI CompositeMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
+static HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pCompositeTime);
+static HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
+static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
+static HRESULT WINAPI CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
+static HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
+static HRESULT WINAPI CompositeMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
+static HRESULT WINAPI CompositeMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
+
+/********************************************************************************/
+/* IROTData prototype functions */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI CompositeMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
+static ULONG WINAPI CompositeMonikerROTDataImpl_AddRef(IROTData* iface);
+static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface);
+
+/* IROTData prototype function */
+static HRESULT WINAPI CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
+
+/* Local function used by CompositeMoniker implementation */
+HRESULT WINAPI CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,LPMONIKER pmkFirst, LPMONIKER pmkRest);
+HRESULT WINAPI CompositeMonikerImpl_Destroy(CompositeMonikerImpl* iface);
+
+/********************************************************************************/
+/* IEnumMoniker prototype functions */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject);
+static ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface);
+static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface);
+
+/* IEnumMonker prototype functions */
+static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt,IMoniker** rgelt,ULONG* pceltFetched);
+static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt);
+static HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface);
+static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum);
+
+HRESULT WINAPI EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRigth,IEnumMoniker ** ppmk);
+
+/********************************************************************************/
+/* Virtual function table for the CompositeMonikerImpl class witch include */
+/* Ipersist, IPersistStream and IMoniker functions. */
+
+static ICOM_VTABLE(IMoniker) VT_CompositeMonikerImpl =
+{
+ CompositeMonikerImpl_QueryInterface,
+ CompositeMonikerImpl_AddRef,
+ CompositeMonikerImpl_Release,
+ CompositeMonikerImpl_GetClassID,
+ CompositeMonikerImpl_IsDirty,
+ CompositeMonikerImpl_Load,
+ CompositeMonikerImpl_Save,
+ CompositeMonikerImpl_GetSizeMax,
+ CompositeMonikerImpl_BindToObject,
+ CompositeMonikerImpl_BindToStorage,
+ CompositeMonikerImpl_Reduce,
+ CompositeMonikerImpl_ComposeWith,
+ CompositeMonikerImpl_Enum,
+ CompositeMonikerImpl_IsEqual,
+ CompositeMonikerImpl_Hash,
+ CompositeMonikerImpl_IsRunning,
+ CompositeMonikerImpl_GetTimeOfLastChange,
+ CompositeMonikerImpl_Inverse,
+ CompositeMonikerImpl_CommonPrefixWith,
+ CompositeMonikerImpl_RelativePathTo,
+ CompositeMonikerImpl_GetDisplayName,
+ CompositeMonikerImpl_ParseDisplayName,
+ CompositeMonikerImpl_IsSystemMoniker
+};
+
+/********************************************************************************/
+/* Virtual function table for the IROTData class. */
+static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
+{
+ CompositeMonikerROTDataImpl_QueryInterface,
+ CompositeMonikerROTDataImpl_AddRef,
+ CompositeMonikerROTDataImpl_Release,
+ CompositeMonikerROTDataImpl_GetComparaisonData
+};
+
+/********************************************************************************/
+/* Virtual function table for the IROTData class */
+static ICOM_VTABLE(IEnumMoniker) VT_EnumMonikerImpl =
+{
+ EnumMonikerImpl_QueryInterface,
+ EnumMonikerImpl_AddRef,
+ EnumMonikerImpl_Release,
+ EnumMonikerImpl_Next,
+ EnumMonikerImpl_Skip,
+ EnumMonikerImpl_Reset,
+ EnumMonikerImpl_Clone
+};
+
+/*******************************************************************************
+ * CompositeMoniker_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
+{
+ ICOM_THIS(CompositeMonikerImpl,iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
+
+ /* Perform a sanity check on the parameters.*/
+ if ( (This==0) || (ppvObject==0) )
+ return E_INVALIDARG;
+
+ /* Initialize the return parameter */
+ *ppvObject = 0;
+
+ /* Compare the riid with the interface IDs implemented by this object.*/
+ if (IsEqualIID(&IID_IUnknown, riid) ||
+ IsEqualIID(&IID_IPersist, riid) ||
+ IsEqualIID(&IID_IPersistStream, riid) ||
+ IsEqualIID(&IID_IMoniker, riid)
+ )
+ *ppvObject = iface;
+ else if (IsEqualIID(&IID_IROTData, riid))
+ *ppvObject = (IROTData*)&(This->lpvtbl2);
+
+ /* Check that we obtained an interface.*/
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ /* Query Interface always increases the reference count by one when it is successful */
+ CompositeMonikerImpl_AddRef(iface);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * CompositeMoniker_AddRef
+ ******************************************************************************/
+ULONG WINAPI CompositeMonikerImpl_AddRef(IMoniker* iface)
+{
+ ICOM_THIS(CompositeMonikerImpl,iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ return ++(This->ref);
+}
+
+/******************************************************************************
+ * CompositeMoniker_Release
+ ******************************************************************************/
+ULONG WINAPI CompositeMonikerImpl_Release(IMoniker* iface)
+{
+ ICOM_THIS(CompositeMonikerImpl,iface);
+ ULONG i;
+
+ TRACE(ole,"(%p)\n",This);
+
+ This->ref--;
+
+ /* destroy the object if there's no more reference on it */
+ if (This->ref==0){
+
+ /* release all the components before destroying this object */
+ for (i=0;i<This->tabLastIndex;i++)
+ IMoniker_Release(This->tabMoniker[i]);
+
+ CompositeMonikerImpl_Destroy(This);
+
+ return 0;
+ }
+ return This->ref;;
+}
+
+/******************************************************************************
+ * CompositeMoniker_GetClassID
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_GetClassID(const IMoniker* iface,CLSID *pClassID)
+{
+ TRACE(ole,"(%p,%p),stub!\n",iface,pClassID);
+
+ if (pClassID==NULL)
+ return E_POINTER;
+
+ *pClassID = CLSID_CompositeMoniker;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * CompositeMoniker_IsDirty
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_IsDirty(IMoniker* iface)
+{
+ /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
+ method in the OLE-provided moniker interfaces always return S_FALSE because
+ their internal state never changes. */
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return S_FALSE;
+}
+
+/******************************************************************************
+ * CompositeMoniker_Load
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
+{
+ HRESULT res;
+ DWORD constant;
+ CLSID clsid;
+ WCHAR string[1]={0};
+
+ ICOM_THIS(CompositeMonikerImpl,iface);
+
+ TRACE(ole,"(%p,%p)\n",iface,pStm);
+
+ /* this function call OleLoadFromStream function for each moniker within this object */
+
+ /* read the a constant writen by CompositeMonikerImpl_Save (see CompositeMonikerImpl_Save for more details)*/
+ res=IStream_Read(pStm,&constant,sizeof(DWORD),NULL);
+
+ if (SUCCEEDED(res)&& constant!=3)
+ return E_FAIL;
+
+ while(1){
+
+ //res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]);
+ res=ReadClassStm(pStm,&clsid);
+ printf("res=%ld",res);
+ if (FAILED(res))
+ break;
+
+ if (IsEqualIID(&clsid,&CLSID_FileMoniker)){
+ res=CreateFileMoniker(string,&This->tabMoniker[This->tabLastIndex]);
+ if (FAILED(res))
+ break;
+ res=IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
+ if (FAILED(res))
+ break;
+ }
+ else if (IsEqualIID(&clsid,&CLSID_ItemMoniker)){
+ CreateItemMoniker(string,string,&This->tabMoniker[This->tabLastIndex]);
+ if (res!=S_OK)
+ break;
+ IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
+ if (FAILED(res))
+ break;
+ }
+ else if (IsEqualIID(&clsid,&CLSID_AntiMoniker)){
+ CreateAntiMoniker(&This->tabMoniker[This->tabLastIndex]);
+ if (FAILED(res))
+ break;
+ IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
+ if (FAILED(res))
+ break;
+ }
+ else if (IsEqualIID(&clsid,&CLSID_CompositeMoniker))
+ return E_FAIL;
+
+ else{
+ FIXME(ole,"()");
+ break;
+ return E_NOTIMPL;
+ }
+
+ /* resize the table if needed */
+ if (++This->tabLastIndex==This->tabSize){
+
+ This->tabSize+=BLOCK_TAB_SIZE;
+ This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,sizeof(IMoniker[This->tabSize]));
+
+ if (This->tabMoniker==NULL)
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ return res;
+}
+
+/******************************************************************************
+ * CompositeMoniker_Save
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
+{
+ HRESULT res;
+ IEnumMoniker *enumMk;
+ IMoniker *pmk;
+ DWORD constant=3;
+
+ TRACE(ole,"(%p,%p,%d)\n",iface,pStm,fClearDirty);
+
+ /* this function call OleSaveToStream function for each moniker within this object */
+
+ /* when I tested this function in windows system ! I usually found this constant in the begining of */
+ /* the stream I dont known why (there's no indication in specification) ! */
+ res=IStream_Write(pStm,&constant,sizeof(constant),NULL);
+
+ IMoniker_Enum(iface,TRUE,&enumMk);
+
+ while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
+
+ res=OleSaveToStream((IPersistStream*)pmk,pStm);
+
+ IMoniker_Release(pmk);
+
+ if (FAILED(res)){
+
+ IEnumMoniker_Release(pmk);
+ return res;
+ }
+ }
+
+ IEnumMoniker_Release(enumMk);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * CompositeMoniker_GetSizeMax
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize)
+{
+ IEnumMoniker *enumMk;
+ IMoniker *pmk;
+ ULARGE_INTEGER ptmpSize;
+
+ /* the sizeMax of this object is calculated by calling GetSizeMax on each moniker within this object then */
+ /* suming all returned sizemax */
+
+ TRACE(ole,"(%p,%p)\n",iface,pcbSize);
+
+ if (pcbSize!=NULL)
+ return E_POINTER;
+
+ pcbSize->LowPart =0;
+ pcbSize->HighPart=0;
+
+ IMoniker_Enum(iface,TRUE,&enumMk);
+
+ while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==TRUE){
+
+ IMoniker_GetSizeMax(pmk,&ptmpSize);
+
+ IMoniker_Release(pmk);
+
+ pcbSize->LowPart +=ptmpSize.LowPart;
+ pcbSize->HighPart+=ptmpSize.HighPart;
+ }
+
+ IEnumMoniker_Release(enumMk);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * Composite-Moniker_Construct (local function)
+ *******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,LPMONIKER pmkFirst, LPMONIKER pmkRest)
+{
+ DWORD mkSys;
+ IEnumMoniker *enumMoniker;
+ IMoniker *tempMk;
+ HRESULT res;
+
+ TRACE(ole,"(%p,%p,%p)\n",This,pmkFirst,pmkRest);
+
+ /* Initialize the virtual fgunction table. */
+ This->lpvtbl1 = &VT_CompositeMonikerImpl;
+ This->lpvtbl2 = &VT_ROTDataImpl;
+ This->ref = 0;
+
+ This->tabSize=BLOCK_TAB_SIZE;
+ This->tabLastIndex=0;
+
+ This->tabMoniker=HeapAlloc(GetProcessHeap(),0,sizeof(IMoniker[This->tabSize]));
+ if (This->tabMoniker==NULL)
+ return E_OUTOFMEMORY;
+
+ IMoniker_IsSystemMoniker(pmkFirst,&mkSys);
+
+ /* put the first moniker contents in the begining of the table */
+ if (mkSys!=MKSYS_GENERICCOMPOSITE){
+
+ This->tabMoniker[(This->tabLastIndex)++]=pmkFirst;
+ IMoniker_AddRef(pmkFirst);
+ }
+ else{
+
+ IMoniker_Enum(pmkFirst,TRUE,&enumMoniker);
+
+ while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
+
+
+ if (++This->tabLastIndex==This->tabSize){
+
+ This->tabSize+=BLOCK_TAB_SIZE;
+ This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,sizeof(IMoniker[This->tabSize]));
+
+ if (This->tabMoniker==NULL)
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ IEnumMoniker_Release(enumMoniker);
+ }
+
+ /* put the rest moniker contents after the first one and make simplification if needed */
+
+ IMoniker_IsSystemMoniker(pmkRest,&mkSys);
+
+ if (mkSys!=MKSYS_GENERICCOMPOSITE){
+
+ /* add a simple moniker to the moniker table */
+
+ res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],pmkRest,TRUE,&tempMk);
+
+ if (res==MK_E_NEEDGENERIC){
+
+ /* there's no simplification in this case */
+ This->tabMoniker[This->tabLastIndex]=pmkRest;
+
+ This->tabLastIndex++;
+
+ IMoniker_AddRef(pmkRest);
+ }
+ else if (tempMk==NULL){
+
+ /* we have an antimoniker after a simple moniker so we can make a simplification in this case */
+ IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
+
+ This->tabLastIndex--;
+ }
+ else if (SUCCEEDED(res)){
+
+ /* the non-generic composition was successful so we can make a simplification in this case */
+ IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
+
+ This->tabMoniker[This->tabLastIndex-1]=tempMk;
+ } else
+ return res;
+
+ /* resize tabMoniker if needed */
+ if (This->tabLastIndex==This->tabSize){
+
+ This->tabSize+=BLOCK_TAB_SIZE;
+
+ This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,sizeof(IMoniker[This->tabSize]));
+
+ if (This->tabMoniker==NULL)
+ return E_OUTOFMEMORY;
+ }
+ }
+ else{
+
+ /* add a composite moniker to the moniker table (do the same thing for each moniker within the */
+ /* composite moniker as a simple moniker (see above how to add a simple moniker case) ) */
+ IMoniker_Enum(pmkRest,TRUE,&enumMoniker);
+
+ while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
+
+ res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],This->tabMoniker[This->tabLastIndex],TRUE,&tempMk);
+
+ if (res==MK_E_NEEDGENERIC){
+
+ This->tabLastIndex++;
+ }
+ else if (tempMk==NULL){
+
+ IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
+ IMoniker_Release(This->tabMoniker[This->tabLastIndex]);
+ This->tabLastIndex--;
+ }
+ else{
+
+ IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
+
+ This->tabMoniker[This->tabLastIndex-1]=tempMk;
+ }
+
+ if (This->tabLastIndex==This->tabSize){
+
+ This->tabSize+=BLOCK_TAB_SIZE;
+
+ This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,sizeof(IMoniker[This->tabSize]));
+
+ if (This->tabMoniker==NULL)
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ IEnumMoniker_Release(enumMoniker);
+ }
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * CompositeMoniker_Destroy (local function)
+ *******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Destroy(CompositeMonikerImpl* This)
+{
+ TRACE(ole,"(%p)\n",This);
+
+ HeapFree(GetProcessHeap(),0,This->tabMoniker);
+
+ HeapFree(GetProcessHeap(),0,This);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * CompositeMoniker_BindToObject
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvResult)
+{
+ HRESULT res;
+ IRunningObjectTable *prot;
+ IMoniker *tempMk,*antiMk,*mostRigthMk;
+ IEnumMoniker *enumMoniker;
+
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+
+ if (ppvResult==NULL)
+ return E_POINTER;
+
+ *ppvResult=0;
+ /* If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved */
+ /* object for the requested interface pointer. */
+ if(pmkToLeft==NULL){
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&prot);
+
+ if (SUCCEEDED(res)){
+
+ /* if the requested class was loaded befor ! we dont need to reload it */
+ res = IRunningObjectTable_GetObject(prot,iface,(IUnknown**)ppvResult);
+
+ if (res==S_OK)
+ return res;
+ }
+ }
+ else{
+ /* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */
+ /* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */
+
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ res=CreateAntiMoniker(&antiMk);
+ res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ res=CompositeMonikerImpl_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult);
+
+ IMoniker_Release(tempMk);
+ IMoniker_Release(mostRigthMk);
+ }
+
+ return res;
+}
+
+/******************************************************************************
+ * CompositeMoniker_BindToStorage
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvResult)
+{
+ HRESULT res;
+ IMoniker *tempMk,*antiMk,*mostRigthMk;
+ IEnumMoniker *enumMoniker;
+
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+
+ *ppvResult=0;
+
+ /* This method recursively calls BindToStorage on the rightmost component of the composite, */
+ /* passing the rest of the composite as the pmkToLeft parameter for that call. */
+
+ if (pmkToLeft!=NULL){
+
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ res=CreateAntiMoniker(&antiMk);
+ res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ res=CompositeMonikerImpl_BindToStorage(mostRigthMk,pbc,tempMk,riid,ppvResult);
+
+ IMoniker_Release(tempMk);
+
+ IMoniker_Release(mostRigthMk);
+
+ return res;
+ }
+ else
+ return IMoniker_BindToStorage(iface,pbc,NULL,riid,ppvResult);
+}
+
+/******************************************************************************
+ * CompositeMoniker_Reduce
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface,
+ IBindCtx* pbc,
+ DWORD dwReduceHowFar,
+ IMoniker** ppmkToLeft,
+ IMoniker** ppmkReduced)
+{
+ HRESULT res;
+ IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk;
+ IEnumMoniker *enumMoniker;
+
+ TRACE(ole,"(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
+
+ if (ppmkReduced==NULL)
+ return E_POINTER;
+
+ /* This method recursively calls Reduce for each of its component monikers. */
+
+ if (ppmkToLeft==NULL){
+
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ res=CreateAntiMoniker(&antiMk);
+ res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ return CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
+ }
+ else if (*ppmkToLeft==NULL)
+
+ return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced);
+
+ else{
+
+ /* separate the copmosite moniker in to left and wrigth moniker */
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ res=CreateAntiMoniker(&antiMk);
+ res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ /* If any of the components reduces itself, the method returns S_OK and passes back a composite */
+ /* of the reduced components */
+ if (IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,NULL,&mostRigthReducedMk) &&
+ CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
+ )
+
+ return CreateGenericComposite(leftReducedComposedMk,mostRigthReducedMk,ppmkReduced);
+
+ else{
+ /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/
+
+ IMoniker_AddRef(iface);
+
+ *ppmkReduced=iface;
+
+ return MK_S_REDUCED_TO_SELF;
+ }
+ }
+}
+
+/******************************************************************************
+ * CompositeMoniker_ComposeWith
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker* iface,
+ IMoniker* pmkRight,
+ BOOL fOnlyIfNotGeneric,
+ IMoniker** ppmkComposite)
+{
+ TRACE(ole,"(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
+
+ if ((ppmkComposite==NULL)||(pmkRight==NULL))
+ return E_POINTER;
+
+ *ppmkComposite=0;
+
+ /* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */
+ /* otherwise, the method returns the result of combining the two monikers by calling the */
+ /* CreateGenericComposite function */
+
+ if (fOnlyIfNotGeneric)
+ return MK_E_NEEDGENERIC;
+
+ return CreateGenericComposite(iface,pmkRight,ppmkComposite);
+}
+
+/******************************************************************************
+ * CompositeMoniker_Enum
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
+{
+ ICOM_THIS(CompositeMonikerImpl,iface);
+
+ TRACE(ole,"(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
+
+ if (ppenumMoniker == NULL)
+ return E_POINTER;
+
+ return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabLastIndex,0,fForward,ppenumMoniker);
+}
+
+/******************************************************************************
+ * CompositeMoniker_IsEqual
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
+{
+ IEnumMoniker *enumMoniker1,*enumMoniker2;
+ IMoniker *tempMk1,*tempMk2;
+ HRESULT res1,res2,res;
+
+ TRACE(ole,"(%p,%p)\n",iface,pmkOtherMoniker);
+
+ if (pmkOtherMoniker==NULL)
+ return S_FALSE;
+
+ /* This method returns S_OK if the components of both monikers are equal when compared in the */
+ /* left-to-right order.*/
+ IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1);
+
+ if (enumMoniker1==NULL)
+ return S_FALSE;
+
+ IMoniker_Enum(iface,TRUE,&enumMoniker2);
+
+ while(1){
+
+ res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
+ res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
+
+ if((res1==S_OK)&&(res2==S_OK)){
+
+ if(IMoniker_IsEqual(tempMk1,tempMk2)==S_FALSE){
+ res= S_FALSE;
+ break;
+ }
+ else
+ continue;
+ }
+ else if ( (res1==S_FALSE) && (res2==S_FALSE) ){
+ res = S_OK;
+ break;
+ }
+ else{
+ res = S_FALSE;
+ break;
+ }
+
+ if (res1==S_OK)
+ IMoniker_Release(tempMk1);
+
+ if (res2==S_OK)
+ IMoniker_Release(tempMk2);
+ }
+
+ IEnumMoniker_Release(enumMoniker1);
+ IEnumMoniker_Release(enumMoniker2);
+
+ return res;
+}
+/******************************************************************************
+ * CompositeMoniker_Hash
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
+{
+ FIXME(ole,"(),stub!\n");
+
+ return E_NOTIMPL;
+}
+
+/******************************************************************************
+ * CompositeMoniker_IsRunning
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_IsRunning(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ IMoniker* pmkNewlyRunning)
+{
+ IRunningObjectTable* rot;
+ HRESULT res;
+ IMoniker *tempMk,*antiMk,*mostRigthMk;
+ IEnumMoniker *enumMoniker;
+
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
+
+ /* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/
+ if (pmkToLeft!=NULL){
+
+ CreateGenericComposite(pmkToLeft,iface,&tempMk);
+
+ res = IMoniker_IsRunning(tempMk,pbc,NULL,pmkNewlyRunning);
+
+ IMoniker_Release(tempMk);
+
+ return res;
+ }
+ else
+ /* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */
+ /* to this moniker */
+
+ if (pmkNewlyRunning!=NULL)
+
+ if (IMoniker_IsEqual(iface,pmkNewlyRunning)==S_OK)
+ return S_OK;
+
+ else
+ return S_FALSE;
+
+ else{
+
+ if (pbc==NULL)
+ return E_POINTER;
+
+ /* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
+ /* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */
+ /* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */
+ /* the composite as the pmkToLeft parameter for that call. */
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+ if (FAILED(res))
+ return res;
+
+ res = IRunningObjectTable_IsRunning(rot,iface);
+ IRunningObjectTable_Release(rot);
+
+ if(res==S_OK)
+ return S_OK;
+
+ else{
+
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ res=CreateAntiMoniker(&antiMk);
+ res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ res=IMoniker_IsRunning(mostRigthMk,pbc,tempMk,pmkNewlyRunning);
+
+ IMoniker_Release(tempMk);
+ IMoniker_Release(mostRigthMk);
+
+ return res;
+ }
+ }
+}
+
+/******************************************************************************
+ * CompositeMoniker_GetTimeOfLastChange
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ FILETIME* pCompositeTime)
+{
+ IRunningObjectTable* rot;
+ HRESULT res;
+ IMoniker *tempMk,*antiMk,*mostRigthMk;
+ IEnumMoniker *enumMoniker;
+
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);
+
+ if (pCompositeTime==NULL)
+ return E_INVALIDARG;
+
+ /* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to */
+ /* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
+ /* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
+ /* of the composite as the pmkToLeft parameter for that call. */
+ if (pmkToLeft!=NULL){
+
+ res=CreateGenericComposite(pmkToLeft,iface,&tempMk);
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+ if (FAILED(res))
+ return res;
+
+ if (IRunningObjectTable_GetTimeOfLastChange(rot,tempMk,pCompositeTime)==S_OK)
+ return res;
+ else
+
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ res=CreateAntiMoniker(&antiMk);
+ res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ res=CompositeMonikerImpl_GetTimeOfLastChange(mostRigthMk,pbc,tempMk,pCompositeTime);
+
+ IMoniker_Release(tempMk);
+ IMoniker_Release(mostRigthMk);
+
+ return res;
+ }
+ else
+ return IMoniker_GetTimeOfLastChange(iface,pbc,NULL,pCompositeTime);
+}
+
+/******************************************************************************
+ * CompositeMoniker_Inverse
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
+{
+ HRESULT res;
+ IMoniker *tempMk,*antiMk,*mostRigthMk,*tempInvMk,*mostRigthInvMk;
+ IEnumMoniker *enumMoniker;
+
+ TRACE(ole,"(%p,%p)\n",iface,ppmk);
+
+ if (ppmk==NULL)
+ return E_POINTER;
+
+ /* This method returns a composite moniker that consists of the inverses of each of the components */
+ /* of the original composite, stored in reverse order */
+
+ res=CreateAntiMoniker(&antiMk);
+ res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ if (tempMk==NULL)
+
+ return IMoniker_Inverse(iface,ppmk);
+
+ else{
+
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ IMoniker_Inverse(mostRigthMk,&mostRigthInvMk);
+ CompositeMonikerImpl_Inverse(tempMk,&tempInvMk);
+
+ res=CreateGenericComposite(mostRigthInvMk,tempInvMk,ppmk);
+
+ IMoniker_Release(tempMk);
+ IMoniker_Release(mostRigthMk);
+ IMoniker_Release(tempInvMk);
+ IMoniker_Release(mostRigthInvMk);
+
+ return res;
+ }
+}
+
+/******************************************************************************
+ * CompositeMoniker_CommonPrefixWith
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
+{
+ DWORD mkSys;
+ HRESULT res1,res2;
+ IMoniker *tempMk1,*tempMk2,*mostLeftMk1,*mostLeftMk2;
+ IEnumMoniker *enumMoniker1,*enumMoniker2;
+ ULONG i,nbCommonMk=0;
+
+ /* If the other moniker is a composite, this method compares the components of each composite from left */
+ /* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */
+ /* of the leftmost components were common to both monikers. */
+
+ if (ppmkPrefix==NULL)
+ return E_POINTER;
+
+ *ppmkPrefix=0;
+
+ if (pmkOther==NULL)
+ return MK_E_NOPREFIX;
+
+ IMoniker_IsSystemMoniker(pmkOther,&mkSys);
+
+ if((mkSys==MKSYS_GENERICCOMPOSITE)){
+
+ IMoniker_Enum(iface,TRUE,&enumMoniker1);
+ IMoniker_Enum(pmkOther,TRUE,&enumMoniker2);
+
+ while(1){
+
+ res1=IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
+ res2=IEnumMoniker_Next(enumMoniker2,1,&mostLeftMk2,NULL);
+
+ if ((res1==S_FALSE) && (res2==S_FALSE)){
+
+ /* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/
+ *ppmkPrefix=iface;
+ IMoniker_AddRef(iface);
+ return MK_S_US;
+ }
+ else if ((res1==S_OK) && (res2==S_OK)){
+
+ if (IMoniker_IsEqual(mostLeftMk1,mostLeftMk2)==S_OK)
+
+ nbCommonMk++;
+
+ else
+ break;
+
+ }
+ else if (res1==S_OK){
+
+ /* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */
+ /* ppmkPrefix to the other moniker. */
+ *ppmkPrefix=pmkOther;
+ return MK_S_HIM;
+ }
+ else{
+ /* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */
+ /* to this moniker. */
+ *ppmkPrefix=iface;
+ return MK_S_ME;
+ }
+ }
+
+ IEnumMoniker_Release(enumMoniker1);
+ IEnumMoniker_Release(enumMoniker2);
+
+ /* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */
+ if (nbCommonMk==0)
+ return MK_E_NOPREFIX;
+
+ IEnumMoniker_Reset(enumMoniker1);
+
+ IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
+
+ /* if we have more than one commun moniker the result will be a composite moniker */
+ if (nbCommonMk>1){
+
+ /* initialize the common prefix moniker with the composite of two first moniker (from the left)*/
+ IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
+ CreateGenericComposite(tempMk1,tempMk2,ppmkPrefix);
+ IMoniker_Release(tempMk1);
+ IMoniker_Release(tempMk2);
+
+ /* compose all common monikers in a composite moniker */
+ for(i=0;i<nbCommonMk;i++){
+
+ IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
+
+ CreateGenericComposite(*ppmkPrefix,tempMk1,&tempMk2);
+
+ IMoniker_Release(*ppmkPrefix);
+
+ IMoniker_Release(tempMk1);
+
+ *ppmkPrefix=tempMk2;
+ }
+ return S_OK;
+ }
+ else{
+ /* if we have only one commun moniker the result will be a simple moniker which is the most-left one*/
+ *ppmkPrefix=tempMk1;
+
+ return S_OK;
+ }
+ }
+ else{
+ /* If the other moniker is not a composite, the method simply compares it to the leftmost component
+ of this moniker.*/
+
+ IMoniker_Enum(iface,TRUE,&enumMoniker1);
+
+ IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
+
+ if (IMoniker_IsEqual(pmkOther,mostLeftMk1)==S_OK){
+
+ *ppmkPrefix=pmkOther;
+
+ return MK_S_HIM;
+ }
+ else
+ return MK_E_NOPREFIX;
+ }
+}
+/***************************************************************************************************
+ * GetAfterCommonPrefix (local function)
+ * This function returns a moniker that consist of the remainder when the common prefix is removed
+ ***************************************************************************************************/
+VOID WINAPI GetAfterCommonPrefix(IMoniker* pGenMk,IMoniker* commonMk,IMoniker** restMk)
+{
+ IMoniker *tempMk,*tempMk1,*tempMk2;
+ IEnumMoniker *enumMoniker1,*enumMoniker2,*enumMoniker3;
+ ULONG nbRestMk=0;
+ DWORD mkSys;
+ HRESULT res1,res2;
+
+ *restMk=0;
+
+ /* to create an enumerator for pGenMk with current position pointed on the first element after common */
+ /* prefix: enum the two monikers (left-wrigth) then compare these enumerations (left-wrigth) and stop */
+ /* on the first difference. */
+ IMoniker_Enum(pGenMk,TRUE,&enumMoniker1);
+
+ IMoniker_IsSystemMoniker(commonMk,&mkSys);
+
+ if (mkSys==MKSYS_GENERICCOMPOSITE){
+
+ IMoniker_Enum(commonMk,TRUE,&enumMoniker2);
+ while(1){
+
+ res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
+ res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
+
+ if ((res1==S_FALSE)||(res2==S_FALSE)){
+
+ if (res1==S_OK)
+
+ nbRestMk++;
+
+ IMoniker_Release(tempMk1);
+ IMoniker_Release(tempMk1);
+
+ break;
+ }
+ IMoniker_Release(tempMk1);
+ IMoniker_Release(tempMk1);
+ }
+ }
+ else{
+ IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
+ IMoniker_Release(tempMk1);
+ }
+
+ /* count the number of elements in the enumerator after the common prefix */
+ IEnumMoniker_Clone(enumMoniker1,&enumMoniker3);
+
+ for(;IEnumMoniker_Next(enumMoniker3,1,&tempMk,NULL)==S_OK;nbRestMk++)
+
+ IMoniker_Release(tempMk);;
+
+ if (nbRestMk==0)
+ return;
+
+ /* create a generic composite moniker with monikers located after the common prefix */
+ IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
+
+ if (nbRestMk==1){
+
+ *restMk= tempMk1;
+ return;
+ }
+ else {
+
+ IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
+
+ CreateGenericComposite(tempMk1,tempMk2,restMk);
+
+ IMoniker_Release(tempMk1);
+
+ IMoniker_Release(tempMk2);
+
+ while(IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL)==S_OK){
+
+ CreateGenericComposite(*restMk,tempMk1,&tempMk2);
+
+ IMoniker_Release(tempMk1);
+
+ IMoniker_Release(*restMk);
+
+ *restMk=tempMk2;
+ }
+ }
+}
+/******************************************************************************
+ * CompositeMoniker_RelativePathTo
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkRelPath)
+{
+ HRESULT res;
+ IMoniker *restOtherMk=0,*restThisMk=0,*invRestThisMk=0,*commonMk=0;
+
+ TRACE(ole,"(%p,%p,%p)\n",iface,pmkOther,ppmkRelPath);
+
+ if (ppmkRelPath==NULL)
+ return E_POINTER;
+
+ *ppmkRelPath=0;
+
+ /* This method finds the common prefix of the two monikers and creates two monikers that consist */
+ /* of the remainder when the common prefix is removed. Then it creates the inverse for the remainder */
+ /* of this moniker and composes the remainder of the other moniker on the right of it. */
+
+ /* finds the common prefix of the two monikers */
+ res=IMoniker_CommonPrefixWith(iface,pmkOther,&commonMk);
+
+ /* if there's no common prefix or the two moniker are equal the relative is the other moniker */
+ if ((res== MK_E_NOPREFIX)||(res==MK_S_US)){
+
+ *ppmkRelPath=pmkOther;
+ IMoniker_AddRef(pmkOther);
+ return MK_S_HIM;
+ }
+
+ GetAfterCommonPrefix(iface,commonMk,&restThisMk);
+ GetAfterCommonPrefix(pmkOther,commonMk,&restOtherMk);
+
+ /* if other is a prefix of this moniker the relative path is the inverse of the remainder path of this */
+ /* moniker when the common prefix is removed */
+ if (res==MK_S_HIM){
+
+ IMoniker_Inverse(restThisMk,ppmkRelPath);
+ IMoniker_Release(restThisMk);
+ }
+ /* if this moniker is a prefix of other moniker the relative path is the remainder path of other moniker */
+ /* when the common prefix is removed */
+ else if (res==MK_S_ME){
+
+ *ppmkRelPath=restOtherMk;
+ IMoniker_AddRef(restOtherMk);
+ }
+ /* the relative path is the inverse for the remainder of this moniker and the remainder of the other */
+ /* moniker on the right of it. */
+ else if (res==S_OK){
+
+ IMoniker_Inverse(restThisMk,&invRestThisMk);
+ IMoniker_Release(restThisMk);
+ CreateGenericComposite(invRestThisMk,restOtherMk,ppmkRelPath);
+ IMoniker_Release(invRestThisMk);
+ IMoniker_Release(restOtherMk);
+ }
+ return S_OK;
+}
+
+/******************************************************************************
+ * CompositeMoniker_GetDisplayName
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ LPOLESTR *ppszDisplayName)
+{
+ ULONG lengthStr=1;
+ IEnumMoniker *enumMoniker;
+ IMoniker* tempMk;
+ LPOLESTR tempStr;
+
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
+
+ if (ppszDisplayName==NULL)
+ return E_POINTER;
+
+ *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR));
+
+ if (*ppszDisplayName==NULL)
+ return E_OUTOFMEMORY;
+
+ /* This method returns the concatenation of the display names returned by each component moniker of */
+ /* the composite */
+
+ **ppszDisplayName=0;
+
+ IMoniker_Enum(iface,TRUE,&enumMoniker);
+
+ while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
+
+ IMoniker_GetDisplayName(tempMk,pbc,NULL,&tempStr);
+
+ lengthStr+=lstrlenW(tempStr);
+
+ *ppszDisplayName=CoTaskMemRealloc(*ppszDisplayName,lengthStr * sizeof(WCHAR));
+
+ if (*ppszDisplayName==NULL)
+ return E_OUTOFMEMORY;
+
+ lstrcatW(*ppszDisplayName,tempStr);
+
+ CoTaskMemFree(tempStr);
+ IMoniker_Release(tempMk);
+ }
+
+ IEnumMoniker_Release(enumMoniker);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * CompositeMoniker_ParseDisplayName
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_ParseDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ LPOLESTR pszDisplayName,
+ ULONG* pchEaten,
+ IMoniker** ppmkOut)
+{
+ IEnumMoniker *enumMoniker;
+ IMoniker *tempMk,*mostRigthMk,*antiMk;
+ /* This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite,*/
+ /* passing everything else as the pmkToLeft parameter for that call. */
+
+ /* get the most rigth moniker */
+ IMoniker_Enum(iface,FALSE,&enumMoniker);
+ IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
+ IEnumMoniker_Release(enumMoniker);
+
+ /* get the left moniker */
+ CreateAntiMoniker(&antiMk);
+ IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
+ IMoniker_Release(antiMk);
+
+ return IMoniker_ParseDisplayName(mostRigthMk,pbc,tempMk,pszDisplayName,pchEaten,ppmkOut);
+}
+
+/******************************************************************************
+ * CompositeMoniker_IsSystemMonker
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
+{
+ TRACE(ole,"(%p,%p)\n",iface,pwdMksys);
+
+ if (!pwdMksys)
+ return E_POINTER;
+
+ (*pwdMksys)=MKSYS_GENERICCOMPOSITE;
+
+ return S_OK;
+}
+
+/*******************************************************************************
+ * CompositeMonikerIROTData_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI CompositeMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
+{
+
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",iface,riid,ppvObject);
+
+ return CompositeMonikerImpl_QueryInterface(This, riid, ppvObject);
+}
+
+/***********************************************************************
+ * CompositeMonikerIROTData_AddRef
+ */
+ULONG WINAPI CompositeMonikerROTDataImpl_AddRef(IROTData *iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return CompositeMonikerImpl_AddRef(This);
+}
+
+/***********************************************************************
+ * CompositeMonikerIROTData_Release
+ */
+ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return CompositeMonikerImpl_Release(This);
+}
+
+/******************************************************************************
+ * CompositeMonikerIROTData_GetComparaisonData
+ ******************************************************************************/
+HRESULT WINAPI CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
+ BYTE* pbData,
+ ULONG cbMax,
+ ULONG* pcbData)
+{
+ FIXME(ole,"(),stub!\n");
+ return E_NOTIMPL;
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_QueryInterface
+ ******************************************************************************/
+HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
+{
+ ICOM_THIS(EnumMonikerImpl,iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
+
+ /* Perform a sanity check on the parameters.*/
+ if ( (This==0) || (ppvObject==0) )
+ return E_INVALIDARG;
+
+ /* Initialize the return parameter */
+ *ppvObject = 0;
+
+ /* Compare the riid with the interface IDs implemented by this object.*/
+ if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IEnumMoniker, riid))
+ *ppvObject = iface;
+
+ /* Check that we obtained an interface.*/
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ /* Query Interface always increases the reference count by one when it is successful */
+ EnumMonikerImpl_AddRef(iface);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_AddRef
+ ******************************************************************************/
+ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface)
+{
+ ICOM_THIS(EnumMonikerImpl,iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ return ++(This->ref);
+
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_Release
+ ******************************************************************************/
+ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface)
+{
+ ICOM_THIS(EnumMonikerImpl,iface);
+ ULONG i
+ ;
+ TRACE(ole,"(%p)\n",This);
+
+ This->ref--;
+
+ /* destroy the object if there's no more reference on it */
+ if (This->ref==0){
+
+ for(i=0;i<This->tabSize;i++)
+ IMoniker_Release(This->tabMoniker[i]);
+
+ HeapFree(GetProcessHeap(),0,This->tabMoniker);
+ HeapFree(GetProcessHeap(),0,This);
+
+ return 0;
+ }
+ return This->ref;;
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_Next
+ ******************************************************************************/
+HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt, ULONG* pceltFethed){
+
+ ICOM_THIS(EnumMonikerImpl,iface);
+ ULONG i;
+
+ /* retrieve the requested number of moniker from the current position */
+ for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
+
+ rgelt[i]=This->tabMoniker[This->currentPos++];
+
+ if (pceltFethed!=NULL)
+ *pceltFethed= i;
+
+ if (i==celt)
+ return S_OK;
+ else
+ return S_FALSE;
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_Skip
+ ******************************************************************************/
+HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt){
+
+ ICOM_THIS(EnumMonikerImpl,iface);
+
+ if ((This->currentPos+celt) >= This->tabSize)
+ return S_FALSE;
+
+ This->currentPos+=celt;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_Reset
+ ******************************************************************************/
+HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface){
+
+ ICOM_THIS(EnumMonikerImpl,iface);
+
+ This->currentPos=0;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_Clone
+ ******************************************************************************/
+HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum){
+
+ ICOM_THIS(EnumMonikerImpl,iface);
+
+ return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum);
+}
+
+/******************************************************************************
+ * EnumMonikerImpl_CreateEnumMoniker
+ ******************************************************************************/
+HRESULT WINAPI EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,
+ ULONG tabSize,
+ ULONG currentPos,
+ BOOL leftToRigth,
+ IEnumMoniker ** ppmk)
+{
+ EnumMonikerImpl* newEnumMoniker;
+ int i;
+
+
+ newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
+
+ if (newEnumMoniker == 0)
+ return STG_E_INSUFFICIENTMEMORY;
+
+ if (currentPos > tabSize)
+ return E_INVALIDARG;
+
+ /* Initialize the virtual function table. */
+ newEnumMoniker->lpvtbl = &VT_EnumMonikerImpl;
+ newEnumMoniker->ref = 0;
+
+ newEnumMoniker->tabSize=tabSize;
+ newEnumMoniker->currentPos=currentPos;
+
+ newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,sizeof(IMoniker[tabSize]));
+
+ if (newEnumMoniker->tabMoniker==NULL)
+ return E_OUTOFMEMORY;
+
+ if (leftToRigth)
+ for (i=0;i<tabSize;i++){
+
+ newEnumMoniker->tabMoniker[i]=tabMoniker[i];
+ IMoniker_AddRef(tabMoniker[i]);
+ }
+ else
+ for (i=tabSize-1;i>=0;i--){
+
+ newEnumMoniker->tabMoniker[tabSize-i-1]=tabMoniker[i];
+ IMoniker_AddRef(tabMoniker[i]);
+ }
+
+ *ppmk=(IEnumMoniker*)newEnumMoniker;
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * CreateCompositeMoniker [OLE.55]
+ ******************************************************************************/
+HRESULT WINAPI CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest, LPMONIKER* ppmkComposite)
+{
+ CompositeMonikerImpl* newCompositeMoniker = 0;
+ HRESULT hr = S_OK;
+
+ TRACE(ole,"(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);
+
+ if (ppmkComposite==NULL)
+ return E_POINTER;
+
+ *ppmkComposite=0;
+
+ if (pmkFirst==NULL && pmkRest!=NULL){
+
+ *ppmkComposite=pmkRest;
+ return S_OK;
+ }
+ else if (pmkFirst!=NULL && pmkRest==NULL){
+ *ppmkComposite=pmkFirst;
+ return S_OK;
+ }
+ else if (pmkFirst==NULL && pmkRest==NULL)
+ return S_OK;
+
+ newCompositeMoniker = HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl));
+
+ if (newCompositeMoniker == 0)
+ return STG_E_INSUFFICIENTMEMORY;
+
+ hr = CompositeMonikerImpl_Construct(newCompositeMoniker,pmkFirst,pmkRest);
+
+ if (FAILED(hr)){
+
+ HeapFree(GetProcessHeap(),0,newCompositeMoniker);
+ return hr;
+ }
+ if (newCompositeMoniker->tabLastIndex==1)
+
+ hr = IMoniker_QueryInterface(newCompositeMoniker->tabMoniker[0],&IID_IMoniker,(void**)ppmkComposite);
+ else
+
+ hr = CompositeMonikerImpl_QueryInterface((IMoniker*)newCompositeMoniker,&IID_IMoniker,(void**)ppmkComposite);
+
+ return hr;
+}
+
+/******************************************************************************
+ * MonikerCommonPrefixWith [OLE.55]
+ ******************************************************************************/
+HRESULT WINAPI MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon)
+{
+ FIXME(ole,"(),stub!\n");
+ return E_NOTIMPL;
+}
+
+
diff --git a/ole/filemoniker.c b/ole/filemoniker.c
index 8d77def..a8eb1b7 100644
--- a/ole/filemoniker.c
+++ b/ole/filemoniker.c
@@ -4,31 +4,51 @@
* Copyright 1999 Noomen Hamza
***************************************************************************************/
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
#include <assert.h>
-#include "wine/obj_moniker.h"
#include "winerror.h"
#include "debug.h"
#include "heap.h"
+#include "winuser.h"
+#include "file.h"
+#include "winreg.h"
+#include "objbase.h"
+#include "wine/obj_storage.h"
+#include "wine/obj_base.h"
+/* filemoniker data structure */
typedef struct FileMonikerImpl{
- ICOM_VTABLE(IMoniker)* lpvtbl;
+ ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
- ULONG ref;
+ /* 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.*/
+
+ ULONG ref; /* reference counter for this object */
+
+ LPOLESTR filePathName; /* path string identified by this filemoniker */
} FileMonikerImpl;
+/********************************************************************************/
+/* FileMoniker prototype functions : */
+
+/* IUnknown prototype functions */
static HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
static ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface);
static ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface);
+
+/* IPersist prototype functions */
static HRESULT WINAPI FileMonikerImpl_GetClassID(const IMoniker* iface, CLSID *pClassID);
+
+/* IPersistStream prototype functions */
static HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface);
static HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface, IStream* pStm);
static HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
static HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
+
+/* IMoniker prototype functions */
static HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
@@ -45,10 +65,26 @@
static HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
static HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
-static HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
-static HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
+/********************************************************************************/
+/* IROTData prototype functions */
-// Virtual function table for the FileMonikerImpl class.
+/* IUnknown prototype functions */
+static HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
+static ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData* iface);
+static ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface);
+
+/* IROTData prototype function */
+static HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
+
+/* Local function used by filemoniker implementation */
+HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
+HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
+int WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** tabStr);
+
+
+/********************************************************************************/
+/* Virtual function table for the FileMonikerImpl class witch include Ipersist,*/
+/* IPersistStream and IMoniker functions. */
static ICOM_VTABLE(IMoniker) VT_FileMonikerImpl =
{
FileMonikerImpl_QueryInterface,
@@ -76,40 +112,51 @@
FileMonikerImpl_IsSystemMoniker
};
+/********************************************************************************/
+/* Virtual function table for the IROTData class. */
+static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
+{
+ FileMonikerROTDataImpl_QueryInterface,
+ FileMonikerROTDataImpl_AddRef,
+ FileMonikerROTDataImpl_Release,
+ FileMonikerROTDataImpl_GetComparaisonData
+};
+
/*******************************************************************************
* FileMoniker_QueryInterface
*******************************************************************************/
HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
+
TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
- // Perform a sanity check on the parameters.
- if ( (This==0) || (ppvObject==0) ) return E_INVALIDARG;
+ /* Perform a sanity check on the parameters.*/
+ if ( (This==0) || (ppvObject==0) )
+ return E_INVALIDARG;
- // Initialize the return parameter.
+ /* Initialize the return parameter */
*ppvObject = 0;
- // Compare the riid with the interface IDs implemented by this object.
- if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
- *ppvObject = (IMoniker*)This;
- else
- if (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0)
- *ppvObject = (IMoniker*)This;
- else
- if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
- *ppvObject = (IMoniker*)This;
- else
- if (memcmp(&IID_IMoniker, riid, sizeof(IID_IMoniker)) == 0)
- *ppvObject = (IMoniker*)This;
+ /* Compare the riid with the interface IDs implemented by this object.*/
+ if (IsEqualIID(&IID_IUnknown, riid) ||
+ IsEqualIID(&IID_IPersist, riid) ||
+ IsEqualIID(&IID_IPersistStream,riid) ||
+ IsEqualIID(&IID_IMoniker, riid)
+ )
+ *ppvObject = iface;
+
+ else if (IsEqualIID(&IID_IROTData, riid))
+ *ppvObject = (IROTData*)&(This->lpvtbl2);
- // Check that we obtained an interface.
- if ((*ppvObject)==0) return E_NOINTERFACE;
+ /* Check that we obtained an interface.*/
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
- // Query Interface always increases the reference count by one when it is successful
+ /* Query Interface always increases the reference count by one when it is successful */
FileMonikerImpl_AddRef(iface);
- return S_OK;;
+ return S_OK;
}
/******************************************************************************
@@ -117,9 +164,9 @@
******************************************************************************/
ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
- TRACE(ole,"(%p)\n",This);
+ TRACE(ole,"(%p)\n",iface);
return ++(This->ref);
}
@@ -129,14 +176,17 @@
******************************************************************************/
ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
- TRACE(ole,"(%p)\n",This);
+ TRACE(ole,"(%p)\n",iface);
This->ref--;
+ /* destroy the object if there's no more reference on it */
if (This->ref==0){
+
FileMonikerImpl_Destroy(This);
+
return 0;
}
return This->ref;;
@@ -145,13 +195,17 @@
/******************************************************************************
* FileMoniker_GetClassID
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_GetClassID(const IMoniker* iface, CLSID *pClassID)//Pointer to CLSID of object
+HRESULT WINAPI FileMonikerImpl_GetClassID(const IMoniker* iface,
+ CLSID *pClassID)/* Pointer to CLSID of object */
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ TRACE(ole,"(%p,%p),stub!\n",iface,pClassID);
- FIXME(ole,"(%p,%p),stub!\n",This,pClassID);
+ if (pClassID==NULL)
+ return E_POINTER;
- return E_NOTIMPL;
+ *pClassID = CLSID_FileMoniker;
+
+ return S_OK;
}
/******************************************************************************
@@ -159,131 +213,597 @@
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
+ method in the OLE-provided moniker interfaces always return S_FALSE because
+ their internal state never changes. */
- FIXME(ole,"(%p),stub!\n",This);
+ TRACE(ole,"(%p)\n",iface);
- return E_NOTIMPL;
+ return S_FALSE;
}
/******************************************************************************
* FileMoniker_Load
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_Load(
- IMoniker* iface,
- IStream* pStm)
+HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ HRESULT res;
+ CHAR* filePathA;
+ WCHAR* filePathW;
+ ULONG bread;
+ WORD wbuffer;
+ DWORD dwbuffer,length,i,doubleLenHex,doubleLenDec;
- FIXME(ole,"(%p,%p),stub!\n",This,pStm);
+ ICOM_THIS(FileMonikerImpl,iface);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p)\n",iface,pStm);
+
+ /* this function locate and read from the stream the filePath string writen by FileMonikerImpl_Save */
+
+ /* first WORD is non significative */
+ res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
+ if (bread!=sizeof(WORD) || wbuffer!=0)
+ return E_FAIL;
+
+ /* read filePath string length (plus one) */
+ res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
+ if (bread != sizeof(DWORD))
+ return E_FAIL;
+
+ /* read filePath string */
+ filePathA=HeapAlloc(GetProcessHeap(),0,length);
+ res=IStream_Read(pStm,filePathA,length,&bread);
+ if (bread != length)
+ return E_FAIL;
+
+ /* read the first constant */
+ IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
+ if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
+ return E_FAIL;
+
+ length--;
+
+ for(i=0;i<10;i++){
+ res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
+ if (bread!=sizeof(WORD) || wbuffer!=0)
+ return E_FAIL;
+ }
+
+ if (length>8)
+ length=0;
+
+ doubleLenHex=doubleLenDec=2*length;
+ if (length > 5)
+ doubleLenDec+=6;
+
+ res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
+ if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenDec)
+ return E_FAIL;
+
+ if (length==0)
+ return res;
+
+ res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
+ if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenHex)
+ return E_FAIL;
+
+ res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
+ if (bread!=sizeof(WORD) || wbuffer!=0x3)
+ return E_FAIL;
+
+ filePathW=HeapAlloc(GetProcessHeap(),0,(length+1)*sizeof(WCHAR));
+ filePathW[length]=0;
+ res=IStream_Read(pStm,filePathW,doubleLenHex,&bread);
+ if (bread!=doubleLenHex)
+ return E_FAIL;
+
+ if (This->filePathName!=NULL)
+ HeapFree(GetProcessHeap(),0,This->filePathName);
+
+ This->filePathName=filePathW;
+
+ HeapFree(GetProcessHeap(),0,filePathA);
+
+ return res;
}
/******************************************************************************
* FileMoniker_Save
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_Save(
- IMoniker* iface,
- IStream* pStm,
- BOOL fClearDirty)
+HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
+ IStream* pStm,/* poniter to the stream where the object is to be saved */
+ BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ /* this function saves data of this object. In the begining I thougth that I have just to write
+ * the filePath string on Stream. But, when I tested this function whith windows programs samples !
+ * I noted that it was not the case. So I analysed data writen by this function on Windows system and
+ * what did this function do exactly ! but I have no idear a bout its logic !
+ * I guessed data who must be writen on stream wich is:
+ * 1) WORD constant:zero 2) length of the path string ("\0" included) 3) path string type A
+ * 4) DWORD constant : 0xDEADFFFF 5) ten WORD constant: zero 6) DWORD: double-length of the the path
+ * string type W ("\0" not included) 7) WORD constant: 0x3 8) filePath unicode string.
+ * if the length(filePath) > 8 or.length(filePath) == 8 stop at step 5)
+ */
- FIXME(ole,"(%p,%p,%d),stub!\n",This,pStm,fClearDirty);
+ ICOM_THIS(FileMonikerImpl,iface);
- return E_NOTIMPL;
+ HRESULT res;
+ LPOLESTR filePathW=This->filePathName;
+ CHAR* filePathA;
+ DWORD len=1+lstrlenW(filePathW);
+
+ DWORD constant1 = 0xDEADFFFF; /* these constants are detected after analysing the data structure writen by */
+ WORD constant2 = 0x3; /* FileMoniker_Save function in a windows program system */
+
+ WORD zero=0;
+ DWORD doubleLenHex;
+ DWORD doubleLenDec;
+ int i=0;
+
+ TRACE(ole,"(%p,%p,%d)\n",iface,pStm,fClearDirty);
+
+ if (pStm==NULL)
+ return E_POINTER;
+
+ /* write a DWORD seted to 0 : constant */
+ res=IStream_Write(pStm,&zero,sizeof(WORD),NULL);
+
+ /* write length of filePath string ( "\0" included )*/
+ res=IStream_Write(pStm,&len,sizeof(DWORD),NULL);
+
+ /* write filePath string type A */
+ filePathA=HeapAlloc(GetProcessHeap(),0,len);
+ lstrcpyWtoA(filePathA,filePathW);
+ res=IStream_Write(pStm,filePathA,len,NULL);
+ HeapFree(GetProcessHeap(),0,filePathA);
+
+ /* write a DWORD seted to 0xDEADFFFF: constant */
+ res=IStream_Write(pStm,&constant1,sizeof(DWORD),NULL);
+
+ len--;
+ /* write 10 times a DWORD seted to 0 : constants */
+ for(i=0;i<10;i++)
+ res=IStream_Write(pStm,&zero,sizeof(WORD),NULL);
+
+ if (len>8)
+ len=0;
+
+ doubleLenHex=doubleLenDec=2*len;
+ if (len > 5)
+ doubleLenDec+=6;
+
+ /* write double-length of the path string ( "\0" included )*/
+ res=IStream_Write(pStm,&doubleLenDec,sizeof(DWORD),NULL);
+
+ if (len==0)
+ return res;
+
+ /* write double-length (hexa representation) of the path string ( "\0" included ) */
+ res=IStream_Write(pStm,&doubleLenHex,sizeof(DWORD),NULL);
+
+ /* write a WORD seted to 0x3: constant */
+ res=IStream_Write(pStm,&constant2,sizeof(WORD),NULL);
+
+ /* write path unicode string */
+ res=IStream_Write(pStm,filePathW,doubleLenHex,NULL);
+
+ return res;
}
/******************************************************************************
* FileMoniker_GetSizeMax
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_GetSizeMax(
- IMoniker* iface,
- ULARGE_INTEGER* pcbSize)
+HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
+ ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
+ DWORD len=lstrlenW(This->filePathName);
+ DWORD sizeMAx;
- FIXME(ole,"(%p,%p),stub!\n",This,pcbSize);
+ TRACE(ole,"(%p,%p)\n",iface,pcbSize);
- return E_NOTIMPL;
-}
+ if (pcbSize!=NULL)
+ return E_POINTER;
-/******************************************************************************
- * FileMoniker_Construct
- *******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName){
+ /* for more details see FileMonikerImpl_Save coments */
+
+ sizeMAx = sizeof(WORD) + /* first WORD is 0 */
+ sizeof(DWORD)+ /* length of filePath including "\0" in the end of the string */
+ (len+1)+ /* filePath string */
+ sizeof(DWORD)+ /* constant : 0xDEADFFFF */
+ 10*sizeof(WORD)+ /* 10 zero WORD */
+ sizeof(DWORD); /* size of the unicode filePath: "\0" not included */
- FIXME(ole,"(%p,%p),stub!\n",This,lpszPathName);
+ if (len==0 || len > 8)
+ return S_OK;
+
+ sizeMAx += sizeof(DWORD)+ /* size of the unicode filePath: "\0" not included */
+ sizeof(WORD)+ /* constant : 0x3 */
+ len*sizeof(WCHAR); /* unicde filePath string */
+
+ pcbSize->LowPart=sizeMAx;
+ pcbSize->HighPart=0;
- memset(This, 0, sizeof(FileMonikerImpl));
-
- //Initialize the virtual fgunction table.
- This->lpvtbl = &VT_FileMonikerImpl;
return S_OK;
}
/******************************************************************************
- * FileMoniker_Destroy
+ * FileMoniker_Construct (local function)
*******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This){
+HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName)
+{
+ int nb=0,i;
+ int sizeStr=lstrlenW(lpszPathName);
+ LPOLESTR *tabStr=0;
+ WCHAR twoPoint[]={'.','.',0};
+ WCHAR bkSlash[]={'\\',0};
+ BYTE addBkSlash;
+
+ TRACE(ole,"(%p,%p)\n",This,lpszPathName);
- FIXME(ole,"(%p),stub!\n",This);
+ /* Initialize the virtual fgunction table. */
+ This->lpvtbl1 = &VT_FileMonikerImpl;
+ This->lpvtbl2 = &VT_ROTDataImpl;
+ This->ref = 0;
- SEGPTR_FREE(This);
+ This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1));
+
+ if (This->filePathName==NULL)
+ return E_OUTOFMEMORY;
+
+ lstrcpyW(This->filePathName,lpszPathName);
+
+ nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr);
+
+ if (nb > 0 ){
+
+ addBkSlash=1;
+ if (lstrcmpW(tabStr[0],twoPoint)!=0)
+ addBkSlash=0;
+ else
+ for(i=0;i<nb;i++){
+
+ if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
+ addBkSlash=0;
+ break;
+ }
+ else
+
+ if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
+ *tabStr[i]=0;
+ sizeStr--;
+ addBkSlash=0;
+ break;
+ }
+ }
+
+ if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
+ addBkSlash=0;
+
+ This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
+
+ *This->filePathName=0;
+
+ for(i=0;tabStr[i]!=NULL;i++)
+ lstrcatW(This->filePathName,tabStr[i]);
+
+ if (addBkSlash)
+ lstrcatW(This->filePathName,bkSlash);
+ }
+
+ for(i=0; tabStr[i]!=NULL;i++)
+ CoTaskMemFree(tabStr[i]);
+ CoTaskMemFree(tabStr);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * FileMoniker_Destroy (local function)
+ *******************************************************************************/
+HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
+{
+ TRACE(ole,"(%p)\n",This);
+
+ if (This->filePathName!=NULL)
+ HeapFree(GetProcessHeap(),0,This->filePathName);
+
+ HeapFree(GetProcessHeap(),0,This);
+
return S_OK;
}
/******************************************************************************
* FileMoniker_BindToObject
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
- REFIID riid, VOID** ppvResult)
+HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvResult)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ HRESULT res=E_FAIL;
+ CLSID clsID;
+ IUnknown* pObj=0;
+ IRunningObjectTable *prot=0;
+ IPersistFile *ppf=0;
+ IClassFactory *pcf=0;
+ IClassActivator *pca=0;
- FIXME(ole,"(%p,%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,riid,ppvResult);
+ ICOM_THIS(FileMonikerImpl,iface);
- return E_NOTIMPL;
+ *ppvResult=0;
+
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+
+ if(pmkToLeft==NULL){
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&prot);
+
+ if (SUCCEEDED(res)){
+ /* if the requested class was loaded befor ! we dont need to reload it */
+ res = IRunningObjectTable_GetObject(prot,iface,&pObj);
+
+ if (res==S_FALSE){
+ /* first activation of this class */
+ res=GetClassFile(This->filePathName,&clsID);
+ if (SUCCEEDED(res)){
+
+ res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IPersistFile,(void**)&ppf);
+ if (SUCCEEDED(res)){
+
+ res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
+ if (SUCCEEDED(res)){
+
+ pObj=(IUnknown*)ppf;
+ IUnknown_AddRef(pObj);
+ }
+ }
+ }
+ }
+ }
+ }
+ else{
+ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassFactory,(void**)&pcf);
+
+ if (res==E_NOINTERFACE){
+
+ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassActivator,(void**)&pca);
+
+ if (res==E_NOINTERFACE)
+ return MK_E_INTERMEDIATEINTERFACENOTSUPPORTED;
+ }
+ if (pcf!=NULL){
+
+ IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)ppf);
+
+ res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
+
+ if (SUCCEEDED(res)){
+
+ pObj=(IUnknown*)ppf;
+ IUnknown_AddRef(pObj);
+ }
+ }
+ if (pca!=NULL){
+
+ FIXME(ole,"()");
+
+ /*res=GetClassFile(This->filePathName,&clsID);
+
+ if (SUCCEEDED(res)){
+
+ res=IClassActivator_GetClassObject(pca,&clsID,CLSCTX_ALL,0,&IID_IPersistFile,(void**)&ppf);
+
+ if (SUCCEEDED(res)){
+
+ pObj=(IUnknown*)ppf;
+ IUnknown_AddRef(pObj);
+ }
+ }*/
+ }
+}
+
+ if (pObj!=NULL){
+ /* get the requested interface from the loaded class */
+ res= IUnknown_QueryInterface(pObj,riid,ppvResult);
+
+ IBindCtx_RegisterObjectBound(pbc,(IUnknown*)*ppvResult);
+
+ IUnknown_Release(pObj);
+ }
+
+ if (prot!=NULL)
+ IRunningObjectTable_Release(prot);
+
+ if (ppf!=NULL)
+ IPersistFile_Release(ppf);
+
+ if (pca!=NULL)
+ IClassActivator_Release(pca);
+
+ if (pcf!=NULL)
+ IClassFactory_Release(pcf);
+
+ return res;
}
/******************************************************************************
* FileMoniker_BindToStorage
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
- REFIID riid, VOID** ppvResult)
+HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvObject)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ LPOLESTR filePath=0;
+ IStorage *pstg=0;
+ HRESULT res;
- FIXME(ole,"(%p,%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,riid,ppvResult);
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);
+
+ if (pmkToLeft==NULL){
+
+ if (IsEqualIID(&IID_IStorage, riid)){
+
+ /* get the file name */
+ FileMonikerImpl_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
+
+ /* verifie if the file contains a storage object */
+ res=StgIsStorageFile(filePath);
+
+ if(res==S_OK){
+
+ res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
+
+ if (SUCCEEDED(res)){
+
+ *ppvObject=pstg;
+
+ IStorage_AddRef(pstg);
+
+ return res;
+ }
+ }
+ CoTaskMemFree(filePath);
+ }
+ else
+ if ( (IsEqualIID(&IID_IStream, riid)) || (IsEqualIID(&IID_ILockBytes, riid)) )
+
+ return E_UNSPEC;
+ else
+
+ return E_NOINTERFACE;
+ }
+ else {
+
+ FIXME(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);
return E_NOTIMPL;
}
+ return res;
+}
/******************************************************************************
* FileMoniker_Reduce
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,
- IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
+HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,
+ IBindCtx* pbc,
+ DWORD dwReduceHowFar,
+ IMoniker** ppmkToLeft,
+ IMoniker** ppmkReduced)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ TRACE(ole,"(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
- FIXME(ole,"(%p,%p,%ld,%p,%p),stub!\n",This,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
+ if (ppmkReduced==NULL)
+ return E_POINTER;
- return E_NOTIMPL;
+ FileMonikerImpl_AddRef(iface);
+
+ *ppmkReduced=iface;
+
+ return MK_S_REDUCED_TO_SELF;
}
-
/******************************************************************************
* FileMoniker_ComposeWith
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric,
+HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
+ IMoniker* pmkRight,
+ BOOL fOnlyIfNotGeneric,
IMoniker** ppmkComposite)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ HRESULT res;
+ LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
+ WCHAR twoPoint[]={'.','.',0};
+ WCHAR bkSlash[]={'\\',0};
+ IBindCtx *bind=0;
+ int i=0,j=0,lastIdx1=0,lastIdx2=0;
+ DWORD mkSys;
- FIXME(ole,"(%p,%p,%d,%p),stub!\n",This,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
+ TRACE(ole,"(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
- return E_NOTIMPL;
+ if (ppmkComposite==NULL)
+ return E_POINTER;
+
+ if (pmkRight==NULL)
+ return E_INVALIDARG;
+
+ *ppmkComposite=0;
+
+ IMoniker_IsSystemMoniker(pmkRight,&mkSys);
+
+ /* check if we have two filemonikers to compose or not */
+ if(mkSys==MKSYS_FILEMONIKER){
+
+ CreateBindCtx(0,&bind);
+
+ FileMonikerImpl_GetDisplayName(iface,bind,NULL,&str1);
+ IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
+
+ /* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
+ lastIdx1=FileMonikerImpl_DecomposePath(str1,&strDec1)-1;
+ lastIdx2=FileMonikerImpl_DecomposePath(str2,&strDec2)-1;
+
+ if ((lastIdx1==-1 && lastIdx2>-1)||(lastIdx1==1 && lstrcmpW(strDec1[0],twoPoint)==0))
+ return MK_E_SYNTAX;
+
+ if(lstrcmpW(strDec1[lastIdx1],bkSlash)==0)
+ lastIdx1--;
+
+ /* for etch "..\" in the left of str2 remove the right element from str1 */
+ for(i=0; ( (lastIdx1>=0) && (strDec2[i]!=NULL) && (lstrcmpW(strDec2[i],twoPoint)==0) ) ;i+=2){
+
+ lastIdx1-=2;
+ }
+
+ /* the length of the composed path string is raised by the sum of the two paths lengths */
+ newStr=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(lstrlenW(str1)+lstrlenW(str2)+1));
+
+ if (newStr==NULL)
+ return E_OUTOFMEMORY;
+
+ /* new path is the concatenation of the rest of str1 and str2 */
+ for(*newStr=0,j=0;j<=lastIdx1;j++)
+ lstrcatW(newStr,strDec1[j]);
+
+ if ((strDec2[i]==NULL && lastIdx1>-1 && lastIdx2>-1) || lstrcmpW(strDec2[i],bkSlash)!=0)
+ lstrcatW(newStr,bkSlash);
+
+ for(j=i;j<=lastIdx2;j++)
+ lstrcatW(newStr,strDec2[j]);
+
+ /* create a new moniker with the new string */
+ res=CreateFileMoniker(newStr,ppmkComposite);
+
+ /* free all strings space memory used by this function */
+ HeapFree(GetProcessHeap(),0,newStr);
+
+ for(i=0; strDec1[i]!=NULL;i++)
+ CoTaskMemFree(strDec1[i]);
+ for(i=0; strDec2[i]!=NULL;i++)
+ CoTaskMemFree(strDec2[i]);
+ CoTaskMemFree(strDec1);
+ CoTaskMemFree(strDec2);
+
+ CoTaskMemFree(str1);
+ CoTaskMemFree(str2);
+
+ return res;
+ }
+ else if(mkSys==MKSYS_ANTIMONIKER){
+
+ *ppmkComposite=NULL;
+ return S_OK;
+ }
+ else if (fOnlyIfNotGeneric){
+
+ *ppmkComposite=NULL;
+ return MK_E_NEEDGENERIC;
+ }
+ else
+
+ return CreateGenericComposite(iface,pmkRight,ppmkComposite);
}
/******************************************************************************
@@ -291,12 +811,14 @@
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ TRACE(ole,"(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
- FIXME(ole,"(%p,%d,%p),stub!\n",This,fForward,ppenumMoniker);
+ if (ppenumMoniker == NULL)
+ return E_POINTER;
- return E_NOTIMPL;
+ *ppenumMoniker = NULL;
+ return S_OK;
}
/******************************************************************************
@@ -304,11 +826,35 @@
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
+ CLSID clsid;
+ LPOLESTR filePath;
+ IBindCtx* bind;
+ HRESULT res;
- FIXME(ole,"(%p,%p),stub!\n",This,pmkOtherMoniker);
+ TRACE(ole,"(%p,%p)\n",iface,pmkOtherMoniker);
- return E_NOTIMPL;
+ if (pmkOtherMoniker==NULL)
+ return S_FALSE;
+
+ IMoniker_GetClassID(pmkOtherMoniker,&clsid);
+
+ if (!IsEqualCLSID(&clsid,&CLSID_FileMoniker))
+
+ return S_FALSE;
+
+ res=CreateBindCtx(0,&bind);
+ if (FAILED(res))
+ return res;
+
+ IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath);
+
+ if (lstrcmpiW(filePath,
+ This->filePathName)!=0)
+
+ return S_FALSE;
+
+ return S_OK;
}
/******************************************************************************
@@ -316,37 +862,103 @@
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,pdwHash);
+ int h = 0,i,skip,len;
+ int off = 0;
+ LPOLESTR val;
- return E_NOTIMPL;
+ if (pdwHash==NULL)
+ return E_POINTER;
+
+ val = This->filePathName;
+ 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];
+ }
+}
+
+ *pdwHash=h;
+
+ return S_OK;
}
/******************************************************************************
* FileMoniker_IsRunning
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
+HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ IRunningObjectTable* rot;
+ HRESULT res;
- FIXME(ole,"(%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,pmkNewlyRunning);
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
- return E_NOTIMPL;
+ if ( (pmkNewlyRunning!=NULL) && (IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK) )
+ return S_OK;
+
+ if (pbc==NULL)
+ return E_POINTER;
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+ if (FAILED(res))
+ return res;
+
+ res = IRunningObjectTable_IsRunning(rot,iface);
+
+ IRunningObjectTable_Release(rot);
+
+ return res;
}
/******************************************************************************
* FileMoniker_GetTimeOfLastChange
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
+HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
FILETIME* pFileTime)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
+ IRunningObjectTable* rot;
+ HRESULT res;
+ WIN32_FILE_ATTRIBUTE_DATA info;
- FIXME(ole,"(%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,pFileTime);
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pFileTime);
- return E_NOTIMPL;
+ if (pFileTime==NULL)
+ return E_POINTER;
+
+ if (pmkToLeft!=NULL)
+ return E_INVALIDARG;
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+ if (FAILED(res))
+ return res;
+
+ res= IRunningObjectTable_GetTimeOfLastChange(rot,iface,pFileTime);
+
+ if (FAILED(res)){ /* the moniker is not registred */
+
+ if (!GetFileAttributesExW(This->filePathName,GetFileExInfoStandard,&info))
+ return MK_E_NOOBJECT;
+
+ *pFileTime=info.ftLastWriteTime;
+}
+
+ return S_OK;
}
/******************************************************************************
@@ -354,24 +966,148 @@
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
- FIXME(ole,"(%p,%p),stub!\n",This,ppmk);
+ TRACE(ole,"(%p,%p)\n",iface,ppmk);
- return E_NOTIMPL;
+ return CreateAntiMoniker(ppmk);
}
/******************************************************************************
* FileMoniker_CommonPrefixWith
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,
- IMoniker** ppmkPrefix)
+HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
- FIXME(ole,"(%p,%p,%p),stub!\n",This,pmkOther,ppmkPrefix);
+ LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath;
+ IBindCtx *pbind;
+ DWORD mkSys;
+ ULONG nb1,nb2,i,sameIdx;
+ BOOL machimeNameCase=FALSE;
- return E_NOTIMPL;
+ if (ppmkPrefix==NULL)
+ return E_POINTER;
+
+ if (pmkOther==NULL)
+ return E_INVALIDARG;
+
+ *ppmkPrefix=0;
+
+ /* check if we have the same type of moniker */
+ IMoniker_IsSystemMoniker(pmkOther,&mkSys);
+
+ if(mkSys==MKSYS_FILEMONIKER){
+
+ CreateBindCtx(0,&pbind);
+
+ /* create a string based on common part of the two paths */
+
+ IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis);
+ IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther);
+
+ nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1);
+ nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2);
+
+ if (nb1==0 || nb2==0)
+ return MK_E_NOPREFIX;
+
+ commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1));
+
+ *commonPath=0;
+
+ for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) &&
+ (stringTable2[sameIdx]!=NULL) &&
+ (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++);
+
+ if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){
+
+ machimeNameCase=TRUE;
+
+ for(i=2;i<sameIdx;i++)
+
+ if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){
+ machimeNameCase=FALSE;
+ break;
+}
+ }
+
+ if (machimeNameCase && *stringTable1[sameIdx-1]=='\\')
+ sameIdx--;
+
+ if (machimeNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) )
+ return MK_E_NOPREFIX;
+
+ for(i=0;i<sameIdx;i++)
+ lstrcatW(commonPath,stringTable1[i]);
+
+ for(i=0;i<nb1;i++)
+ CoTaskMemFree(stringTable1[i]);
+
+ CoTaskMemFree(stringTable1);
+
+ for(i=0;i<nb2;i++)
+ CoTaskMemFree(stringTable2[i]);
+
+ CoTaskMemFree(stringTable2);
+
+ HeapFree(GetProcessHeap(),0,commonPath);
+
+ return CreateFileMoniker(commonPath,ppmkPrefix);
+ }
+ else
+ return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
+}
+
+/******************************************************************************
+ * DecomposePath (local function)
+ ******************************************************************************/
+int WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** stringTable)
+{
+ WCHAR bSlash[] = {'\\',0};
+ WCHAR word[100];
+ int i=0,j,tabIndex=0;
+ LPOLESTR *strgtable ;
+
+ int len=lstrlenW(str);
+
+ strgtable =CoTaskMemAlloc(sizeof(LPOLESTR[len]));
+
+ if (strgtable==NULL)
+ return E_OUTOFMEMORY;
+
+ while(str[i]!=0){
+
+ if(str[i]==bSlash[0]){
+
+ strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR));
+
+ if (strgtable[tabIndex]==NULL)
+ return E_OUTOFMEMORY;
+
+ lstrcpyW(strgtable[tabIndex++],bSlash);
+
+ i++;
+
+ }
+ else {
+
+ for(j=0; str[i]!=0 && str[i]!=bSlash[0] ; i++,j++)
+ word[j]=str[i];
+
+ word[j]=0;
+
+ strgtable[tabIndex]=CoTaskMemAlloc(sizeof(WCHAR)*(j+1));
+
+ if (strgtable[tabIndex]==NULL)
+ return E_OUTOFMEMORY;
+
+ lstrcpyW(strgtable[tabIndex++],word);
+ }
+ }
+ strgtable[tabIndex]=NULL;
+
+ *stringTable=strgtable;
+
+ return tabIndex;
}
/******************************************************************************
@@ -379,36 +1115,116 @@
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ IBindCtx *bind;
+ HRESULT res;
+ LPOLESTR str1=0,str2=0,*tabStr1=0,*tabStr2=0,relPath=0;
+ DWORD len1=0,len2=0,sameIdx=0,j=0;
+ WCHAR back[] ={'.','.','\\',0};
+
+ TRACE(ole,"(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
- FIXME(ole,"(%p,%p,%p),stub!\n",This,pmOther,ppmkRelPath);
+ if (ppmkRelPath==NULL)
+ return E_POINTER;
- return E_NOTIMPL;
+ if (pmOther==NULL)
+ return E_INVALIDARG;
+
+ res=CreateBindCtx(0,&bind);
+ if (FAILED(res))
+ return res;
+
+ res=IMoniker_GetDisplayName(iface,bind,NULL,&str1);
+ if (FAILED(res))
+ return res;
+ res=IMoniker_GetDisplayName(pmOther,bind,NULL,&str2);
+ if (FAILED(res))
+ return res;
+
+ len1=FileMonikerImpl_DecomposePath(str1,&tabStr1);
+ len2=FileMonikerImpl_DecomposePath(str2,&tabStr2);
+
+ if (FAILED(len1) || FAILED(len2))
+ return E_OUTOFMEMORY;
+
+ /* count the number of similar items from the begin of the two paths */
+ for(sameIdx=0; ( (tabStr1[sameIdx]!=NULL) &&
+ (tabStr2[sameIdx]!=NULL) &&
+ (lstrcmpiW(tabStr1[sameIdx],tabStr2[sameIdx])==0)); sameIdx++);
+
+ /* begin the construction of relativePath */
+ /* if the two paths have a consecutive similar item from the begin ! the relativePath will be composed */
+ /* by "..\\" in the begin */
+ relPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(1+lstrlenW(str1)+lstrlenW(str2)));
+
+ *relPath=0;
+
+ if (len2>0 && !(len1==1 && len2==1 && sameIdx==0))
+ for(j=sameIdx;(tabStr1[j] != NULL); j++)
+ if (*tabStr1[j]!='\\')
+ lstrcatW(relPath,back);
+
+ /* add items of the second path (similar items with the first path are not included) to the relativePath */
+ for(j=sameIdx;tabStr2[j]!=NULL;j++)
+ lstrcatW(relPath,tabStr2[j]);
+
+ res=CreateFileMoniker(relPath,ppmkRelPath);
+
+ for(j=0; tabStr1[j]!=NULL;j++)
+ CoTaskMemFree(tabStr1[j]);
+ for(j=0; tabStr2[j]!=NULL;j++)
+ CoTaskMemFree(tabStr2[j]);
+ CoTaskMemFree(tabStr1);
+ CoTaskMemFree(tabStr2);
+ CoTaskMemFree(str1);
+ CoTaskMemFree(str2);
+ HeapFree(GetProcessHeap(),0,relPath);
+
+ if (len1==0 || len2==0 || (len1==1 && len2==1 && sameIdx==0))
+ return MK_S_HIM;
+
+ return res;
}
/******************************************************************************
* FileMoniker_GetDisplayName
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
+HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ ICOM_THIS(FileMonikerImpl,iface);
- FIXME(ole,"(%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,ppszDisplayName);
+ int len=lstrlenW(This->filePathName);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
+
+ if (ppszDisplayName==NULL)
+ return E_POINTER;
+
+ if (pmkToLeft!=NULL)
+ return E_INVALIDARG;
+
+ *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
+ if (*ppszDisplayName==NULL)
+ return E_OUTOFMEMORY;
+
+ lstrcpyW(*ppszDisplayName,This->filePathName);
+
+ return S_OK;
}
/******************************************************************************
* FileMoniker_ParseDisplayName
******************************************************************************/
-HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
- LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
+HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ LPOLESTR pszDisplayName,
+ ULONG* pchEaten,
+ IMoniker** ppmkOut)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
-
- FIXME(ole,"(%p,%p,%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
-
+ FIXME(ole,"(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
return E_NOTIMPL;
}
@@ -417,44 +1233,105 @@
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
- FileMonikerImpl* This=(FileMonikerImpl*)iface;
+ TRACE(ole,"(%p,%p)\n",iface,pwdMksys);
- FIXME(ole,"(%p,%p),stub!\n",This,pwdMksys);
+ if (!pwdMksys)
+ return E_POINTER;
+
+ (*pwdMksys)=MKSYS_FILEMONIKER;
+ return S_OK;
+}
+
+/*******************************************************************************
+ * FileMonikerIROTData_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
+{
+
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
+
+ return FileMonikerImpl_QueryInterface(This, riid, ppvObject);
+}
+
+/***********************************************************************
+ * FileMonikerIROTData_AddRef
+ */
+ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData *iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ return FileMonikerImpl_AddRef(This);
+}
+
+/***********************************************************************
+ * FileMonikerIROTData_Release
+ */
+ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ return FileMonikerImpl_Release(This);
+}
+
+/******************************************************************************
+ * FileMonikerIROTData_GetComparaisonData
+ ******************************************************************************/
+HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
+ BYTE* pbData,
+ ULONG cbMax,
+ ULONG* pcbData)
+{
+ FIXME(ole,"(),stub!\n");
return E_NOTIMPL;
}
/******************************************************************************
* CreateFileMoniker16
******************************************************************************/
-HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName,LPMONIKER* ppmk){
+HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName,LPMONIKER* ppmk)
+{
FIXME(ole,"(%s,%p),stub!\n",lpszPathName,ppmk);
-
return E_NOTIMPL;
}
/******************************************************************************
- * CreateFileMoniker32
+ * CreateFileMoniker
******************************************************************************/
HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
{
FileMonikerImpl* newFileMoniker = 0;
- HRESULT hr = S_OK;
+ HRESULT hr = E_FAIL;
+ IID riid=IID_IMoniker;
TRACE(ole,"(%p,%p)\n",lpszPathName,ppmk);
+ if (ppmk==NULL)
+ return E_POINTER;
+
+ if(lpszPathName==NULL)
+ return MK_E_SYNTAX;
+
+ *ppmk=0;
+
newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));
if (newFileMoniker == 0)
- return STG_E_INSUFFICIENTMEMORY;
+ return E_OUTOFMEMORY;
hr = FileMonikerImpl_Construct(newFileMoniker,lpszPathName);
- if (FAILED(hr))
- return hr;
-
- hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&IID_IMoniker,(void**)ppmk);
+ if (SUCCEEDED(hr))
+ hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&riid,(void**)ppmk);
+ else
+ HeapFree(GetProcessHeap(),0,newFileMoniker);
return hr;
}
diff --git a/ole/itemmoniker.c b/ole/itemmoniker.c
index b55dfd8..64db628 100644
--- a/ole/itemmoniker.c
+++ b/ole/itemmoniker.c
@@ -4,31 +4,52 @@
* Copyright 1999 Noomen Hamza
***************************************************************************************/
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
#include <assert.h>
#include "winerror.h"
-#include "wine/obj_moniker.h"
-#include "heap.h"
#include "debug.h"
+#include "heap.h"
+#include "winuser.h"
+#include "file.h"
+#include "winreg.h"
+#include "objbase.h"
+#include "wine/obj_inplace.h"
+/* ItemMoniker data structure */
typedef struct ItemMonikerImpl{
- ICOM_VTABLE(IMoniker)* lpvtbl;
+ ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
- ULONG ref;
+ /* 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.*/
+ ULONG ref; /* reference counter for this object */
+
+ LPOLESTR itemName; /* item name identified by this ItemMoniker */
+
+ LPOLESTR itemDelimiter; /* Delimiter string */
+
} ItemMonikerImpl;
+/********************************************************************************/
+/* ItemMoniker prototype functions : */
+
+/* IUnknown prototype functions */
static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface);
+
+/* IPersist prototype functions */
static HRESULT WINAPI ItemMonikerImpl_GetClassID(const IMoniker* iface, CLSID *pClassID);
+
+/* IPersistStream prototype functions */
static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
+
+/* IMoniker prototype functions */
static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
@@ -45,10 +66,24 @@
static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
-static HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszItem);
-static HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
+/* Local function used by ItemMoniker implementation */
+HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
+HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
-// Virtual function table for the ItemMonikerImpl class.
+/********************************************************************************/
+/* IROTData prototype functions */
+
+/* IUnknown prototype functions */
+static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
+static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
+static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
+
+/* IROTData prototype function */
+static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
+
+/********************************************************************************/
+/* Virtual function table for the ItemMonikerImpl class witch include Ipersist,*/
+/* IPersistStream and IMoniker functions. */
static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl =
{
ItemMonikerImpl_QueryInterface,
@@ -76,38 +111,48 @@
ItemMonikerImpl_IsSystemMoniker
};
+/********************************************************************************/
+/* Virtual function table for the IROTData class. */
+static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
+{
+ ItemMonikerROTDataImpl_QueryInterface,
+ ItemMonikerROTDataImpl_AddRef,
+ ItemMonikerROTDataImpl_Release,
+ ItemMonikerROTDataImpl_GetComparaisonData
+};
+
/*******************************************************************************
* ItemMoniker_QueryInterface
*******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
- // Perform a sanity check on the parameters.
- if ( (This==0) || (ppvObject==0) ) return E_INVALIDARG;
+ /* Perform a sanity check on the parameters.*/
+ if ( (This==0) || (ppvObject==0) )
+ return E_INVALIDARG;
- // Initialize the return parameter.
+ /* Initialize the return parameter */
*ppvObject = 0;
- // Compare the riid with the interface IDs implemented by this object.
- if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
- *ppvObject = (IMoniker*)This;
- else
- if (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0)
- *ppvObject = (IMoniker*)This;
- else
- if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
- *ppvObject = (IMoniker*)This;
- else
- if (memcmp(&IID_IMoniker, riid, sizeof(IID_IMoniker)) == 0)
- *ppvObject = (IMoniker*)This;
-
- // Check that we obtained an interface.
- if ((*ppvObject)==0) return E_NOINTERFACE;
+ /* Compare the riid with the interface IDs implemented by this object.*/
+ if (IsEqualIID(&IID_IUnknown, riid) ||
+ IsEqualIID(&IID_IPersist, riid) ||
+ IsEqualIID(&IID_IPersistStream, riid) ||
+ IsEqualIID(&IID_IMoniker, riid)
+ )
+ *ppvObject = iface;
- // Query Interface always increases the reference count by one when it is successful
+ else if (IsEqualIID(&IID_IROTData, riid))
+ *ppvObject = (IROTData*)&(This->lpvtbl2);
+
+ /* Check that we obtained an interface.*/
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ /* Query Interface always increases the reference count by one when it is successful */
ItemMonikerImpl_AddRef(iface);
return S_OK;
@@ -118,7 +163,7 @@
******************************************************************************/
ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
TRACE(ole,"(%p)\n",This);
@@ -130,27 +175,35 @@
******************************************************************************/
ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
- TRACE(ole,"(%p),stub!\n",This);
+ TRACE(ole,"(%p)\n",This);
This->ref--;
+ /* destroy the object if there's no more reference on it */
if (This->ref==0){
+
ItemMonikerImpl_Destroy(This);
+
return 0;
}
-
- return This->ref;
+ return This->ref;;
}
/******************************************************************************
* ItemMoniker_GetClassID
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_GetClassID(const IMoniker* iface, CLSID *pClassID)//Pointer to CLSID of object
+HRESULT WINAPI ItemMonikerImpl_GetClassID(const IMoniker* iface,CLSID *pClassID)
{
- FIXME(ole,"(%p),stub!\n",pClassID);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p),stub!\n",iface,pClassID);
+
+ if (pClassID==NULL)
+ return E_POINTER;
+
+ *pClassID = CLSID_ItemMoniker;
+
+ return S_OK;
}
/******************************************************************************
@@ -158,123 +211,334 @@
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
+ method in the OLE-provided moniker interfaces always return S_FALSE because
+ their internal state never changes. */
- FIXME(ole,"(%p),stub!\n",This);
- return E_NOTIMPL;
+ TRACE(ole,"(%p)\n",iface);
+
+ return S_FALSE;
}
/******************************************************************************
* ItemMoniker_Load
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_Load(
- IMoniker* iface,
- IStream* pStm)
+HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
- FIXME(ole,"(%p,%p),stub!\n",This,pStm);
- return E_NOTIMPL;
+ ICOM_THIS(ItemMonikerImpl,iface);
+ HRESULT res;
+ DWORD delimiterLength,nameLength;
+ CHAR *itemNameA,*itemDelimiterA;
+ ULONG bread;
+
+ /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
+
+ /* read item delimiter string length + 1 */
+ res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
+ if (bread != sizeof(DWORD))
+ return E_FAIL;
+
+ /* read item delimiter string */
+ itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
+ res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
+ if (bread != delimiterLength)
+ return E_FAIL;
+
+ This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,delimiterLength*sizeof(WCHAR));
+ if (!This->itemDelimiter)
+ return E_OUTOFMEMORY;
+
+ lstrcpyAtoW(This->itemDelimiter,itemDelimiterA);
+
+ /* read item name string length + 1*/
+ res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
+ if (bread != sizeof(DWORD))
+ return E_FAIL;
+
+ /* read item name string */
+ itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
+ res=IStream_Read(pStm,itemNameA,nameLength,&bread);
+ if (bread != nameLength)
+ return E_FAIL;
+
+ This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,nameLength*sizeof(WCHAR));
+ if (!This->itemName)
+ return E_OUTOFMEMORY;
+
+ lstrcpyAtoW(This->itemName,itemNameA);
+
+ return res;
}
/******************************************************************************
* ItemMoniker_Save
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_Save(
- IMoniker* iface,
- IStream* pStm,
- BOOL fClearDirty)
+HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
+ IStream* pStm,/* pointer to the stream where the object is to be saved */
+ BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
+ HRESULT res;
+ DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
+ DWORD nameLength=lstrlenW(This->itemName)+1;
+ CHAR *itemNameA,*itemDelimiterA;
- FIXME(ole,"(%p,%p,%d),stub!\n",This,pStm,fClearDirty);
- return E_NOTIMPL;
+ /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
+ /* 2) String (type A): item delimiter string ('\0' included) */
+ /* 3) DWORD : size of item name string ('\0' included) */
+ /* 4) String (type A): item name string ('\0' included) */
+
+ itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
+ itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
+ lstrcpyWtoA(itemNameA,This->itemName);
+ lstrcpyWtoA(itemDelimiterA,This->itemDelimiter);
+
+ 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);
+ res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
+
+ return res;
}
/******************************************************************************
* ItemMoniker_GetSizeMax
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_GetSizeMax(
- IMoniker* iface,
- ULARGE_INTEGER* pcbSize)
+HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
+ ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
+ DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
+ DWORD nameLength=lstrlenW(This->itemName)+1;
- FIXME(ole,"(%p,%p),stub!\n",This,pcbSize);
- return E_NOTIMPL;
-}
+ TRACE(ole,"(%p,%p)\n",iface,pcbSize);
-/******************************************************************************
- * ItemMoniker_Construct
- *******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem){
+ if (pcbSize!=NULL)
+ return E_POINTER;
- FIXME(ole,"(%p,%p,%p),stub!\n",This,lpszDelim,lpszItem);
+ /* for more details see ItemMonikerImpl_Save coments */
+
+ pcbSize->LowPart = sizeof(DWORD) + /* DWORD witch contains delimiter length */
+ delimiterLength + /* item delimiter string */
+ sizeof(DWORD) + /* DWORD witch 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->HighPart=0;
- memset(This, 0, sizeof(ItemMonikerImpl));
-
- //Initialize the virtual fgunction table.
- This->lpvtbl = &VT_ItemMonikerImpl;
return S_OK;
}
/******************************************************************************
- * ItemMoniker_Destroy
+ * ItemMoniker_Construct (local function)
*******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This){
+HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
+{
- FIXME(ole,"(%p),stub!\n",This);
+ int sizeStr1=lstrlenW(lpszItem);
+ int sizeStr2=lstrlenW(lpszDelim);
- SEGPTR_FREE(This);
+ TRACE(ole,"(%p,%p)\n",This,lpszItem);
+
+ /* Initialize the virtual fgunction table. */
+ This->lpvtbl1 = &VT_ItemMonikerImpl;
+ This->lpvtbl2 = &VT_ROTDataImpl;
+ This->ref = 0;
+
+ This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
+ This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
+
+ if ((This->itemName==NULL)||(This->itemDelimiter==NULL))
+ return E_OUTOFMEMORY;
+
+ lstrcpyW(This->itemName,lpszItem);
+ lstrcpyW(This->itemDelimiter,lpszDelim);
+
+ return S_OK;
+}
+
+/******************************************************************************
+ * ItemMoniker_Destroy (local function)
+ *******************************************************************************/
+HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
+{
+ TRACE(ole,"(%p)\n",This);
+
+ if (This->itemName)
+ HeapFree(GetProcessHeap(),0,This->itemName);
+
+ if (This->itemDelimiter)
+ HeapFree(GetProcessHeap(),0,This->itemDelimiter);
+
+ HeapFree(GetProcessHeap(),0,This);
+
return S_OK;
}
/******************************************************************************
* ItemMoniker_BindToObject
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
- REFIID riid, VOID** ppvResult)
+HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvResult)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
- FIXME(ole,"(%p,%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,riid,ppvResult);
- return E_NOTIMPL;
+ HRESULT res;
+ IID refid=IID_IOleItemContainer;
+ IOleItemContainer *poic=0;
+
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+
+ if(ppvResult ==NULL)
+ return E_POINTER;
+
+ if(pmkToLeft==NULL)
+ return E_INVALIDARG;
+
+ *ppvResult=0;
+
+ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
+
+ if (SUCCEEDED(res)){
+
+ res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
+
+ IOleItemContainer_Release(poic);
+ }
+
+ return res;
}
/******************************************************************************
* ItemMoniker_BindToStorage
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
- REFIID riid, VOID** ppvResult)
+HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ REFIID riid,
+ VOID** ppvResult)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
- FIXME(ole,"(%p,%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,riid,ppvResult);
- return E_NOTIMPL;
+ HRESULT res;
+ IOleItemContainer *poic=0;
+
+ TRACE(ole,"(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+
+ *ppvResult=0;
+
+ if(pmkToLeft==NULL)
+ return E_INVALIDARG;
+
+ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
+
+ if (SUCCEEDED(res)){
+
+ res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
+
+ IOleItemContainer_Release(poic);
+ }
+
+ return res;
}
/******************************************************************************
* ItemMoniker_Reduce
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,
- IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
+HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
+ IBindCtx* pbc,
+ DWORD dwReduceHowFar,
+ IMoniker** ppmkToLeft,
+ IMoniker** ppmkReduced)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ TRACE(ole,"(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
- FIXME(ole,"(%p,%p,%ld,%p,%p),stub!\n",This,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
- return E_NOTIMPL;
+ if (ppmkReduced==NULL)
+ return E_POINTER;
+
+ ItemMonikerImpl_AddRef(iface);
+
+ *ppmkReduced=iface;
+
+ return MK_S_REDUCED_TO_SELF;
}
-
/******************************************************************************
* ItemMoniker_ComposeWith
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric,
+HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
+ IMoniker* pmkRight,
+ BOOL fOnlyIfNotGeneric,
IMoniker** ppmkComposite)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ HRESULT res=S_OK;
+ DWORD mkSys,mkSys2;
+ IEnumMoniker* penumMk=0;
+ IMoniker *pmostLeftMk=0;
+ IMoniker* tempMkComposite=0;
- FIXME(ole,"(%p,%p,%d,%p),stub!\n",This,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
+
+ if ((ppmkComposite==NULL)||(pmkRight==NULL))
+ return E_POINTER;
+
+ *ppmkComposite=0;
+
+ IMoniker_IsSystemMoniker(pmkRight,&mkSys);
+
+ /* If pmkRight is an anti-moniker, the returned moniker is NULL */
+ if(mkSys==MKSYS_ANTIMONIKER)
+ return res;
+
+ else
+ /* if pmkRight is a composite whose leftmost component is an anti-moniker, */
+ /* the returned moniker is the composite after the leftmost anti-moniker is removed. */
+
+ if(mkSys==MKSYS_GENERICCOMPOSITE){
+
+ res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
+
+ if (FAILED(res))
+ return res;
+
+ res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
+
+ IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
+
+ if(mkSys2==MKSYS_ANTIMONIKER){
+
+ IMoniker_Release(pmostLeftMk);
+
+ tempMkComposite=iface;
+ IMoniker_AddRef(iface);
+
+ while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
+
+ res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
+
+ IMoniker_Release(tempMkComposite);
+ IMoniker_Release(pmostLeftMk);
+
+ tempMkComposite=*ppmkComposite;
+ IMoniker_AddRef(tempMkComposite);
+}
+ return res;
+ }
+ else
+ return CreateGenericComposite(iface,pmkRight,ppmkComposite);
+ }
+ /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
+ composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
+ a NULL moniker and a return value of MK_E_NEEDGENERIC */
+ else
+ if (!fOnlyIfNotGeneric)
+ return CreateGenericComposite(iface,pmkRight,ppmkComposite);
+
+ else
+ return MK_E_NEEDGENERIC;
}
/******************************************************************************
@@ -282,11 +546,14 @@
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ TRACE(ole,"(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
- FIXME(ole,"(%p,%d,%p),stub!\n",This,fForward,ppenumMoniker);
- return E_NOTIMPL;
+ if (ppenumMoniker == NULL)
+ return E_POINTER;
+ *ppenumMoniker = NULL;
+
+ return S_OK;
}
/******************************************************************************
@@ -294,10 +561,36 @@
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
- FIXME(ole,"(%p,%p),stub!\n",This,pmkOtherMoniker);
- return E_NOTIMPL;
+ CLSID clsid;
+ LPOLESTR dispName1,dispName2;
+ IBindCtx* bind;
+ HRESULT res;
+
+ TRACE(ole,"(%p,%p)\n",iface,pmkOtherMoniker);
+
+ if (pmkOtherMoniker==NULL)
+ return S_FALSE;
+
+ /* This method returns S_OK if both monikers are item monikers and their display names are */
+ /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */
+
+ IMoniker_GetClassID(pmkOtherMoniker,&clsid);
+
+ if (!IsEqualCLSID(&clsid,&CLSID_ItemMoniker))
+ return S_FALSE;
+
+ res=CreateBindCtx(0,&bind);
+ if (FAILED(res))
+ return res;
+
+ IMoniker_GetDisplayName(iface,bind,NULL,&dispName1);
+ IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2);
+
+ if (lstrcmpW(dispName1,dispName2)!=0)
+ return S_FALSE;
+
+ return S_OK;
}
/******************************************************************************
@@ -305,34 +598,126 @@
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
- FIXME(ole,"(%p,%p),stub!\n",This,pdwHash);
- return E_NOTIMPL;
+ int h = 0,i,skip,len;
+ int off = 0;
+ LPOLESTR val;
+
+ if (pdwHash==NULL)
+ return E_POINTER;
+
+ 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];
+ }
+ }
+
+ *pdwHash=h;
+
+ return S_OK;
}
/******************************************************************************
* ItemMoniker_IsRunning
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
+HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ IRunningObjectTable* rot;
+ HRESULT res;
+ IOleItemContainer *poic=0;
+ ICOM_THIS(ItemMonikerImpl,iface);
- FIXME(ole,"(%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,pmkNewlyRunning);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
+
+ /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
+ /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
+ if (pmkToLeft==NULL)
+ if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
+ return S_OK;
+ else {
+ if (pbc==NULL)
+ return E_POINTER;
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+ if (FAILED(res))
+ return res;
+
+ res = IRunningObjectTable_IsRunning(rot,iface);
+
+ IRunningObjectTable_Release(rot);
+ }
+ else{
+
+ /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
+ /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
+ /* passing the string contained within this moniker. */
+
+ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
+
+ if (SUCCEEDED(res)){
+
+ res=IOleItemContainer_IsRunning(poic,This->itemName);
+
+ IOleItemContainer_Release(poic);
+ }
+ }
+
+ return res;
}
/******************************************************************************
* ItemMoniker_GetTimeOfLastChange
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
- FILETIME* pFileTime)
+HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ FILETIME* pItemTime)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ IRunningObjectTable* rot;
+ HRESULT res;
+ IMoniker *compositeMk;
- FIXME(ole,"(%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,pFileTime);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
+
+ if (pItemTime==NULL)
+ return E_INVALIDARG;
+
+ /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
+ if (pmkToLeft==NULL)
+
+ return MK_E_NOTBINDABLE;
+ else {
+
+ /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
+ /* the time of last change. If the object is not in the ROT, the method calls */
+ /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
+
+ res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
+
+ res=IBindCtx_GetRunningObjectTable(pbc,&rot);
+
+ if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
+
+ res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
+
+ IMoniker_Release(compositeMk);
+}
+
+ return res;
}
/******************************************************************************
@@ -340,22 +725,36 @@
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ TRACE(ole,"(%p,%p)\n",iface,ppmk);
- FIXME(ole,"(%p,%p),stub!\n",This,ppmk);
- return E_NOTIMPL;
+ if (ppmk==NULL)
+ return E_POINTER;
+
+ return CreateAntiMoniker(ppmk);
}
/******************************************************************************
* ItemMoniker_CommonPrefixWith
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,
- IMoniker** ppmkPrefix)
+HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ DWORD mkSys;
+ 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 */
- FIXME(ole,"(%p,%p,%p),stub!\n",This,pmkOther,ppmkPrefix);
- return E_NOTIMPL;
+ if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
+
+ *ppmkPrefix=iface;
+
+ IMoniker_AddRef(iface);
+
+ return MK_S_US;
+ }
+ else
+ /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
+ /* the case where the other moniker is a generic composite. */
+ return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
}
/******************************************************************************
@@ -363,34 +762,85 @@
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ TRACE(ole,"(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
- FIXME(ole,"(%p,%p,%p),stub!\n",This,pmOther,ppmkRelPath);
- return E_NOTIMPL;
+ if (ppmkRelPath==NULL)
+ return E_POINTER;
+
+ *ppmkRelPath=0;
+
+ return MK_E_NOTBINDABLE;
}
/******************************************************************************
* ItemMoniker_GetDisplayName
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
+HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ ICOM_THIS(ItemMonikerImpl,iface);
- FIXME(ole,"(%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,ppszDisplayName);
- return E_NOTIMPL;
+ TRACE(ole,"(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
+
+ if (ppszDisplayName==NULL)
+ return E_POINTER;
+
+ if (pmkToLeft!=NULL){
+ return E_INVALIDARG;
+ }
+
+ *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
+
+ if (*ppszDisplayName==NULL)
+ return E_OUTOFMEMORY;
+
+ lstrcpyW(*ppszDisplayName,This->itemDelimiter);
+ lstrcatW(*ppszDisplayName,This->itemName);
+
+ return S_OK;
}
/******************************************************************************
* ItemMoniker_ParseDisplayName
******************************************************************************/
-HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft,
- LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
+HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
+ IBindCtx* pbc,
+ IMoniker* pmkToLeft,
+ LPOLESTR pszDisplayName,
+ ULONG* pchEaten,
+ IMoniker** ppmkOut)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ IOleItemContainer* poic=0;
+ IParseDisplayName* ppdn=0;
+ LPOLESTR displayName;
+ HRESULT res;
+ ICOM_THIS(ItemMonikerImpl,iface);
- FIXME(ole,"(%p,%p,%p,%p,%p,%p),stub!\n",This,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
- return E_NOTIMPL;
+ /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
+ if (pmkToLeft==NULL)
+
+ return MK_E_SYNTAX;
+
+ else{
+ /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
+ /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ /* name to IParseDisplayName::ParseDisplayName */
+ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
+
+ if (SUCCEEDED(res)){
+
+ res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
+
+ res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
+
+ res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
+
+ IOleItemContainer_Release(poic);
+ IParseDisplayName_Release(ppdn);
+ }
+}
+ return res;
}
/******************************************************************************
@@ -398,16 +848,70 @@
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
- ItemMonikerImpl* This=(ItemMonikerImpl*)iface;
+ TRACE(ole,"(%p,%p)\n",iface,pwdMksys);
- FIXME(ole,"(%p,%p),stub!\n",This,pwdMksys);
+ if (!pwdMksys)
+ return E_POINTER;
+
+ (*pwdMksys)=MKSYS_ITEMMONIKER;
+
+ return S_OK;
+}
+
+/*******************************************************************************
+ * ItemMonikerIROTData_QueryInterface
+ *******************************************************************************/
+HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
+{
+
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",iface,riid,ppvObject);
+
+ return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
+}
+
+/***********************************************************************
+ * ItemMonikerIROTData_AddRef
+ */
+ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return ItemMonikerImpl_AddRef(This);
+}
+
+/***********************************************************************
+ * ItemMonikerIROTData_Release
+ */
+ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
+{
+ ICOM_THIS_From_IROTData(IMoniker, iface);
+
+ TRACE(ole,"(%p)\n",iface);
+
+ return ItemMonikerImpl_Release(This);
+}
+
+/******************************************************************************
+ * ItemMonikerIROTData_GetComparaisonData
+ ******************************************************************************/
+HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
+ BYTE* pbData,
+ ULONG cbMax,
+ ULONG* pcbData)
+{
+ FIXME(ole,"(),stub!\n");
return E_NOTIMPL;
}
/******************************************************************************
* CreateItemMoniker16 [OLE2.28]
******************************************************************************/
-HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk){// [in] pathname [out] new moniker object
+HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk)
+{
FIXME(ole,"(%s,%p),stub!\n",lpszDelim,ppmk);
*ppmk = NULL;
@@ -415,13 +919,13 @@
}
/******************************************************************************
- * CreateItemMoniker32 [OLE32.55]
+ * CreateItemMoniker [OLE.55]
******************************************************************************/
HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
{
-
ItemMonikerImpl* newItemMoniker = 0;
HRESULT hr = S_OK;
+ IID riid=IID_IMoniker;
TRACE(ole,"(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
@@ -432,10 +936,11 @@
hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
- if (FAILED(hr))
- return hr;
+ if (FAILED(hr)){
- hr = ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);
-
+ HeapFree(GetProcessHeap(),0,newItemMoniker);
return hr;
+ }
+
+ return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);
}
diff --git a/ole/moniker.c b/ole/moniker.c
index aa0dc46..44c968d 100644
--- a/ole/moniker.c
+++ b/ole/moniker.c
@@ -5,27 +5,468 @@
* Copyright 1999 Noomen Hamza
*/
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
#include <assert.h>
#include "winerror.h"
#include "wine/obj_moniker.h"
#include "debug.h"
+#include "heap.h"
+
+#define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
+
+/* define the structure of the running object table elements */
+typedef struct RunObject{
+
+ IUnknown* pObj; /* points on a running object*/
+ IMoniker* pmkObj; /* points on a moniker who identifies this object */
+ FILETIME lastModifObj;
+ DWORD identRegObj; /* registration key relative to this object */
+ DWORD regTypeObj; /* registration type : strong or weak */
+}RunObject;
+
+/* define de RunningObjectTableImpl structure */
+typedef struct RunningObjectTableImpl{
+
+ ICOM_VTABLE(IRunningObjectTable)* lpvtbl;
+ ULONG ref;
+
+ RunObject* runObjTab; /* pointe to the first object in the table */
+ DWORD runObjTabSize; /* current table size */
+ DWORD runObjTabLastIndx; /* first free index element in the table. */
+ DWORD runObjTabRegister; /* registration key of the next registred object */
+
+} RunningObjectTableImpl;
+
+RunningObjectTableImpl* runningObjectTableInstance=0;
+
+/* IRunningObjectTable prototipe functions : */
+/* IUnknown functions*/
+static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
+static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
+static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
+/* IRunningObjectTable functions */
+static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
+static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
+static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
+static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
+static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
+static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
+static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
+/* Local functions*/
+HRESULT WINAPI RunningObjectTableImpl_Initialize();
+HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
+HRESULT WINAPI RunningObjectTableImpl_Destroy();
+HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
+
+/* Virtual function table for the IRunningObjectTable class. */
+static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
+{
+ RunningObjectTableImpl_QueryInterface,
+ RunningObjectTableImpl_AddRef,
+ RunningObjectTableImpl_Release,
+ RunningObjectTableImpl_Register,
+ RunningObjectTableImpl_Revoke,
+ RunningObjectTableImpl_IsRunning,
+ RunningObjectTableImpl_GetObject,
+ RunningObjectTableImpl_NoteChangeTime,
+ RunningObjectTableImpl_GetTimeOfLastChange,
+ RunningObjectTableImpl_EnumRunning
+};
+
+/***********************************************************************
+ * RunningObjectTable_QueryInterface
+ */
+HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
+{
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
+
+ /* validate arguments*/
+ if (This==0)
+ return CO_E_NOTINITIALIZED;
+
+ if (ppvObject==0)
+ return E_INVALIDARG;
+
+ *ppvObject = 0;
+
+ if (IsEqualIID(&IID_IUnknown, riid))
+ *ppvObject = (IRunningObjectTable*)This;
+ else
+ if (IsEqualIID(&IID_IRunningObjectTable, riid))
+ *ppvObject = (IRunningObjectTable*)This;
+
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ RunningObjectTableImpl_AddRef(iface);
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_AddRef
+ */
+ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
+{
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ return ++(This->ref);
+}
+
+/***********************************************************************
+ * RunningObjectTable_Initialize
+ */
+HRESULT WINAPI RunningObjectTableImpl_Destroy()
+{
+ TRACE(ole,"()\n");
+
+ if (runningObjectTableInstance==NULL)
+ return E_INVALIDARG;
+
+ /* free the ROT table memory */
+ HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
+
+ /* free the ROT structure memory */
+ HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_Release
+ */
+ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
+{
+ DWORD i;
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p)\n",This);
+
+ This->ref--;
+
+ /* unitialize ROT structure if there's no more reference to it*/
+ if (This->ref==0){
+
+ /* release all registred objects */
+ for(i=0;i<This->runObjTabLastIndx;i++)
+ {
+ if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
+ IUnknown_Release(This->runObjTab[i].pObj);
+
+ IMoniker_Release(This->runObjTab[i].pmkObj);
+ }
+ /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
+ * when RunningObjectTableImpl_UnInitialize function is called
+ */
+
+ /* there's no more elements in the table */
+ This->runObjTabRegister=0;
+ This->runObjTabLastIndx=0;
+
+ return 0;
+ }
+
+ return This->ref;
+}
+
+/***********************************************************************
+ * RunningObjectTable_Initialize
+ */
+HRESULT WINAPI RunningObjectTableImpl_Initialize()
+{
+ TRACE(ole,"()\n");
+
+ /* create the unique instance of the RunningObjectTableImpl structure */
+ runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
+
+ if (runningObjectTableInstance == 0)
+ return E_OUTOFMEMORY;
+
+ /* initialize the virtual table function */
+ runningObjectTableInstance->lpvtbl = &VT_RunningObjectTableImpl;
+
+ /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
+ /* the ROT refered many times not in the same time (all the objects in the ROT will */
+ /* be removed evry time the ROT is removed ) */
+ runningObjectTableInstance->ref = 1;
+
+ /* allocate space memory for the table witch contains all the running objects */
+ runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
+
+ if (runningObjectTableInstance->runObjTab == NULL)
+ return E_OUTOFMEMORY;
+
+ runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
+ runningObjectTableInstance->runObjTabRegister=0;
+ runningObjectTableInstance->runObjTabLastIndx=0;
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_UnInitialize
+ */
+HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
+{
+ TRACE(ole,"()\n");
+
+ if (runningObjectTableInstance==NULL)
+ return E_POINTER;
+
+ RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
+
+ RunningObjectTableImpl_Destroy();
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_Register
+ */
+HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
+ DWORD grfFlags, /* Registration options */
+ IUnknown *punkObject, /* Pointer to the object being registered */
+ IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
+ DWORD *pdwRegister) /* Pointer to the value identifying the registration */
+{
+ HRESULT res=S_OK;
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
+
+ /* there's only tow types of register : strong and or weak registration (only one must be passed on parameter) */
+ if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
+ (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
+ (grfFlags) )
+ return E_INVALIDARG;
+
+ if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
+ return E_INVALIDARG;
+
+ /* verify if the object to be registred was registred befor */
+ if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
+ res = MK_S_MONIKERALREADYREGISTERED;
+
+ /* put the new registred object in the first free element in the table */
+ This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
+ This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
+ This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
+ This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
+ CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
+
+ /* gives a registration identifier to the registred object*/
+ (*pdwRegister)= This->runObjTabRegister;
+
+ if (This->runObjTabRegister == 0xFFFFFFFF){
+
+ FIXME(ole,"runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
+ return E_FAIL;
+}
+ This->runObjTabRegister++;
+ This->runObjTabLastIndx++;
+
+ if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
+
+ This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
+ This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
+ This->runObjTabSize * sizeof(RunObject));
+ if (!This->runObjTab)
+ return E_OUTOFMEMORY;
+ }
+ /* add a reference to the object in the strong registration case */
+ if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
+ IUnknown_AddRef(punkObject);
+
+ IMoniker_AddRef(pmkObjectName);
+
+ return res;
+}
+
+/***********************************************************************
+ * RunningObjectTable_Revoke
+ */
+HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
+ DWORD dwRegister) /* Value identifying registration to be revoked*/
+{
+
+ DWORD index,j;
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p,%ld)\n",This,dwRegister);
+
+ /* verify if the object to be revoked was registred befor or not */
+ if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
+
+ return E_INVALIDARG;
+
+ /* release the object if it was registred with a strong registrantion option */
+ if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
+ IUnknown_Release(This->runObjTab[index].pObj);
+
+ IMoniker_Release(This->runObjTab[index].pmkObj);
+
+ /* remove the object from the table */
+ for(j=index; j<This->runObjTabLastIndx-1; j++)
+ This->runObjTab[j]= This->runObjTab[j+1];
+
+ This->runObjTabLastIndx--;
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_IsRunning
+ */
+HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
+ IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
+{
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p,%p)\n",This,pmkObjectName);
+
+ return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
+}
+
+/***********************************************************************
+ * RunningObjectTable_GetObject
+ */
+HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
+ IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
+ IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
+{
+ DWORD index;
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
+
+ if (ppunkObject==NULL)
+ return E_POINTER;
+
+ *ppunkObject=0;
+
+ /* verify if the object was registred befor or not */
+ if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
+ return MK_E_UNAVAILABLE;
+
+ /* add a reference to the object then set output object argument */
+ IUnknown_AddRef(This->runObjTab[index].pObj);
+ *ppunkObject=This->runObjTab[index].pObj;
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_NoteChangeTime
+ */
+HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
+ DWORD dwRegister, /* Value identifying registration being updated */
+ FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
+{
+ DWORD index=-1;
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p,%ld,%p)\n",This,dwRegister,pfiletime);
+
+ /* verify if the object to be changed was registred befor or not */
+ if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
+ return E_INVALIDARG;
+
+ /* set the new value of the last time change */
+ This->runObjTab[index].lastModifObj= (*pfiletime);
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_GetTimeOfLastChange
+ */
+HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
+ IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
+ FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
+{
+ DWORD index=-1;
+ ICOM_THIS(RunningObjectTableImpl,iface);
+
+ TRACE(ole,"(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
+
+ if (pmkObjectName==NULL || pfiletime==NULL)
+ return E_INVALIDARG;
+
+ /* verify if the object was registred befor or not */
+ if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
+ return MK_E_UNAVAILABLE;;
+
+ (*pfiletime)= This->runObjTab[index].lastModifObj;
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * RunningObjectTable_EnumRunning
+ */
+HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
+ IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
+{
+ FIXME(ole,"(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
+ return E_NOTIMPL;
+}
+
+/***********************************************************************
+ * GetObjectIndex
+ */
+HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
+ DWORD identReg,
+ IMoniker* pmk,
+ DWORD *indx)
+{
+
+ DWORD i;
+
+ TRACE(ole,"(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
+
+ if (pmk!=NULL)
+ /* search object identified by a moniker*/
+ for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
+ else
+ /* search object identified by a register identifier*/
+ for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
+
+ if (i==This->runObjTabLastIndx) return S_FALSE;
+
+ if (indx != NULL) *indx=i;
+
+ return S_OK;
+}
/******************************************************************************
* GetRunningObjectTable16 [OLE2.30]
*/
-HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPVOID *pprot) {
+HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPVOID *pprot)
+{
FIXME(ole,"(%ld,%p),stub!\n",reserved,pprot);
- return E_FAIL;
+ return E_NOTIMPL;
}
-
/***********************************************************************
- * GetRunningObjectTable32 (OLE2.73)
+ * GetRunningObjectTable (OLE2.73)
*/
-HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPVOID *pprot) {
- FIXME(ole,"(%ld,%p),stub!\n",reserved,pprot);
- return E_FAIL;
+HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPVOID *pprot)
+{
+ IID riid=IID_IRunningObjectTable;
+ HRESULT res;
+
+ TRACE(ole,"()\n");
+
+ if (reserved!=0)
+ return E_UNEXPECTED;
+
+ if(runningObjectTableInstance==NULL)
+ return CO_E_NOTINITIALIZED;
+
+ res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
+
+ return res;
}
diff --git a/ole/storage32.c b/ole/storage32.c
index dfecf14..cc30781 100644
--- a/ole/storage32.c
+++ b/ole/storage32.c
@@ -25,6 +25,7 @@
#include "windef.h"
#include "storage32.h"
+#include "ole2.h"
#define FILE_BEGIN 0
@@ -5159,6 +5160,83 @@
return hRes;
}
+/*******************************************************************************************
+ * ReadClassStg
+ *
+ * This method reads the CLSID previously written to a storage object with the WriteClassStg.
+ */
+HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid){
+
+ STATSTG pstatstg;
+ HRESULT hRes;
+
+ TRACE(ole,"()\n");
+
+ if(pclsid==NULL)
+ return E_POINTER;
+ /*
+ * read a STATSTG structure (contains the clsid) from the storage
+ */
+ hRes=IStorage_Stat(pstg,&pstatstg,STATFLAG_DEFAULT);
+
+ if(SUCCEEDED(hRes))
+ *pclsid=pstatstg.clsid;
+
+ return hRes;
+}
+
+/*************************************************************************************
+ * OleLoadFromStream
+ *
+ * This function loads an object from stream
+ */
+HRESULT WINAPI OleLoadFromStream(IStream *pStm,REFIID iidInterface,void** ppvObj)
+{
+ CLSID clsid;
+ HRESULT res;
+
+ FIXME(ole,"(),stub!\n");
+
+ res=ReadClassStm(pStm,&clsid);
+
+ if (SUCCEEDED(res)){
+
+ res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj);
+
+ if (SUCCEEDED(res))
+
+ res=IPersistStream_Load((IPersistStream*)ppvObj,pStm);
+ }
+
+ return res;
+}
+
+/************************************************************************************************
+ * OleSaveToStream
+ *
+ * This function saves an object with the IPersistStream interface on it to the specified stream
+ */
+HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm)
+{
+
+ CLSID clsid;
+ HRESULT res;
+
+ TRACE(ole,"(%p,%p)\n",pPStm,pStm);
+
+ res=IPersistStream_GetClassID(pPStm,&clsid);
+
+ if (SUCCEEDED(res)){
+
+ res=WriteClassStm(pStm,&clsid);
+
+ if (SUCCEEDED(res))
+
+ res=IPersistStream_Save(pPStm,pStm,FALSE);
+ }
+
+ return res;
+}
/****************************************************************************
* This method validate a STGM parameter that can contain the values below
@@ -5306,7 +5384,7 @@
*/
static DWORD GetAccessModeFromSTGM(DWORD stgm)
{
- DWORD dwDesiredAccess = 0;
+ DWORD dwDesiredAccess = GENERIC_READ;
BOOL bSTGM_WRITE = ((stgm & STGM_WRITE) == STGM_WRITE);
BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE);
BOOL bSTGM_READ = ! (bSTGM_WRITE || bSTGM_READWRITE);
diff --git a/relay32/ole32.spec b/relay32/ole32.spec
index 7a0bed8..e0e19d1 100644
--- a/relay32/ole32.spec
+++ b/relay32/ole32.spec
@@ -51,12 +51,12 @@
48 stub CoUnloadingWOW
49 stub CoUnmarshalHresult # stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
50 stub CoUnmarshalInterface # stdcall (ptr ptr ptr) return 0,ERR_NOTIMPLEMENTED
- 51 stub CreateAntiMoniker # stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
+ 51 stdcall CreateAntiMoniker(ptr) CreateAntiMoniker
52 stdcall CreateBindCtx(long ptr) CreateBindCtx
53 stub CreateDataAdviseHolder # stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
54 stub CreateDataCache # stdcall (ptr ptr ptr ptr) return 0,ERR_NOTIMPLEMENTED
55 stdcall CreateFileMoniker(wstr ptr) CreateFileMoniker
- 56 stub CreateGenericComposite # stdcall (ptr ptr ptr) return 0,ERR_NOTIMPLEMENTED
+ 56 stdcall CreateGenericComposite(ptr ptr ptr) CreateGenericComposite
57 stub CreateILockBytesOnHGlobal # stdcall (ptr long ptr) return 0,ERR_NOTIMPLEMENTED
58 stdcall CreateItemMoniker(wstr wstr ptr) CreateItemMoniker
59 stdcall CreateOleAdviseHolder(ptr) CreateOleAdviseHolder
@@ -67,7 +67,7 @@
64 stub DllGetClassObjectWOW
65 stdcall DoDragDrop(ptr ptr long ptr) DoDragDrop
66 stub EnableHookObject
- 67 stub GetClassFile
+ 67 stdcall GetClassFile(ptr ptr) GetClassFile
68 stub GetConvertStg
69 stub GetDocumentBitStg
70 stub GetHGlobalFromILockBytes
@@ -134,8 +134,8 @@
131 stdcall OleUninitialize() OleUninitialize
132 stub OpenOrCreateStream
133 stub ProgIDFromCLSID
-134 stub ReadClassStg
-135 stub ReadClassStm
+134 stdcall ReadClassStg(ptr ptr) ReadClassStg
+135 stdcall ReadClassStm(ptr ptr) ReadClassStm
136 stub ReadFmtUserTypeStg
137 stub ReadOleStg
138 stub ReadStringStream
@@ -159,7 +159,7 @@
156 stub UtGetDvtd16Info
157 stub UtGetDvtd32Info
158 stdcall WriteClassStg(ptr ptr) WriteClassStg
-159 stub WriteClassStm
+159 stdcall WriteClassStm(ptr ptr) WriteClassStm
160 stub WriteFmtUserTypeStg
161 stub WriteOleStg
162 stub WriteStringStream