From e7110f0982d1e58b3ee67bf45afeb1f7c6989f21 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Tue, 7 Dec 2004 14:37:11 +0000 Subject: [PATCH] Clean up devenum and properly implement DllCanUnloadNow ref counting. --- dlls/devenum/createdevenum.c | 37 ++++-------------- dlls/devenum/devenum_main.c | 8 ++-- dlls/devenum/devenum_private.h | 29 ++++++--------- dlls/devenum/factory.c | 35 ++++++----------- dlls/devenum/mediacatenum.c | 66 ++++++++++++++++++++++++--------- dlls/devenum/parsedisplayname.c | 24 +++--------- 6 files changed, 87 insertions(+), 112 deletions(-) diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c index 8860e43e1c9..1129adcf8b0 100644 --- a/dlls/devenum/createdevenum.c +++ b/dlls/devenum/createdevenum.c @@ -33,8 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum); -extern IEnumMonikerVtbl IEnumMoniker_Vtbl; - extern HINSTANCE DEVENUM_hInstance; const WCHAR wszInstanceKeyName[] ={'I','n','s','t','a','n','c','e',0}; @@ -56,10 +54,9 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_QueryInterface( REFIID riid, LPVOID *ppvObj) { - CreateDevEnumImpl *This = (CreateDevEnumImpl *)iface; TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); - if (This == NULL || ppvObj == NULL) return E_POINTER; + if (ppvObj == NULL) return E_POINTER; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ICreateDevEnum)) @@ -78,15 +75,11 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_QueryInterface( */ static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface) { - CreateDevEnumImpl *This = (CreateDevEnumImpl *)iface; TRACE("\n"); - if (This == NULL) return E_POINTER; + DEVENUM_LockModule(); - if (InterlockedIncrement(&This->ref) == 1) { - InterlockedIncrement(&dll_ref); - } - return This->ref; + return 2; /* non-heap based object */ } /********************************************************************** @@ -94,15 +87,11 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface) */ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum * iface) { - CreateDevEnumImpl *This = (CreateDevEnumImpl *)iface; TRACE("\n"); - if (This == NULL) return E_POINTER; + DEVENUM_UnlockModule(); - if (InterlockedDecrement(&This->ref) == 0) { - InterlockedDecrement(&dll_ref); - } - return This->ref; + return 1; /* non-heap based object */ } /********************************************************************** @@ -115,7 +104,6 @@ HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( DWORD dwFlags) { WCHAR wszRegKey[MAX_PATH]; - EnumMonikerImpl * pEnumMoniker; HKEY hkey; HKEY hbasekey; CreateDevEnumImpl *This = (CreateDevEnumImpl *)iface; @@ -173,18 +161,7 @@ HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( } } - pEnumMoniker = (EnumMonikerImpl *)CoTaskMemAlloc(sizeof(EnumMonikerImpl)); - if (!pEnumMoniker) - return E_OUTOFMEMORY; - - pEnumMoniker->lpVtbl = &IEnumMoniker_Vtbl; - pEnumMoniker->ref = 1; - pEnumMoniker->index = 0; - pEnumMoniker->hkey = hkey; - - *ppEnumMoniker = (IEnumMoniker *)pEnumMoniker; - - return S_OK; + return DEVENUM_IEnumMoniker_Construct(hkey, ppEnumMoniker); } /********************************************************************** @@ -201,7 +178,7 @@ static ICreateDevEnumVtbl ICreateDevEnum_Vtbl = /********************************************************************** * static CreateDevEnum instance */ -CreateDevEnumImpl DEVENUM_CreateDevEnum = { &ICreateDevEnum_Vtbl, 0 }; +CreateDevEnumImpl DEVENUM_CreateDevEnum = { &ICreateDevEnum_Vtbl }; /********************************************************************** * DEVENUM_CreateAMCategoryKey (INTERNAL) diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c index fb2f28e5e42..d4880258d9d 100644 --- a/dlls/devenum/devenum_main.c +++ b/dlls/devenum/devenum_main.c @@ -25,7 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum); -DWORD dll_ref = 0; +LONG dll_refs; HINSTANCE DEVENUM_hInstance; typedef struct @@ -43,7 +43,6 @@ static void DEVENUM_RegisterQuartz(void); */ const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 }; - /*********************************************************************** * DllEntryPoint */ @@ -77,7 +76,8 @@ HRESULT WINAPI DEVENUM_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *pp * Oh well - works just fine as it is */ if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) || IsEqualGUID(rclsid, &CLSID_CDeviceMoniker)) - return IClassFactory_QueryInterface((LPCLASSFACTORY)(char*)&DEVENUM_ClassFactory, iid, ppv); + return IClassFactory_QueryInterface((IClassFactory*)&DEVENUM_ClassFactory, iid, ppv); + FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid)); return CLASS_E_CLASSNOTAVAILABLE; } @@ -87,7 +87,7 @@ HRESULT WINAPI DEVENUM_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *pp */ HRESULT WINAPI DEVENUM_DllCanUnloadNow(void) { - return dll_ref != 0 ? S_FALSE : S_OK; + return dll_refs != 0 ? S_FALSE : S_OK; } /*********************************************************************** diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h index c303ba49a8c..596beb8da82 100644 --- a/dlls/devenum/devenum_private.h +++ b/dlls/devenum/devenum_private.h @@ -42,24 +42,29 @@ /********************************************************************** * Dll lifetime tracking declaration for devenum.dll */ -extern DWORD dll_ref; +extern LONG dll_refs; +static inline void DEVENUM_LockModule(void) { InterlockedIncrement(&dll_refs); } +static inline void DEVENUM_UnlockModule(void) { InterlockedDecrement(&dll_refs); } + /********************************************************************** * ClassFactory declaration for devenum.dll */ typedef struct { - /* IUnknown fields */ IClassFactoryVtbl *lpVtbl; - DWORD ref; } ClassFactoryImpl; typedef struct { ICreateDevEnumVtbl *lpVtbl; - DWORD ref; } CreateDevEnumImpl; +typedef struct +{ + IParseDisplayNameVtbl *lpVtbl; +} ParseDisplayNameImpl; + typedef struct { IEnumMonikerVtbl *lpVtbl; @@ -72,24 +77,12 @@ typedef struct { IMonikerVtbl *lpVtbl; - DWORD ref; + ULONG ref; HKEY hkey; } MediaCatMoniker; -typedef struct -{ - IPropertyBagVtbl *lpVtbl; - DWORD ref; - HKEY hkey; -} RegPropBagImpl; - -typedef struct -{ - IParseDisplayNameVtbl *lpVtbl; - DWORD ref; -} ParseDisplayNameImpl; - MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(); +HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker); HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( ICreateDevEnum * iface, REFCLSID clsidDeviceClass, diff --git a/dlls/devenum/factory.c b/dlls/devenum/factory.c index 8c5409b5ca5..d93e62d43dd 100644 --- a/dlls/devenum/factory.c +++ b/dlls/devenum/factory.c @@ -33,10 +33,9 @@ static HRESULT WINAPI DEVENUM_IClassFactory_QueryInterface( REFIID riid, LPVOID *ppvObj) { - ClassFactoryImpl *This = (ClassFactoryImpl *)iface; TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); - if (This == NULL || ppvObj == NULL) return E_POINTER; + if (ppvObj == NULL) return E_POINTER; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IClassFactory)) @@ -59,17 +58,11 @@ static HRESULT WINAPI DEVENUM_IClassFactory_QueryInterface( */ static ULONG WINAPI DEVENUM_IClassFactory_AddRef(LPCLASSFACTORY iface) { - ClassFactoryImpl *This = (ClassFactoryImpl *)iface; TRACE("\n"); - if (This == NULL) return E_POINTER; + DEVENUM_LockModule(); - This->ref++; - - if (InterlockedIncrement(&This->ref) == 1) { - InterlockedIncrement(&dll_ref); - } - return This->ref; + return 2; /* non-heap based object */ } /********************************************************************** @@ -77,15 +70,11 @@ static ULONG WINAPI DEVENUM_IClassFactory_AddRef(LPCLASSFACTORY iface) */ static ULONG WINAPI DEVENUM_IClassFactory_Release(LPCLASSFACTORY iface) { - ClassFactoryImpl *This = (ClassFactoryImpl *)iface; TRACE("\n"); - if (This == NULL) return E_POINTER; + DEVENUM_UnlockModule(); - if (InterlockedDecrement(&This->ref) == 0) { - InterlockedDecrement(&dll_ref); - } - return This->ref; + return 1; /* non-heap based object */ } /********************************************************************** @@ -97,10 +86,9 @@ static HRESULT WINAPI DEVENUM_IClassFactory_CreateInstance( REFIID riid, LPVOID *ppvObj) { - ClassFactoryImpl *This = (ClassFactoryImpl *)iface; TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); - if (This == NULL || ppvObj == NULL) return E_POINTER; + if (ppvObj == NULL) return E_POINTER; /* Don't support aggregation (Windows doesn't) */ if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION; @@ -128,11 +116,10 @@ static HRESULT WINAPI DEVENUM_IClassFactory_LockServer( { TRACE("\n"); - if (fLock != FALSE) { - IClassFactory_AddRef(iface); - } else { - IClassFactory_Release(iface); - } + if (fLock) + DEVENUM_LockModule(); + else + DEVENUM_UnlockModule(); return S_OK; } @@ -151,4 +138,4 @@ static IClassFactoryVtbl IClassFactory_Vtbl = /********************************************************************** * static ClassFactory instance */ -ClassFactoryImpl DEVENUM_ClassFactory = { &IClassFactory_Vtbl, 0 }; +ClassFactoryImpl DEVENUM_ClassFactory = { &IClassFactory_Vtbl }; diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c index e709e251888..24a5ab12c33 100644 --- a/dlls/devenum/mediacatenum.c +++ b/dlls/devenum/mediacatenum.c @@ -34,10 +34,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum); static ULONG WINAPI DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface); -static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Hash(LPMONIKER iface, DWORD* pdwHash); static ULONG WINAPI DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface); static ULONG WINAPI DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface); +typedef struct +{ + IPropertyBagVtbl *lpVtbl; + DWORD ref; + HKEY hkey; +} RegPropBagImpl; + + static HRESULT WINAPI DEVENUM_IPropertyBag_QueryInterface( LPPROPERTYBAG iface, REFIID riid, @@ -83,6 +90,7 @@ static ULONG WINAPI DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface) if (InterlockedDecrement(&This->ref) == 0) { RegCloseKey(This->hkey); CoTaskMemFree(This); + DEVENUM_UnlockModule(); return 0; } return This->ref; @@ -262,6 +270,17 @@ static IPropertyBagVtbl IPropertyBag_Vtbl = DEVENUM_IPropertyBag_Write }; +static HRESULT DEVENUM_IPropertyBag_Construct(HANDLE hkey, IPropertyBag **ppBag) +{ + RegPropBagImpl * rpb = CoTaskMemAlloc(sizeof(RegPropBagImpl)); + if (!rpb) + return E_OUTOFMEMORY; + rpb->lpVtbl = &IPropertyBag_Vtbl; + rpb->ref = 1; + *ppBag = (IPropertyBag*)rpb; + DEVENUM_LockModule(); + return S_OK; +} static HRESULT WINAPI DEVENUM_IMediaCatMoniker_QueryInterface( @@ -298,9 +317,7 @@ static ULONG WINAPI DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface) MediaCatMoniker *This = (MediaCatMoniker *)iface; TRACE("\n"); - if (This == NULL) return E_POINTER; - - return ++This->ref; + return InterlockedIncrement(&This->ref); } /********************************************************************** @@ -312,12 +329,11 @@ static ULONG WINAPI DEVENUM_IMediaCatMoniker_Release(LPMONIKER iface) ULONG ref; TRACE("\n"); - if (This == NULL) return E_POINTER; - - ref = --This->ref; + ref = InterlockedDecrement(&This->ref); if (ref == 0) { RegCloseKey(This->hkey); CoTaskMemFree(This); + DEVENUM_UnlockModule(); } return ref; } @@ -444,14 +460,9 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToStorage( if (IsEqualGUID(riid, &IID_IPropertyBag)) { - RegPropBagImpl * rpb = CoTaskMemAlloc(sizeof(RegPropBagImpl)); - if (!rpb) - return E_OUTOFMEMORY; - rpb->lpVtbl = &IPropertyBag_Vtbl; - DuplicateHandle(GetCurrentProcess(), This->hkey, GetCurrentProcess(), (LPHANDLE)&(rpb->hkey), 0, 0, DUPLICATE_SAME_ACCESS); - rpb->ref = 1; - *ppvObj = (LPVOID)rpb; - return S_OK; + HANDLE hkey; + DuplicateHandle(GetCurrentProcess(), This->hkey, GetCurrentProcess(), &hkey, 0, 0, DUPLICATE_SAME_ACCESS); + return DEVENUM_IPropertyBag_Construct(hkey, (IPropertyBag**)ppvObj); } return MK_E_NOSTORAGE; @@ -670,6 +681,8 @@ MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct() DEVENUM_IMediaCatMoniker_AddRef((LPMONIKER)pMoniker); + DEVENUM_LockModule(); + return pMoniker; } @@ -707,8 +720,6 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface) TRACE("\n"); - if (This == NULL) return E_POINTER; - return InterlockedIncrement(&This->ref); } @@ -725,6 +736,7 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(LPENUMMONIKER iface) { RegCloseKey(This->hkey); CoTaskMemFree(This); + DEVENUM_UnlockModule(); return 0; } return This->ref; @@ -805,7 +817,7 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Clone(LPENUMMONIKER iface, IEnumMonik /********************************************************************** * IEnumMoniker_Vtbl */ -IEnumMonikerVtbl IEnumMoniker_Vtbl = +static IEnumMonikerVtbl IEnumMoniker_Vtbl = { DEVENUM_IEnumMoniker_QueryInterface, DEVENUM_IEnumMoniker_AddRef, @@ -815,3 +827,21 @@ IEnumMonikerVtbl IEnumMoniker_Vtbl = DEVENUM_IEnumMoniker_Reset, DEVENUM_IEnumMoniker_Clone }; + +HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker) +{ + EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl)); + if (!pEnumMoniker) + return E_OUTOFMEMORY; + + pEnumMoniker->lpVtbl = &IEnumMoniker_Vtbl; + pEnumMoniker->ref = 1; + pEnumMoniker->index = 0; + pEnumMoniker->hkey = hkey; + + *ppEnumMoniker = (IEnumMoniker *)pEnumMoniker; + + DEVENUM_LockModule(); + + return S_OK; +} diff --git a/dlls/devenum/parsedisplayname.c b/dlls/devenum/parsedisplayname.c index eb8cb076ad5..f1b8505f10f 100644 --- a/dlls/devenum/parsedisplayname.c +++ b/dlls/devenum/parsedisplayname.c @@ -32,10 +32,9 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_QueryInterface( REFIID riid, LPVOID *ppvObj) { - ParseDisplayNameImpl *This = (ParseDisplayNameImpl *)iface; TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); - if (This == NULL || ppvObj == NULL) return E_POINTER; + if (ppvObj == NULL) return E_POINTER; if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IParseDisplayName)) @@ -54,16 +53,11 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_QueryInterface( */ static ULONG WINAPI DEVENUM_IParseDisplayName_AddRef(LPPARSEDISPLAYNAME iface) { - ParseDisplayNameImpl *This = (ParseDisplayNameImpl *)iface; TRACE("\n"); - if (This == NULL) return E_POINTER; + DEVENUM_LockModule(); - if (InterlockedIncrement(&This->ref) == 1) { - InterlockedIncrement(&dll_ref); - } - - return ++This->ref; + return 2; /* non-heap based object */ } /********************************************************************** @@ -71,17 +65,11 @@ static ULONG WINAPI DEVENUM_IParseDisplayName_AddRef(LPPARSEDISPLAYNAME iface) */ static ULONG WINAPI DEVENUM_IParseDisplayName_Release(LPPARSEDISPLAYNAME iface) { - ParseDisplayNameImpl *This = (ParseDisplayNameImpl *)iface; - ULONG ref; TRACE("\n"); - if (This == NULL) return E_POINTER; + DEVENUM_UnlockModule(); - ref = --This->ref; - if (InterlockedDecrement(&This->ref) == 0) { - InterlockedDecrement(&dll_ref); - } - return ref; + return 1; /* non-heap based object */ } /********************************************************************** @@ -176,4 +164,4 @@ static IParseDisplayNameVtbl IParseDisplayName_Vtbl = }; /* The one instance of this class */ -ParseDisplayNameImpl DEVENUM_ParseDisplayName = { &IParseDisplayName_Vtbl, 0 }; +ParseDisplayNameImpl DEVENUM_ParseDisplayName = { &IParseDisplayName_Vtbl };