Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
March 2005
- 178 participants
- 1179 messages
Re: [dlls/msi/*] Strncpy elimination.
by Peter Berg Larsen
On Mon, 28 Mar 2005, Jakob Eriksson wrote:
> Good thing you sent these patches. I was just thinking, should I dig
> in? :-)
You could recheck them? I tend to get code blind, when having so many
cases that nearly are identical. As I said there are probably one two
places where I didnt get the sematic of the code. Especially look for
off-by-one (\0) when the replacement is a memcpy. I tend to do this,
because of codestyle, like:
> >+++ dlls/msi/dialog.c 26 Mar 2005 09:40:51 -0000
> >@@ -131,7 +131,7 @@
> > ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
> > if( !ret )
> > return ret;
> >- strncpyW( ret, p, len );
> >+ memcpy( ret, p, len*sizeof(WCHAR) );
> > ret[len-1] = 0;
> > return ret;
> > }
This memcpyies one element more than needed.. but seemed much nicer than
memcpy( ret, p, (len - 1)*sizeof(WHCAR);
I probably should have subtracted one from len, making it obvious
that this is a strdupW, like:
ret = HeapAlloc( GetProcessHeap(), 0, (len+1)*sizeof(WCHAR) );
memcpy( ret, p, len*sizeof(WCHAR) );
ret[len] = 0;
Peter
March 28, 2005
Re: Implementation of EnumMoniker and Partial impl on MkParseDisplayName
by Robert Shearman
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 [OLE32.@]
>+ * olerun [ole32.@]
>
>
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 [OLE32.@]
>+ * MkParseDisplayName [ole32.@]
> */
> 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
March 28, 2005
March 28, 2005
Re: [libs/wine/*] Strncpy elimination.
by Peter Berg Larsen
On 28 Mar 2005, Alexandre Julliard wrote:
> > Janitorial Task: Check the usage of strncpy/strncpyW.
>
> You can't use lstrcpynA in the libs/ directory, you have to stick to
> Unix APIs.
Ok, I just compiled and wine seemed to work.
Peter
--
E-Mail: pebl(a)math.ku.dk
Real name: Peter Berg Larsen
Where: Department of Computer Science, Copenhagen Uni., Denmark
March 28, 2005
Re: OLE32, compositemoniker: remove function prototypes, make functions static
by Mike McCormack
James Hawkins wrote:
> Candidate for a janitorial project? :)
Well, it may be a little bit complex to describe for Janitorial ... but
by looking at my patches you can see what I'm trying to do. This was
Juan's idea in the first place though :)
Mike
March 28, 2005
Re: Implementation of EnumMoniker and Partial impl on MkParseDisplayName
by Mike McCormack
Hi Jeff,
Jeff Latimer wrote:
> This is the first installment of the implementation of
> MkParseDisplayName. I would like feed back on style and usage.
>
> I think the implementation of the EnumMoniker interface looks ok.
> Comments appreciated.
I like that you've taken the time to write a test case! I don't know
alot about monikers, but seeing that you've tested it gives me confidence...
The following comments are a crash course in Wine programming...
> +/***********************************************************************
> + * EnmumMoniker_Next
> + */
> +HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface, ULONG celt, IMoniker** rgelt, ULONG * pceltFetched)
> +{
> +// DWORD i;
> +// ULONG ref;
We avoid C++ comments in Wine code to keep compatability with older
compilers.
> + EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
> + TRACE("(%p) currentPos %d Tablastindx %d\n",This, (int)This->currentPos, (int)This->TabLastIndx);
> + ULONG i;
You declared "i" above, but commented it out. Try avoid putting dead
code in comments. If code isn't compiled, it will become stale and
confuse people.
> + rc = CoGetMalloc(1, (LPMALLOC *) &ppMalloc);
> 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
That's alot of casts. I don't think you really need that many, do you?
> + /* 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;
Better to avoid tabs... and too many brackets. A space or two extra in
the for( i=0; (This->... might make things look better.
> + if (szUserName[char_cnt] == '/' ||
> + szUserName[char_cnt] == '?' ||
> + szUserName[char_cnt] == '<' ||
> + szUserName[char_cnt] == '>' ||
> + szUserName[char_cnt] == '*' ||
> + szUserName[char_cnt] == '|' ||
> + szUserName[char_cnt] == ':')
Maybe that can be shortened to :
if (strchr("/?<>*|:",szUserName[char_cnt]))
> + todo_wine { ok(hr==0x800401e4, "MkParseDisplayName - Progid not implemented hr=%08x\n", (int) hr); }
0x800401e4 is defined as MK_E_SYNTAX. It would be clearer to use the
define rather than a number.
%08lx is probably what you want instead of casting hr to (int) to get
rid of the printf parameter type warning.
> +
> + 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};
Again, for compatability, we avoid inline declarations, even though gcc
can deal with them fine.
Mike
March 28, 2005
Re: OLE32, compositemoniker: remove function prototypes, make functions static
by James Hawkins
On Mon, 28 Mar 2005 14:48:40 +0900, Mike McCormack <mike(a)codeweavers.com> wrote:
>
> There's more work like this to be done. Anybody want to help out?
>
> Mike
>
> ChangeLog:
> * remove function prototypes, make functions static
Candidate for a janitorial project? :)
--
James Hawkins
March 28, 2005
Re: [libs/wine/*] Strncpy elimination.
by Alexandre Julliard
Peter Berg Larsen <pebl(a)math.ku.dk> writes:
> Changelog:
> Janitorial Task: Check the usage of strncpy/strncpyW.
You can't use lstrcpynA in the libs/ directory, you have to stick to
Unix APIs.
--
Alexandre Julliard
julliard(a)winehq.org
March 28, 2005
Re: Two small scrollbar fixes
by Rein Klazes
On 28 Mar 2005 12:48:11 +0200, you wrote:
> Rein Klazes <wijn(a)wanadoo.nl> writes:
>
> > dlls/user : scroll.c
> > dlls/user/tests : win.c
> >
> > - GetScrollRange should return an empty range, both upper and lower
> > limit zero, if the window has no scrollbars (msdn);
> > - GetScrollInfo's return value is FALSE if the window has no scrollbars;
>
> This breaks the message test:
>
> msg.c:2761: Test failed: GetScrollInfo error 5
> msg.c:2761: Test failed: GetScrollInfo error 5
I see, SB_CTL is treated different. Attached is an upgraded patch.
Changelog:
dlls/user : scroll.c
dlls/user/tests : win.c
- GetScrollRange should return an empty range, both upper and lower
limit zero, if the window has no scrollbars (msdn);
- GetScrollInfo's return value is TRUE is nBar is SB_CTL or if anything
is filled in the SCROLLINFO structure, otherwise the return value is
FALSE.
Rein.
March 28, 2005
Re: Add a stdole2 typelib
by Huw D M Davies
On Sun, Mar 27, 2005 at 11:43:34PM -0500, Vincent Béron wrote:
> Robert, Huw: Do you have something else to add before this one goes in,
> or is Wine ready for it?
>
> Huw: I had to name the enum at line 181, else I'd get a SIGSEGV in widl.
> Would you mind trying to make it accept
>
> typedef enum {
> foo
> } BAR;
>
> instead of
>
> typedef enum BAR {
> foo
> } BAR;
>
> please?
Hi Vincent,
Sorry I got distracted with other things before I had a chance to
finish off the work on stdole2. I'll see if I can knock up something
to get these typedefs to work.
One remaining issue is the dispinterface FontEvents that is part of
coclass StdFont and yet is not defined until right at the end of the
typelib. There isn't a clean way to do this in idl and still maintain
the original order of the typeinfos - it's clear that the native
stdole2 is generated by a program rather than from idl. I guess we
could introduce a Wine specific attribute that allows us to hack
around this...
Huw.
March 28, 2005