[PATCH 2/6] adsldp: Store original LDAP values pointer in hReserved.

Dmitry Timoshkov dmitry at baikal.ru
Tue Mar 31 05:59:51 CDT 2020


AD Explorer depends on this.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/adsldp/adsldp.c | 169 ++++++++++++++++++++++++++++++-------------
 1 file changed, 120 insertions(+), 49 deletions(-)

diff --git a/dlls/adsldp/adsldp.c b/dlls/adsldp/adsldp.c
index e0a14f2c70..8af7a59632 100644
--- a/dlls/adsldp/adsldp.c
+++ b/dlls/adsldp/adsldp.c
@@ -1308,65 +1308,141 @@ static HRESULT WINAPI search_GetNextColumnName(IDirectorySearch *iface, ADS_SEAR
     return S_ADS_NOMORE_COLUMNS;
 }
 
-static HRESULT add_column_values(LDAP_namespace *ldap, ADS_SEARCH_COLUMN *col,
-                                 const WCHAR *name, struct berval **values, DWORD count)
+static HRESULT add_column_values(LDAP_namespace *ldap, struct ldap_search_context *ldap_ctx,
+                                 LPWSTR name, ADS_SEARCH_COLUMN *col)
 {
     ADSTYPEENUM type;
-    DWORD i;
+    DWORD i, count;
 
     type = get_schema_type(name, ldap->at, ldap->at_count);
+    TRACE("%s => type %d\n", debugstr_w(name), type);
 
-    col->pADsValues = heap_alloc(count * sizeof(col->pADsValues[0]));
-    if (!col->pADsValues)
-        return E_OUTOFMEMORY;
+    switch (type)
+    {
+    default:
+        FIXME("no special handling for type %d\n", type);
+        /* fall through */
+    case ADSTYPE_DN_STRING:
+    case ADSTYPE_CASE_EXACT_STRING:
+    case ADSTYPE_CASE_IGNORE_STRING:
+    case ADSTYPE_PRINTABLE_STRING:
+    {
+        WCHAR **values = ldap_get_valuesW(ldap->ld, ldap_ctx->entry, name);
+        if (!values)
+        {
+            memset(col, 0, sizeof(*col));
+            return E_ADS_COLUMN_NOT_SET;
+        }
+        count = ldap_count_valuesW(values);
 
-    for (i = 0; i < count; i++)
+        col->pADsValues = heap_alloc(count * sizeof(col->pADsValues[0]));
+        if (!col->pADsValues)
+        {
+            ldap_value_freeW(values);
+            return E_OUTOFMEMORY;
+        }
+
+        for (i = 0; i < count; i++)
+        {
+            TRACE("=> %s\n", debugstr_w(values[i]));
+            col->pADsValues[i].u.CaseIgnoreString = values[i];
+        }
+
+        col->hReserved = values;
+        break;
+    }
+
+    case ADSTYPE_BOOLEAN:
     {
-        switch (type)
+        WCHAR **values = ldap_get_valuesW(ldap->ld, ldap_ctx->entry, name);
+        if (!values)
         {
-        default:
-            FIXME("no special handling for type %d\n", type);
-            /* fall through */
-        case ADSTYPE_DN_STRING:
-        case ADSTYPE_CASE_EXACT_STRING:
-        case ADSTYPE_CASE_IGNORE_STRING:
-        case ADSTYPE_PRINTABLE_STRING:
+            memset(col, 0, sizeof(*col));
+            return E_ADS_COLUMN_NOT_SET;
+        }
+        count = ldap_count_valuesW(values);
+
+        col->pADsValues = heap_alloc(count * sizeof(col->pADsValues[0]));
+        if (!col->pADsValues)
         {
-            DWORD outlen;
-            TRACE("=> %s\n", debugstr_an(values[i]->bv_val, values[i]->bv_len));
-            col->pADsValues[i].u.CaseIgnoreString = strnUtoW(values[i]->bv_val, values[i]->bv_len, &outlen);
-            if (!col->pADsValues[i].u.CaseIgnoreString)
-            {
-                heap_free(col->pADsValues);
-                return E_OUTOFMEMORY;
-            }
-            break;
+            ldap_value_freeW(values);
+            return E_OUTOFMEMORY;
         }
 
-        case ADSTYPE_BOOLEAN:
-            if (stricmp(values[i]->bv_val, "TRUE"))
+        for (i = 0; i < count; i++)
+        {
+            if (wcsicmp(values[i], L"TRUE"))
                 col->pADsValues[i].u.Boolean = 1;
-            else if (stricmp(values[i]->bv_val, "FALSE"))
+            else if (wcsicmp(values[i], L"FALSE"))
                 col->pADsValues[i].u.Boolean = 0;
             else
             {
-                FIXME("not recognized boolean value %s\n", debugstr_an(values[i]->bv_val, values[i]->bv_len));
+                FIXME("not recognized boolean value %s\n", debugstr_w(values[i]));
                 col->pADsValues[i].u.Boolean = 0;
             }
             TRACE("=> %d\n", col->pADsValues[i].u.Boolean);
-            break;
+        }
 
-        case ADSTYPE_INTEGER:
-            col->pADsValues[i].u.Integer = strtol(values[i]->bv_val, NULL, 10);
-            TRACE("%s => %d\n", debugstr_an(values[i]->bv_val, values[i]->bv_len), col->pADsValues[i].u.Integer);
-            break;
+        ldap_value_freeW(values);
+        col->hReserved = NULL;
+        break;
+    }
+
+    case ADSTYPE_INTEGER:
+    {
+        WCHAR **values = ldap_get_valuesW(ldap->ld, ldap_ctx->entry, name);
+        if (!values)
+        {
+            memset(col, 0, sizeof(*col));
+            return E_ADS_COLUMN_NOT_SET;
+        }
+        count = ldap_count_valuesW(values);
+
+        col->pADsValues = heap_alloc(count * sizeof(col->pADsValues[0]));
+        if (!col->pADsValues)
+        {
+            ldap_value_freeW(values);
+            return E_OUTOFMEMORY;
+        }
+
+        for (i = 0; i < count; i++)
+        {
+            col->pADsValues[i].u.Integer = wcstol(values[i], NULL, 10);
+            TRACE("%s => %d\n", debugstr_w(values[i]), col->pADsValues[i].u.Integer);
+        }
 
-        case ADSTYPE_OCTET_STRING:
+        ldap_value_freeW(values);
+        col->hReserved = NULL;
+        break;
+    }
+
+    case ADSTYPE_OCTET_STRING:
+    {
+        struct berval **values = ldap_get_values_lenW(ldap->ld, ldap_ctx->entry, name);;
+        if (!values)
+        {
+            memset(col, 0, sizeof(*col));
+            return E_ADS_COLUMN_NOT_SET;
+        }
+        count = ldap_count_values_len(values);
+
+        col->pADsValues = heap_alloc(count * sizeof(col->pADsValues[0]));
+        if (!col->pADsValues)
+        {
+            ldap_value_free_len(values);
+            return E_OUTOFMEMORY;
+        }
+
+        for (i = 0; i < count; i++)
+        {
             TRACE("=> %s\n", debugstr_an(values[i]->bv_val, values[i]->bv_len));
             col->pADsValues[i].u.OctetString.dwLength = values[i]->bv_len;
             col->pADsValues[i].u.OctetString.lpValue = (BYTE *)values[i]->bv_val;
-            break;
         }
+
+        col->hReserved = values;
+        break;
+    }
     }
 
     col->dwADsType = type;
@@ -1382,7 +1458,6 @@ static HRESULT WINAPI search_GetColumn(IDirectorySearch *iface, ADS_SEARCH_HANDL
     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);
@@ -1417,6 +1492,7 @@ static HRESULT WINAPI search_GetColumn(IDirectorySearch *iface, ADS_SEARCH_HANDL
         col->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
         col->dwNumValues = 1;
         col->pszAttrName = strdupW(name);
+        col->hReserved = NULL;
 
         TRACE("=> %s\n", debugstr_w(col->pADsValues[0].u.CaseIgnoreString));
         hr = S_OK;
@@ -1425,19 +1501,7 @@ exit:
         return hr;
     }
 
-    values = ldap_get_values_lenW(ldap->ld, ldap_ctx->entry, name);
-    if (!values)
-    {
-        memset(col, 0, sizeof(*col));
-        return E_ADS_COLUMN_NOT_SET;
-    }
-
-    count = ldap_count_values_len(values);
-
-    hr = add_column_values(ldap, col, name, values, count);
-    ldap_value_free_len(values);
-
-    return hr;
+    return add_column_values(ldap, ldap_ctx, name, col);
 }
 
 static HRESULT WINAPI search_FreeColumn(IDirectorySearch *iface, PADS_SEARCH_COLUMN col)
@@ -1447,6 +1511,13 @@ static HRESULT WINAPI search_FreeColumn(IDirectorySearch *iface, PADS_SEARCH_COL
     if (!col) return E_ADS_BAD_PARAMETER;
 
     heap_free(col->pADsValues);
+    if (col->hReserved)
+    {
+        if (col->dwADsType == ADSTYPE_OCTET_STRING)
+            ldap_value_free_len(col->hReserved);
+        else
+            ldap_value_freeW(col->hReserved);
+    }
 
     return S_OK;
 }
-- 
2.25.1




More information about the wine-devel mailing list