Dmitry Timoshkov : adsldp: Store original LDAP values pointer in hReserved.
Alexandre Julliard
julliard at winehq.org
Tue Mar 31 16:44:24 CDT 2020
Module: wine
Branch: master
Commit: f0f24b4be4ee9a1dd0ebac6e40cb9277079c917b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f0f24b4be4ee9a1dd0ebac6e40cb9277079c917b
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Tue Mar 31 18:59:51 2020 +0800
adsldp: Store original LDAP values pointer in hReserved.
AD Explorer depends on this.
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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..f8e8adccf4 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;
}
More information about the wine-cvs
mailing list