wbemprox: Parse the resource string in IWbemLocator::ConnectServer.

This commit is contained in:
Hans Leidekker 2012-06-25 11:20:21 +02:00 committed by Alexandre Julliard
parent 7b8c10f0b1
commit 0588ba6939
4 changed files with 172 additions and 5 deletions

View File

@ -136,6 +136,7 @@ struct wbem_services
{
IWbemServices IWbemServices_iface;
LONG refs;
WCHAR *namespace;
};
static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface )
@ -158,6 +159,7 @@ static ULONG WINAPI wbem_services_Release(
if (!refs)
{
TRACE("destroying %p\n", ws);
heap_free( ws->namespace );
heap_free( ws );
}
return refs;
@ -486,7 +488,7 @@ static const IWbemServicesVtbl wbem_services_vtbl =
wbem_services_ExecMethodAsync
};
HRESULT WbemServices_create( IUnknown *pUnkOuter, LPVOID *ppObj )
HRESULT WbemServices_create( IUnknown *pUnkOuter, WCHAR *namespace, LPVOID *ppObj )
{
struct wbem_services *ws;
@ -497,6 +499,7 @@ HRESULT WbemServices_create( IUnknown *pUnkOuter, LPVOID *ppObj )
ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl;
ws->refs = 1;
ws->namespace = namespace;
*ppObj = &ws->IWbemServices_iface;

View File

@ -84,9 +84,96 @@ static void test_IClientSecurity(void)
SysFreeString( path );
}
static void test_IWbemLocator(void)
{
static const WCHAR path0W[] = {0};
static const WCHAR path1W[] = {'\\',0};
static const WCHAR path2W[] = {'\\','\\',0};
static const WCHAR path3W[] = {'\\','\\','.',0};
static const WCHAR path4W[] = {'\\','\\','.','\\',0};
static const WCHAR path5W[] = {'\\','R','O','O','T',0};
static const WCHAR path6W[] = {'\\','\\','R','O','O','T',0};
static const WCHAR path7W[] = {'\\','\\','.','R','O','O','T',0};
static const WCHAR path8W[] = {'\\','\\','.','\\','N','O','N','E',0};
static const WCHAR path9W[] = {'\\','\\','.','\\','R','O','O','T',0};
static const WCHAR path10W[] = {'\\','\\','\\','.','\\','R','O','O','T',0};
static const WCHAR path11W[] = {'\\','/','.','\\','R','O','O','T',0};
static const WCHAR path12W[] = {'/','/','.','\\','R','O','O','T',0};
static const WCHAR path13W[] = {'\\','\\','.','/','R','O','O','T',0};
static const WCHAR path14W[] = {'/','/','.','/','R','O','O','T',0};
static const WCHAR path15W[] = {'N','O','N','E',0};
static const WCHAR path16W[] = {'R','O','O','T',0};
static const WCHAR path17W[] = {'R','O','O','T','\\','N','O','N','E',0};
static const WCHAR path18W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
static const WCHAR path19W[] = {'R','O','O','T','\\','\\','C','I','M','V','2',0};
static const WCHAR path20W[] = {'R','O','O','T','\\','C','I','M','V','2','\\',0};
static const WCHAR path21W[] = {'R','O','O','T','/','C','I','M','V','2',0};
static const struct
{
const WCHAR *path;
HRESULT result;
int todo;
HRESULT result_broken;
}
test[] =
{
{ path0W, WBEM_E_INVALID_NAMESPACE },
{ path1W, WBEM_E_INVALID_NAMESPACE },
{ path2W, WBEM_E_INVALID_NAMESPACE },
{ path3W, WBEM_E_INVALID_NAMESPACE },
{ path4W, WBEM_E_INVALID_NAMESPACE, 0, WBEM_E_INVALID_PARAMETER },
{ path5W, WBEM_E_INVALID_NAMESPACE },
{ path6W, 0x800706ba, 1 },
{ path7W, 0x800706ba, 1 },
{ path8W, WBEM_E_INVALID_NAMESPACE },
{ path9W, S_OK },
{ path10W, WBEM_E_INVALID_PARAMETER },
{ path11W, S_OK },
{ path12W, S_OK },
{ path13W, S_OK },
{ path14W, S_OK },
{ path15W, WBEM_E_INVALID_NAMESPACE },
{ path16W, S_OK },
{ path17W, WBEM_E_INVALID_NAMESPACE },
{ path18W, S_OK },
{ path19W, WBEM_E_INVALID_NAMESPACE },
{ path20W, WBEM_E_INVALID_NAMESPACE },
{ path21W, S_OK }
};
IWbemLocator *locator;
IWbemServices *services;
unsigned int i;
HRESULT hr;
BSTR resource;
hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (void **)&locator );
if (hr != S_OK)
{
win_skip("can't create instance of WbemLocator\n");
return;
}
ok( hr == S_OK, "failed to create IWbemLocator interface %08x\n", hr );
for (i = 0; i < sizeof(test) / sizeof(test[0]); i++)
{
resource = SysAllocString( test[i].path );
hr = IWbemLocator_ConnectServer( locator, resource, NULL, NULL, NULL, 0, NULL, NULL, &services );
if (test[i].todo) todo_wine
ok( hr == test[i].result || broken(hr == test[i].result_broken),
"%u: expected %08x got %08x\n", i, test[i].result, hr );
else
ok( hr == test[i].result || broken(hr == test[i].result_broken),
"%u: expected %08x got %08x\n", i, test[i].result, hr );
SysFreeString( resource );
if (hr == S_OK) IWbemServices_Release( services );
}
IWbemLocator_Release( locator );
}
START_TEST(services)
{
CoInitialize( NULL );
test_IClientSecurity();
test_IWbemLocator();
CoUninitialize();
}

View File

@ -86,6 +86,77 @@ static HRESULT WINAPI wbem_locator_QueryInterface(
return S_OK;
}
static BOOL is_local_machine( const WCHAR *server )
{
static const WCHAR dotW[] = {'.',0};
WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1];
DWORD len = sizeof(buffer) / sizeof(buffer[0]);
if (!server || !strcmpW( server, dotW )) return TRUE;
if (GetComputerNameW( buffer, &len ) && !strcmpiW( server, buffer )) return TRUE;
return FALSE;
}
static HRESULT parse_resource( const WCHAR *resource, WCHAR **server, WCHAR **namespace )
{
static const WCHAR rootW[] = {'R','O','O','T'};
static const WCHAR cimv2W[] = {'C','I','M','V','2'};
HRESULT hr = WBEM_E_INVALID_NAMESPACE;
const WCHAR *p, *q;
unsigned int len;
*server = NULL;
*namespace = NULL;
p = q = resource;
if (*p == '\\' || *p == '/')
{
p++;
if (*p == '\\' || *p == '/') p++;
if (!*p) return WBEM_E_INVALID_NAMESPACE;
if (*p == '\\' || *p == '/') return WBEM_E_INVALID_PARAMETER;
q = p + 1;
while (*q && *q != '\\' && *q != '/') q++;
if (!*q) return WBEM_E_INVALID_NAMESPACE;
len = q - p;
if (!(*server = heap_alloc( (len + 1) * sizeof(WCHAR) )))
{
hr = E_OUTOFMEMORY;
goto done;
}
memcpy( *server, p, len * sizeof(WCHAR) );
(*server)[len] = 0;
q++;
}
if (!*q) goto done;
p = q;
while (*q && *q != '\\' && *q != '/') q++;
len = q - p;
if (len >= sizeof(rootW) / sizeof(rootW[0]) && memicmpW( rootW, p, len )) goto done;
if (!*q)
{
hr = S_OK;
goto done;
}
q++;
if ((len = strlenW( q )) != sizeof(cimv2W) / sizeof(cimv2W[0]) || memicmpW( q, cimv2W, len ))
goto done;
if (!(*namespace = heap_alloc( (len + 1) * sizeof(WCHAR) ))) hr = E_OUTOFMEMORY;
else
{
memcpy( *namespace, p, len * sizeof(WCHAR) );
(*namespace)[len] = 0;
hr = S_OK;
}
done:
if (hr != S_OK)
{
heap_free( *server );
heap_free( *namespace );
}
return hr;
}
static HRESULT WINAPI wbem_locator_ConnectServer(
IWbemLocator *iface,
const BSTR NetworkResource,
@ -98,14 +169,19 @@ static HRESULT WINAPI wbem_locator_ConnectServer(
IWbemServices **ppNamespace)
{
HRESULT hr;
WCHAR *server, *namespace;
TRACE("%p, %s, %s, %s, %s, 0x%08x, %s, %p, %p)\n", iface, debugstr_w(NetworkResource), debugstr_w(User),
debugstr_w(Password), debugstr_w(Locale), SecurityFlags, debugstr_w(Authority), pCtx, ppNamespace);
if (((NetworkResource[0] == '\\' && NetworkResource[1] == '\\') ||
(NetworkResource[0] == '/' && NetworkResource[1] == '/')) && NetworkResource[2] != '.')
hr = parse_resource( NetworkResource, &server, &namespace );
if (hr != S_OK) return hr;
if (!is_local_machine( server ))
{
FIXME("remote computer not supported\n");
heap_free( server );
heap_free( namespace );
return WBEM_E_TRANSPORT_FAILURE;
}
if (User || Password || Authority)
@ -115,10 +191,11 @@ static HRESULT WINAPI wbem_locator_ConnectServer(
if (SecurityFlags)
FIXME("unsupported flags\n");
hr = WbemServices_create( NULL, (void **)ppNamespace );
hr = WbemServices_create( NULL, namespace, (void **)ppNamespace );
if (SUCCEEDED( hr ))
return WBEM_NO_ERROR;
heap_free( namespace );
return WBEM_E_FAILED;
}

View File

@ -121,7 +121,7 @@ HRESULT get_propval( const struct view *, UINT, const WCHAR *, VARIANT *,
HRESULT get_properties( const struct view *, SAFEARRAY ** ) DECLSPEC_HIDDEN;
HRESULT WbemLocator_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN;
HRESULT WbemServices_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN;
HRESULT WbemServices_create(IUnknown *, WCHAR *, LPVOID *) DECLSPEC_HIDDEN;
HRESULT WbemClassObject_create(IUnknown *, IEnumWbemClassObject *, UINT, LPVOID *) DECLSPEC_HIDDEN;
HRESULT EnumWbemClassObject_create(IUnknown *, struct query *, LPVOID *) DECLSPEC_HIDDEN;