2nd attemp at DllCanUnloadNow
Robert Shearman
rob at codeweavers.com
Fri Dec 3 14:55:26 CST 2004
James Hawkins wrote:
>This time I respect heap-based objects, leaving there internal ref
>counts and respective HeapFree's. I also took Alexandre's suggestions
>and changed Un/LockServer to DMCOMPOS_LockServer etc and change cLocks
>to refCount. Let me know if this is any closer to what it needs to
>be. Thanks.
>
>
Looking better. A few comments though:
>------------------------------------------------------------------------
>
>Index: dlls/dmcompos/chordmap.c
>===================================================================
>RCS file: /home/wine/wine/dlls/dmcompos/chordmap.c,v
>retrieving revision 1.7
>diff -u -r1.7 chordmap.c
>--- dlls/dmcompos/chordmap.c 23 Aug 2004 19:39:57 -0000 1.7
>+++ dlls/dmcompos/chordmap.c 2 Dec 2004 22:28:45 -0000
>@@ -55,6 +55,9 @@
> ULONG WINAPI IDirectMusicChordMapImpl_IUnknown_AddRef (LPUNKNOWN iface) {
> ICOM_THIS_MULTI(IDirectMusicChordMapImpl, UnknownVtbl, iface);
> TRACE("(%p): AddRef from %ld\n", This, This->ref);
>+
>+ DMCOMPOS_LockModule();
>+
> return ++(This->ref);
> }
>
>@@ -62,9 +65,13 @@
> ICOM_THIS_MULTI(IDirectMusicChordMapImpl, UnknownVtbl, iface);
> ULONG ref = --This->ref;
> TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
>+
> if (ref == 0) {
> HeapFree(GetProcessHeap(), 0, This);
> }
>+
>+ DMCOMPOS_UnlockModule();
>+
> return ref;
> }
>
>Index: dlls/dmcompos/chordmaptrack.c
>===================================================================
>RCS file: /home/wine/wine/dlls/dmcompos/chordmaptrack.c,v
>retrieving revision 1.6
>diff -u -r1.6 chordmaptrack.c
>--- dlls/dmcompos/chordmaptrack.c 23 Aug 2004 19:39:57 -0000 1.6
>+++ dlls/dmcompos/chordmaptrack.c 2 Dec 2004 22:28:45 -0000
>@@ -52,6 +52,9 @@
> ULONG WINAPI IDirectMusicChordMapTrack_IUnknown_AddRef (LPUNKNOWN iface) {
> ICOM_THIS_MULTI(IDirectMusicChordMapTrack, UnknownVtbl, iface);
> TRACE("(%p): AddRef from %ld\n", This, This->ref);
>+
>+ DMCOMPOS_LockModule();
>+
> return ++(This->ref);
> }
>
>@@ -59,9 +62,13 @@
> ICOM_THIS_MULTI(IDirectMusicChordMapTrack, UnknownVtbl, iface);
> ULONG ref = --This->ref;
> TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
>+
> if (ref == 0) {
> HeapFree(GetProcessHeap(), 0, This);
> }
>+
>+ DMCOMPOS_UnlockModule();
>+
> return ref;
> }
>
>Index: dlls/dmcompos/composer.c
>===================================================================
>RCS file: /home/wine/wine/dlls/dmcompos/composer.c,v
>retrieving revision 1.8
>diff -u -r1.8 composer.c
>--- dlls/dmcompos/composer.c 6 Sep 2004 21:34:26 -0000 1.8
>+++ dlls/dmcompos/composer.c 2 Dec 2004 22:28:45 -0000
>@@ -39,6 +39,9 @@
> ULONG WINAPI IDirectMusicComposerImpl_AddRef (LPDIRECTMUSICCOMPOSER iface) {
> IDirectMusicComposerImpl *This = (IDirectMusicComposerImpl *)iface;
> TRACE("(%p): AddRef from %ld\n", This, This->ref);
>+
>+ DMCOMPOS_LockModule();
>+
> return ++(This->ref);
> }
>
>@@ -46,9 +49,13 @@
> IDirectMusicComposerImpl *This = (IDirectMusicComposerImpl *)iface;
> ULONG ref = --This->ref;
> TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
>+
> if (ref == 0) {
> HeapFree(GetProcessHeap(), 0, This);
> }
>+
>+ DMCOMPOS_UnlockModule();
>+
> return ref;
> }
>
>Index: dlls/dmcompos/dmcompos_main.c
>===================================================================
>RCS file: /home/wine/wine/dlls/dmcompos/dmcompos_main.c,v
>retrieving revision 1.9
>diff -u -r1.9 dmcompos_main.c
>--- dlls/dmcompos/dmcompos_main.c 6 Sep 2004 21:34:26 -0000 1.9
>+++ dlls/dmcompos/dmcompos_main.c 2 Dec 2004 22:28:45 -0000
>@@ -21,41 +21,54 @@
>
> WINE_DEFAULT_DEBUG_CHANNEL(dmcompos);
>
>+LONG refCount;
>+
>
>
This can be be made static since it is not used outside of this file and
tells anyone looking it that this is the case too.
> typedef struct {
>- /* IUnknown fields */
> IClassFactoryVtbl *lpVtbl;
>- DWORD ref;
> } IClassFactoryImpl;
>
> /******************************************************************
> * DirectMusicChordMap ClassFactory
> */
> static HRESULT WINAPI ChordMapCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %s, %p): stub\n", This, debugstr_dmguid(riid), ppobj);
>+ FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
>+
>+ if (ppobj == NULL) return E_POINTER;
>+
> return E_NOINTERFACE;
> }
>
> static ULONG WINAPI ChordMapCF_AddRef(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- return ++(This->ref);
>+ DMCOMPOS_LockModule();
>+
>+ return 2; /* non-heap based object */
> }
>
> static ULONG WINAPI ChordMapCF_Release(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- /* static class, won't be freed */
>- return --(This->ref);
>+ DMCOMPOS_UnlockModule();
>+
>+ return 1; /* non-heap based object */
> }
>
> static HRESULT WINAPI ChordMapCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- TRACE ("(%p, %p, %s, %p)\n", This, pOuter, debugstr_dmguid(riid), ppobj);
>- return DMUSIC_CreateDirectMusicChordMapImpl (riid, ppobj, pOuter);
>+ HRESULT result;
>+
>+ TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
>+
>+ result = DMUSIC_CreateDirectMusicChordMapImpl (riid, ppobj, pOuter);
>+ DMCOMPOS_LockModule();
>+
>+ return result;
> }
>
>
LockModule should only be called if the creation succeeded. In this
instance it should be moved inside of the
DMUSIC_CreateDirectMusicChordMapImpl into the success case (I presume this function returns an appropriate error if it cannot allocate any memory).
> static HRESULT WINAPI ChordMapCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %d): stub\n", This, dolock);
>+ TRACE("(%d)\n", dolock);
>+
>+ if (dolock)
>+ DMCOMPOS_LockModule();
>+ else
>+ DMCOMPOS_UnlockModule();
>+
> return S_OK;
> }
>
>@@ -67,37 +80,49 @@
> ChordMapCF_LockServer
> };
>
>-static IClassFactoryImpl ChordMap_CF = {&ChordMapCF_Vtbl, 1 };
>+static IClassFactoryImpl ChordMap_CF = {&ChordMapCF_Vtbl};
>
> /******************************************************************
> * DirectMusicComposer ClassFactory
> */
> static HRESULT WINAPI ComposerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %s, %p): stub\n",This,debugstr_dmguid(riid),ppobj);
>+ FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
>+
>+ if (ppobj == NULL) return E_POINTER;
>+
> return E_NOINTERFACE;
> }
>
> static ULONG WINAPI ComposerCF_AddRef(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- return ++(This->ref);
>+ DMCOMPOS_LockModule();
>+
>+ return 2; /* non-heap based object */
> }
>
> static ULONG WINAPI ComposerCF_Release(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- /* static class, won't be freed */
>- return --(This->ref);
>+ DMCOMPOS_UnlockModule();
>+
>+ return 1; /* non-heap based object */
> }
>
> static HRESULT WINAPI ComposerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- TRACE ("(%p, %p, %s, %p)\n", This, pOuter, debugstr_dmguid(riid), ppobj);
>- return DMUSIC_CreateDirectMusicComposerImpl (riid, ppobj, pOuter);
>+ HRESULT result;
>+ TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
>+
>+ result = DMUSIC_CreateDirectMusicComposerImpl (riid, ppobj, pOuter);
>+ DMCOMPOS_LockModule();
>+
>+ return result;
> }
>
LockModule should only be called if the creation succeeded. In this
instance it should be moved inside of the
DMUSIC_CreateDirectMusicComposerImpl into the success case (I presume this function returns an appropriate error if it cannot allocate any memory).
>
> static HRESULT WINAPI ComposerCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %d): stub\n", This, dolock);
>+ TRACE("(%d)\n", dolock);
>+
>+ if (dolock)
>+ DMCOMPOS_LockModule();
>+ else
>+ DMCOMPOS_UnlockModule();
>+
> return S_OK;
> }
>
>@@ -109,37 +134,49 @@
> ComposerCF_LockServer
> };
>
>-static IClassFactoryImpl Composer_CF = {&ComposerCF_Vtbl, 1 };
>+static IClassFactoryImpl Composer_CF = {&ComposerCF_Vtbl};
>
> /******************************************************************
> * DirectMusicChordMapTrack ClassFactory
> */
> static HRESULT WINAPI ChordMapTrackCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %s, %p): stub\n",This,debugstr_dmguid(riid),ppobj);
>+ FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
>+
>+ if (ppobj == NULL) return E_POINTER;
>+
> return E_NOINTERFACE;
> }
>
> static ULONG WINAPI ChordMapTrackCF_AddRef(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- return ++(This->ref);
>+ DMCOMPOS_LockModule();
>+
>+ return 2; /* non-heap based object */
> }
>
> static ULONG WINAPI ChordMapTrackCF_Release(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- /* static class, won't be freed */
>- return --(This->ref);
>+ DMCOMPOS_UnlockModule();
>+
>+ return 1; /* non-heap based object */
> }
>
> static HRESULT WINAPI ChordMapTrackCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- TRACE ("(%p, %p, %s, %p)\n", This, pOuter, debugstr_dmguid(riid), ppobj);
>- return DMUSIC_CreateDirectMusicChordMapTrack (riid, ppobj, pOuter);
>+ HRESULT result;
>+ TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
>+
>+ result = DMUSIC_CreateDirectMusicChordMapTrack (riid, ppobj, pOuter);
>+ DMCOMPOS_LockModule();
>+
>+ return result;
> }
>
>
Same again here.
>
> static HRESULT WINAPI ChordMapTrackCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %d): stub\n", This, dolock);
>+ TRACE("(%d)\n", dolock);
>+
>+ if (dolock)
>+ DMCOMPOS_LockModule();
>+ else
>+ DMCOMPOS_UnlockModule();
>+
> return S_OK;
> }
>
>@@ -151,39 +188,49 @@
> ChordMapTrackCF_LockServer
> };
>
>-static IClassFactoryImpl ChordMapTrack_CF = {&ChordMapTrackCF_Vtbl, 1 };
>+static IClassFactoryImpl ChordMapTrack_CF = {&ChordMapTrackCF_Vtbl};
>
> /******************************************************************
> * DirectMusicTemplate ClassFactory
> */
> static HRESULT WINAPI TemplateCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %s, %p): stub\n", This, debugstr_dmguid(riid), ppobj);
>+ FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
>+
>+ if (ppobj == NULL) return E_POINTER;
>+
> return E_NOINTERFACE;
> }
>
> static ULONG WINAPI TemplateCF_AddRef(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- return ++(This->ref);
>+ DMCOMPOS_LockModule();
>+
>+ return 2; /* non-heap based object */
> }
>
> static ULONG WINAPI TemplateCF_Release(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- /* static class, won't be freed */
>- return --(This->ref);
>+ DMCOMPOS_UnlockModule();
>+
>+ return 1; /* non-heap based object */
> }
>
> static HRESULT WINAPI TemplateCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- TRACE ("(%p, %p, %s, %p)\n", This, pOuter, debugstr_dmguid(riid), ppobj);
>+ TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
> /* nothing yet */
>- WARN("(%p, %s,%p): not found\n", This, debugstr_dmguid(riid), ppobj);
>+ WARN("(%s,%p): not found\n", debugstr_dmguid(riid), ppobj);
>+
>+ DMCOMPOS_LockModule();
>+
> return E_NOINTERFACE;
> }
>
>
Remove the DMCOMPOS_LockModule call, otherwise it will leak a ref count
if (and its a pretty big if) the app handles the error returned by this
function correctly.
>
> static HRESULT WINAPI TemplateCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %d): stub\n", This, dolock);
>+ TRACE("(%d)\n", dolock);
>+
>+ if (dolock)
>+ DMCOMPOS_LockModule();
>+ else
>+ DMCOMPOS_UnlockModule();
>+
> return S_OK;
> }
>
>@@ -195,37 +242,49 @@
> TemplateCF_LockServer
> };
>
>-static IClassFactoryImpl Template_CF = {&TemplateCF_Vtbl, 1 };
>+static IClassFactoryImpl Template_CF = {&TemplateCF_Vtbl};
>
> /******************************************************************
> * DirectMusicSignPostTrack ClassFactory
> */
> static HRESULT WINAPI SignPostTrackCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %s, %p): stub\n",This,debugstr_dmguid(riid),ppobj);
>+ FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
>+
>+ if (ppobj == NULL) return E_POINTER;
>+
> return E_NOINTERFACE;
> }
>
> static ULONG WINAPI SignPostTrackCF_AddRef(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- return ++(This->ref);
>+ DMCOMPOS_LockModule();
>+
>+ return 2; /* non-heap based object */
> }
>
> static ULONG WINAPI SignPostTrackCF_Release(LPCLASSFACTORY iface) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- /* static class, won't be freed */
>- return --(This->ref);
>+ DMCOMPOS_UnlockModule();
>+
>+ return 1; /* non-heap based object */
> }
>
> static HRESULT WINAPI SignPostTrackCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- TRACE ("(%p, %p, %s, %p)\n", This, pOuter, debugstr_dmguid(riid), ppobj);
>- return DMUSIC_CreateDirectMusicSignPostTrack (riid, ppobj, pOuter);
>+ HRESULT result;
>+ TRACE ("(%p, %s, %p)\n", pOuter, debugstr_dmguid(riid), ppobj);
>+
>+ result = DMUSIC_CreateDirectMusicSignPostTrack (riid, ppobj, pOuter);
>+ DMCOMPOS_LockModule();
>+
>+ return result;
> }
>
>
>
Same as the two other instances of this problem.
> static HRESULT WINAPI SignPostTrackCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
>- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
>- FIXME("(%p, %d): stub\n", This, dolock);
>+ TRACE("(%d)\n", dolock);
>+
>+ if (dolock)
>+ DMCOMPOS_LockModule();
>+ else
>+ DMCOMPOS_UnlockModule();
>+
> return S_OK;
> }
>
>@@ -237,7 +296,7 @@
> SignPostTrackCF_LockServer
> };
>
>-static IClassFactoryImpl SignPostTrack_CF = {&SignPostTrackCF_Vtbl, 1 };
>+static IClassFactoryImpl SignPostTrack_CF = {&SignPostTrackCF_Vtbl};
>
> /******************************************************************
> * DllMain
>@@ -256,6 +315,18 @@
> return TRUE;
> }
>
>+/**********************************************************************
>+ * Dll lifetime tracking declaration
>+ */
>+void DMCOMPOS_LockModule()
>+{
>+ InterlockedIncrement(&refCount);
>+}
>+
>+void DMCOMPOS_UnlockModule()
>+{
>+ InterlockedDecrement(&refCount);
>+}
>
> /******************************************************************
> * DllCanUnloadNow (DMCOMPOS.1)
>@@ -263,8 +334,7 @@
> *
> */
> HRESULT WINAPI DMCOMPOS_DllCanUnloadNow(void) {
>- FIXME("(void): stub\n");
>- return S_FALSE;
>+ return refCount != 0 ? S_FALSE : S_OK;
> }
>
>
>Index: dlls/dmcompos/dmcompos_private.h
>===================================================================
>RCS file: /home/wine/wine/dlls/dmcompos/dmcompos_private.h,v
>retrieving revision 1.10
>diff -u -r1.10 dmcompos_private.h
>--- dlls/dmcompos/dmcompos_private.h 22 Aug 2004 21:38:47 -0000 1.10
>+++ dlls/dmcompos/dmcompos_private.h 2 Dec 2004 22:28:45 -0000
>@@ -134,11 +134,11 @@
> extern ULONG WINAPI IDirectMusicComposerImpl_AddRef (LPDIRECTMUSICCOMPOSER iface);
> extern ULONG WINAPI IDirectMusicComposerImpl_Release (LPDIRECTMUSICCOMPOSER iface);
> /* IDirectMusicComposer: */
>-extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeSegmentFromTemplate (LPDIRECTMUSICCOMPOSER iface, IDirectMusicStyle* pStyle, IDirectMusicSegment* pTemplate, WORD wActivity, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppSegment);
>-extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeSegmentFromShape (LPDIRECTMUSICCOMPOSER iface, IDirectMusicStyle* pStyle, WORD wNumMeasures, WORD wShape, WORD wActivity, BOOL fIntro, BOOL fEnd, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppSegment);
>-extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeTransition (LPDIRECTMUSICCOMPOSER iface, IDirectMusicSegment* pFromSeg, IDirectMusicSegment* pToSeg, MUSIC_TIME mtTime, WORD wCommand, DWORD dwFlags, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppTransSeg);
>-extern HRESULT WINAPI IDirectMusicComposerImpl_AutoTransition (LPDIRECTMUSICCOMPOSER iface, IDirectMusicPerformance* pPerformance, IDirectMusicSegment* pToSeg, WORD wCommand, DWORD dwFlags, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppTransSeg, IDirectMusicSegmentState** ppToSegState, IDirectMusicSegmentState** ppTransSegState);
>-extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeTemplateFromShape (LPDIRECTMUSICCOMPOSER iface, WORD wNumMeasures, WORD wShape, BOOL fIntro, BOOL fEnd, WORD wEndLength, IDirectMusicSegment** ppTemplate);
>+extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeSegmentFromTemplate (LPDIRECTMUSICCOMPOSER iface, IDirectMusicStyle* pStyle, IDirectMusicSegment* pTemplate, WORD wActivity, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppSegment);
>+extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeSegmentFromShape (LPDIRECTMUSICCOMPOSER iface, IDirectMusicStyle* pStyle, WORD wNumMeasures, WORD wShape, WORD wActivity, BOOL fIntro, BOOL fEnd, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppSegment);
>+extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeTransition (LPDIRECTMUSICCOMPOSER iface, IDirectMusicSegment* pFromSeg, IDirectMusicSegment* pToSeg, MUSIC_TIME mtTime, WORD wCommand, DWORD dwFlags, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppTransSeg);
>+extern HRESULT WINAPI IDirectMusicComposerImpl_AutoTransition (LPDIRECTMUSICCOMPOSER iface, IDirectMusicPerformance* pPerformance, IDirectMusicSegment* pToSeg, WORD wCommand, DWORD dwFlags, IDirectMusicChordMap* pChordMap, IDirectMusicSegment** ppTransSeg, IDirectMusicSegmentState** ppToSegState, IDirectMusicSegmentState** ppTransSegState);
>+extern HRESULT WINAPI IDirectMusicComposerImpl_ComposeTemplateFromShape (LPDIRECTMUSICCOMPOSER iface, WORD wNumMeasures, WORD wShape, BOOL fIntro, BOOL fEnd, WORD wEndLength, IDirectMusicSegment** ppTemplate);
> extern HRESULT WINAPI IDirectMusicComposerImpl_ChangeChordMap (LPDIRECTMUSICCOMPOSER iface, IDirectMusicSegment* pSegment, BOOL fTrackScale, IDirectMusicChordMap* pChordMap);
>
>
>@@ -237,6 +237,11 @@
> extern HRESULT WINAPI IDirectMusicSignPostTrack_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty);
> extern HRESULT WINAPI IDirectMusicSignPostTrack_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize);
>
>+/**********************************************************************
>+ * Dll lifetime tracking declaration for devenum.dll
>+ */
>+void DMCOMPOS_LockModule();
>+void DMCOMPOS_UnlockModule();
>
> /*****************************************************************************
> * Misc.
>Index: dlls/dmcompos/signposttrack.c
>===================================================================
>RCS file: /home/wine/wine/dlls/dmcompos/signposttrack.c,v
>retrieving revision 1.7
>diff -u -r1.7 signposttrack.c
>--- dlls/dmcompos/signposttrack.c 6 Sep 2004 21:34:26 -0000 1.7
>+++ dlls/dmcompos/signposttrack.c 2 Dec 2004 22:28:45 -0000
>@@ -52,6 +52,9 @@
> ULONG WINAPI IDirectMusicSignPostTrack_IUnknown_AddRef (LPUNKNOWN iface) {
> ICOM_THIS_MULTI(IDirectMusicSignPostTrack, UnknownVtbl, iface);
> TRACE("(%p): AddRef from %ld\n", This, This->ref);
>+
>+ DMCOMPOS_LockModule();
>+
> return ++(This->ref);
> }
>
>@@ -59,9 +62,13 @@
> ICOM_THIS_MULTI(IDirectMusicSignPostTrack, UnknownVtbl, iface);
> ULONG ref = --This->ref;
> TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
>+
> if (ref == 0) {
> HeapFree(GetProcessHeap(), 0, This);
> }
>+
>+ DMCOMPOS_UnlockModule();
>+
> return ref;
> }
>
>
>
Rob
More information about the wine-devel
mailing list