[2/2] wbemprox: Parse the resource string in IWbemLocator::ConnectServer.

Hans Leidekker hans at codeweavers.com
Mon Jun 25 04:20:21 CDT 2012


---
 dlls/wbemprox/services.c         |    5 ++-
 dlls/wbemprox/tests/services.c   |   87 ++++++++++++++++++++++++++++++++++++++
 dlls/wbemprox/wbemlocator.c      |   83 ++++++++++++++++++++++++++++++++++--
 dlls/wbemprox/wbemprox_private.h |    2 +-
 4 files changed, 172 insertions(+), 5 deletions(-)

diff --git a/dlls/wbemprox/services.c b/dlls/wbemprox/services.c
index c2aaa3a..e33ff36 100644
--- a/dlls/wbemprox/services.c
+++ b/dlls/wbemprox/services.c
@@ -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;
 
diff --git a/dlls/wbemprox/tests/services.c b/dlls/wbemprox/tests/services.c
index 64be978..ff798a3 100644
--- a/dlls/wbemprox/tests/services.c
+++ b/dlls/wbemprox/tests/services.c
@@ -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();
 }
diff --git a/dlls/wbemprox/wbemlocator.c b/dlls/wbemprox/wbemlocator.c
index b80e080..e382186 100644
--- a/dlls/wbemprox/wbemlocator.c
+++ b/dlls/wbemprox/wbemlocator.c
@@ -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;
 }
 
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index 779d43d..d0cdb76 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -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;
 
-- 
1.7.10






More information about the wine-patches mailing list