Commit e7110f09 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

Clean up devenum and properly implement DllCanUnloadNow ref counting.

parent 5f1ef6d0
......@@ -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)
......
......@@ -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;
}
/***********************************************************************
......
......@@ -42,26 +42,31 @@
/**********************************************************************
* 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;
DWORD ref;
DWORD index;
......@@ -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,
......
......@@ -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 };
......@@ -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;
}
......@@ -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 };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment