From ef6fa2b9f2e5141000d8602625159dfe45867fe6 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 10 Oct 2012 12:01:44 +0200 Subject: [PATCH] wbemprox: Add reference counting to the table structure. --- dlls/wbemprox/class.c | 35 +++++++++++++++++------------- dlls/wbemprox/query.c | 4 ++-- dlls/wbemprox/services.c | 8 ++++--- dlls/wbemprox/table.c | 37 ++++++++++++++++++++++++++------ dlls/wbemprox/wbemprox_private.h | 8 ++++--- 5 files changed, 62 insertions(+), 30 deletions(-) diff --git a/dlls/wbemprox/class.c b/dlls/wbemprox/class.c index 5a70e9d6266..5bbd6aab123 100644 --- a/dlls/wbemprox/class.c +++ b/dlls/wbemprox/class.c @@ -382,11 +382,14 @@ static HRESULT WINAPI class_object_Put( if (co->record) { - struct table *table = get_table( co->name ); + struct table *table = grab_table( co->name ); UINT index; HRESULT hr; - if ((hr = get_column_index( table, wszName, &index )) != S_OK) return hr; + if (!table) return WBEM_E_FAILED; + hr = get_column_index( table, wszName, &index ); + release_table( table ); + if (hr != S_OK) return hr; return record_set_value( co->record, index, pVal ); } return put_propval( ec->query->view, co->index, wszName, pVal, Type ); @@ -450,18 +453,18 @@ static HRESULT WINAPI class_object_Next( struct class_object *co = impl_from_IWbemClassObject( iface ); struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); struct view *view = ec->query->view; - const WCHAR *property; + BSTR property; HRESULT hr; TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor); if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA; - if (!(*strName = SysAllocString( property ))) return E_OUTOFMEMORY; if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK)) { - SysFreeString( *strName ); + SysFreeString( property ); return hr; } + *strName = property; co->index_property++; return S_OK; } @@ -834,7 +837,7 @@ static HRESULT WINAPI class_object_NextMethod( IWbemClassObject **ppOutSignature) { struct class_object *co = impl_from_IWbemClassObject( iface ); - const WCHAR *method; + BSTR method; HRESULT hr; TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature); @@ -842,18 +845,20 @@ static HRESULT WINAPI class_object_NextMethod( if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA; hr = create_signature( co->name, method, PARAM_IN, ppInSignature ); - if (hr != S_OK) return hr; - + if (hr != S_OK) + { + SysFreeString( method ); + return hr; + } hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature ); - if (hr != S_OK) IWbemClassObject_Release( *ppInSignature ); + if (hr != S_OK) + { + SysFreeString( method ); + IWbemClassObject_Release( *ppInSignature ); + } else { - if (!(*pstrName = SysAllocString( method ))) - { - IWbemClassObject_Release( *ppInSignature ); - IWbemClassObject_Release( *ppOutSignature ); - return E_OUTOFMEMORY; - } + *pstrName = method; co->index_method++; } return hr; diff --git a/dlls/wbemprox/query.c b/dlls/wbemprox/query.c index 223a373857b..8df09bc72c5 100644 --- a/dlls/wbemprox/query.c +++ b/dlls/wbemprox/query.c @@ -37,7 +37,7 @@ HRESULT create_view( const struct property *proplist, const WCHAR *class, if (!view) return E_OUTOFMEMORY; view->proplist = proplist; - view->table = get_table( class ); + view->table = grab_table( class ); view->cond = cond; view->result = NULL; view->count = 0; @@ -47,7 +47,7 @@ HRESULT create_view( const struct property *proplist, const WCHAR *class, void destroy_view( struct view *view ) { - free_table( view->table ); + if (view->table) release_table( view->table ); heap_free( view->result ); heap_free( view ); } diff --git a/dlls/wbemprox/services.c b/dlls/wbemprox/services.c index 5e9cec0ca89..3f87d5b1a88 100644 --- a/dlls/wbemprox/services.c +++ b/dlls/wbemprox/services.c @@ -578,7 +578,7 @@ static HRESULT WINAPI wbem_services_ExecMethod( IWbemClassObject **ppOutParams, IWbemCallResult **ppCallResult ) { - const struct table *table; + struct table *table; class_method *func; struct path *path; HRESULT hr; @@ -590,11 +590,13 @@ static HRESULT WINAPI wbem_services_ExecMethod( if ((hr = parse_path( strObjectPath, &path )) != S_OK) return hr; - table = get_table( path->class ); + table = grab_table( path->class ); free_path( path ); if (!table) return WBEM_E_NOT_FOUND; - if ((hr = get_method( table, strMethodName, &func )) != S_OK) return hr; + hr = get_method( table, strMethodName, &func ); + release_table( table ); + if (hr != S_OK) return hr; return func( pInParams, ppOutParams ); } diff --git a/dlls/wbemprox/table.c b/dlls/wbemprox/table.c index c414aa9d7fb..a49bf585cc2 100644 --- a/dlls/wbemprox/table.c +++ b/dlls/wbemprox/table.c @@ -316,7 +316,12 @@ void free_table( struct table *table ) } } -struct table *get_table( const WCHAR *name ) +void release_table( struct table *table ) +{ + if (!InterlockedDecrement( &table->refs )) free_table( table ); +} + +struct table *grab_table( const WCHAR *name ) { struct table *table; @@ -325,6 +330,8 @@ struct table *get_table( const WCHAR *name ) if (!strcmpiW( table->name, name )) { if (table->fill && !table->data) table->fill( table ); + InterlockedIncrement( &table->refs ); + TRACE("returning %p\n", table); return table; } } @@ -344,6 +351,7 @@ struct table *create_table( const WCHAR *name, UINT num_cols, const struct colum table->data = data; table->fill = fill; table->flags = TABLE_FLAG_DYNAMIC; + table->refs = 0; list_init( &table->entry ); return table; } @@ -361,41 +369,56 @@ BOOL add_table( struct table *table ) } } list_add_tail( table_list, &table->entry ); + TRACE("added %p\n", table); return TRUE; } -const WCHAR *get_method_name( const WCHAR *class, UINT index ) +BSTR get_method_name( const WCHAR *class, UINT index ) { struct table *table; UINT i, count = 0; + BSTR ret; - if (!(table = get_table( class ))) return NULL; + if (!(table = grab_table( class ))) return NULL; for (i = 0; i < table->num_cols; i++) { if (table->columns[i].type & COL_FLAG_METHOD) { - if (index == count) return table->columns[i].name; + if (index == count) + { + ret = SysAllocString( table->columns[i].name ); + release_table( table ); + return ret; + } count++; } } + release_table( table ); return NULL; } -const WCHAR *get_property_name( const WCHAR *class, UINT index ) +BSTR get_property_name( const WCHAR *class, UINT index ) { struct table *table; UINT i, count = 0; + BSTR ret; - if (!(table = get_table( class ))) return NULL; + if (!(table = grab_table( class ))) return NULL; for (i = 0; i < table->num_cols; i++) { if (!(table->columns[i].type & COL_FLAG_METHOD)) { - if (index == count) return table->columns[i].name; + if (index == count) + { + ret = SysAllocString( table->columns[i].name ); + release_table( table ); + return ret; + } count++; } } + release_table( table ); return NULL; } diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h index b99897e61fa..b0e993335eb 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -57,6 +57,7 @@ struct table void (*fill)(struct table *); UINT flags; struct list entry; + LONG refs; }; struct property @@ -151,7 +152,8 @@ HRESULT create_view( const struct property *, const WCHAR *, const struct expr * struct view ** ) DECLSPEC_HIDDEN; void destroy_view( struct view * ) DECLSPEC_HIDDEN; void init_table_list( void ) DECLSPEC_HIDDEN; -struct table *get_table( const WCHAR * ) DECLSPEC_HIDDEN; +struct table *grab_table( const WCHAR * ) DECLSPEC_HIDDEN; +void release_table( struct table * ) DECLSPEC_HIDDEN; struct table *create_table( const WCHAR *, UINT, const struct column *, UINT, BYTE *, void (*)(struct table *)) DECLSPEC_HIDDEN; BOOL add_table( struct table * ) DECLSPEC_HIDDEN; @@ -169,8 +171,8 @@ HRESULT put_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYP HRESULT variant_to_longlong( VARIANT *, LONGLONG *, CIMTYPE * ) DECLSPEC_HIDDEN; HRESULT get_properties( const struct view *, SAFEARRAY ** ) DECLSPEC_HIDDEN; HRESULT get_object( const WCHAR *, IWbemClassObject ** ) DECLSPEC_HIDDEN; -const WCHAR *get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; -const WCHAR *get_property_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; +BSTR get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; +BSTR get_property_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; HRESULT WbemLocator_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; HRESULT WbemServices_create(IUnknown *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN;