[PATCH] wldap32: Convert berval structures.

Hans Leidekker hans at codeweavers.com
Mon Feb 8 05:33:54 CST 2021


The layout is different on 64-bit. As a side effect this patch fixes bug 50622
because we no longer include the Windows header.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50622
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/wldap32/ber.c             | 158 ++++++++++++++++++++++++---------
 dlls/wldap32/page.c            |  54 +++++++----
 dlls/wldap32/winldap_private.h |  18 ++--
 dlls/wldap32/wldap32.h         | 115 +++++++++++++++++++++---
 4 files changed, 265 insertions(+), 80 deletions(-)

diff --git a/dlls/wldap32/ber.c b/dlls/wldap32/ber.c
index c4c77d68da8..7f39b9cfe17 100644
--- a/dlls/wldap32/ber.c
+++ b/dlls/wldap32/ber.c
@@ -21,18 +21,21 @@
 #include "config.h"
 
 #include <stdarg.h>
+#ifdef HAVE_LDAP_H
+#include <ldap.h>
+#endif
+
 #include "windef.h"
 #include "winbase.h"
-#include "winldap.h"
+#include "winldap_private.h"
+#include "wldap32.h"
 #include "wine/debug.h"
 
 #ifdef HAVE_LDAP
 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
 #endif
 
-#ifndef LBER_ERROR
-# define LBER_ERROR (~0U)
-#endif
+#define WLDAP32_LBER_ERROR (~0U)
 
 /***********************************************************************
  *      ber_alloc_t     (WLDAP32.@)
@@ -49,7 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
  * NOTES
  *  Free the berelement structure with ber_free.
  */
-BerElement * CDECL WLDAP32_ber_alloc_t( INT options )
+WLDAP32_BerElement * CDECL WLDAP32_ber_alloc_t( INT options )
 {
 #ifdef HAVE_LDAP
     return ber_alloc_t( options );
@@ -76,11 +79,7 @@ BerElement * CDECL WLDAP32_ber_alloc_t( INT options )
  */
 BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval )
 {
-#ifdef HAVE_LDAP
-    return ber_bvdup( berval );
-#else
-    return NULL;
-#endif
+    return bervalWtoW( berval );
 }
 
 
@@ -101,9 +100,7 @@ BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval )
  */
 void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval )
 {
-#ifdef HAVE_LDAP
-    ber_bvecfree( berval );
-#endif
+    bvarrayfreeW( berval );
 }
 
 
@@ -124,9 +121,7 @@ void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval )
  */
 void CDECL WLDAP32_ber_bvfree( BERVAL *berval )
 {
-#ifdef HAVE_LDAP
-    ber_bvfree( berval );
-#endif
+    heap_free( berval );
 }
 
 
@@ -147,12 +142,25 @@ void CDECL WLDAP32_ber_bvfree( BERVAL *berval )
  * NOTES
  *  len and cookie should be passed to ber_next_element.
  */
-ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR **opaque )
+ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR **opaque )
 {
 #ifdef HAVE_LDAP
-    return ber_first_element( berelement, len, opaque );
+    ber_len_t len;
+    ber_tag_t ret;
+
+    if ((ret = ber_first_element( berelement, &len, opaque )) != LBER_ERROR)
+    {
+        if (len > ~0u)
+        {
+            ERR( "len too large\n" );
+            return WLDAP32_LBER_ERROR;
+        }
+        *ret_len = len;
+    }
+    return ret;
+
 #else
-    return LBER_ERROR;
+    return WLDAP32_LBER_ERROR;
 #endif
 }
 
@@ -173,12 +181,22 @@ ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR
  * NOTES
  *  Free the berval structure with ber_bvfree.
  */
-INT CDECL WLDAP32_ber_flatten( BerElement *berelement, PBERVAL *berval )
+INT CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *berelement, PBERVAL *berval )
 {
 #ifdef HAVE_LDAP
-    return ber_flatten( berelement, berval );
+    struct berval *bervalU;
+    struct WLDAP32_berval *bervalW;
+
+    if (ber_flatten( berelement, &bervalU )) return WLDAP32_LBER_ERROR;
+
+    bervalW = bervalUtoW( bervalU );
+    ber_bvfree( bervalU );
+    if (!bervalW) return WLDAP32_LBER_ERROR;
+    *berval = bervalW;
+    return 0;
+
 #else
-    return LBER_ERROR;
+    return WLDAP32_LBER_ERROR;
 #endif
 }
 
