diff --git a/dlls/wldap32/ber.c b/dlls/wldap32/ber.c index 7f39b9cfe17..ae5e9292e04 100644 --- a/dlls/wldap32/ber.c +++ b/dlls/wldap32/ber.c @@ -18,24 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include -#ifdef HAVE_LDAP_H -#include -#endif - #include "windef.h" #include "winbase.h" -#include "winldap_private.h" -#include "wldap32.h" +#include "winnls.h" + #include "wine/debug.h" +#include "wine/heap.h" +#include "winldap_private.h" -#ifdef HAVE_LDAP WINE_DEFAULT_DEBUG_CHANNEL(wldap32); -#endif - -#define WLDAP32_LBER_ERROR (~0U) /*********************************************************************** * ber_alloc_t (WLDAP32.@) @@ -52,13 +44,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(wldap32); * NOTES * Free the berelement structure with ber_free. */ -WLDAP32_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 ); -#else - return NULL; -#endif + WLDAP32_BerElement *ret; + + if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; + if (!(ret->opaque = ldap_funcs->ber_alloc_t( options ))) + { + heap_free( ret ); + return NULL; + } + return ret; } @@ -98,7 +94,7 @@ BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval ) * Use this function only to free an array of berval structures * returned by a call to ber_scanf with a 'V' in the format string. */ -void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval ) +void CDECL WLDAP32_ber_bvecfree( BERVAL **berval ) { bvarrayfreeW( berval ); } @@ -142,26 +138,9 @@ void CDECL WLDAP32_ber_bvfree( BERVAL *berval ) * NOTES * len and cookie should be passed to ber_next_element. */ -ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR **opaque ) +ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *ber, ULONG *len, char **opaque ) { -#ifdef HAVE_LDAP - 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 WLDAP32_LBER_ERROR; -#endif + return ldap_funcs->ber_first_element( ber->opaque, len, opaque ); } @@ -181,23 +160,18 @@ ULONG CDECL WLDAP32_ber_first_element( WLDAP32_BerElement *berelement, ULONG *re * NOTES * Free the berval structure with ber_bvfree. */ -INT CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *berelement, PBERVAL *berval ) +int CDECL WLDAP32_ber_flatten( WLDAP32_BerElement *ber, BERVAL **berval ) { -#ifdef HAVE_LDAP - struct berval *bervalU; + struct bervalU *bervalU; struct WLDAP32_berval *bervalW; - if (ber_flatten( berelement, &bervalU )) return WLDAP32_LBER_ERROR; + if (ldap_funcs->ber_flatten( ber->opaque, &bervalU )) return WLDAP32_LBER_ERROR; - bervalW = bervalUtoW( bervalU ); - ber_bvfree( bervalU ); + if (!(bervalW = bervalUtoW( bervalU ))) return WLDAP32_LBER_ERROR; + ldap_funcs->ber_bvfree( bervalU ); if (!bervalW) return WLDAP32_LBER_ERROR; *berval = bervalW; return 0; - -#else - return WLDAP32_LBER_ERROR; -#endif } @@ -217,11 +191,10 @@ INT CDECL WLDAP32_ber_flatten( WLDAP32_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( WLDAP32_BerElement *berelement, INT buf ) +void CDECL WLDAP32_ber_free( WLDAP32_BerElement *ber, int freebuf ) { -#ifdef HAVE_LDAP - ber_free( berelement, buf ); -#endif + ldap_funcs->ber_free( ber->opaque, freebuf ); + heap_free( ber ); } @@ -242,17 +215,22 @@ void CDECL WLDAP32_ber_free( WLDAP32_BerElement *berelement, INT buf ) */ WLDAP32_BerElement * CDECL WLDAP32_ber_init( BERVAL *berval ) { -#ifdef HAVE_LDAP - struct berval *bervalU; + struct bervalU *bervalU; WLDAP32_BerElement *ret; - if (!(bervalU = bervalWtoU( berval ))) return NULL; - ret = ber_init( bervalU ); + if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; + if (!(bervalU = bervalWtoU( berval ))) + { + heap_free( ret ); + return NULL; + } + if (!(ret->opaque = ldap_funcs->ber_init( bervalU ))) + { + heap_free( ret ); + ret = NULL; + } heap_free( bervalU ); return ret; -#else - return NULL; -#endif } @@ -274,26 +252,9 @@ WLDAP32_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( WLDAP32_BerElement *berelement, ULONG *ret_len, CHAR *opaque ) +ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *ber, ULONG *len, char *opaque ) { -#ifdef HAVE_LDAP - 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 WLDAP32_LBER_ERROR; -#endif + return ldap_funcs->ber_next_element( ber->opaque, len, opaque ); } @@ -310,26 +271,9 @@ ULONG CDECL WLDAP32_ber_next_element( WLDAP32_BerElement *berelement, ULONG *ret * Success: Tag of the next element. * Failure: LBER_DEFAULT (no more data). */ -ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *berelement, ULONG *ret_len ) +ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *ber, ULONG *len ) { -#ifdef HAVE_LDAP - 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 WLDAP32_LBER_ERROR; -#endif + return ldap_funcs->ber_peek_tag( ber->opaque, len ); } @@ -346,26 +290,9 @@ ULONG CDECL WLDAP32_ber_peek_tag( WLDAP32_BerElement *berelement, ULONG *ret_len * Success: Tag of the next element. * Failure: LBER_DEFAULT (no more data). */ -ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *berelement, ULONG *ret_len ) +ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *ber, ULONG *len ) { -#ifdef HAVE_LDAP - 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 WLDAP32_LBER_ERROR; -#endif + return ldap_funcs->ber_skip_tag( ber->opaque, len ); } @@ -380,16 +307,15 @@ ULONG CDECL WLDAP32_ber_skip_tag( WLDAP32_BerElement *berelement, ULONG *ret_len * ... [I] Values to encode. * * RETURNS - * Success: Non-negative number. + * Success: Non-negative number. * Failure: LBER_ERROR * * NOTES * berelement must have been allocated with ber_alloc_t. This function * can be called multiple times to append data. */ -INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) +int WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *ber, char *fmt, ... ) { -#ifdef HAVE_LDAP __ms_va_list list; int ret = 0; char new_fmt[2]; @@ -399,63 +325,64 @@ INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) while (*fmt) { new_fmt[0] = *fmt++; - switch(new_fmt[0]) + switch (new_fmt[0]) { case 'b': case 'e': case 'i': - { - int i = va_arg( list, int ); - ret = ber_printf( berelement, new_fmt, i ); - break; - } + { + int i = va_arg( list, int ); + ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, i ); + break; + } case 'o': case 's': - { - char *str = va_arg( list, char * ); - ret = ber_printf( berelement, new_fmt, str ); - break; - } + { + char *str = va_arg( list, char * ); + ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, str ); + break; + } case 't': - { - unsigned int tag = va_arg( list, unsigned int ); - ret = ber_printf( berelement, new_fmt, tag ); - break; - } + { + unsigned int tag = va_arg( list, unsigned int ); + ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, tag ); + break; + } case 'v': - { - char **array = va_arg( list, char ** ); - ret = ber_printf( berelement, new_fmt, array ); - break; - } + { + char **array = va_arg( list, char ** ); + ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, array ); + break; + } case 'V': + { + struct WLDAP32_berval **array = va_arg( list, struct WLDAP32_berval ** ); + struct bervalU **arrayU; + if (!(arrayU = bvarrayWtoU( 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 ); + ret = -1; break; } + ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, arrayU ); + bvarrayfreeU( arrayU ); + break; + } case 'X': - { - char *str = va_arg( list, char * ); - int len = va_arg( list, int ); - new_fmt[0] = 'B'; /* 'X' is deprecated */ - ret = ber_printf( berelement, new_fmt, str, len ); - break; - } + { + char *str = va_arg( list, char * ); + int len = va_arg( list, int ); + new_fmt[0] = 'B'; /* 'X' is deprecated */ + ret = ldap_funcs->ber_printf( ber->opaque, new_fmt, str, len ); + break; + } case 'n': case '{': case '}': case '[': case ']': - ret = ber_printf( berelement, new_fmt ); + ret = ldap_funcs->ber_printf( ber->opaque, new_fmt ); break; + default: FIXME( "Unknown format '%c'\n", new_fmt[0] ); ret = -1; @@ -465,9 +392,6 @@ INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) } __ms_va_end( list ); return ret; -#else - return WLDAP32_LBER_ERROR; -#endif } @@ -482,16 +406,15 @@ INT WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) * ... [I] Pointers to values to be decoded. * * RETURNS - * Success: Non-negative number. + * Success: Non-negative number. * Failure: LBER_ERROR * * NOTES * berelement must have been allocated with ber_init. This function * can be called multiple times to decode data. */ -INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) +int WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *ber, char *fmt, ... ) { -#ifdef HAVE_LDAP __ms_va_list list; int ret = 0; char new_fmt[2]; @@ -501,65 +424,81 @@ INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) while (*fmt) { new_fmt[0] = *fmt++; - switch(new_fmt[0]) + switch (new_fmt[0]) { case 'a': - { - char **ptr = va_arg( list, char ** ); - ret = ber_scanf( berelement, new_fmt, ptr ); - break; - } + { + char *str, **ptr = va_arg( list, char ** ); + if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &str )) == -1) break; + *ptr = strdupU( str ); + ldap_funcs->ldap_memfree( str ); + break; + } case 'b': case 'e': case 'i': - { - int *i = va_arg( list, int * ); - ret = ber_scanf( berelement, new_fmt, i ); - break; - } + { + int *i = va_arg( list, int * ); + ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, i ); + break; + } case 't': - { - unsigned int *tag = va_arg( list, unsigned int * ); - ret = ber_scanf( berelement, new_fmt, tag ); - break; - } + { + unsigned int *tag = va_arg( list, unsigned int * ); + ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, tag ); + break; + } case 'v': + { + char *str, **arrayU, **ptr, ***array = va_arg( list, char *** ); + if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &arrayU )) == -1) break; + *array = strarrayUtoU( arrayU ); + ptr = arrayU; + while ((str = *ptr)) { - char ***array = va_arg( list, char *** ); - ret = ber_scanf( berelement, new_fmt, array ); - break; + ldap_funcs->ldap_memfree( str ); + ptr++; } + ldap_funcs->ldap_memfree( arrayU ); + break; + } case 'B': - { - char **str = va_arg( list, char ** ); - int *len = va_arg( list, int * ); - ret = ber_scanf( berelement, new_fmt, str, len ); - break; - } + { + char *strU, **str = va_arg( list, char ** ); + int *len = va_arg( list, int * ); + if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &strU, len )) == -1) break; + *str = heap_alloc( *len ); + memcpy( *str, strU, *len ); + ldap_funcs->ldap_memfree( strU ); + break; + } case 'O': - { - struct berval **ptr = va_arg( list, struct berval ** ); - ret = ber_scanf( berelement, new_fmt, ptr ); - break; - } + { + struct WLDAP32_berval **berval = va_arg( list, struct WLDAP32_berval ** ); + struct bervalU *bervalU; + if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &bervalU )) == -1) break; + *berval = bervalUtoW( bervalU ); + ldap_funcs->ber_bvfree( bervalU ); + break; + } case 'V': - { - 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; - } + { + struct WLDAP32_berval ***array = va_arg( list, struct WLDAP32_berval *** ); + struct bervalU **arrayU; + if ((ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt, &arrayU )) == -1) break; + *array = bvarrayUtoW( arrayU ); + ldap_funcs->ber_bvecfree( arrayU ); + break; + } case 'n': case 'x': case '{': case '}': case '[': case ']': - ret = ber_scanf( berelement, new_fmt ); + ret = ldap_funcs->ber_scanf( ber->opaque, new_fmt ); break; + default: FIXME( "Unknown format '%c'\n", new_fmt[0] ); ret = -1; @@ -569,7 +508,4 @@ INT WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *berelement, PCHAR fmt, ... ) } __ms_va_end( list ); return ret; -#else - return WLDAP32_LBER_ERROR; -#endif } diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c index 0372206062a..3436cffc4a1 100644 --- a/dlls/wldap32/libldap.c +++ b/dlls/wldap32/libldap.c @@ -42,6 +42,8 @@ #include "wine/debug.h" #include "winldap_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(wldap32); + C_ASSERT( sizeof(BerValueU) == sizeof(BerValue) ); C_ASSERT( sizeof(LDAPModU) == sizeof(LDAPMod) ); C_ASSERT( sizeof(LDAPControlU) == sizeof(LDAPControl) ); @@ -50,6 +52,246 @@ C_ASSERT( sizeof(LDAPVLVInfoU) == sizeof(LDAPVLVInfo) ); static LDAPMod *nullattrs[] = { NULL }; +void * CDECL wrap_ber_alloc_t( int options ) +{ + return ber_alloc_t( options ); +} + +void CDECL wrap_ber_bvecfree( struct bervalU **berval ) +{ + ber_bvecfree( (struct berval **)berval ); +} + +void CDECL wrap_ber_bvfree( struct bervalU *berval ) +{ + ber_bvfree( (struct berval *)berval ); +} + +unsigned int CDECL wrap_ber_first_element( void *ber, ULONG *ret_len, char **last ) +{ + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_first_element( ber, &len, last )) == LBER_ERROR) return WLDAP32_LBER_ERROR; + if (ret > ~0u) + { + ERR( "ret too large\n" ); + return WLDAP32_LBER_ERROR; + } + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + + *ret_len = len; + return ret; +} + +int CDECL wrap_ber_flatten( void *ber, struct bervalU **berval ) +{ + return ber_flatten( ber, (struct berval **)berval ); +} + +void CDECL wrap_ber_free( void *ber, int freebuf ) +{ + ber_free( ber, freebuf ); +} + +void * CDECL wrap_ber_init( struct bervalU *berval ) +{ + return ber_init( (struct berval *)berval ); +} + +unsigned int CDECL wrap_ber_next_element( void *ber, unsigned int *ret_len, char *last ) +{ + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_next_element( ber, &len, last )) == LBER_ERROR) return WLDAP32_LBER_ERROR; + if (ret > ~0u) + { + ERR( "ret too large\n" ); + return WLDAP32_LBER_ERROR; + } + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + + *ret_len = len; + return ret; +} + +unsigned int CDECL wrap_ber_peek_tag( void *ber, unsigned int *ret_len ) +{ + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_peek_tag( ber, &len )) == LBER_ERROR) return WLDAP32_LBER_ERROR; + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + + *ret_len = len; + return ret; +} + +unsigned int CDECL wrap_ber_skip_tag( void *ber, unsigned int *ret_len ) +{ + ber_len_t len; + ber_tag_t ret; + + if ((ret = ber_skip_tag( ber, &len )) == LBER_ERROR) return WLDAP32_LBER_ERROR; + if (len > ~0u) + { + ERR( "len too large\n" ); + return WLDAP32_LBER_ERROR; + } + + *ret_len = len; + return ret; +} + +int WINAPIV wrap_ber_printf( void *ber, char *fmt, ... ) +{ + int ret; + __ms_va_list args; + + assert( strlen(fmt) == 1 ); + + __ms_va_start( args, fmt ); + switch (fmt[0]) + { + case 'b': + case 'e': + case 'i': + { + int i = va_arg( args, int ); + ret = ber_printf( ber, fmt, i ); + break; + } + case 'o': + case 's': + { + char *str = va_arg( args, char * ); + ret = ber_printf( ber, fmt, str ); + break; + } + case 't': + { + unsigned int tag = va_arg( args, unsigned int ); + ret = ber_printf( ber, fmt, tag ); + break; + } + case 'v': + { + char **array = va_arg( args, char ** ); + ret = ber_printf( ber, fmt, array ); + break; + } + case 'V': + { + struct berval **array = va_arg( args, struct berval ** ); + ret = ber_printf( ber, fmt, array ); + break; + } + case 'B': + { + char *str = va_arg( args, char * ); + int len = va_arg( args, int ); + ret = ber_printf( ber, fmt, str, len ); + break; + } + case 'n': + case '{': + case '}': + case '[': + case ']': + ret = ber_printf( ber, fmt ); + break; + + default: + assert( 0 ); + } + __ms_va_end( args ); + return ret; +} + +int WINAPIV wrap_ber_scanf( void *ber, char *fmt, ... ) +{ + int ret; + __ms_va_list args; + + assert( strlen(fmt) == 1 ); + + __ms_va_start( args, fmt ); + switch (fmt[0]) + { + case 'a': + { + char **str = va_arg( args, char ** ); + ret = ber_scanf( ber, fmt, str ); + break; + } + case 'b': + case 'e': + case 'i': + { + int *i = va_arg( args, int * ); + ret = ber_scanf( ber, fmt, i ); + break; + } + case 't': + { + unsigned int *tag = va_arg( args, unsigned int * ); + ret = ber_scanf( ber, fmt, tag ); + break; + } + case 'v': + { + char ***array = va_arg( args, char *** ); + ret = ber_scanf( ber, fmt, array ); + break; + } + case 'B': + { + char **str = va_arg( args, char ** ); + int *len = va_arg( args, int * ); + ret = ber_scanf( ber, fmt, str, len ); + break; + } + case 'O': + { + struct berval **berval = va_arg( args, struct berval ** ); + ret = ber_scanf( ber, fmt, berval ); + break; + } + case 'V': + { + struct berval ***array = va_arg( args, struct berval *** ); + ret = ber_scanf( ber, fmt, array ); + break; + } + case 'n': + case 'x': + case '{': + case '}': + case '[': + case ']': + ret = ber_scanf( ber, fmt ); + break; + + default: + assert( 0 ); + } + __ms_va_end( args ); + return ret; +} + int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls, LDAPControlU **clientctrls, ULONG *msg ) { @@ -65,10 +307,28 @@ int CDECL wrap_ldap_add_ext_s( void *ld, char *dn, LDAPModU **attrs, LDAPControl (LDAPControl **)clientctrls ); } +void CDECL wrap_ldap_memfree( void *ptr ) +{ + return ldap_memfree( ptr ); +} + static const struct ldap_funcs funcs = { + wrap_ber_alloc_t, + wrap_ber_bvecfree, + wrap_ber_bvfree, + wrap_ber_first_element, + wrap_ber_flatten, + wrap_ber_free, + wrap_ber_init, + wrap_ber_next_element, + wrap_ber_peek_tag, + wrap_ber_skip_tag, + wrap_ber_printf, + wrap_ber_scanf, wrap_ldap_add_ext, wrap_ldap_add_ext_s, + wrap_ldap_memfree, }; NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h index d9d833cdcb8..4ca90d298a0 100644 --- a/dlls/wldap32/libldap.h +++ b/dlls/wldap32/libldap.h @@ -60,13 +60,41 @@ typedef struct void *ldvlv_extradata; } LDAPVLVInfoU; +extern void * CDECL wrap_ber_alloc_t(int) DECLSPEC_HIDDEN; +extern void CDECL wrap_ber_bvecfree(struct bervalU **) DECLSPEC_HIDDEN; +extern void CDECL wrap_ber_bvfree(struct bervalU *) DECLSPEC_HIDDEN; +extern unsigned int CDECL wrap_ber_first_element(void *, unsigned int *, char **) DECLSPEC_HIDDEN; +extern int CDECL wrap_ber_flatten(void *, struct bervalU **) DECLSPEC_HIDDEN; +extern void CDECL wrap_ber_free(void *, int) DECLSPEC_HIDDEN; +extern void * CDECL wrap_ber_init(struct bervalU *) DECLSPEC_HIDDEN; +extern unsigned int CDECL wrap_ber_next_element(void *, unsigned int *, char *) DECLSPEC_HIDDEN; +extern unsigned int CDECL wrap_ber_peek_tag(void *, unsigned int *) DECLSPEC_HIDDEN; +extern unsigned int CDECL wrap_ber_skip_tag(void *, unsigned int *) DECLSPEC_HIDDEN; +extern int WINAPIV wrap_ber_printf(void *, char *, ...) DECLSPEC_HIDDEN; +extern int WINAPIV wrap_ber_scanf(void *, char *, ...) DECLSPEC_HIDDEN; + extern int CDECL wrap_ldap_add_ext(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *) DECLSPEC_HIDDEN; extern int CDECL wrap_ldap_add_ext_s(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN; +extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN; struct ldap_funcs { + void * (CDECL *ber_alloc_t)(int); + void (CDECL *ber_bvecfree)(struct bervalU **); + void (CDECL *ber_bvfree)(struct bervalU *); + unsigned int (CDECL *ber_first_element)(void *, unsigned int *, char **); + int (CDECL *ber_flatten)(void *, struct bervalU **); + void (CDECL *ber_free)(void *, int); + void * (CDECL *ber_init)(struct bervalU *); + unsigned int (CDECL *ber_next_element)(void *, unsigned int *, char *); + unsigned int (CDECL *ber_peek_tag)(void *, unsigned int *); + unsigned int (CDECL *ber_skip_tag)(void *, unsigned int *); + int (WINAPIV *ber_printf)(void *, char *, ...); + int (WINAPIV *ber_scanf)(void *, char *, ...); + int (CDECL *ldap_add_ext)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *); int (CDECL *ldap_add_ext_s)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **); + void (CDECL *ldap_memfree)(void *); }; extern const struct ldap_funcs *ldap_funcs; diff --git a/dlls/wldap32/misc.c b/dlls/wldap32/misc.c index 39642960955..dd1a1ef3f12 100644 --- a/dlls/wldap32/misc.c +++ b/dlls/wldap32/misc.c @@ -328,15 +328,22 @@ PWCHAR CDECL ldap_first_attributeW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry { PWCHAR ret = NULL; #ifdef HAVE_LDAP + BerElement *berU; char *retU; TRACE( "(%p, %p, %p)\n", ld, entry, ptr ); if (!ld || !entry) return NULL; - retU = ldap_first_attribute( ld->ld, entry, ptr ); - ret = strUtoW( retU ); - ldap_memfree( retU ); + retU = ldap_first_attribute( ld->ld, entry, &berU ); + if (retU) + { + WLDAP32_BerElement *ber = heap_alloc( sizeof(*ber) ); + ber->opaque = (char *)berU; + *ptr = ber; + ret = strUtoW( retU ); + ldap_memfree( retU ); + } #endif return ret; @@ -487,19 +494,22 @@ PCHAR CDECL ldap_next_attributeA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry, * When done iterating and when ptr != NULL, call ber_free( ptr, 0 ). */ PWCHAR CDECL ldap_next_attributeW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry, - WLDAP32_BerElement *ptr ) + WLDAP32_BerElement *ber ) { PWCHAR ret = NULL; #ifdef HAVE_LDAP char *retU; - TRACE( "(%p, %p, %p)\n", ld, entry, ptr ); + TRACE( "(%p, %p, %p)\n", ld, entry, ber ); - if (!ld || !entry || !ptr) return NULL; - retU = ldap_next_attribute( ld->ld, entry, ptr ); + if (!ld || !entry) return NULL; - ret = strUtoW( retU ); - ldap_memfree( retU ); + retU = ldap_next_attribute( ld->ld, entry, (BerElement *)ber->opaque ); + if (retU) + { + ret = strUtoW( retU ); + ldap_memfree( retU ); + } #endif return ret; diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h index d0583c61f50..22e981cb26d 100644 --- a/dlls/wldap32/winldap_private.h +++ b/dlls/wldap32/winldap_private.h @@ -27,6 +27,8 @@ #include "winnls.h" #include "libldap.h" +#define WLDAP32_LBER_ERROR (~0L) + typedef enum { WLDAP32_LDAP_SUCCESS = 0x00, WLDAP32_LDAP_UNWILLING_TO_PERFORM = 0x35, @@ -1187,6 +1189,26 @@ static inline WCHAR **strarrayUtoW( char **strarray ) return strarrayW; } +static inline char **strarrayUtoU( char **strarray ) +{ + char **strarrayU = NULL; + DWORD size; + + if (strarray) + { + size = sizeof(char *) * (strarraylenU( strarray ) + 1); + if ((strarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size ))) + { + char **p = strarray; + char **q = strarrayU; + + while (*p) *q++ = strdupU( *p++ ); + *q = NULL; + } + } + return strarrayU; +} + static inline LDAPControlW *controlUtoW( const LDAPControlU *control ) { LDAPControlW *controlW; diff --git a/include/winber.h b/include/winber.h index 40ab0f40ed8..372cc321269 100644 --- a/include/winber.h +++ b/include/winber.h @@ -27,11 +27,17 @@ typedef unsigned int ber_tag_t; typedef unsigned int ber_len_t; BerElement * CDECL ber_alloc_t( int ); +BERVAL * CDECL ber_bvdup( BERVAL * ); +void CDECL ber_bvecfree( BERVAL ** ); void CDECL ber_bvfree( BERVAL * ); +ULONG CDECL ber_first_element( BerElement *, ULONG *, char ** ); int CDECL ber_flatten( BerElement *, BERVAL ** ); void CDECL ber_free( BerElement *, int ); BerElement * CDECL ber_init( BERVAL * ); +ULONG CDECL ber_next_element( BerElement *, ULONG *, char ** ); +ULONG CDECL ber_peek_tag( BerElement *, ULONG * ); int WINAPIV ber_printf( BerElement *, char *, ... ); ULONG WINAPIV ber_scanf( BerElement *, char *, ... ); +ULONG CDECL ber_skip_tag( BerElement *, ULONG * ); #endif /* __WINE_WINBER_H */