Jeff Latimer wrote:

This is the first installment of the implementation of MkParseDisplayName. I would like feed back on style and usage.


Ok, I'll happily add comments on the patch.


I think the implementation of the EnumMoniker interface looks ok. Comments appreciated.


Jeff Latimer

------------------------------------------------------------------------

Index: moniker.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/moniker.c,v
retrieving revision 1.38
diff -u -r1.38 moniker.c
--- moniker.c   13 Dec 2004 21:19:02 -0000      1.38
+++ moniker.c   28 Mar 2005 12:06:51 -0000
@@ -29,7 +29,6 @@

#include <assert.h>
#include <stdarg.h>
-#include <string.h>

#define COBJMACROS

@@ -38,6 +37,7 @@
#include "winbase.h"
#include "winuser.h"
#include "wtypes.h"
+#include "wine/unicode.h"
#include "wine/debug.h"
#include "ole2.h"

@@ -50,11 +50,11 @@
/* 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 */
+    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 */
+    DWORD      identRegObj;    /* registration key relative to this object */
+    DWORD      regTypeObj;     /* registration type : strong or weak */
}RunObject;

/* define the RunningObjectTableImpl structure */
@@ -106,6 +106,55 @@
    RunningObjectTableImpl_EnumRunning
};

+/* define the EnumMonikerImpl structure */
+typedef struct EnumMonikerImpl{
+
+ IEnumMonikerVtbl *lpVtbl;
+ ULONG ref;
+
+ RunObject* TabMoniker; /* pointer to the first object in the table */
+ DWORD TabSize; /* current table size */
+ DWORD TabLastIndx; /* first free index element in the table. */



Since you asked for feedback on style, I'll say that you should try to keep the naming conventions consistent.


+ DWORD runObjTabRegister; /* registration key of the next registered object */
+ DWORD currentPos; /* enum position in the list */
+
+} EnumMonikerImpl;
+
+
+/* IEnumMoniker prototype functions : */
+/* IUnknown 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);
+/* IEnumMoniker 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);



If you put the vtable after the implementations of the functions then you don't need to declare the prototypes here.


+
+/* Local functions*/
+HRESULT WINAPI EnumMonikerImpl_Initialize(void);
+HRESULT WINAPI EnumMonikerImpl_CreateEnumROTMoniker(RunObject* runObjTab,
+ ULONG TabSize,
+ ULONG TabLastIndx,
+ ULONG currentPos,
+ IEnumMoniker ** ppenumMoniker);
+HRESULT WINAPI EnumMonikerImpl_UnInitialize(void);
+HRESULT WINAPI EnumMonikerImpl_Destroy(void);
+HRESULT WINAPI EnumMonikerImpl_GetObjectIndex(EnumMonikerImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);



Presumably, these should all be static since they are not used outside the file.


+
+/* Virtual function table for the IEnumMoniker class. */
+static IEnumMonikerVtbl VT_EnumMonikerImpl =
+{
+ EnumMonikerImpl_QueryInterface,
+ EnumMonikerImpl_AddRef,
+ EnumMonikerImpl_Release,
+ EnumMonikerImpl_Next,
+ EnumMonikerImpl_Skip,
+ EnumMonikerImpl_Reset,
+ EnumMonikerImpl_Clone
+};
+
/***********************************************************************
* RunningObjectTable_QueryInterface
*/
+/***********************************************************************
+ * EnumMonikerImpl_CreateEnumROTMoniker
+ * Used by EnumRunning to create the structure and EnumClone
+ * to copy the structure
+ */
+HRESULT WINAPI EnumMonikerImpl_CreateEnumROTMoniker(RunObject* TabMoniker,
+ ULONG TabSize,
+ ULONG TabLastIndx,
+ ULONG currentPos,
+ IEnumMoniker ** ppenumMoniker)
+{
+ int i;
+ if (currentPos > TabSize)
+ return E_INVALIDARG;
+
+ if (ppenumMoniker == 0)
+ return E_OUTOFMEMORY;



This should probably be E_INVALIDARG.

+
+ *ppenumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
+



if (!*ppenumMoniker) return E_OUTOFMEMORY;

+ void *vpThis=*ppenumMoniker;



Variable used just for changing types?!?!

+ EnumMonikerImpl* This=0;



Using NULL instead of 0 tends to make it clearer that you are using a pointer.


+ This=vpThis;



All of these variable declarations need moving to the top of the block.

+    TRACE("(%p)\n",This);
+    /* initialize the virtual table function */
+    This->lpVtbl = &VT_EnumMonikerImpl;
+
+    /* the initial reference is set to "1" because if set to "0" it will be 
not practis when */
+    /* the ROT referred many times not in the same time (all the objects in 
the ROT will */
+    /* be removed every time the ROT is removed ) */
+    This->ref = 1;                  /* set the ref count to one         */
+    This->currentPos=0;                     /* Set the list start posn to 
start */
+    This->TabSize=TabSize;          /* Need the same size table as ROT */
+    This->TabLastIndx=TabLastIndx;  /* end element */
+    
This->TabMoniker=HeapAlloc(GetProcessHeap(),0,This->TabSize*sizeof(RunObject));
+
+    if (This->TabMoniker==NULL) {
+        HeapFree(GetProcessHeap(), 0, This);
+        return E_OUTOFMEMORY;
+    }
+    for (i=0;i<This->TabLastIndx;i++){
+
+        This->TabMoniker[i]=TabMoniker[i];
+        IMoniker_AddRef(TabMoniker[i].pmkObj);
+    }
+
+    return S_OK;
}