@@ -199,7 +217,7 @@ INT CDECL WLDAP32_ber_flatten( BerElement *berelement, PBERVAL *berval )
  *  Set buf to 0 if the berelement was allocated with ldap_first_attribute
  *  or ldap_next_attribute, otherwise set it to 1.
  */
-void CDECL WLDAP32_ber_free( BerElement *berelement, INT buf )
+void CDECL WLDAP32_ber_free( WLDAP32_BerElement *berelement, INT buf )
 {
 #ifdef HAVE_LDAP
     ber_free( berelement, buf );
@@ -222,10 +240,16 @@ void CDECL WLDAP32_ber_free( BerElement *berelement, INT buf )
  * NOTES
  *  Call ber_free to free the returned berelement structure.
  */
-BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
+WLDAP32_BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
 {
 #ifdef HAVE_LDAP
-    return ber_init( berval );
+    struct berval *bervalU;
+    WLDAP32_BerElement *ret;
+
+    if (!(bervalU = bervalWtoU( berval ))) return NULL;
+    ret = ber_init( bervalU );
+    heap_free( bervalU );
+    return ret;
 #else
     return NULL;
 #endif
@@ -250,12 +274,25 @@ BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
  *  len and cookie are initialized by ber_first_element and should
  *  be passed on in subsequent calls to ber_next_element.
  */
-ULONG CDECL WLDAP32_ber_next_element( BerElement *berelement, ULONG *len, CHAR *opaque )
+ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR *opaque )
 {
 #ifdef HAVE_LDAP
-    return ber_next_element( berelement, len, opaque );
+    ber_len_t len;
+    ber_tag_t ret;
+
+    if ((ret = ber_next_element( berelement, &len, opaque )) != LBER_ERROR)
+    {
+        if (len > ~0u)
+        {
+            ERR( "len too large\n" );
+            return WLDAP32_LBER_ERROR;
+        }
+        *ret_len = len;
+    }
+    return ret;
+
 #else
-    return LBER_ERROR;
+    return WLDAP32_LBER_ERROR;
 #endif
 }
 
@@ -273,12 +310,25 @@ ULONG CDECL WLDAP32_ber_next_element( BerElement *berelement, ULONG *len, CHAR *
  *  Success: Tag of the next element.
  *  Failure: LBER_DEFAULT (no more data).
  */
-ULONG CDECL WLDAP32_ber_peek_tag( BerElement *berelement, ULONG *len )
+ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *berelement, ULONG *ret_len )
 {
 #ifdef HAVE_LDAP
-    return ber_peek_tag( berelement, len );
+    ber_len_t len;
+    ber_tag_t ret;
+
+    if ((ret = ber_peek_tag( berelement, &len )) != LBER_ERROR)
+    {
+        if (len > ~0u)
+        {
+            ERR( "len too large\n" );
+            return WLDAP32_LBER_ERROR;
+        }
+        *ret_len = len;
+    }
+    return ret;
+
 #else
-    return LBER_ERROR;
+    return WLDAP32_LBER_ERROR;
 #endif
 }
 
@@ -296,12 +346,25 @@ ULONG CDECL WLDAP32_ber_peek_tag( BerElement *berelement, ULONG *len )
  *  Success: Tag of the next element.
  *  Failure: LBER_DEFAULT (no more data).
  */
-ULONG CDECL WLDAP32_ber_skip_tag( BerElement *berelement, ULONG *len )
+ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *berelement, ULONG *ret_len )
 {
 #ifdef HAVE_LDAP
-    return ber_skip_tag( berelement, len );
+    ber_len_t len;
+    ber_tag_t ret;
+
+    if ((ret = ber_skip_tag( berelement, &len )) != LBER_ERROR)
+    {
+        if (len > ~0u)
+        {
+            ERR( "len too large\n" );
+            return WLDAP32_LBER_ERROR;
+        }
+        *ret_len = len;
+    }
+    return ret;
+
 #else
-    return LBER_ERROR;
+    return WLDAP32_LBER_ERROR;
 #endif
 }
 
@@ -324,7 +387,7 @@ ULONG CDECL WLDAP32_ber_skip_tag( BerElement *berelement, ULONG *len )
  *  berelement must have been allocated with ber_alloc_t. This function
  *  can be called multiple times to append data.
  */
-INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... )
+INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
 {
 #ifdef HAVE_LDAP
     __ms_va_list list;
@@ -367,8 +430,15 @@ INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... )
             }
         case 'V':
             {
-                struct berval **array = va_arg( list, struct berval ** );
-                ret = ber_printf( berelement, new_fmt, array );
+                struct WLDAP32_berval **array = va_arg( list, struct WLDAP32_berval ** );
+                struct berval **arrayU;
+                if (!(arrayU = bvarrayWtoU( array )))
+                {
+                    ret = -1;
+                    break;
+                }
+                ret = ber_printf( berelement, new_fmt, arrayU );
+                bvarrayfreeU( arrayU );
                 break;
             }
         case 'X':
@@ -396,7 +466,7 @@ INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... )
     __ms_va_end( list );
     return ret;
 #else
-    return LBER_ERROR;
+    return WLDAP32_LBER_ERROR;
 #endif
 }
 
@@ -419,7 +489,7 @@ INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... )
  *  berelement must have been allocated with ber_init. This function
  *  can be called multiple times to decode data.
  */
-INT WINAPIV WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... )
+INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... )
 {
 #ifdef HAVE_LDAP
     __ms_va_list list;
@@ -474,8 +544,12 @@ INT WINAPIV WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... )
             }
         case 'V':
             {
-                struct berval ***array = va_arg( list, struct berval *** );
-                ret = ber_scanf( berelement, new_fmt, array );
+                struct WLDAP32_berval **arrayW, ***array = va_arg( list, struct WLDAP32_berval *** );
+                struct berval **arrayU;
+                if ((ret = ber_scanf( berelement, new_fmt, &arrayU )) == -1) break;
+                if ((arrayW = bvarrayUtoW( arrayU ))) *array = arrayW;
+                else ret = -1;
+                bvarrayfreeU( arrayU );
                 break;
             }
         case 'n':
@@ -496,6 +570,6 @@ INT WINAPIV WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... )
     __ms_va_end( list );
     return ret;
 #else
-    return LBER_ERROR;
+    return WLDAP32_LBER_ERROR;
 #endif
 }
diff --git a/dlls/wldap32/page.c b/dlls/wldap32/page.c
index 959567c2bfd..a16ea52409e 100644
--- a/dlls/wldap32/page.c
+++ b/dlls/wldap32/page.c
@@ -40,7 +40,8 @@
 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
 
 #ifdef HAVE_LDAP
-static struct berval null_cookie = { 0, NULL };
+static struct berval null_cookieU = { 0, NULL };
+static struct WLDAP32_berval null_cookieW = { 0, NULL };
 #endif
 
 /***********************************************************************
@@ -75,7 +76,7 @@ ULONG CDECL ldap_create_page_controlA( WLDAP32_LDAP *ld, ULONG pagesize,
 #ifdef HAVE_LDAP
 
 /* create a page control by hand */
-static ULONG create_page_control( ULONG pagesize, struct WLDAP32_berval *cookie,
+static ULONG create_page_control( ULONG pagesize, struct berval *cookie,
     UCHAR critical, PLDAPControlW *control )
 {
     LDAPControlW *ctrl;
@@ -91,7 +92,7 @@ static ULONG create_page_control( ULONG pagesize, struct WLDAP32_berval *cookie,
     if (cookie)
         tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, cookie );
     else
-        tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, &null_cookie );
+        tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, &null_cookieU );
 
     ret = ber_flatten( ber, &berval );
     ber_free( ber, 1 );
@@ -149,13 +150,19 @@ ULONG CDECL ldap_create_page_controlW( WLDAP32_LDAP *ld, ULONG pagesize,
     struct WLDAP32_berval *cookie, UCHAR critical, PLDAPControlW *control )
 {
 #ifdef HAVE_LDAP
+    struct berval *cookieU = NULL;
+    ULONG ret;
+
     TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie,
            critical, control );
 
     if (!ld || !control || pagesize > LDAP_MAXINT)
         return WLDAP32_LDAP_PARAM_ERROR;
 
-    return create_page_control( pagesize, cookie, critical, control );
+    if (cookie && !(cookieU = bervalWtoU( cookie ))) return WLDAP32_LDAP_NO_MEMORY;
+    ret = create_page_control( pagesize, cookieU, critical, control );
+    heap_free( cookieU );
+    return ret;
 
 #else
     return WLDAP32_LDAP_NOT_SUPPORTED;
