Nikolay Sivov : wbemdisp: Iterate properties and methods once when collecting supported member names.
Alexandre Julliard
julliard at winehq.org
Tue Mar 2 15:35:58 CST 2021
Module: wine
Branch: master
Commit: 501a99f2a972158f82cc6be5228c2382f3e93686
URL: https://source.winehq.org/git/wine.git/?a=commit;h=501a99f2a972158f82cc6be5228c2382f3e93686
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue Mar 2 09:25:03 2021 +0300
wbemdisp: Iterate properties and methods once when collecting supported member names.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/wbemdisp/locator.c | 82 ++++++++++++++++++++++++-------------------------
1 file changed, 41 insertions(+), 41 deletions(-)
diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c
index 867a19c1ab2..deef4d83fb8 100644
--- a/dlls/wbemdisp/locator.c
+++ b/dlls/wbemdisp/locator.c
@@ -1059,50 +1059,52 @@ static HRESULT WINAPI object_GetTypeInfo(
return E_NOTIMPL;
}
+static BOOL object_reserve_member( struct object *object, unsigned int count, unsigned int *capacity )
+{
+ unsigned int new_capacity, max_capacity;
+ struct member *new_members;
+
+ if (count <= *capacity)
+ return TRUE;
+
+ max_capacity = ~0u / sizeof(*object->members);
+ if (count > max_capacity)
+ return FALSE;
+
+ new_capacity = max(4, *capacity);
+ while (new_capacity < count && new_capacity <= max_capacity / 2)
+ new_capacity *= 2;
+ if (new_capacity < count)
+ new_capacity = max_capacity;
+
+ if (!(new_members = heap_realloc( object->members, new_capacity * sizeof(*new_members) )))
+ return FALSE;
+
+ object->members = new_members;
+ *capacity = new_capacity;
+
+ return TRUE;
+}
+
static HRESULT init_members( struct object *object )
{
IWbemClassObject *sig_in, *sig_out;
- LONG i = 0, count = 0;
- BSTR name;
+ unsigned int i, capacity = 0, count = 0;
HRESULT hr;
+ BSTR name;
if (object->members) return S_OK;
- hr = IWbemClassObject_BeginEnumeration( object->object, 0 );
- if (SUCCEEDED( hr ))
- {
- while (IWbemClassObject_Next( object->object, 0, NULL, NULL, NULL, NULL ) == S_OK) count++;
- IWbemClassObject_EndEnumeration( object->object );
- }
-
- hr = IWbemClassObject_BeginMethodEnumeration( object->object, 0 );
- if (SUCCEEDED( hr ))
- {
- while (IWbemClassObject_NextMethod( object->object, 0, &name, &sig_in, &sig_out ) == S_OK)
- {
- count++;
- SysFreeString( name );
- if (sig_in) IWbemClassObject_Release( sig_in );
- if (sig_out) IWbemClassObject_Release( sig_out );
- }
- IWbemClassObject_EndMethodEnumeration( object->object );
- }
-
- if (!(object->members = heap_alloc( sizeof(struct member) * count ))) return E_OUTOFMEMORY;
-
hr = IWbemClassObject_BeginEnumeration( object->object, 0 );
if (SUCCEEDED( hr ))
{
while (IWbemClassObject_Next( object->object, 0, &name, NULL, NULL, NULL ) == S_OK)
{
- object->members[i].name = name;
- object->members[i].is_method = FALSE;
- object->members[i].dispid = 0;
- if (++i > count)
- {
- IWbemClassObject_EndEnumeration( object->object );
- goto error;
- }
+ if (!object_reserve_member( object, count + 1, &capacity )) goto error;
+ object->members[count].name = name;
+ object->members[count].is_method = FALSE;
+ object->members[count].dispid = 0;
+ count++;
TRACE( "added property %s\n", debugstr_w(name) );
}
IWbemClassObject_EndEnumeration( object->object );
@@ -1113,14 +1115,11 @@ static HRESULT init_members( struct object *object )
{
while (IWbemClassObject_NextMethod( object->object, 0, &name, &sig_in, &sig_out ) == S_OK)
{
- object->members[i].name = name;
- object->members[i].is_method = TRUE;
- object->members[i].dispid = 0;
- if (++i > count)
- {
- IWbemClassObject_EndMethodEnumeration( object->object );
- goto error;
- }
+ if (!object_reserve_member( object, count + 1, &capacity )) goto error;
+ object->members[count].name = name;
+ object->members[count].is_method = TRUE;
+ object->members[count].dispid = 0;
+ count++;
if (sig_in) IWbemClassObject_Release( sig_in );
if (sig_out) IWbemClassObject_Release( sig_out );
TRACE( "added method %s\n", debugstr_w(name) );
@@ -1133,7 +1132,8 @@ static HRESULT init_members( struct object *object )
return S_OK;
error:
- for (--i; i >= 0; i--) SysFreeString( object->members[i].name );
+ for (i = 0; i < count; ++i)
+ SysFreeString( object->members[i].name );
heap_free( object->members );
object->members = NULL;
object->nb_members = 0;
More information about the wine-cvs
mailing list