/***********************************************************************
@@ -512,8 +621,180 @@
    return res;
}

+/***********************************************************************
+ * EnumMoniker_QueryInterface
+ */
+HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
+{
+ EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
+
+ TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
+
+ /* validate arguments */
+ if (This==0)
+ return CO_E_NOTINITIALIZED;


Remove this check. It is completely bogus.

+
+ if (ppvObject==0)
+ return E_INVALIDARG;
+
+ *ppvObject = 0;
+
+ if (IsEqualIID(&IID_IUnknown, riid))
+ *ppvObject = (IEnumMoniker*)This;
+ else
+ if (IsEqualIID(&IID_IEnumMoniker, riid))
+ *ppvObject = (IEnumMoniker*)This;
+
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ EnumMonikerImpl_AddRef(iface);
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * EnumMoniker_AddRef
+ */
+ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface)
+{
+ EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
+
+ TRACE("(%p)\n",This);
+
+ return InterlockedIncrement(&This->ref);
+}
+
+/***********************************************************************
+ * EnumMoniker_Destroy
+ */
+HRESULT WINAPI EnumMonikerImpl_Destroy()
+{
+ TRACE("(?)\n");
+
+// if (enumMonikerInstance==NULL)
+// return E_INVALIDARG;
+
+ /* free the enummoniker structure memory */
+// HeapFree(GetProcessHeap(),0,enumMonikerInstance);
+
+ return S_OK;
+}



You are not using this function, so remove it.