@@ -197,7 +204,7 @@ ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, PLDAPSearch search,
     }
 
     TRACE("search->cookie: %s\n", search->cookie ? debugstr_an(search->cookie->bv_val, search->cookie->bv_len) : "NULL");
-    ret = ldap_create_page_controlW( ld, pagesize, (struct WLDAP32_berval *)search->cookie, 1, &search->serverctrls[0] );
+    ret = ldap_create_page_controlW( ld, pagesize, search->cookie, 1, &search->serverctrls[0] );
     if (ret != WLDAP32_LDAP_SUCCESS) return ret;
 
     ret = ldap_search_ext_sW( ld, search->dn, search->scope,
@@ -230,17 +237,17 @@ ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, PLDAPSearch search,
 
     if (!server_ctrls) /* assume end of paged results */
     {
-        search->cookie = &null_cookie;
+        search->cookie = &null_cookieW;
         return WLDAP32_LDAP_SUCCESS;
     }
 
     if (search->cookie)
     {
-        ber_bvfree( search->cookie );
+        heap_free( search->cookie );
         search->cookie = NULL;
     }
 
-    ret = ldap_parse_page_controlW( ld, server_ctrls, count, (struct WLDAP32_berval **)&search->cookie );
+    ret = ldap_parse_page_controlW( ld, server_ctrls, count, &search->cookie );
     if (ret == WLDAP32_LDAP_SUCCESS)
         TRACE("new search->cookie: %s, count %u\n", debugstr_an(search->cookie->bv_val, search->cookie->bv_len), *count);
 
@@ -286,6 +293,7 @@ ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, PLDAPControlW *ctrls,
     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
 #ifdef HAVE_LDAP
     LDAPControlW *control = NULL;
+    struct berval *cookieU = NULL, *valueU;
     BerElement *ber;
     ber_tag_t tag;
     ULONG i;
@@ -302,20 +310,34 @@ ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, PLDAPControlW *ctrls,
     }
 
     if (!control)
-        return WLDAP32_LDAP_CONTROL_NOT_FOUND; 
-            
-    ber = ber_init( &((LDAPControl *)control)->ldctl_value );
+        return WLDAP32_LDAP_CONTROL_NOT_FOUND;
+
+    if (cookie && !(cookieU = bervalWtoU( *cookie )))
+        return WLDAP32_LDAP_NO_MEMORY;
+
+    if (!(valueU = bervalWtoU( &control->ldctl_value )))
+    {
+        heap_free( cookieU );
+        return WLDAP32_LDAP_NO_MEMORY;
+    }
+
+    ber = ber_init( valueU );
+    heap_free( valueU );
     if (!ber)
+    {
+        heap_free( cookieU );
         return WLDAP32_LDAP_NO_MEMORY;
+    }
 
-    tag = ber_scanf( ber, "{iO}", count, cookie );
-    if ( tag == LBER_ERROR )
+    tag = ber_scanf( ber, "{iO}", count, &cookieU );
+    if (tag == LBER_ERROR)
         ret = WLDAP32_LDAP_DECODING_ERROR;
     else
         ret = WLDAP32_LDAP_SUCCESS;
 
+    heap_free( cookieU );
     ber_free( ber, 1 );
-    
+
 #endif
     return ret;
 }
@@ -338,8 +360,8 @@ ULONG CDECL ldap_search_abandon_page( WLDAP32_LDAP *ld, PLDAPSearch search )
     while (*ctrls) controlfreeW( *ctrls++ );
     heap_free( search->serverctrls );
     controlarrayfreeW( search->clientctrls );
-    if (search->cookie && search->cookie != &null_cookie)
-        ber_bvfree( search->cookie );
+    if (search->cookie && search->cookie != &null_cookieW)
+        heap_free( search->cookie );
     heap_free( search );
 
     return WLDAP32_LDAP_SUCCESS;
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 69035050961..8cd546b88b5 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -103,6 +103,12 @@ typedef struct berelement
 
 #define WLDAP32_LDAP_AUTH_NEGOTIATE             0x486
 
