[PATCH 6/8] adsldp: Implement IDirectorySearch::GetColumn().

Dmitry Timoshkov dmitry at baikal.ru
Thu Mar 26 02:10:16 CDT 2020


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/adsldp/adsldp.c         | 51 ++++++++++++++++++++++++++++++++++--
 dlls/adsldp/adsldp_private.h | 17 ++++++++++++
 2 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/dlls/adsldp/adsldp.c b/dlls/adsldp/adsldp.c
index 859d42546f..fed9a8afca 100644
--- a/dlls/adsldp/adsldp.c
+++ b/dlls/adsldp/adsldp.c
@@ -1301,11 +1301,58 @@ static HRESULT WINAPI search_GetNextColumnName(IDirectorySearch *iface, ADS_SEAR
     return S_ADS_NOMORE_COLUMNS;
 }
 
+static HRESULT add_column_values(ADS_SEARCH_COLUMN *col, struct berval **values, DWORD count)
+{
+    DWORD i;
+
+    col->pADsValues = heap_alloc(count * sizeof(col->pADsValues[0]));
+    if (!col->pADsValues)
+        return E_OUTOFMEMORY;
+
+    for (i = 0; i < count; i++)
+    {
+        DWORD outlen;
+        TRACE("=> %s\n", debugstr_an(values[i]->bv_val, values[i]->bv_len));
+        col->pADsValues[i].u.CaseIgnoreString = strnAtoW(values[i]->bv_val, values[i]->bv_len, &outlen);
+        if (!col->pADsValues[i].u.CaseIgnoreString)
+        {
+            heap_free(col->pADsValues);
+            return E_OUTOFMEMORY;
+        }
+    }
+
+    col->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
+    col->dwNumValues = count;
+
+    return S_OK;
+}
+
 static HRESULT WINAPI search_GetColumn(IDirectorySearch *iface, ADS_SEARCH_HANDLE res,
                                        LPWSTR name, PADS_SEARCH_COLUMN col)
 {
-    FIXME("%p,%p,%s,%p: stub\n", iface, res, debugstr_w(name), col);
-    return E_NOTIMPL;
+    LDAP_namespace *ldap = impl_from_IDirectorySearch(iface);
+    struct ldap_search_context *ldap_ctx = res;
+    HRESULT hr;
+    struct berval **values;
+    ULONG count;
+
+    TRACE("%p,%p,%s,%p\n", iface, res, debugstr_w(name), col);
+
+    if (!ldap->ld) return E_NOTIMPL;
+
+    if (!res || !name || !ldap_ctx->entry) return E_ADS_BAD_PARAMETER;
+
+    values = ldap_get_values_lenW(ldap->ld, ldap_ctx->entry, name);
+    if (!values) return ERROR_DS_NO_ATTRIBUTE_OR_VALUE;
+
+    count = ldap_count_values_len(values);
+
+    hr = add_column_values(col, values, count);
+    ldap_value_free_len(values);
+    if (hr == S_OK)
+        col->pszAttrName = strdupW(name);
+
+    return hr;
 }
 
 static HRESULT WINAPI search_FreeColumn(IDirectorySearch *iface, PADS_SEARCH_COLUMN col)
diff --git a/dlls/adsldp/adsldp_private.h b/dlls/adsldp/adsldp_private.h
index 0443ffbf6e..149d52eb63 100644
--- a/dlls/adsldp/adsldp_private.h
+++ b/dlls/adsldp/adsldp_private.h
@@ -29,6 +29,23 @@ static inline WCHAR *strdupW(const WCHAR *src)
     return dst;
 }
 
+static inline LPWSTR strnAtoW( LPCSTR str, DWORD inlen, DWORD *outlen )
+{
+    LPWSTR ret = NULL;
+    *outlen = 0;
+    if (str)
+    {
+        DWORD len = MultiByteToWideChar( CP_ACP, 0, str, inlen, NULL, 0 );
+        if ((ret = heap_alloc( (len + 1) * sizeof(WCHAR) )))
+        {
+            MultiByteToWideChar( CP_ACP, 0, str, inlen, ret, len );
+            ret[len] = 0;
+            *outlen = len;
+        }
+    }
+    return ret;
+}
+
 DWORD map_ldap_error(DWORD) DECLSPEC_HIDDEN;
 
 #endif
-- 
2.25.1




More information about the wine-devel mailing list