+
+/***********************************************************************
+ * EnumMoniker_release
+ */
+ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface)
+{
+ DWORD i;
+ EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
+ ULONG ref;
+
+ TRACE("(%p)\n",This);
+
+ if (This==0)
+ return E_INVALIDARG;



Another bogus This pointer check.

+
+ ref = InterlockedDecrement(&This->ref);
+
+ /* unitialize rot structure if there's no more reference to it*/
+ if (ref == 0) {
+
+ /* release all registered objects in Moniker list */
+ for(i=0;i<This->TabLastIndx;i++)
+ {
+ IMoniker_Release(This->TabMoniker[i].pmkObj);
+ }
+
+ /* there're no more elements in the table */
+
+ TRACE("(%p) Deleting\n",This);
+ HeapFree (GetProcessHeap(), 0, This->TabMoniker); // free Moniker list
+ HeapFree (GetProcessHeap(), 0, This); // free Enum Instance
+
+ }
+
+ return ref;
+}
+/***********************************************************************
+ * EnmumMoniker_Next
+ */
+HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface, ULONG celt, IMoniker** rgelt, ULONG * pceltFetched)
+{
+// DWORD i;
+// ULONG ref;



Remove these lines.

+
+ EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
+ TRACE("(%p) currentPos %d Tablastindx %d\n",This, (int)This->currentPos, (int)This->TabLastIndx);
+ ULONG i;
+
+ /* retrieve the requested number of moniker from the current position */
+ for(i=0;((This->currentPos < This->TabLastIndx) && (i < celt));i++)
+ rgelt[i]=(IMoniker*)This->TabMoniker[This->currentPos++].pmkObj;
+
+ if (pceltFetched!=NULL)
+ *pceltFetched= i;
+
+ if (i==celt)
+ return S_OK;
+ else
+ return S_FALSE;
+
+}
+
+/***********************************************************************
+ * EnmumMoniker_Skip
+ */
+HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface, ULONG celt)
+{
+ EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
+
+ TRACE("(%p)\n",This);
+ if (This==0)
+ return E_INVALIDARG;



Another bogus check. I'll stop commenting about these now, but you should remove all of them.


+
+ if ((This->currentPos+celt) >= This->TabLastIndx)
+ return S_FALSE;
+
+ This->currentPos+=celt;
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * EnmumMoniker_Reset
+ */
+HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface)
+{
+ EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
+ if (This==0)
+ return E_INVALIDARG;
+
+ This->currentPos = 0; /* set back to start of list */
+
+ TRACE("(%p)\n",This);
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * EnmumMoniker_Clone
+ */
+HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface, IEnumMoniker ** ppenum)
+{
+ EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
+ if (This==0)
+ return E_INVALIDARG;
+
+ TRACE("(%p)\n",This);
+ /* copy the enum structure */ + return EnumMonikerImpl_CreateEnumROTMoniker(This->TabMoniker, This->TabSize,
+ This->TabLastIndx, This->currentPos,
+ ppenum);
+}
+
/******************************************************************************
- * OleRun [EMAIL PROTECTED]
+ * olerun [EMAIL PROTECTED]



The name of the function really is OleRun, not olerun. Feel free to submit the change from OLE32->ole32 in another patch, but make sure you change every instance of this.


 */
HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
{
@@ -523,22 +804,142 @@

  ret = 
IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
  if (ret)
-       return 0; /* Appears to return no error. */
+       return 0; /* appears to return no error. */
  ret  = IRunnableObject_Run(runable,NULL);
  IRunnableObject_Release(runable);
  return ret;
}

/******************************************************************************
- * MkParseDisplayName [EMAIL PROTECTED]
+ * MkParseDisplayName [EMAIL PROTECTED]
*/
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
- FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
+ int char_cnt = 0;
+ int usernamelen = 0;
+ HRESULT rc =0;
+ WCHAR username [2048]; // workspace to parse name into



Please don't use C99 comments. Use "/* comment */" instead.

+ IRunningObjectTable * pprot;
+ IEnumMoniker *spEM;
+ IMoniker * spMoniker;
+// IUnknown * spUnk;
+ LPMALLOC * ppMalloc;
+ TRACE("(%p)\n", pbc);
+ rc = CoGetMalloc(1, (LPMALLOC *) &ppMalloc);



You leak references to ppMalloc everywhere. Is it really necessary to use CoGetMalloc?


    if (!(IsValidInterface((LPUNKNOWN) pbc)))
        return E_INVALIDARG;
+    usernamelen = (int) lstrlenW(szUserName);  // overall string len
+

+ if (szUserName[char_cnt] == (WCHAR) '@') { // This is a progid not a file name
+ FIXME("Progid not implemented\n");
+ return MK_E_SYNTAX;
+ } else {
+ char_cnt = 0;
+ if (szUserName[char_cnt+1] == ':') {
+ if ((szUserName[char_cnt] < 'a' || szUserName[char_cnt] > 'z') &&
+ (szUserName[char_cnt] < 'A' || szUserName[char_cnt] > 'Z')) {
+ FIXME("bad drive %c\n", szUserName[char_cnt]);



This should be an ERR instead of FIXME, unless there is something you haven't implemented. If that is the case, please add a comment here as to what that could be.


+ return MK_E_SYNTAX;
+ }
+ username[0] = (WCHAR)szUserName[0];
+ username[1] = szUserName[1];
+ char_cnt += 2; // point past drive spec
+ }
+ for (; szUserName[char_cnt] != 0x0 && // until end of string or
+ szUserName[char_cnt] != '!' ; char_cnt++) { // end of component
+ FIXME("%c",szUserName[char_cnt]);



Is this just a debugging statement?

+ if (szUserName[char_cnt] == '\\' && szUserName[char_cnt+1] == '\\') {
+ FIXME("badchar %c\n",szUserName[char_cnt]);
+ return MK_E_SYNTAX;
+ }
+ if (szUserName[char_cnt] == '/' ||
+ szUserName[char_cnt] == '?' ||
+ szUserName[char_cnt] == '<' ||
+ szUserName[char_cnt] == '>' ||
+ szUserName[char_cnt] == '*' ||
+ szUserName[char_cnt] == '|' ||
+ szUserName[char_cnt] == ':')
+ {
+ FIXME("badchar %c\n",szUserName[char_cnt]);
+ return MK_E_SYNTAX;
+ }
+ username[char_cnt] = (WCHAR) szUserName[char_cnt];



Shouldn't need a cast here.

+ }
+ FIXME("\n");
+ username[char_cnt] = 0x0; // terminate the substring
+ TRACE("File name to be converted to Moniker: %s\n", debugstr_w(username));
+ rc = IBindCtx_GetRunningObjectTable(pbc, &pprot);
+ if (!SUCCEEDED(rc))
+ {
+ ERR("IBindCtx_GetRunningObjectTable failed %04x\n", (int) rc);



This should be:

+           ERR("IBindCtx_GetRunningObjectTable failed 0x%08lx\n", rc);


+ return MK_E_SYNTAX;
+ }
+ rc = IRunningObjectTable_EnumRunning(pprot, &spEM);
+ TRACE("IRunningObjectTable_EnumRunning rc:%04x %p\n", (int)rc, spEM);


+ if (SUCCEEDED(rc))
+ {
+ rc = MK_E_NOOBJECT;
+ while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK) &&
+ (*ppmk ==NULL)) + {
+ WCHAR *szDisplayn=NULL;
+ rc=IMoniker_GetDisplayName(spMoniker, pbc, NULL, + (LPOLESTR*) &szDisplayn);
+ TRACE("Display Name %s for Moniker %p\n", debugstr_w(szDisplayn), spMoniker);
+ if (SUCCEEDED(rc)) + {
+ TRACE("IMoniker_GetDisplayName succeeded, rc %08x ROT Name:%s, New name:%s\n", + (int)rc, debugstr_w(szDisplayn), debugstr_w(username));
+ if (0==strcmpiW((WCHAR *)szDisplayn, (WCHAR *)username))
+ {
+ TRACE("is Equal %p\n", spMoniker);
+ *ppmk = spMoniker; // we already have the Moniker, so use it
+ IMoniker_AddRef(spMoniker); // say we are reusing this Moniker
+ }
+ else
+ TRACE("Not Equal\n");
+
+ CoTaskMemFree(szDisplayn);
+ }
+ }
+// rc = IRunningObjectTable_GetObject(pprot, spMoniker, &spUnk);
+// if (!SUCCEEDED(rc)) +// TRACE("ok\n");
+ IEnumMoniker_Release(spEM); // Free Enum interface
+ IRunningObjectTable_Release(pprot); // Decrement ROT count
+ pprot = NULL; // Finished with ROT pointer
+ }
+ else
+ ERR("IRunningObjectTable_EnumRunning failed %04x\n", (int ) rc);
+
+ if (*ppmk == NULL)
+ {
+ rc = CreateFileMoniker(username, ppmk); // convert to moniker
+ if (SUCCEEDED(rc))
+ {
+ *pchEaten = (int) char_cnt;
+ if (usernamelen > char_cnt) // there is more to do and not implemented
+ {
+ TRACE("Username len %i exceeds parsed text %i\n", usernamelen, char_cnt);



This should be a FIXME then.

+ return MK_E_SYNTAX;
+ } + TRACE(" CreateFileMoniker Succeeded %04x\n", (int) rc);
+ return (S_OK);
+ } else
+ {
+ TRACE("CreateFileMoniker Failed %04x\n", (int) rc);



ERR

+ return(rc);
+ }
+ }
+ else
+ {
+ *pchEaten = (int) char_cnt;
+ TRACE(" Reused Moniker %p\n", *ppmk);
+ return (S_OK); + } + }
return MK_E_SYNTAX;
}