+typedef struct WLDAP32_berval
+{
+    ULONG bv_len;
+    PCHAR bv_val;
+} LDAP_BERVAL, *PLDAP_BERVAL, BERVAL, *PBERVAL, WLDAP32_BerValue;
+
 typedef struct wldap32
 {
 #ifdef HAVE_LDAP
@@ -139,7 +145,7 @@ typedef struct ldapmodA {
     PCHAR mod_type;
     union {
         PCHAR *modv_strvals;
-        struct berval **modv_bvals;
+        struct WLDAP32_berval **modv_bvals;
     } mod_vals;
 } LDAPModA, *PLDAPModA;
 
@@ -148,7 +154,7 @@ typedef struct ldapmodW {
     PWCHAR mod_type;
     union {
         PWCHAR *modv_strvals;
-        struct berval **modv_bvals;
+        struct WLDAP32_berval **modv_bvals;
     } mod_vals;
 } LDAPModW, *PLDAPModW;
 
@@ -188,12 +194,6 @@ typedef struct ldap_version_info
     ULONG lv_minor;
 } LDAP_VERSION_INFO, *PLDAP_VERSION_INFO;
 
-typedef struct WLDAP32_berval
-{
-    ULONG bv_len;
-    PCHAR bv_val;
-} LDAP_BERVAL, *PLDAP_BERVAL, BERVAL, *PBERVAL, WLDAP32_BerValue;
-
 #define LDAP_PAGED_RESULT_OID_STRING "1.2.840.113556.1.4.319"
 #define LDAP_SERVER_RESP_SORT_OID "1.2.840.113556.1.4.474"
 #define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10"
@@ -242,7 +242,7 @@ typedef struct ldapsearch
     LDAPControlW **clientctrls;
     struct l_timeval timeout;
     ULONG sizelimit;
-    struct berval *cookie;
+    struct WLDAP32_berval *cookie;
 } LDAPSearch, *PLDAPSearch;
 
 typedef struct ldapsortkeyA
diff --git a/dlls/wldap32/wldap32.h b/dlls/wldap32/wldap32.h
index 3059df8603e..5b099c9fabc 100644
--- a/dlls/wldap32/wldap32.h
+++ b/dlls/wldap32/wldap32.h
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <assert.h>
 #include "wine/heap.h"
 #include "wine/unicode.h"
 
@@ -293,16 +294,39 @@ static inline void strarrayfreeU( char **strarray )
     }
 }
 
+static inline struct WLDAP32_berval *bervalWtoW( struct WLDAP32_berval *bv )
+{
+    struct WLDAP32_berval *berval;
+    DWORD size = sizeof(*berval) + bv->bv_len;
+
+    if ((berval = heap_alloc( size )))
+    {
+        char *val = (char *)(berval + 1);
+
+        berval->bv_len = bv->bv_len;
+        berval->bv_val = val;
+        memcpy( val, bv->bv_val, bv->bv_len );
+    }
+    return berval;
+}
+
+static inline void bvarrayfreeW( struct WLDAP32_berval **bv )
+{
+    struct WLDAP32_berval **p = bv;
+    while (*p) heap_free( *p++ );
+    heap_free( bv );
+}
+
 #ifdef HAVE_LDAP
 
