Nikolay Sivov : ole32: Fix refcount of returned enumeration instances.
Alexandre Julliard
julliard at winehq.org
Fri Dec 6 10:54:16 CST 2013
Module: wine
Branch: master
Commit: b968c9c5420619000a9a98e99c829df2b1e395dc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b968c9c5420619000a9a98e99c829df2b1e395dc
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri Dec 6 16:05:28 2013 +0400
ole32: Fix refcount of returned enumeration instances.
---
dlls/ole32/comcat.c | 111 ++++++++++++++++++++++++++++----------------------
1 files changed, 62 insertions(+), 49 deletions(-)
diff --git a/dlls/ole32/comcat.c b/dlls/ole32/comcat.c
index 91244da..b8dcc53 100644
--- a/dlls/ole32/comcat.c
+++ b/dlls/ole32/comcat.c
@@ -61,9 +61,9 @@ struct class_categories
ULONG req_offset;
};
-static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid);
-static IEnumGUID* CLSIDEnumGUID_Construct(struct class_categories *class_categories);
-static IEnumGUID* CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req);
+static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret);
+static HRESULT CLSIDEnumGUID_Construct(struct class_categories *class_categories, IEnumCLSID **ret);
+static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req, IEnumCATID **ret);
/**********************************************************************
* File-scope string constants
@@ -496,10 +496,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumCategories(
if (ppenumCatInfo == NULL) return E_POINTER;
- *ppenumCatInfo = COMCAT_IEnumCATEGORYINFO_Construct(lcid);
- if (*ppenumCatInfo == NULL) return E_OUTOFMEMORY;
- IEnumCATEGORYINFO_AddRef(*ppenumCatInfo);
- return S_OK;
+ return EnumCATEGORYINFO_Construct(lcid, ppenumCatInfo);
}
/**********************************************************************
@@ -556,6 +553,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumClassesOfCategories(
LPENUMCLSID *ppenumCLSID)
{
struct class_categories *categories;
+ HRESULT hr;
TRACE("\n");
@@ -571,13 +569,15 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumClassesOfCategories(
categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl,
cRequired, rgcatidReq);
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);
- 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)
return E_POINTER;
- *ppenumCATID = CATIDEnumGUID_Construct(rclsid, postfix);
- if (*ppenumCATID == NULL) return E_OUTOFMEMORY;
- return S_OK;
+ return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
}
/**********************************************************************
@@ -666,9 +664,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumReqCategoriesOfClass(
if (rclsid == NULL || ppenumCATID == NULL)
return E_POINTER;
- *ppenumCATID = CATIDEnumGUID_Construct(rclsid, postfix);
- if (*ppenumCATID == NULL) return E_OUTOFMEMORY;
- return S_OK;
+ return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
}
/**********************************************************************
@@ -970,21 +966,23 @@ static const IEnumCATEGORYINFOVtbl COMCAT_IEnumCATEGORYINFO_Vtbl =
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;
+ *ret = NULL;
+
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumCATEGORYINFOImpl));
- if (This) {
- 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->lcid = lcid;
- open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
- }
- return &This->IEnumCATEGORYINFO_iface;
+ if (!This) return E_OUTOFMEMORY;
+
+ This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl;
+ This->ref = 1;
+ This->lcid = lcid;
+ open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
+
+ *ret = &This->IEnumCATEGORYINFO_iface;
+ return S_OK;
}
/**********************************************************************
@@ -1164,19 +1162,24 @@ static const IEnumGUIDVtbl CLSIDEnumGUIDVtbl =
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;
+ *ret = NULL;
+
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl));
- if (This) {
- static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 };
+ if (!This) return E_OUTOFMEMORY;
- This->IEnumGUID_iface.lpVtbl = &CLSIDEnumGUIDVtbl;
- This->categories = categories;
- open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
- }
- return &This->IEnumGUID_iface;
+ This->IEnumGUID_iface.lpVtbl = &CLSIDEnumGUIDVtbl;
+ This->ref = 1;
+ This->categories = categories;
+ open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
+
+ *ret = &This->IEnumGUID_iface;
+
+ return S_OK;
}
/**********************************************************************
@@ -1337,20 +1340,30 @@ static const IEnumGUIDVtbl CATIDEnumGUIDVtbl =
CATIDEnumGUID_Clone
};
-static IEnumGUID* CATIDEnumGUID_Construct(
- REFCLSID rclsid, LPCWSTR postfix)
+static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR postfix, IEnumGUID **ret)
{
+ static const WCHAR prefixW[] = {'C','L','S','I','D','\\',0};
+ WCHAR keyname[100], clsidW[CHARS_IN_GUID];
CATID_IEnumGUIDImpl *This;
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl));
- if (This) {
- WCHAR prefix[] = { 'C', 'L', 'S', 'I', 'D', '\\' };
-
- This->IEnumGUID_iface.lpVtbl = &CATIDEnumGUIDVtbl;
- memcpy(This->keyname, prefix, sizeof(prefix));
- StringFromGUID2(rclsid, This->keyname + 6, CHARS_IN_GUID);
- lstrcpyW(This->keyname + 44, postfix);
- open_classes_key(HKEY_CLASSES_ROOT, This->keyname, KEY_READ, &This->key);
- }
- return &This->IEnumGUID_iface;
+ if (!This) return E_OUTOFMEMORY;
+
+ *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->ref = 1;
+ strcpyW(keyname, prefixW);
+ strcatW(keyname, clsidW);
+ strcatW(keyname, postfix);
+
+ open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
+
+ *ret = &This->IEnumGUID_iface;
+ return S_OK;
}
More information about the wine-cvs
mailing list