Index: Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ole32/Makefile.in,v
retrieving revision 1.43
diff -u -r1.43 Makefile.in
--- Makefile.in 17 Mar 2005 20:50:35 -0000 1.43
+++ Makefile.in 28 Mar 2005 12:06:52 -0000
@@ -5,7 +5,7 @@
VPATH = @srcdir@
MODULE = ole32.dll
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
-EXTRALIBS = -luuid $(LIBUNICODE)
+EXTRALIBS = -luuid $(LIBUNICODE)


C_SRCS = \
antimoniker.c \



Useless whitespace only change.

Index: tests/moniker.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/tests/moniker.c,v
retrieving revision 1.2
diff -u -r1.2 moniker.c
--- tests/moniker.c     28 Jan 2005 12:39:13 -0000      1.2
+++ tests/moniker.c     28 Mar 2005 12:06:56 -0000
@@ -22,40 +22,166 @@
#define COBJMACROS

#include <stdarg.h>
+//#include <wchar.h>



Remove this line.


#include "windef.h" #include "winbase.h" #include "objbase.h" +#include "objidl.h" #include "comcat.h"

#include "wine/test.h"

#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 
0x%08lx\n", hr)

+LPTSTR * prt(HRESULT hr, LPTSTR * lpMsgBuf);



Not used anywhere.

