From 7a264997d540007c1458517d8ef852a3df04644a Mon Sep 17 00:00:00 2001
From: Hans Leidekker <hans@it.vu.nl>
Date: Mon, 1 Aug 2005 14:51:17 +0000
Subject: [PATCH] Implement ldap_compare* functions.

---
 dlls/wldap32/Makefile.in       |   1 +
 dlls/wldap32/compare.c         | 401 +++++++++++++++++++++++++++++++++
 dlls/wldap32/winldap_private.h |   8 +
 dlls/wldap32/wldap32.spec      |  12 +
 4 files changed, 422 insertions(+)
 create mode 100644 dlls/wldap32/compare.c

diff --git a/dlls/wldap32/Makefile.in b/dlls/wldap32/Makefile.in
index ac0cd8a3d2b..935dad63413 100644
--- a/dlls/wldap32/Makefile.in
+++ b/dlls/wldap32/Makefile.in
@@ -10,6 +10,7 @@ EXTRALIBS = @LDAPLIBS@
 C_SRCS = \
 	ber.c \
 	bind.c \
+	compare.c \
 	error.c \
 	init.c \
 	main.c \
diff --git a/dlls/wldap32/compare.c b/dlls/wldap32/compare.c
new file mode 100644
index 00000000000..cd408b7e4c5
--- /dev/null
+++ b/dlls/wldap32/compare.c
@@ -0,0 +1,401 @@
+/*
+ * WLDAP32 - LDAP support for Wine
+ *
+ * Copyright 2005 Hans Leidekker
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+
+#include "wine/port.h"
+#include "wine/debug.h"
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+
+#ifdef HAVE_LDAP_H
+#include <ldap.h>
+#else
+#define LDAP_NOT_SUPPORTED  0x5c
+#endif
+
+#include "winldap_private.h"
+#include "wldap32.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
+
+ULONG ldap_compareA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr),
+           debugstr_a(value) );
+
+    if (!ld) return ~0UL;
+
+    if (dn) {
+        dnW = strAtoW( dn );
+        if (!dnW) goto exit;
+    }
+    if (attr) {
+        attrW = strAtoW( attr );
+        if (!attrW) goto exit;
+    }
+    if (value) {
+        valueW = strAtoW( value );
+        if (!valueW) goto exit;
+    }
+
+    ret = ldap_compareW( ld, dnW, attrW, valueW );
+
+exit:
+    strfreeW( dnW );
+    strfreeW( attrW );
+    strfreeW( valueW );
+
+#endif
+    return ret;
+}
+
+ULONG ldap_compareW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    char *dnU = NULL, *attrU = NULL, *valueU = NULL;
+
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr),
+           debugstr_w(value) );
+
+    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+    if (!attr) return ~0UL;
+
+    if (dn) {
+        dnU = strWtoU( dn );
+        if (!dnU) goto exit;
+    }
+
+    attrU = strWtoU( attr );
+    if (!attrU) goto exit;
+
+    if (value) {
+        valueU = strWtoU( value );
+        if (!valueU) goto exit;
+    }
+
+    ret = ldap_compare( ld, dn ? dnU : "", attrU, value ? valueU : "" );
+
+exit:
+    strfreeU( dnU );
+    strfreeU( attrU );
+    strfreeU( valueU );
+
+#endif
+    return ret;
+}
+
+ULONG ldap_compare_extA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
+    struct berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls,
+    ULONG *message )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
+    LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
+           debugstr_a(attr), debugstr_a(value), data, serverctrls,
+           clientctrls, message );
+
+    if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR;
+
+    if (dn) {
+        dnW = strAtoW( dn );
+        if (!dnW) goto exit;
+    }
+    if (attr) {
+        attrW = strAtoW( attr );
+        if (!attrW) goto exit;
+    }
+    if (value) {
+        valueW = strAtoW( value );
+        if (!valueW) goto exit;
+    }
+    if (serverctrls) {
+        serverctrlsW = controlarrayAtoW( serverctrls );
+        if (!serverctrlsW) goto exit;
+    }
+    if (clientctrls) {
+        clientctrlsW = controlarrayAtoW( clientctrls );
+        if (!clientctrlsW) goto exit;
+    }
+
+    ret = ldap_compare_extW( ld, dnW, attrW, valueW, data,
+                             serverctrlsW, clientctrlsW, message );
+
+exit:
+    strfreeW( dnW );
+    strfreeW( attrW );
+    strfreeW( valueW );
+    controlarrayfreeW( serverctrlsW );
+    controlarrayfreeW( clientctrlsW );
+
+#endif
+    return ret;
+}
+
+ULONG ldap_compare_extW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
+    struct berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls,
+    ULONG *message )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    char *dnU = NULL, *attrU = NULL, *valueU = NULL;
+    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
+    struct berval berval;
+
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
+           debugstr_w(attr), debugstr_w(value), data, serverctrls,
+           clientctrls, message );
+
+    if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR;
+    if (!attr) return WLDAP32_LDAP_NO_MEMORY;
+
+    if (dn) {
+        dnU = strWtoU( dn );
+        if (!dnU) goto exit;
+    }
+
+    attrU = strWtoU( attr );
+    if (!attrU) goto exit;
+
+    if (!data) {
+        if (value) {
+            valueU = strWtoU( value );
+            if (!valueU) goto exit;
+        }
+        berval.bv_len = valueU ? strlen( valueU ) : 0;
+        berval.bv_val = valueU;
+    }
+    if (serverctrls) {
+        serverctrlsU = controlarrayWtoU( serverctrls );
+        if (!serverctrlsU) goto exit;
+    }
+    if (clientctrls) {
+        clientctrlsU = controlarrayWtoU( clientctrls );
+        if (!clientctrlsU) goto exit;
+    }
+
+    ret = ldap_compare_ext( ld, dn ? dnU : "", attrU, data ? data : &berval,
+                            serverctrlsU, clientctrlsU, (int *)message );
+
+exit:
+    strfreeU( dnU );
+    strfreeU( attrU );
+    strfreeU( valueU );
+    controlarrayfreeU( serverctrlsU );
+    controlarrayfreeU( clientctrlsU );
+
+#endif
+    return ret;
+}
+
+ULONG ldap_compare_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
+    struct berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
+    LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_a(dn),
+           debugstr_a(attr), debugstr_a(value), data, serverctrls,
+           clientctrls );
+
+    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+    if (dn) {
+        dnW = strAtoW( dn );
+        if (!dnW) goto exit;
+    }
+    if (attr) {
+        attrW = strAtoW( attr );
+        if (!attrW) goto exit;
+    }
+    if (value) {
+        valueW = strAtoW( value );
+        if (!valueW) goto exit;
+    }
+    if (serverctrls) {
+        serverctrlsW = controlarrayAtoW( serverctrls );
+        if (!serverctrlsW) goto exit;
+    }
+    if (clientctrls) {
+        clientctrlsW = controlarrayAtoW( clientctrls );
+        if (!clientctrlsW) goto exit;
+    }
+
+    ret = ldap_compare_ext_sW( ld, dnW, attrW, valueW, data, serverctrlsW,
+                               clientctrlsW );
+
+exit:
+    strfreeW( dnW );
+    strfreeW( attrW );
+    strfreeW( valueW );
+    controlarrayfreeW( serverctrlsW );
+    controlarrayfreeW( clientctrlsW );
+
+#endif
+    return ret;
+}
+
+ULONG ldap_compare_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
+    struct berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    struct berval berval;
+    char *dnU = NULL, *attrU = NULL, *valueU = NULL;
+    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_w(dn),
+           debugstr_w(attr), debugstr_w(value), data, serverctrls,
+           clientctrls );
+
+    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+    if (dn) {
+        dnU = strWtoU( dn );
+        if (!dnU) goto exit;
+    }
+    if (attr) {
+        attrU = strWtoU( attr );
+        if (!attrU) goto exit;
+    }
+    if (!data) {
+        if (value) {
+            valueU = strWtoU( value );
+            if (!valueU) goto exit;
+        }
+        berval.bv_len = valueU ? strlen( valueU ) : 0;
+        berval.bv_val = valueU;
+    }
+    if (serverctrls) {
+        serverctrlsU = controlarrayWtoU( serverctrls );
+        if (!serverctrlsU) goto exit;
+    }
+    if (clientctrls) {
+        clientctrlsU = controlarrayWtoU( clientctrls );
+        if (!clientctrlsU) goto exit;
+    }
+
+    ret = ldap_compare_ext_s( ld, dn ? dnU : "", attr ? attrU : "", data ? data : &berval,
+                              serverctrlsU, clientctrlsU );
+
+exit:
+    strfreeU( dnU );
+    strfreeU( attrU );
+    strfreeU( valueU );
+    controlarrayfreeU( serverctrlsU );
+    controlarrayfreeU( clientctrlsU );
+
+#endif
+    return ret;
+}
+
+ULONG ldap_compare_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr),
+           debugstr_a(value) );
+
+    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+    if (dn) {
+        dnW = strAtoW( dn );
+        if (!dnW) goto exit;
+    }
+    if (attr) {
+        attrW = strAtoW( attr );
+        if (!attrW) goto exit;
+    }
+    if (value) {
+        valueW = strAtoW( value );
+        if (!valueW) goto exit;
+    }
+
+    ret = ldap_compare_sW( ld, dnW, attrW, valueW );
+
+exit:
+    strfreeW( dnW );
+    strfreeW( attrW );
+    strfreeW( valueW );
+
+#endif
+    return ret;
+}
+
+ULONG ldap_compare_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
+{
+    ULONG ret = LDAP_NOT_SUPPORTED;
+#ifdef HAVE_LDAP
+    char *dnU = NULL, *attrU = NULL, *valueU = NULL;
+    ret = WLDAP32_LDAP_NO_MEMORY;
+
+    TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr),
+           debugstr_w(value) );
+
+    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+    if (dn) {
+        dnU = strWtoU( dn );
+        if (!dnU) goto exit;
+    }
+    if (attr) {
+        attrU = strWtoU( attr );
+        if (!attrU) goto exit;
+    }
+    if (value) {
+        valueU = strWtoU( value );
+        if (!valueU) goto exit;
+    }
+
+    ret = ldap_compare_s( ld, dn ? dnU : "", attr ? attrU : "", value ? valueU : "" );
+
+exit:
+    strfreeU( dnU );
+    strfreeU( attrU );
+    strfreeU( valueU );
+
+#endif
+    return ret;
+}
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 64c7544aa44..77228ff5167 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -120,6 +120,14 @@ ULONG ldap_bindA(WLDAP32_LDAP*,PCHAR,PCHAR,ULONG);
 ULONG ldap_bindW(WLDAP32_LDAP*,PWCHAR,PWCHAR,ULONG);
 ULONG ldap_bind_sA(WLDAP32_LDAP*,PCHAR,PCHAR,ULONG);
 ULONG ldap_bind_sW(WLDAP32_LDAP*,PWCHAR,PWCHAR,ULONG);
+ULONG ldap_compareA(WLDAP32_LDAP*,PCHAR,PCHAR,PCHAR);
+ULONG ldap_compareW(WLDAP32_LDAP*,PWCHAR,PWCHAR,PWCHAR);
+ULONG ldap_compare_extA(WLDAP32_LDAP*,PCHAR,PCHAR,PCHAR,struct berval*,PLDAPControlA*,PLDAPControlA*,ULONG*);
+ULONG ldap_compare_extW(WLDAP32_LDAP*,PWCHAR,PWCHAR,PWCHAR,struct berval*,PLDAPControlW*,PLDAPControlW*,ULONG*);
+ULONG ldap_compare_ext_sA(WLDAP32_LDAP*,PCHAR,PCHAR,PCHAR,struct berval*,PLDAPControlA*,PLDAPControlA*);
+ULONG ldap_compare_ext_sW(WLDAP32_LDAP*,PWCHAR,PWCHAR,PWCHAR,struct berval*,PLDAPControlW*,PLDAPControlW*);
+ULONG ldap_compare_sA(WLDAP32_LDAP*,PCHAR,PCHAR,PCHAR);
+ULONG ldap_compare_sW(WLDAP32_LDAP*,PWCHAR,PWCHAR,PWCHAR);
 PCHAR ldap_err2stringA(ULONG);
 PWCHAR ldap_err2stringW(ULONG);
 WLDAP32_LDAP *ldap_initA(const PCHAR,ULONG);
diff --git a/dlls/wldap32/wldap32.spec b/dlls/wldap32/wldap32.spec
index 1d8524fa94e..2bf22b4d87d 100644
--- a/dlls/wldap32/wldap32.spec
+++ b/dlls/wldap32/wldap32.spec
@@ -19,6 +19,18 @@
 @ cdecl ldap_bind_s(ptr str str long) ldap_bind_sA
 @ cdecl ldap_bind_sA(ptr str str long)
 @ cdecl ldap_bind_sW(ptr wstr wstr long)
+@ cdecl ldap_compare(ptr str str str) ldap_compareA
+@ cdecl ldap_compareA(ptr str str str)
+@ cdecl ldap_compareW(ptr wstr wstr wstr)
+@ cdecl ldap_compare_ext(ptr str str str ptr ptr ptr ptr) ldap_compare_extA
+@ cdecl ldap_compare_extA(ptr str str str ptr ptr ptr ptr)
+@ cdecl ldap_compare_extW(ptr wstr wstr wstr ptr ptr ptr ptr)
+@ cdecl ldap_compare_ext_s(ptr str str str ptr ptr ptr) ldap_compare_ext_sA
+@ cdecl ldap_compare_ext_sA(ptr str str str ptr ptr ptr)
+@ cdecl ldap_compare_ext_sW(ptr wstr wstr wstr ptr ptr ptr)
+@ cdecl ldap_compare_s(ptr str str str) ldap_compare_sA
+@ cdecl ldap_compare_sA(ptr str str str)
+@ cdecl ldap_compare_sW(ptr wstr wstr wstr)
 @ cdecl ldap_err2string(long) ldap_err2stringA
 @ cdecl ldap_err2stringA(long)
 @ cdecl ldap_err2stringW(long)
-- 
GitLab