[5/5] wbemprox: Avoid storing rows that don't match the query condition.

Hans Leidekker hans at codeweavers.com
Wed May 22 03:10:16 CDT 2013


---
 dlls/wbemprox/builtin.c          |  164 +++++++++++++++++++++++++++-----------
 dlls/wbemprox/table.c            |   35 ++++----
 dlls/wbemprox/wbemprox_private.h |    1 +
 3 files changed, 135 insertions(+), 65 deletions(-)

diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index b277750..2d89281 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -682,13 +682,32 @@ static const struct record_stdregprov data_stdregprov[] =
     { reg_enum_key, reg_enum_values, reg_get_stringvalue }
 };
 
+/* check if row matches condition and update status */
+static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
+{
+    LONGLONG val;
+    if (!cond)
+    {
+        *status = FILL_STATUS_UNFILTERED;
+        return TRUE;
+    }
+    if (eval_cond( table, row, cond, &val ) != S_OK)
+    {
+        *status = FILL_STATUS_FAILED;
+        return FALSE;
+    }
+    *status = FILL_STATUS_FILTERED;
+    return val != 0;
+}
+
 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
 {
     static const WCHAR fmtW[] = {'%','c',':',0};
     WCHAR drive[3], root[] = {'A',':','\\',0};
     struct record_cdromdrive *rec;
-    UINT i, num_rows = 0, offset = 0, count = 1;
+    UINT i, row = 0, offset = 0, count = 1;
     DWORD drives = GetLogicalDrives();
+    enum fill_status status = FILL_STATUS_UNFILTERED;
 
     if (!(table->data = heap_alloc( count * sizeof(*rec) ))) return FILL_STATUS_FAILED;
 
@@ -700,7 +719,7 @@ static enum fill_status fill_cdromdrive( struct table *table, const struct expr
             if (GetDriveTypeW( root ) != DRIVE_CDROM)
                 continue;
 
-            if (num_rows > count)
+            if (row > count)
             {
                 BYTE *data;
                 count *= 2;
@@ -713,13 +732,18 @@ static enum fill_status fill_cdromdrive( struct table *table, const struct expr
             rec->drive        = heap_strdupW( drive );
             rec->name         = cdromdrive_nameW;
             rec->pnpdevice_id = cdromdrive_pnpdeviceidW;
+            if (!match_row( table, row, cond, &status ))
+            {
+                free_row_values( table, row );
+                continue;
+            }
             offset += sizeof(*rec);
-            num_rows++;
+            row++;
         }
     }
-    TRACE("created %u rows\n", num_rows);
-    table->num_rows = num_rows;
-    return FILL_STATUS_UNFILTERED;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
 }
 
 static UINT get_processor_count(void)
@@ -768,7 +792,7 @@ static UINT64 get_total_physical_memory(void)
 static WCHAR *get_computername(void)
 {
     WCHAR *ret;
-    DWORD size=MAX_COMPUTERNAME_LENGTH;
+    DWORD size = MAX_COMPUTERNAME_LENGTH;
 
     if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
     GetComputerNameW( ret, &size );
@@ -778,6 +802,8 @@ static WCHAR *get_computername(void)
 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
 {
     struct record_computersystem *rec;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    UINT row = 0;
 
     if (!(table->data = heap_alloc( sizeof(*rec) ))) return FILL_STATUS_FAILED;
 
@@ -791,10 +817,12 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
     rec->num_logical_processors = get_logical_processor_count();
     rec->num_processors         = get_processor_count();
     rec->total_physical_memory  = get_total_physical_memory();
+    if (!match_row( table, row, cond, &status )) free_row_values( table, row );
+    else row++;
 
-    TRACE("created 1 row\n");
-    table->num_rows = 1;
-    return FILL_STATUS_UNFILTERED;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
 }
 
 static WCHAR *get_filesystem( const WCHAR *root )
@@ -834,9 +862,10 @@ static enum fill_status fill_diskpartition( struct table *table, const struct ex
         {'D','i','s','k',' ','#','%','u',',',' ','P','a','r','t','i','t','i','o','n',' ','#','0',0};
     WCHAR device_id[32], root[] = {'A',':','\\',0};
     struct record_diskpartition *rec;
-    UINT i, num_rows = 0, offset = 0, count = 4, type, index = 0;
+    UINT i, row = 0, offset = 0, count = 4, type, index = 0;
     UINT64 size = 1024 * 1024 * 1024;
     DWORD drives = GetLogicalDrives();
+    enum fill_status status = FILL_STATUS_UNFILTERED;
 
     if (!(table->data = heap_alloc( count * sizeof(*rec) ))) return FILL_STATUS_FAILED;
 
@@ -849,7 +878,7 @@ static enum fill_status fill_diskpartition( struct table *table, const struct ex
             if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
                 continue;
 
-            if (num_rows > count)
+            if (row > count)
             {
                 BYTE *data;
                 count *= 2;
@@ -868,14 +897,19 @@ static enum fill_status fill_diskpartition( struct table *table, const struct ex
             rec->size           = size;
             rec->startingoffset = 0;
             rec->type           = get_filesystem( root );
+            if (!match_row( table, row, cond, &status ))
+            {
+                free_row_values( table, row );
+                continue;
+            }
             offset += sizeof(*rec);
-            num_rows++;
+            row++;
             index++;
         }
     }
-    TRACE("created %u rows\n", num_rows);
-    table->num_rows = num_rows;
-    return FILL_STATUS_UNFILTERED;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
 }
 
 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
@@ -883,9 +917,10 @@ static enum fill_status fill_logicaldisk( struct table *table, const struct expr
     static const WCHAR fmtW[] = {'%','c',':',0};
     WCHAR device_id[3], root[] = {'A',':','\\',0};
     struct record_logicaldisk *rec;
-    UINT i, num_rows = 0, offset = 0, count = 4, type;
+    UINT i, row = 0, offset = 0, count = 4, type;
     UINT64 size = 1024 * 1024 * 1024;
     DWORD drives = GetLogicalDrives();
+    enum fill_status status = FILL_STATUS_UNFILTERED;
 
     if (!(table->data = heap_alloc( count * sizeof(*rec) ))) return FILL_STATUS_FAILED;
 
@@ -898,7 +933,7 @@ static enum fill_status fill_logicaldisk( struct table *table, const struct expr
             if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
                 continue;
 
-            if (num_rows > count)
+            if (row > count)
             {
                 BYTE *data;
                 count *= 2;
@@ -913,13 +948,18 @@ static enum fill_status fill_logicaldisk( struct table *table, const struct expr
             rec->freespace  = get_freespace( root, &size );
             rec->name       = heap_strdupW( device_id );
             rec->size       = size;
+            if (!match_row( table, row, cond, &status ))
+            {
+                free_row_values( table, row );
+                continue;
+            }
             offset += sizeof(*rec);
-            num_rows++;
+            row++;
         }
     }
-    TRACE("created %u rows\n", num_rows);
-    table->num_rows = num_rows;
-    return FILL_STATUS_UNFILTERED;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
 }
 
 static UINT16 get_connection_status( IF_OPER_STATUS status )
@@ -971,8 +1011,9 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e
     WCHAR device_id[11];
     struct record_networkadapter *rec;
     IP_ADAPTER_ADDRESSES *aa, *buffer;
-    UINT num_rows = 0, offset = 0;
+    UINT row = 0, offset = 0, count = 0;
     DWORD size = 0, ret;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
 
     ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
     if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
@@ -983,8 +1024,8 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e
         heap_free( buffer );
         return FILL_STATUS_FAILED;
     }
-    for (aa = buffer; aa; aa = aa->Next) num_rows++;
-    if (!(table->data = heap_alloc( sizeof(*rec) * num_rows )))
+    for (aa = buffer; aa; aa = aa->Next) count++;
+    if (!(table->data = heap_alloc( sizeof(*rec) * count )))
     {
         heap_free( buffer );
         return FILL_STATUS_FAILED;
@@ -1001,13 +1042,19 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e
         rec->netconnection_status = get_connection_status( aa->OperStatus );
         rec->pnpdevice_id         = networkadapter_pnpdeviceidW;
         rec->speed                = 1000000;
+        if (!match_row( table, row, cond, &status ))
+        {
+            free_row_values( table, row );
+            continue;
+        }
         offset += sizeof(*rec);
+        row++;
     }
-    TRACE("created %u rows\n", num_rows);
-    table->num_rows = num_rows;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
 
     heap_free( buffer );
-    return FILL_STATUS_UNFILTERED;
+    return status;
 }
 
 static WCHAR *get_cmdline( DWORD process_id )
@@ -1024,7 +1071,7 @@ static enum fill_status fill_process( struct table *table, const struct expr *co
     PROCESSENTRY32W entry;
     HANDLE snap;
     enum fill_status status = FILL_STATUS_FAILED;
-    UINT num_rows = 0, offset = 0, count = 8;
+    UINT row = 0, offset = 0, count = 8;
 
     snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
     if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED;
@@ -1035,7 +1082,7 @@ static enum fill_status fill_process( struct table *table, const struct expr *co
 
     do
     {
-        if (num_rows > count)
+        if (row > count)
         {
             BYTE *data;
             count *= 2;
@@ -1053,12 +1100,17 @@ static enum fill_status fill_process( struct table *table, const struct expr *co
         rec->pprocess_id  = entry.th32ParentProcessID;
         rec->thread_count = entry.cntThreads;
         rec->get_owner    = process_get_owner;
+        if (!match_row( table, row, cond, &status ))
+        {
+            free_row_values( table, row );
+            continue;
+        }
         offset += sizeof(*rec);
-        num_rows++;
+        row++;
     } while (Process32NextW( snap, &entry ));
 
-    TRACE("created %u rows\n", num_rows);
-    table->num_rows = num_rows;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
     status = FILL_STATUS_UNFILTERED;
 
 done:
@@ -1144,6 +1196,7 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
     WCHAR device_id[14], processor_id[17], manufacturer[13], name[49] = {0};
     struct record_processor *rec;
     UINT i, offset = 0, maxclockspeed, num_logical_processors, count = get_processor_count();
+    enum fill_status status = FILL_STATUS_UNFILTERED;
 
     if (!(table->data = heap_alloc( sizeof(*rec) * count ))) return FILL_STATUS_FAILED;
 
@@ -1167,12 +1220,17 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
         rec->num_logical_processors = num_logical_processors;
         rec->processor_id           = heap_strdupW( processor_id );
         rec->unique_id              = NULL;
+        if (!match_row( table, i, cond, &status ))
+        {
+            free_row_values( table, i );
+            continue;
+        }
         offset += sizeof(*rec);
     }
 
     TRACE("created %u rows\n", count);
     table->num_rows = count;
-    return FILL_STATUS_UNFILTERED;
+    return status;
 }
 
 static WCHAR *get_lastbootuptime(void)
@@ -1213,6 +1271,8 @@ static WCHAR *get_systemdirectory(void)
 static enum fill_status fill_os( struct table *table, const struct expr *cond )
 {
     struct record_operatingsystem *rec;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    UINT row = 0;
 
     if (!(table->data = heap_alloc( sizeof(*rec) ))) return FILL_STATUS_FAILED;
 
@@ -1228,10 +1288,12 @@ static enum fill_status fill_os( struct table *table, const struct expr *cond )
     rec->suitemask        = 272;     /* Single User + Terminal */
     rec->systemdirectory  = get_systemdirectory();
     rec->version          = os_versionW;
+    if (!match_row( table, row, cond, &status )) free_row_values( table, row );
+    else row++;
 
-    TRACE("created 1 row\n");
-    table->num_rows = 1;
-    return FILL_STATUS_UNFILTERED;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
+    return status;
 }
 
 static const WCHAR *get_service_type( DWORD type )
@@ -1276,7 +1338,6 @@ static const WCHAR *get_service_state( DWORD state )
         return unknownW;
     }
 }
-
 static const WCHAR *get_service_startmode( DWORD mode )
 {
     static const WCHAR bootW[] = {'B','o','o','t',0};
@@ -1298,7 +1359,6 @@ static const WCHAR *get_service_startmode( DWORD mode )
         return unknownW;
     }
 }
-
 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name )
 {
     QUERY_SERVICE_CONFIGW *config = NULL;
@@ -1326,7 +1386,7 @@ static enum fill_status fill_service( struct table *table, const struct expr *co
     SERVICE_STATUS_PROCESS *status;
     WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1];
     DWORD len = sizeof(sysnameW) / sizeof(sysnameW[0]);
-    UINT i, num_rows = 0, offset = 0, size = 256, needed, count;
+    UINT i, row = 0, offset = 0, size = 256, needed, count;
     enum fill_status fill_status = FILL_STATUS_FAILED;
     BOOL ret;
 
@@ -1350,6 +1410,7 @@ static enum fill_status fill_service( struct table *table, const struct expr *co
     if (!(table->data = heap_alloc( sizeof(*rec) * count ))) goto done;
 
     GetComputerNameW( sysnameW, &len );
+    fill_status = FILL_STATUS_UNFILTERED;
 
     for (i = 0; i < count; i++)
     {
@@ -1373,13 +1434,17 @@ static enum fill_status fill_service( struct table *table, const struct expr *co
         rec->start_service  = service_start_service;
         rec->stop_service   = service_stop_service;
         heap_free( config );
+        if (!match_row( table, row, cond, &fill_status ))
+        {
+            free_row_values( table, row );
+            continue;
+        }
         offset += sizeof(*rec);
-        num_rows++;
+        row++;
     }
 
-    TRACE("created %u rows\n", num_rows);
-    table->num_rows = num_rows;
-    fill_status = FILL_STATUS_UNFILTERED;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
 
 done:
     CloseServiceHandle( manager );
@@ -1399,7 +1464,6 @@ static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres )
     ReleaseDC( NULL, hdc );
     return ret;
 }
-
 static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
 {
     static const WCHAR fmtW[] =
@@ -1423,6 +1487,8 @@ static enum fill_status fill_videocontroller( struct table *table, const struct
     DXGI_ADAPTER_DESC desc;
     UINT hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
     const WCHAR *name = videocontroller_deviceidW;
+    enum fill_status status = FILL_STATUS_UNFILTERED;
+    UINT row = 0;
 
     if (!(table->data = heap_alloc( sizeof(*rec) ))) return FILL_STATUS_FAILED;
     memset (&desc, 0, sizeof(desc));
@@ -1449,13 +1515,15 @@ done:
     rec->device_id             = videocontroller_deviceidW;
     rec->name                  = heap_strdupW( name );
     rec->pnpdevice_id          = get_pnpdeviceid( &desc );
+    if (!match_row( table, row, cond, &status )) free_row_values( table, row );
+    else row++;
 
-    TRACE("created 1 row\n");
-    table->num_rows = 1;
+    TRACE("created %u rows\n", row);
+    table->num_rows = row;
 
     if (adapter) IDXGIAdapter_Release( adapter );
     if (factory) IDXGIFactory_Release( factory );
-    return FILL_STATUS_UNFILTERED;
+    return status;
 }
 
 static struct table builtin_classes[] =
diff --git a/dlls/wbemprox/table.c b/dlls/wbemprox/table.c
index e7dc77d..29aef06 100644
--- a/dlls/wbemprox/table.c
+++ b/dlls/wbemprox/table.c
@@ -263,26 +263,30 @@ HRESULT get_method( const struct table *table, const WCHAR *name, class_method *
 
 }
 
-void clear_table( struct table *table )
+void free_row_values( const struct table *table, UINT row )
 {
-    UINT i, j, type;
+    UINT i, type;
     LONGLONG val;
 
-    if (!table->data) return;
-
-    for (i = 0; i < table->num_rows; i++)
+    for (i = 0; i < table->num_cols; i++)
     {
-        for (j = 0; j < table->num_cols; j++)
-        {
-            if (!(table->columns[j].type & COL_FLAG_DYNAMIC)) continue;
+        if (!(table->columns[i].type & COL_FLAG_DYNAMIC)) continue;
 
-            type = table->columns[j].type & COL_TYPE_MASK;
-            if (type == CIM_STRING || type == CIM_DATETIME || (type & CIM_FLAG_ARRAY))
-            {
-                if (get_value( table, i, j, &val ) == S_OK) heap_free( (void *)(INT_PTR)val );
-            }
+        type = table->columns[i].type & COL_TYPE_MASK;
+        if (type == CIM_STRING || type == CIM_DATETIME || (type & CIM_FLAG_ARRAY))
+        {
+            if (get_value( table, row, i, &val ) == S_OK) heap_free( (void *)(INT_PTR)val );
         }
     }
+}
+
+void clear_table( struct table *table )
+{
+    UINT i;
+
+    if (!table->data) return;
+
+    for (i = 0; i < table->num_rows; i++) free_row_values( table, i );
     if (table->fill)
     {
         table->num_rows = 0;
@@ -295,10 +299,7 @@ void free_columns( struct column *columns, UINT num_cols )
 {
     UINT i;
 
-    for (i = 0; i < num_cols; i++)
-    {
-        heap_free( (WCHAR *)columns[i].name );
-    }
+    for (i = 0; i < num_cols; i++) { heap_free( (WCHAR *)columns[i].name ); }
     heap_free( columns );
 }
 
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index bbf2e21..4f3934a 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -178,6 +178,7 @@ struct table *create_table( const WCHAR *, UINT, const struct column *, UINT, BY
                             enum fill_status (*)(struct table *, const struct expr *) ) DECLSPEC_HIDDEN;
 BOOL add_table( struct table * ) DECLSPEC_HIDDEN;
 void free_columns( struct column *, UINT ) DECLSPEC_HIDDEN;
+void free_row_values( const struct table *, UINT ) DECLSPEC_HIDDEN;
 void clear_table( struct table * ) DECLSPEC_HIDDEN;
 void free_table( struct table * ) DECLSPEC_HIDDEN;
 UINT get_type_size( CIMTYPE ) DECLSPEC_HIDDEN;
-- 
1.7.10.4






More information about the wine-patches mailing list