+
static void test_MkParseDisplayName()
{
IBindCtx * pbc = NULL;
HRESULT hr;
- IMoniker * pmk = NULL;
ULONG eaten;
- IUnknown * object = NULL;
+ int cnt;
+
/* CLSID of My Computer */
- static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
+ static const WCHAR wszDisplayName1[] = {'@','c','l','s','i','d',':',
+ '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};



Does "clsid:..." without the "@" still work? I'd prefer to see that test still in there.


+
+ hr = CreateBindCtx(0, &pbc);
+ ok_ole_success(hr, CreateBindCtx);
+ IMoniker *pmk1 = NULL;
+ hr = MkParseDisplayName(pbc, wszDisplayName1, &eaten, &pmk1);
+ todo_wine { ok(hr==0x800401e4, "MkParseDisplayName - Progid not implemented hr=%08x\n", (int) hr); }



MK_E_SYNTAX. See the ok_ole_success macro for how to print out HRESULTs without casts.


+
+    IBindCtx_Release(pbc);
+
+    /* A bad drive */
+    static const WCHAR wszDisplayName2[] = {'1',':','s','i','d',':',
        
'2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};

hr = CreateBindCtx(0, &pbc);
ok_ole_success(hr, CreateBindCtx);
+ IMoniker *pmk2=NULL;
+ hr = MkParseDisplayName(pbc, wszDisplayName2, &eaten, &pmk2);
+ ok(hr==0x800401e4, "MkParseDisplayName hr=%08x\n", (int) hr); +
+ IBindCtx_Release(pbc);


- hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
- todo_wine { ok_ole_success(hr, MkParseDisplayName); }
+ /* A good drive, bad char */
+ static const WCHAR wszDisplayName3[] = {'b',':','s','i','d',':',
+ '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
+
+ hr = CreateBindCtx(0, &pbc);
+ ok_ole_success(hr, CreateBindCtx);
+ IMoniker *pmk3=NULL;
+ hr = MkParseDisplayName(pbc, wszDisplayName3, &eaten, &pmk3);
+ todo_wine { ok(hr==0x800401e4, "MkParseDisplayName hr=%08x\n", (int) hr); }
+
+ IBindCtx_Release(pbc);
+
+ // Good file name
+ static const WCHAR wszDisplayName4[] = {'c',':','\\','w','i','n','d',
+ 'o','w','s','\\','f','r','E','d','.','e','x','E',0x0};
+
+ hr = CreateBindCtx(0, &pbc);
+ ok_ole_success(hr, CreateBindCtx);
+
+ IMoniker *pmk4=NULL;
+ eaten=0;
+ hr = MkParseDisplayName(pbc, wszDisplayName4, &eaten, &pmk4);
+ todo_wine { ok(hr==0, "MkParseDisplayName hr=%08x\n", (int) hr); }
+
+ IBindCtx_Release(pbc);
+
+ /* Good file name + item. This test is to see if the whole display
+ * name is consumed
+ */
+ static const WCHAR wszDisplayName5[] = {'c',':','\\','w','i','n','d',
+ 'o','w','s','\\','f','r','E','d','.','e','x','E','!','m','a','r','k',0x0};
+
+ hr = CreateBindCtx(0, &pbc);
+ ok_ole_success(hr, CreateBindCtx);
+
+ IMoniker *pmk5=NULL;
+ eaten=0;
+ hr = MkParseDisplayName(pbc, wszDisplayName5, &eaten, &pmk5);
+ ok(hr!=0, "MkParseDisplayName failed hr=%08x\n", (int) hr); + cnt = (int) lstrlenW(wszDisplayName5); // Get length of text
+ ok(eaten==cnt, "eaten %d string len %i\n", (int) eaten, cnt); // See if consiumed
+
+ IBindCtx_Release(pbc);
+
+ /* This test is to create a valid Moniker an then load a couple of + * entries into the ROT to test that MkParseDisplayName reuses the
+ * Moniker in the ROT. Currently using the EnumMoniker object as + * part of the Register call to satisfy the syntax
+ */
+
+ static const WCHAR wszDisplayName6[] = {'c',':','\\','P','r','o','g',
+ 'r','a','m',' ','F','i','l','e','s','\\','v','i','m','\\',
+ 'v','i','m','6','1','\\','g','v','i','m','.','e','x','e',0x0};
+ hr = CreateBindCtx(0, &pbc);
+ ok_ole_success(hr, CreateBindCtx);


- if (object)
- {
- hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
- ok_ole_success(hr, IMoniker_BindToObject);
+ IMoniker *pmk6=NULL;
+ eaten=0;
+ hr = MkParseDisplayName(pbc, wszDisplayName6, &eaten, &pmk6);
+ ok(hr==0, "MkParseDisplayName hr=%08x\n", (int) hr);
+ cnt = lstrlenW(wszDisplayName6); // Get length of text
+ ok(eaten==cnt, "eaten %d string len %i\n", (int) eaten, cnt); // See if consiumed
+
+ IRunningObjectTable * pprot=NULL;
+ hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
+ todo_wine { ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", (int) hr); }
+ IEnumMoniker *spEM1=NULL;
+ hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
+ todo_wine { ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", (int) hr);}
+ IUnknown *lpEM1;
+ hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
+ todo_wine { ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", (int) hr, lpEM1); }
+ DWORD pdwReg1=0;
+ DWORD grflags=0;
+ grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
+ hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk5, &pdwReg1); + todo_wine { ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", + (int) hr, pprot, (int) grflags, lpEM1, pmk5, (int) pdwReg1); }
+
+ DWORD pdwReg2=0;
+ grflags=0;
+ grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
+ hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk6, &pdwReg2); + ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", (int) hr,
+ pprot, (int) grflags, lpEM1, pmk6, (int) pdwReg2);
+
+ IEnumMoniker *spEM=NULL;
+ hr = IRunningObjectTable_EnumRunning(pprot, &spEM);
+ todo_wine { ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", (int) hr); }
+ // Now see if the we get the same moniker after querying the ROT
+ IMoniker *pmk61=NULL;
+ eaten=0;
+ hr = MkParseDisplayName(pbc, wszDisplayName6, &eaten, &pmk61);
+ ok(pmk6==pmk61, "Moniker should be the same address %p != %p\n", pmk6, pmk61); +
+ IRunningObjectTable_Revoke(pprot,pdwReg1);
+ IRunningObjectTable_Revoke(pprot,pdwReg2);
+ IEnumMoniker_Release(spEM);
+ IEnumMoniker_Release(spEM1);
+ IRunningObjectTable_Release(pprot);
+ if (pmk61!=NULL)
+ IMoniker_Release(pmk61);
+ if (pmk6!=NULL)
+ IMoniker_Release(pmk6);
+ if (pmk5!=NULL)
+ IMoniker_Release(pmk5);
+ if (pmk4!=NULL)
+ IMoniker_Release(pmk4);
+ if (pmk3!=NULL)
+ IMoniker_Release(pmk3);
+ if (pmk2!=NULL)
+ IMoniker_Release(pmk2);
+ if (pmk1!=NULL)
+ IMoniker_Release(pmk1);


-        IUnknown_Release(object);
-    }
    IBindCtx_Release(pbc);
}




Rob



Reply via email to