2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
29 #include "wbemprox_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox
);
33 HRESULT
get_column_index( const struct table
*table
, const WCHAR
*name
, UINT
*column
)
36 for (i
= 0; i
< table
->num_cols
; i
++)
38 if (!strcmpiW( table
->columns
[i
].name
, name
))
44 return WBEM_E_INVALID_QUERY
;
47 UINT
get_type_size( CIMTYPE type
)
49 if (type
& CIM_FLAG_ARRAY
) return sizeof(void *);
69 return sizeof(WCHAR
*);
71 ERR("unhandled type %u\n", type
);
74 return sizeof(LONGLONG
);
77 static UINT
get_column_size( const struct table
*table
, UINT column
)
79 return get_type_size( table
->columns
[column
].type
& COL_TYPE_MASK
);
82 static UINT
get_column_offset( const struct table
*table
, UINT column
)
85 for (i
= 0; i
< column
; i
++) offset
+= get_column_size( table
, i
);
89 static UINT
get_row_size( const struct table
*table
)
91 return get_column_offset( table
, table
->num_cols
- 1 ) + get_column_size( table
, table
->num_cols
- 1 );
94 HRESULT
get_value( const struct table
*table
, UINT row
, UINT column
, LONGLONG
*val
)
96 UINT col_offset
, row_size
;
99 col_offset
= get_column_offset( table
, column
);
100 row_size
= get_row_size( table
);
101 ptr
= table
->data
+ row
* row_size
+ col_offset
;
103 if (table
->columns
[column
].type
& CIM_FLAG_ARRAY
)
105 *val
= (INT_PTR
)*(const void **)ptr
;
108 switch (table
->columns
[column
].type
& COL_TYPE_MASK
)
111 *val
= *(const int *)ptr
;
115 *val
= (INT_PTR
)*(const WCHAR
**)ptr
;
118 *val
= *(const INT8
*)ptr
;
121 *val
= *(const UINT8
*)ptr
;
124 *val
= *(const INT16
*)ptr
;
127 *val
= *(const UINT16
*)ptr
;
130 *val
= *(const INT32
*)ptr
;
133 *val
= *(const UINT32
*)ptr
;
136 *val
= *(const INT64
*)ptr
;
139 *val
= *(const UINT64
*)ptr
;
142 ERR("invalid column type %u\n", table
->columns
[column
].type
& COL_TYPE_MASK
);
149 BSTR
get_value_bstr( const struct table
*table
, UINT row
, UINT column
)
151 static const WCHAR fmt_signedW
[] = {'%','d',0};
152 static const WCHAR fmt_unsignedW
[] = {'%','u',0};
153 static const WCHAR fmt_signed64W
[] = {'%','I','6','4','d',0};
154 static const WCHAR fmt_unsigned64W
[] = {'%','I','6','4','u',0};
155 static const WCHAR fmt_strW
[] = {'\"','%','s','\"',0};
156 static const WCHAR trueW
[] = {'T','R','U','E',0};
157 static const WCHAR falseW
[] = {'F','A','L','S','E',0};
163 if (table
->columns
[column
].type
& CIM_FLAG_ARRAY
)
165 FIXME("array to string conversion not handled\n");
168 if (get_value( table
, row
, column
, &val
) != S_OK
) return NULL
;
170 switch (table
->columns
[column
].type
& COL_TYPE_MASK
)
173 if (val
) return SysAllocString( trueW
);
174 else return SysAllocString( falseW
);
178 if (!val
) return NULL
;
179 len
= strlenW( (const WCHAR
*)(INT_PTR
)val
) + 2;
180 if (!(ret
= SysAllocStringLen( NULL
, len
))) return NULL
;
181 sprintfW( ret
, fmt_strW
, (const WCHAR
*)(INT_PTR
)val
);
186 sprintfW( number
, fmt_signedW
, val
);
187 return SysAllocString( number
);
191 sprintfW( number
, fmt_unsignedW
, val
);
192 return SysAllocString( number
);
195 wsprintfW( number
, fmt_signed64W
, val
);
196 return SysAllocString( number
);
199 wsprintfW( number
, fmt_unsigned64W
, val
);
200 return SysAllocString( number
);
203 FIXME("unhandled column type %u\n", table
->columns
[column
].type
& COL_TYPE_MASK
);
209 HRESULT
set_value( const struct table
*table
, UINT row
, UINT column
, LONGLONG val
,
212 UINT col_offset
, row_size
;
215 if ((table
->columns
[column
].type
& COL_TYPE_MASK
) != type
) return WBEM_E_TYPE_MISMATCH
;
217 col_offset
= get_column_offset( table
, column
);
218 row_size
= get_row_size( table
);
219 ptr
= table
->data
+ row
* row_size
+ col_offset
;
221 switch (table
->columns
[column
].type
& COL_TYPE_MASK
)
225 *(WCHAR
**)ptr
= (WCHAR
*)(INT_PTR
)val
;
237 *(UINT16
*)ptr
= val
;
243 *(UINT32
*)ptr
= val
;
249 *(UINT64
*)ptr
= val
;
252 FIXME("unhandled column type %u\n", type
);
253 return WBEM_E_FAILED
;
258 HRESULT
get_method( const struct table
*table
, const WCHAR
*name
, class_method
**func
)
262 for (i
= 0; i
< table
->num_rows
; i
++)
264 for (j
= 0; j
< table
->num_cols
; j
++)
266 if (table
->columns
[j
].type
& COL_FLAG_METHOD
&& !strcmpW( table
->columns
[j
].name
, name
))
271 if ((hr
= get_value( table
, i
, j
, &val
)) != S_OK
) return hr
;
272 *func
= (class_method
*)(INT_PTR
)val
;
277 return WBEM_E_INVALID_METHOD
;
281 void free_row_values( const struct table
*table
, UINT row
)
286 for (i
= 0; i
< table
->num_cols
; i
++)
288 if (!(table
->columns
[i
].type
& COL_FLAG_DYNAMIC
)) continue;
290 type
= table
->columns
[i
].type
& COL_TYPE_MASK
;
291 if (type
== CIM_STRING
|| type
== CIM_DATETIME
)
293 if (get_value( table
, row
, i
, &val
) == S_OK
) heap_free( (void *)(INT_PTR
)val
);
295 else if (type
& CIM_FLAG_ARRAY
)
297 if (get_value( table
, row
, i
, &val
) == S_OK
)
298 destroy_array( (void *)(INT_PTR
)val
, type
& CIM_TYPE_MASK
);
303 void clear_table( struct table
*table
)
307 if (!table
->data
) return;
309 for (i
= 0; i
< table
->num_rows
; i
++) free_row_values( table
, i
);
313 table
->num_rows_allocated
= 0;
314 heap_free( table
->data
);
319 void free_columns( struct column
*columns
, UINT num_cols
)
323 for (i
= 0; i
< num_cols
; i
++) { heap_free( (WCHAR
*)columns
[i
].name
); }
324 heap_free( columns
);
327 void free_table( struct table
*table
)
331 clear_table( table
);
332 if (table
->flags
& TABLE_FLAG_DYNAMIC
)
334 TRACE("destroying %p\n", table
);
335 heap_free( (WCHAR
*)table
->name
);
336 free_columns( (struct column
*)table
->columns
, table
->num_cols
);
337 heap_free( table
->data
);
338 list_remove( &table
->entry
);
343 void release_table( struct table
*table
)
345 if (!InterlockedDecrement( &table
->refs
)) free_table( table
);
348 struct table
*addref_table( struct table
*table
)
350 InterlockedIncrement( &table
->refs
);
354 struct table
*grab_table( const WCHAR
*name
)
358 LIST_FOR_EACH_ENTRY( table
, table_list
, struct table
, entry
)
360 if (!strcmpiW( table
->name
, name
))
362 TRACE("returning %p\n", table
);
363 return addref_table( table
);
369 struct table
*create_table( const WCHAR
*name
, UINT num_cols
, const struct column
*columns
,
370 UINT num_rows
, UINT num_allocated
, BYTE
*data
,
371 enum fill_status (*fill
)(struct table
*, const struct expr
*cond
) )
375 if (!(table
= heap_alloc( sizeof(*table
) ))) return NULL
;
376 table
->name
= heap_strdupW( name
);
377 table
->num_cols
= num_cols
;
378 table
->columns
= columns
;
379 table
->num_rows
= num_rows
;
380 table
->num_rows_allocated
= num_allocated
;
383 table
->flags
= TABLE_FLAG_DYNAMIC
;
385 list_init( &table
->entry
);
389 BOOL
add_table( struct table
*table
)
393 LIST_FOR_EACH_ENTRY( iter
, table_list
, struct table
, entry
)
395 if (!strcmpiW( iter
->name
, table
->name
))
397 TRACE("table %s already exists\n", debugstr_w(table
->name
));
401 list_add_tail( table_list
, &table
->entry
);
402 TRACE("added %p\n", table
);
406 BSTR
get_method_name( const WCHAR
*class, UINT index
)
412 if (!(table
= grab_table( class ))) return NULL
;
414 for (i
= 0; i
< table
->num_cols
; i
++)
416 if (table
->columns
[i
].type
& COL_FLAG_METHOD
)
420 ret
= SysAllocString( table
->columns
[i
].name
);
421 release_table( table
);
427 release_table( table
);