From 3656d57a9a4376131249a875bfe84450a678024f Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 10 Apr 2020 15:34:16 +0800 Subject: [PATCH] activeds: Implement IADsPathname::Set(ADS_SETTYPE_FULL). Signed-off-by: Dmitry Timoshkov Signed-off-by: Alexandre Julliard --- dlls/activeds/pathname.c | 90 +++++++++++++++++++++++++++++++--- dlls/activeds/tests/activeds.c | 3 +- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/dlls/activeds/pathname.c b/dlls/activeds/pathname.c index 52a94cbb18c..4733c5315f9 100644 --- a/dlls/activeds/pathname.c +++ b/dlls/activeds/pathname.c @@ -26,6 +26,7 @@ #include "windef.h" #include "winbase.h" #include "iads.h" +#include "adserr.h" #include "wine/heap.h" #include "wine/debug.h" @@ -39,7 +40,7 @@ typedef struct { IADsPathname IADsPathname_iface; LONG ref; - BSTR adspath; + BSTR provider, server, dn; } Pathname; static inline Pathname *impl_from_IADsPathname(IADsPathname *iface) @@ -80,6 +81,9 @@ static ULONG WINAPI path_Release(IADsPathname *iface) if (!ref) { TRACE("destroying %p\n", iface); + SysFreeString(path->provider); + SysFreeString(path->server); + SysFreeString(path->dn); heap_free(path); } @@ -113,16 +117,88 @@ static HRESULT WINAPI path_Invoke(IADsPathname *iface, DISPID dispid, REFIID rii return E_NOTIMPL; } +static HRESULT parse_path(BSTR path, BSTR *provider, BSTR *server, BSTR *dn) +{ + WCHAR *p, *p_server; + int server_len; + + *provider = NULL; + *server = NULL; + *dn = NULL; + + if (wcsnicmp(path, L"LDAP:", 5) != 0) + return E_ADS_BAD_PATHNAME; + + *provider = SysAllocStringLen(path, 4); + if (!*provider) return E_OUTOFMEMORY; + + p = path + 5; + if (!*p) return S_OK; + + if (*p++ != '/' || *p++ != '/' || !*p) + return E_ADS_BAD_PATHNAME; + + p_server = p; + server_len = 0; + while (*p && *p != '/') + { + p++; + server_len++; + } + if (server_len == 0) return E_ADS_BAD_PATHNAME; + + *server = SysAllocStringLen(p_server, server_len); + if (!*server) + { + SysFreeString(*provider); + return E_OUTOFMEMORY; + } + + if (!*p) return S_OK; + + if (*p++ != '/' || !*p) + { + SysFreeString(*provider); + SysFreeString(*server); + return E_ADS_BAD_PATHNAME; + } + + *dn = SysAllocString(p); + if (!*dn) + { + SysFreeString(*provider); + SysFreeString(*server); + return E_OUTOFMEMORY; + } + + return S_OK; +} + static HRESULT WINAPI path_Set(IADsPathname *iface, BSTR adspath, LONG type) { Pathname *path = impl_from_IADsPathname(iface); + HRESULT hr; + BSTR provider, server, dn; - FIXME("%p,%s,%d: stub\n", iface, debugstr_w(adspath), type); + TRACE("%p,%s,%d\n", iface, debugstr_w(adspath), type); if (!adspath) return E_INVALIDARG; - path->adspath = SysAllocString(adspath); - return path->adspath ? S_OK : E_OUTOFMEMORY; + if (type != ADS_SETTYPE_FULL) + FIXME("type %d not implemented\n", type); + + hr = parse_path(adspath, &provider, &server, &dn); + if (hr == S_OK) + { + SysFreeString(path->provider); + SysFreeString(path->server); + SysFreeString(path->dn); + + path->provider = provider; + path->server = server; + path->dn = dn; + } + return hr; } static HRESULT WINAPI path_SetDisplayType(IADsPathname *iface, LONG type) @@ -139,7 +215,7 @@ static HRESULT WINAPI path_Retrieve(IADsPathname *iface, LONG type, BSTR *adspat if (!adspath) return E_INVALIDARG; - *adspath = SysAllocString(path->adspath); + *adspath = SysAllocString(path->provider); return *adspath ? S_OK : E_OUTOFMEMORY; } @@ -223,7 +299,9 @@ static HRESULT Pathname_create(REFIID riid, void **obj) path->IADsPathname_iface.lpVtbl = &IADsPathname_vtbl; path->ref = 1; - path->adspath = NULL; + path->provider = SysAllocString(L"LDAP"); + path->server = NULL; + path->dn = NULL; hr = IADsPathname_QueryInterface(&path->IADsPathname_iface, riid, obj); IADsPathname_Release(&path->IADsPathname_iface); diff --git a/dlls/activeds/tests/activeds.c b/dlls/activeds/tests/activeds.c index 81fe7540585..dff30bbbba1 100644 --- a/dlls/activeds/tests/activeds.c +++ b/dlls/activeds/tests/activeds.c @@ -104,7 +104,6 @@ todo_wine bstr = NULL; hr = IADsPathname_Retrieve(path, ADS_FORMAT_X500, &bstr); -todo_wine ok(hr == S_OK, "got %#x\n", hr); todo_wine ok(bstr && !wcscmp(bstr, L"LDAP://"), "got %s\n", wine_dbgstr_w(bstr)); @@ -148,12 +147,12 @@ todo_wine hr = IADsPathname_Retrieve(path, ADS_FORMAT_X500, &bstr); ok(hr == S_OK, "got %#x\n", hr); +todo_wine ok(!wcscmp(bstr, L"LDAP://sample:123/a=b,c=d,e=f"), "got %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr); hr = IADsPathname_Retrieve(path, ADS_FORMAT_PROVIDER, &bstr); ok(hr == S_OK, "got %#x\n", hr); -todo_wine ok(!wcscmp(bstr, L"LDAP"), "got %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr);