ole32: Fix refcount of returned enumeration instances.

This commit is contained in:
Nikolay Sivov 2013-12-06 16:05:28 +04:00 committed by Alexandre Julliard
parent aeb35b20ec
commit b968c9c542
1 changed files with 62 additions and 49 deletions

View File

@ -61,9 +61,9 @@ struct class_categories
ULONG req_offset; ULONG req_offset;
}; };
static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid); static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret);
static IEnumGUID* CLSIDEnumGUID_Construct(struct class_categories *class_categories); static HRESULT CLSIDEnumGUID_Construct(struct class_categories *class_categories, IEnumCLSID **ret);
static IEnumGUID* CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req); static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req, IEnumCATID **ret);
/********************************************************************** /**********************************************************************
* File-scope string constants * File-scope string constants
@ -496,10 +496,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumCategories(
if (ppenumCatInfo == NULL) return E_POINTER; if (ppenumCatInfo == NULL) return E_POINTER;
*ppenumCatInfo = COMCAT_IEnumCATEGORYINFO_Construct(lcid); return EnumCATEGORYINFO_Construct(lcid, ppenumCatInfo);
if (*ppenumCatInfo == NULL) return E_OUTOFMEMORY;
IEnumCATEGORYINFO_AddRef(*ppenumCatInfo);
return S_OK;
} }
/********************************************************************** /**********************************************************************
@ -556,6 +553,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumClassesOfCategories(
LPENUMCLSID *ppenumCLSID) LPENUMCLSID *ppenumCLSID)
{ {
struct class_categories *categories; struct class_categories *categories;
HRESULT hr;
TRACE("\n"); TRACE("\n");
@ -571,13 +569,15 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumClassesOfCategories(
categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl, categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl,
cRequired, rgcatidReq); cRequired, rgcatidReq);
if (categories == NULL) return E_OUTOFMEMORY; if (categories == NULL) return E_OUTOFMEMORY;
*ppenumCLSID = CLSIDEnumGUID_Construct(categories);
if (*ppenumCLSID == NULL) { hr = CLSIDEnumGUID_Construct(categories, ppenumCLSID);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, categories); HeapFree(GetProcessHeap(), 0, categories);
return E_OUTOFMEMORY; return hr;
} }
IEnumGUID_AddRef(*ppenumCLSID);
return S_OK; return hr;
} }
/********************************************************************** /**********************************************************************
@ -644,9 +644,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumImplCategoriesOfClass(
if (rclsid == NULL || ppenumCATID == NULL) if (rclsid == NULL || ppenumCATID == NULL)
return E_POINTER; return E_POINTER;
*ppenumCATID = CATIDEnumGUID_Construct(rclsid, postfix); return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
if (*ppenumCATID == NULL) return E_OUTOFMEMORY;
return S_OK;
} }
/********************************************************************** /**********************************************************************
@ -666,9 +664,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumReqCategoriesOfClass(
if (rclsid == NULL || ppenumCATID == NULL) if (rclsid == NULL || ppenumCATID == NULL)
return E_POINTER; return E_POINTER;
*ppenumCATID = CATIDEnumGUID_Construct(rclsid, postfix); return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
if (*ppenumCATID == NULL) return E_OUTOFMEMORY;
return S_OK;
} }
/********************************************************************** /**********************************************************************
@ -970,21 +966,23 @@ static const IEnumCATEGORYINFOVtbl COMCAT_IEnumCATEGORYINFO_Vtbl =
COMCAT_IEnumCATEGORYINFO_Clone COMCAT_IEnumCATEGORYINFO_Clone
}; };
static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid) static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret)
{ {
static const WCHAR keyname[] = {'C','o','m','p','o','n','e','n','t',' ','C','a','t','e','g','o','r','i','e','s',0};
IEnumCATEGORYINFOImpl *This; IEnumCATEGORYINFOImpl *This;
*ret = NULL;
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumCATEGORYINFOImpl)); This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumCATEGORYINFOImpl));
if (This) { if (!This) return E_OUTOFMEMORY;
static const WCHAR keyname[] = { 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n',
't', ' ', 'C', 'a', 't', 'e', 'g', 'o',
'r', 'i', 'e', 's', 0 };
This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl; This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl;
This->ref = 1;
This->lcid = lcid; This->lcid = lcid;
open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key); open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
}
return &This->IEnumCATEGORYINFO_iface; *ret = &This->IEnumCATEGORYINFO_iface;
return S_OK;
} }
/********************************************************************** /**********************************************************************
@ -1164,19 +1162,24 @@ static const IEnumGUIDVtbl CLSIDEnumGUIDVtbl =
CLSIDEnumGUID_Clone CLSIDEnumGUID_Clone
}; };
static IEnumGUID* CLSIDEnumGUID_Construct(struct class_categories *categories) static HRESULT CLSIDEnumGUID_Construct(struct class_categories *categories, IEnumCLSID **ret)
{ {
static const WCHAR keyname[] = {'C','L','S','I','D',0};
CLSID_IEnumGUIDImpl *This; CLSID_IEnumGUIDImpl *This;
*ret = NULL;
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl)); This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl));
if (This) { if (!This) return E_OUTOFMEMORY;
static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 };
This->IEnumGUID_iface.lpVtbl = &CLSIDEnumGUIDVtbl; This->IEnumGUID_iface.lpVtbl = &CLSIDEnumGUIDVtbl;
This->ref = 1;
This->categories = categories; This->categories = categories;
open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key); open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
}
return &This->IEnumGUID_iface; *ret = &This->IEnumGUID_iface;
return S_OK;
} }
/********************************************************************** /**********************************************************************
@ -1337,20 +1340,30 @@ static const IEnumGUIDVtbl CATIDEnumGUIDVtbl =
CATIDEnumGUID_Clone CATIDEnumGUID_Clone
}; };
static IEnumGUID* CATIDEnumGUID_Construct( static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR postfix, IEnumGUID **ret)
REFCLSID rclsid, LPCWSTR postfix)
{ {
static const WCHAR prefixW[] = {'C','L','S','I','D','\\',0};
WCHAR keyname[100], clsidW[CHARS_IN_GUID];
CATID_IEnumGUIDImpl *This; CATID_IEnumGUIDImpl *This;
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl)); This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl));
if (This) { if (!This) return E_OUTOFMEMORY;
WCHAR prefix[] = { 'C', 'L', 'S', 'I', 'D', '\\' };
*ret = NULL;
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl));
if (!This) return E_OUTOFMEMORY;
StringFromGUID2(rclsid, clsidW, CHARS_IN_GUID);
This->IEnumGUID_iface.lpVtbl = &CATIDEnumGUIDVtbl; This->IEnumGUID_iface.lpVtbl = &CATIDEnumGUIDVtbl;
memcpy(This->keyname, prefix, sizeof(prefix)); This->ref = 1;
StringFromGUID2(rclsid, This->keyname + 6, CHARS_IN_GUID); strcpyW(keyname, prefixW);
lstrcpyW(This->keyname + 44, postfix); strcatW(keyname, clsidW);
open_classes_key(HKEY_CLASSES_ROOT, This->keyname, KEY_READ, &This->key); strcatW(keyname, postfix);
}
return &This->IEnumGUID_iface; open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
*ret = &This->IEnumGUID_iface;
return S_OK;
} }