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