Clean up devenum and properly implement DllCanUnloadNow ref counting.
This commit is contained in:
parent
5f1ef6d09b
commit
e7110f0982
|
@ -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,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,
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Reference in New Issue