[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