-static inline struct berval *bvdup( struct berval *bv )
+static inline struct berval *bervalWtoU( struct WLDAP32_berval *bv )
 {
     struct berval *berval;
-    DWORD size = sizeof(struct berval) + bv->bv_len;
+    DWORD size = sizeof(*berval) + bv->bv_len;
 
     if ((berval = heap_alloc( size )))
     {
-        char *val = (char *)berval + sizeof(struct berval);
+        char *val = (char *)(berval + 1);
 
         berval->bv_len = bv->bv_len;
         berval->bv_val = val;
@@ -311,34 +335,99 @@ static inline struct berval *bvdup( struct berval *bv )
     return berval;
 }
 
-static inline DWORD bvarraylen( struct berval **bv )
+static inline struct WLDAP32_berval *bervalUtoW( struct berval *bv )
+{
+    struct WLDAP32_berval *berval;
+    DWORD size = sizeof(*berval) + bv->bv_len;
+
+    assert( bv->bv_len <= ~0u );
+
+    if ((berval = heap_alloc( size )))
+    {
+        char *val = (char *)(berval + 1);
+
+        berval->bv_len = bv->bv_len;
+        berval->bv_val = val;
+        memcpy( val, bv->bv_val, bv->bv_len );
+    }
+    return berval;
+}
+
+static inline DWORD bvarraylenU( struct berval **bv )
 {
     struct berval **p = bv;
     while (*p) p++;
     return p - bv;
 }
 
-static inline struct berval **bvarraydup( struct berval **bv )
+static inline DWORD bvarraylenW( struct WLDAP32_berval **bv )
+{
+    struct WLDAP32_berval **p = bv;
+    while (*p) p++;
+    return p - bv;
+}
+
+static inline struct WLDAP32_berval **bvarrayWtoW( struct WLDAP32_berval **bv )
+{
+    struct WLDAP32_berval **berval = NULL;
+    DWORD size;
+
+    if (bv)
+    {
+        size = sizeof(*berval) * (bvarraylenW( bv ) + 1);
+        if ((berval = heap_alloc( size )))
+        {
+            struct WLDAP32_berval **p = bv;
+            struct WLDAP32_berval **q = berval;
+
+            while (*p) *q++ = bervalWtoW( *p++ );
+            *q = NULL;
+        }
+    }
+    return berval;
+}
+
+static inline struct berval **bvarrayWtoU( struct WLDAP32_berval **bv )
 {
     struct berval **berval = NULL;
     DWORD size;
 
     if (bv)
     {
-        size = sizeof(struct berval *) * (bvarraylen( bv ) + 1);
+        size = sizeof(*berval) * (bvarraylenW( bv ) + 1);
         if ((berval = heap_alloc( size )))
         {
-            struct berval **p = bv;
+            struct WLDAP32_berval **p = bv;
             struct berval **q = berval;
 
-            while (*p) *q++ = bvdup( *p++ );
+            while (*p) *q++ = bervalWtoU( *p++ );
+            *q = NULL;
+        }
+    }
+    return berval;
+}
+
+static inline struct WLDAP32_berval **bvarrayUtoW( struct berval **bv )
+{
+    struct WLDAP32_berval **berval = NULL;
+    DWORD size;
+
+    if (bv)
+    {
+        size = sizeof(*berval) * (bvarraylenU( bv ) + 1);
+        if ((berval = heap_alloc( size )))
+        {
+            struct berval **p = bv;
+            struct WLDAP32_berval **q = berval;
+
+            while (*p) *q++ = bervalUtoW( *p++ );
             *q = NULL;
         }
     }
     return berval;
 }
 
-static inline void bvarrayfree( struct berval **bv )
+static inline void bvarrayfreeU( struct berval **bv )
 {
     struct berval **p = bv;
     while (*p) heap_free( *p++ );
@@ -355,7 +444,7 @@ static inline LDAPModW *modAtoW( LDAPModA *mod )
         modW->mod_type = strAtoW( mod->mod_type );
 
         if (mod->mod_op & LDAP_MOD_BVALUES)
-            modW->mod_vals.modv_bvals = bvarraydup( mod->mod_vals.modv_bvals );
+            modW->mod_vals.modv_bvals = bvarrayWtoW( mod->mod_vals.modv_bvals );
         else
             modW->mod_vals.modv_strvals = strarrayAtoW( mod->mod_vals.modv_strvals );
     }
@@ -372,7 +461,7 @@ static inline LDAPMod *modWtoU( LDAPModW *mod )
         modU->mod_type = strWtoU( mod->mod_type );
 
         if (mod->mod_op & LDAP_MOD_BVALUES)
-            modU->mod_vals.modv_bvals = bvarraydup( mod->mod_vals.modv_bvals );
+            modU->mod_vals.modv_bvals = bvarrayWtoU( mod->mod_vals.modv_bvals );
         else
             modU->mod_vals.modv_strvals = strarrayWtoU( mod->mod_vals.modv_strvals );
     }
@@ -382,7 +471,7 @@ static inline LDAPMod *modWtoU( LDAPModW *mod )
 static inline void modfreeW( LDAPModW *mod )
 {
     if (mod->mod_op & LDAP_MOD_BVALUES)
-        bvarrayfree( mod->mod_vals.modv_bvals );
+        bvarrayfreeW( mod->mod_vals.modv_bvals );
     else
         strarrayfreeW( mod->mod_vals.modv_strvals );
     heap_free( mod );
@@ -391,7 +480,7 @@ static inline void modfreeW( LDAPModW *mod )
 static inline void modfreeU( LDAPMod *mod )
 {
     if (mod->mod_op & LDAP_MOD_BVALUES)
-        bvarrayfree( mod->mod_vals.modv_bvals );
+        bvarrayfreeU( mod->mod_vals.modv_bvals );
     else
         strarrayfreeU( mod->mod_vals.modv_strvals );
     heap_free( mod );
-- 
2.30.0




More information about the wine-devel mailing list