mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 17:27:18 +00:00
wmiutils: Add support for for parsing and serializing a key list.
This commit is contained in:
parent
d0d28b96a4
commit
7b00683d6e
|
@ -32,6 +32,14 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wmiutils);
|
||||
|
||||
struct key
|
||||
{
|
||||
WCHAR *name;
|
||||
int len_name;
|
||||
WCHAR *value;
|
||||
int len_value;
|
||||
};
|
||||
|
||||
struct path
|
||||
{
|
||||
IWbemPath IWbemPath_iface;
|
||||
|
@ -46,6 +54,8 @@ struct path
|
|||
int num_namespaces;
|
||||
WCHAR *class;
|
||||
int len_class;
|
||||
struct key *keys;
|
||||
unsigned int num_keys;
|
||||
ULONGLONG flags;
|
||||
};
|
||||
|
||||
|
@ -60,16 +70,26 @@ static void init_path( struct path *path )
|
|||
path->num_namespaces = 0;
|
||||
path->class = NULL;
|
||||
path->len_class = 0;
|
||||
path->keys = NULL;
|
||||
path->num_keys = 0;
|
||||
path->flags = 0;
|
||||
}
|
||||
|
||||
static void clear_path( struct path *path )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
heap_free( path->text );
|
||||
heap_free( path->server );
|
||||
heap_free( path->namespaces );
|
||||
heap_free( path->len_namespaces );
|
||||
heap_free( path->class );
|
||||
for (i = 0; i < path->num_keys; i++)
|
||||
{
|
||||
heap_free( path->keys[i].name );
|
||||
heap_free( path->keys[i].value );
|
||||
}
|
||||
heap_free( path->keys );
|
||||
init_path( path );
|
||||
}
|
||||
|
||||
|
@ -124,6 +144,38 @@ static HRESULT WINAPI path_QueryInterface(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT parse_key( struct key *key, const WCHAR *str, unsigned int *ret_len )
|
||||
{
|
||||
const WCHAR *p, *q;
|
||||
unsigned int len;
|
||||
|
||||
p = q = str;
|
||||
while (*q && *q != '=')
|
||||
{
|
||||
if (*q == ',' || isspaceW( *q )) return WBEM_E_INVALID_PARAMETER;
|
||||
q++;
|
||||
}
|
||||
len = q - p;
|
||||
if (!(key->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
|
||||
memcpy( key->name, p, len * sizeof(WCHAR) );
|
||||
key->name[len] = 0;
|
||||
key->len_name = len;
|
||||
|
||||
p = ++q;
|
||||
if (!*p || *p == ',' || isspaceW( *p )) return WBEM_E_INVALID_PARAMETER;
|
||||
|
||||
while (*q && *q != ',') q++;
|
||||
len = q - p;
|
||||
if (!(key->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
|
||||
memcpy( key->value, p, len * sizeof(WCHAR) );
|
||||
key->value[len] = 0;
|
||||
key->len_value = len;
|
||||
|
||||
*ret_len = q - str;
|
||||
if (*q == ',') (*ret_len)++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT parse_text( struct path *path, ULONG mode, const WCHAR *text )
|
||||
{
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
|
@ -181,7 +233,27 @@ static HRESULT parse_text( struct path *path, ULONG mode, const WCHAR *text )
|
|||
path->class[len] = 0;
|
||||
path->len_class = len;
|
||||
|
||||
if (*q == '.') FIXME("handle key list\n");
|
||||
if (*q == '.')
|
||||
{
|
||||
p = ++q;
|
||||
path->num_keys++;
|
||||
while (*q)
|
||||
{
|
||||
if (*q == ',') path->num_keys++;
|
||||
q++;
|
||||
}
|
||||
if (!(path->keys = heap_alloc_zero( path->num_keys * sizeof(struct key) ))) goto done;
|
||||
i = 0;
|
||||
q = p;
|
||||
while (*q)
|
||||
{
|
||||
if (i >= path->num_keys) break;
|
||||
hr = parse_key( &path->keys[i], q, &len );
|
||||
if (hr != S_OK) goto done;
|
||||
q += len;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
hr = S_OK;
|
||||
|
||||
done:
|
||||
|
@ -267,22 +339,58 @@ static WCHAR *build_server( struct path *path, int *len )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *build_keylist( struct path *path, int *len )
|
||||
{
|
||||
WCHAR *ret, *p;
|
||||
unsigned int i;
|
||||
|
||||
*len = 0;
|
||||
for (i = 0; i < path->num_keys; i++)
|
||||
{
|
||||
if (i > 0) *len += 1;
|
||||
*len += path->keys[i].len_name + path->keys[i].len_value + 1;
|
||||
}
|
||||
if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
|
||||
for (i = 0; i < path->num_keys; i++)
|
||||
{
|
||||
if (i > 0) *p++ = ',';
|
||||
memcpy( p, path->keys[i].name, path->keys[i].len_name * sizeof(WCHAR) );
|
||||
p += path->keys[i].len_name;
|
||||
*p++ = '=';
|
||||
memcpy( p, path->keys[i].value, path->keys[i].len_value * sizeof(WCHAR) );
|
||||
p += path->keys[i].len_value;
|
||||
}
|
||||
*p = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *build_path( struct path *path, LONG flags, int *len )
|
||||
{
|
||||
*len = 0;
|
||||
switch (flags)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
int len_namespace;
|
||||
int len_namespace, len_keylist;
|
||||
WCHAR *ret, *namespace = build_namespace( path, &len_namespace, FALSE );
|
||||
WCHAR *keylist = build_keylist( path, &len_keylist );
|
||||
|
||||
if (!namespace) return NULL;
|
||||
|
||||
if (!namespace || !keylist)
|
||||
{
|
||||
heap_free( namespace );
|
||||
heap_free( keylist );
|
||||
return NULL;
|
||||
}
|
||||
*len = len_namespace;
|
||||
if (path->len_class) *len += 1 + path->len_class;
|
||||
if (path->len_class)
|
||||
{
|
||||
*len += path->len_class + 1;
|
||||
if (path->num_keys) *len += len_keylist + 1;
|
||||
}
|
||||
if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
heap_free( namespace );
|
||||
heap_free( keylist );
|
||||
return NULL;
|
||||
}
|
||||
strcpyW( ret, namespace );
|
||||
|
@ -290,38 +398,66 @@ static WCHAR *build_path( struct path *path, LONG flags, int *len )
|
|||
{
|
||||
ret[len_namespace] = ':';
|
||||
strcpyW( ret + len_namespace + 1, path->class );
|
||||
if (path->num_keys)
|
||||
{
|
||||
ret[len_namespace + path->len_class + 1] = '.';
|
||||
strcpyW( ret + len_namespace + path->len_class + 2, keylist );
|
||||
}
|
||||
}
|
||||
heap_free( namespace );
|
||||
heap_free( keylist );
|
||||
return ret;
|
||||
|
||||
}
|
||||
case WBEMPATH_GET_RELATIVE_ONLY:
|
||||
if (!path->len_class)
|
||||
{
|
||||
int len_keylist;
|
||||
WCHAR *ret, *keylist;
|
||||
|
||||
if (!path->len_class) return NULL;
|
||||
if (!(keylist = build_keylist( path, &len_keylist ))) return NULL;
|
||||
|
||||
*len = path->len_class;
|
||||
if (path->num_keys) *len += len_keylist + 1;
|
||||
if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
*len = 0;
|
||||
heap_free( keylist );
|
||||
return NULL;
|
||||
}
|
||||
*len = path->len_class;
|
||||
return strdupW( path->class );
|
||||
|
||||
strcpyW( ret, path->class );
|
||||
if (path->num_keys)
|
||||
{
|
||||
ret[path->len_class] = '.';
|
||||
strcpyW( ret + path->len_class + 1, keylist );
|
||||
}
|
||||
heap_free( keylist );
|
||||
return ret;
|
||||
}
|
||||
case WBEMPATH_GET_SERVER_TOO:
|
||||
{
|
||||
int len_namespace, len_server;
|
||||
int len_namespace, len_server, len_keylist;
|
||||
WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
|
||||
WCHAR *server = build_server( path, &len_server );
|
||||
WCHAR *keylist = build_keylist( path, &len_keylist );
|
||||
|
||||
if (!namespace || !server)
|
||||
if (!namespace || !server || !keylist)
|
||||
{
|
||||
heap_free( namespace );
|
||||
heap_free( server );
|
||||
heap_free( keylist );
|
||||
return NULL;
|
||||
}
|
||||
*len = len_namespace + len_server;
|
||||
if (path->len_class) *len += 1 + path->len_class;
|
||||
if (path->len_class)
|
||||
{
|
||||
*len += path->len_class + 1;
|
||||
if (path->num_keys) *len += len_keylist + 1;
|
||||
}
|
||||
if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
heap_free( namespace );
|
||||
heap_free( server );
|
||||
heap_free( keylist );
|
||||
return NULL;
|
||||
}
|
||||
strcpyW( p, server );
|
||||
|
@ -330,11 +466,17 @@ static WCHAR *build_path( struct path *path, LONG flags, int *len )
|
|||
p += len_namespace;
|
||||
if (path->len_class)
|
||||
{
|
||||
*p = ':';
|
||||
strcpyW( p + 1, path->class );
|
||||
*p++ = ':';
|
||||
strcpyW( p, path->class );
|
||||
if (path->num_keys)
|
||||
{
|
||||
p[path->len_class] = '.';
|
||||
strcpyW( p + path->len_class + 1, keylist );
|
||||
}
|
||||
}
|
||||
heap_free( namespace );
|
||||
heap_free( server );
|
||||
heap_free( keylist );
|
||||
return ret;
|
||||
}
|
||||
case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY:
|
||||
|
@ -367,11 +509,7 @@ static WCHAR *build_path( struct path *path, LONG flags, int *len )
|
|||
return build_namespace( path, len, FALSE );
|
||||
|
||||
case WBEMPATH_GET_ORIGINAL:
|
||||
if (!path->len_text)
|
||||
{
|
||||
*len = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (!path->len_text) return NULL;
|
||||
*len = path->len_text;
|
||||
return strdupW( path->text );
|
||||
|
||||
|
@ -447,7 +585,7 @@ static HRESULT WINAPI path_GetInfo(
|
|||
else
|
||||
{
|
||||
*response |= WBEMPATH_INFO_HAS_SUBSCOPES;
|
||||
if (path->text && strchrW( path->text, '=' )) /* FIXME */
|
||||
if (path->num_keys)
|
||||
*response |= WBEMPATH_INFO_IS_INST_REF;
|
||||
else
|
||||
*response |= WBEMPATH_INFO_IS_CLASS_REF;
|
||||
|
|
|
@ -59,7 +59,19 @@ static const WCHAR path16[] =
|
|||
{'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0};
|
||||
static const WCHAR path17[] =
|
||||
{'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=','"','C',':','"',0};
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',
|
||||
'"','C',':','"',0};
|
||||
static const WCHAR path18[] =
|
||||
{'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',
|
||||
'"','C',':','"',',','D','r','i','v','e','T','y','p','e','=','3',0};
|
||||
static const WCHAR path19[] =
|
||||
{'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',0};
|
||||
static const WCHAR path20[] =
|
||||
{'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d',' ','=',' ',
|
||||
'"','C',':','"',0};
|
||||
|
||||
static IWbemPath *create_path(void)
|
||||
{
|
||||
|
@ -148,6 +160,13 @@ static void test_IWbemPath_SetText(void)
|
|||
|
||||
static void test_IWbemPath_GetText(void)
|
||||
{
|
||||
static const WCHAR expected1W[] =
|
||||
{'r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',
|
||||
'"','C',':','"',0};
|
||||
static const WCHAR expected2W[] =
|
||||
{'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k','.',
|
||||
'D','e','v','i','c','e','I','d','=','"','C',':','"',0};
|
||||
WCHAR buf[128];
|
||||
ULONG len, count;
|
||||
IWbemPath *path;
|
||||
|
@ -270,8 +289,31 @@ static void test_IWbemPath_GetText(void)
|
|||
memset( buf, 0x55, sizeof(buf) );
|
||||
hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
todo_wine ok( !lstrcmpW( buf, path17 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
|
||||
todo_wine ok( len == lstrlenW( path17 ) + 1, "unexpected length %u\n", len );
|
||||
ok( !lstrcmpW( buf, path17 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
|
||||
ok( len == lstrlenW( path17 ) + 1, "unexpected length %u\n", len );
|
||||
|
||||
len = sizeof(buf)/sizeof(buf[0]);
|
||||
memset( buf, 0x55, sizeof(buf) );
|
||||
hr = IWbemPath_GetText( path, 0, &len, buf );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
ok( !lstrcmpW( buf, expected1W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
|
||||
ok( len == lstrlenW( expected1W ) + 1, "unexpected length %u\n", len );
|
||||
|
||||
len = sizeof(buf)/sizeof(buf[0]);
|
||||
memset( buf, 0x55, sizeof(buf) );
|
||||
hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
ok( !lstrcmpW( buf, expected2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
|
||||
ok( len == lstrlenW( expected2W ) + 1, "unexpected length %u\n", len );
|
||||
|
||||
hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path18 );
|
||||
ok( hr == S_OK, "got %08x\n", hr );
|
||||
|
||||
hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path19 );
|
||||
ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
|
||||
|
||||
hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path20 );
|
||||
ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
|
||||
|
||||
IWbemPath_Release( path );
|
||||
}
|
||||
|
|
|
@ -27,6 +27,12 @@ static inline void *heap_alloc( size_t len )
|
|||
return HeapAlloc( GetProcessHeap(), 0, len );
|
||||
}
|
||||
|
||||
static void *heap_alloc_zero( size_t len ) __WINE_ALLOC_SIZE(1);
|
||||
static inline void *heap_alloc_zero( size_t len )
|
||||
{
|
||||
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
|
||||
}
|
||||
|
||||
static void *heap_realloc( void *mem, size_t len ) __WINE_ALLOC_SIZE(2);
|
||||
static inline void *heap_realloc( void *mem, size_t len )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue