[PATCH 5/5] wldap32: Move support for page functions to the Unix library.
Hans Leidekker
hans at codeweavers.com
Fri Apr 16 02:59:18 CDT 2021
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/wldap32/ber.c | 2 +-
dlls/wldap32/page.c | 281 +++++++++++----------------------
dlls/wldap32/winldap_private.h | 76 +++++++++
3 files changed, 169 insertions(+), 190 deletions(-)
diff --git a/dlls/wldap32/ber.c b/dlls/wldap32/ber.c
index ae5e9292e04..c6dca7153a2 100644
--- a/dlls/wldap32/ber.c
+++ b/dlls/wldap32/ber.c
@@ -413,7 +413,7 @@ int WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *ber, char *fmt, ... )
* 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 *ber, char *fmt, ... )
+ULONG WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *ber, char *fmt, ... )
{
__ms_va_list list;
int ret = 0;
diff --git a/dlls/wldap32/page.c b/dlls/wldap32/page.c
index 07f29be0d50..5364280f271 100644
--- a/dlls/wldap32/page.c
+++ b/dlls/wldap32/page.c
@@ -18,31 +18,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
#include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-#ifndef LDAP_MAXINT
-#define LDAP_MAXINT 2147483647
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "wine/heap.h"
+#include "winldap_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#ifdef HAVE_LDAP
-static struct berval null_cookieU = { 0, NULL };
+#define LDAP_MAXINT (2^31)
+
static struct WLDAP32_berval null_cookieW = { 0, NULL };
-#endif
/***********************************************************************
* ldap_create_page_controlA (WLDAP32.@)
@@ -50,84 +39,73 @@ static struct WLDAP32_berval null_cookieW = { 0, NULL };
* See ldap_create_page_controlW.
*/
ULONG CDECL ldap_create_page_controlA( WLDAP32_LDAP *ld, ULONG pagesize,
- struct WLDAP32_berval *cookie, UCHAR critical, PLDAPControlA *control )
+ struct WLDAP32_berval *cookie, UCHAR critical, LDAPControlA **control )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
LDAPControlW *controlW = NULL;
- TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie,
- critical, control );
+ 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;
+ if (!ld || !control || pagesize > LDAP_MAXINT) return WLDAP32_LDAP_PARAM_ERROR;
ret = ldap_create_page_controlW( ld, pagesize, cookie, critical, &controlW );
- if (ret == LDAP_SUCCESS)
+ if (ret == WLDAP32_LDAP_SUCCESS)
{
*control = controlWtoA( controlW );
ldap_control_freeW( controlW );
}
-
-#endif
return ret;
}
-#ifdef HAVE_LDAP
-
/* create a page control by hand */
-static ULONG create_page_control( ULONG pagesize, struct berval *cookie,
- UCHAR critical, PLDAPControlW *control )
+static ULONG create_page_control( ULONG pagesize, struct WLDAP32_berval *cookie, UCHAR critical, LDAPControlW **control )
{
LDAPControlW *ctrl;
- BerElement *ber;
- ber_tag_t tag;
- struct berval *berval;
- INT ret, len;
+ WLDAP32_BerElement *ber;
+ struct WLDAP32_berval *berval, *vec[2];
+ int ret, len;
char *val;
- ber = ber_alloc_t( LBER_USE_DER );
- if (!ber) return WLDAP32_LDAP_NO_MEMORY;
+ if (!(ber = WLDAP32_ber_alloc_t( WLDAP32_LBER_USE_DER ))) return WLDAP32_LDAP_NO_MEMORY;
+ vec[1] = NULL;
if (cookie)
- tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, cookie );
+ vec[0] = cookie;
else
- tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, &null_cookieU );
+ vec[0] = &null_cookieW;
+ len = WLDAP32_ber_printf( ber, (char *)"{iV}", pagesize, vec );
- ret = ber_flatten( ber, &berval );
- ber_free( ber, 1 );
+ ret = WLDAP32_ber_flatten( ber, &berval );
+ WLDAP32_ber_free( ber, 1 );
- if (tag == LBER_ERROR)
- return WLDAP32_LDAP_ENCODING_ERROR;
-
- if (ret == -1)
- return WLDAP32_LDAP_NO_MEMORY;
+ if (len == WLDAP32_LBER_ERROR) return WLDAP32_LDAP_ENCODING_ERROR;
+ if (ret == -1) return WLDAP32_LDAP_NO_MEMORY;
/* copy the berval so it can be properly freed by the caller */
if (!(val = heap_alloc( berval->bv_len ))) return WLDAP32_LDAP_NO_MEMORY;
len = berval->bv_len;
memcpy( val, berval->bv_val, len );
- ber_bvfree( berval );
+ WLDAP32_ber_bvfree( berval );
- if (!(ctrl = heap_alloc( sizeof(LDAPControlW) )))
+ if (!(ctrl = heap_alloc( sizeof(*ctrl) )))
{
heap_free( val );
return WLDAP32_LDAP_NO_MEMORY;
}
-
- ctrl->ldctl_oid = strAtoW( LDAP_PAGED_RESULT_OID_STRING );
+ if (!(ctrl->ldctl_oid = strAtoW( LDAP_PAGED_RESULT_OID_STRING )))
+ {
+ heap_free( ctrl );
+ return WLDAP32_LDAP_NO_MEMORY;
+ }
ctrl->ldctl_value.bv_len = len;
ctrl->ldctl_value.bv_val = val;
- ctrl->ldctl_iscritical = critical;
+ ctrl->ldctl_iscritical = critical;
*control = ctrl;
-
return WLDAP32_LDAP_SUCCESS;
}
-#endif /* HAVE_LDAP */
-
/***********************************************************************
* ldap_create_page_controlW (WLDAP32.@)
*
@@ -146,31 +124,16 @@ static ULONG create_page_control( ULONG pagesize, struct berval *cookie,
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_create_page_controlW( WLDAP32_LDAP *ld, ULONG pagesize,
- struct WLDAP32_berval *cookie, UCHAR critical, PLDAPControlW *control )
+ULONG CDECL ldap_create_page_controlW( WLDAP32_LDAP *ld, ULONG pagesize, struct WLDAP32_berval *cookie,
+ UCHAR critical, LDAPControlW **control )
{
-#ifdef HAVE_LDAP
- struct berval *cookieU = NULL;
- ULONG ret;
+ TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie, critical, control );
- 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;
-
- 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;
-#endif
+ if (!ld || !control || pagesize > LDAP_MAXINT) return WLDAP32_LDAP_PARAM_ERROR;
+ return create_page_control( pagesize, cookie, critical, control );
}
-ULONG CDECL ldap_get_next_page( WLDAP32_LDAP *ld, PLDAPSearch search, ULONG pagesize,
- ULONG *message )
+ULONG CDECL ldap_get_next_page( WLDAP32_LDAP *ld, LDAPSearch *search, ULONG pagesize, ULONG *message )
{
FIXME( "(%p, %p, 0x%08x, %p)\n", ld, search, pagesize, message );
@@ -178,18 +141,16 @@ ULONG CDECL ldap_get_next_page( WLDAP32_LDAP *ld, PLDAPSearch search, ULONG page
return WLDAP32_LDAP_NOT_SUPPORTED;
}
-ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, PLDAPSearch search,
- struct l_timeval *timeout, ULONG pagesize, ULONG *count,
- WLDAP32_LDAPMessage **results )
+ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, LDAPSearch *search, struct l_timeval *timeout, ULONG pagesize,
+ ULONG *count, WLDAP32_LDAPMessage **results )
{
-#ifdef HAVE_LDAP
ULONG ret;
- TRACE( "(%p, %p, %p, %u, %p, %p)\n", ld, search, timeout,
- pagesize, count, results );
+ TRACE( "(%p, %p, %p, %u, %p, %p)\n", ld, search, timeout, pagesize, count, results );
+
if (!ld || !search || !count || !results) return ~0u;
- if (search->cookie && search->cookie->bv_len == 0)
+ if (search->cookie && !search->cookie->bv_len)
{
/* end of paged results */
*count = 0;
@@ -207,22 +168,16 @@ ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, PLDAPSearch search,
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,
- search->filter, search->attrs, search->attrsonly,
+ ret = ldap_search_ext_sW( ld, search->dn, search->scope, search->filter, search->attrs, search->attrsonly,
search->serverctrls, search->clientctrls,
search->timeout.tv_sec ? &search->timeout : NULL, search->sizelimit, results );
if (ret != WLDAP32_LDAP_SUCCESS) return ret;
return ldap_get_paged_count( ld, search, count, *results );
-
-#endif
- return WLDAP32_LDAP_NOT_SUPPORTED;
}
-ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, PLDAPSearch search,
- ULONG *count, WLDAP32_LDAPMessage *results )
+ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, LDAPSearch *search, ULONG *count, WLDAP32_LDAPMessage *results )
{
-#ifdef HAVE_LDAP
ULONG ret;
LDAPControlW **server_ctrls = NULL;
@@ -249,99 +204,68 @@ ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, PLDAPSearch search,
TRACE("new search->cookie: %s, count %u\n", debugstr_an(search->cookie->bv_val, search->cookie->bv_len), *count);
ldap_controls_freeW( server_ctrls );
-
return ret;
-
-#endif
- return WLDAP32_LDAP_NOT_SUPPORTED;
}
/***********************************************************************
* ldap_parse_page_controlA (WLDAP32.@)
*/
-ULONG CDECL ldap_parse_page_controlA( WLDAP32_LDAP *ld, PLDAPControlA *ctrls,
- ULONG *count, struct WLDAP32_berval **cookie )
+ULONG CDECL ldap_parse_page_controlA( WLDAP32_LDAP *ld, LDAPControlA **ctrls, ULONG *count,
+ struct WLDAP32_berval **cookie )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
LDAPControlW **ctrlsW = NULL;
TRACE( "(%p, %p, %p, %p)\n", ld, ctrls, count, cookie );
- if (!ld || !ctrls || !count || !cookie)
- return WLDAP32_LDAP_PARAM_ERROR;
-
- ctrlsW = controlarrayAtoW( ctrls );
- if (!ctrlsW) return WLDAP32_LDAP_NO_MEMORY;
+ if (!ld || !ctrls || !count || !cookie) return WLDAP32_LDAP_PARAM_ERROR;
+ if (!(ctrlsW = controlarrayAtoW( ctrls ))) return WLDAP32_LDAP_NO_MEMORY;
ret = ldap_parse_page_controlW( ld, ctrlsW, count, cookie );
controlarrayfreeW( ctrlsW );
-
-#endif
return ret;
}
/***********************************************************************
* ldap_parse_page_controlW (WLDAP32.@)
*/
-ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, PLDAPControlW *ctrls,
- ULONG *count, struct WLDAP32_berval **cookie )
+ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, LDAPControlW **ctrls, ULONG *count,
+ struct WLDAP32_berval **cookie )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
LDAPControlW *control = NULL;
- struct berval *cookieU = NULL, *valueU;
- BerElement *ber;
- ber_tag_t tag;
+ WLDAP32_BerElement *ber;
+ struct WLDAP32_berval *vec[2];
+ int tag;
ULONG i;
TRACE( "(%p, %p, %p, %p)\n", ld, ctrls, count, cookie );
- if (!ld || !ctrls || !count || !cookie)
- return WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld || !ctrls || !count || !cookie) return WLDAP32_LDAP_PARAM_ERROR;
for (i = 0; ctrls[i]; i++)
{
if (!lstrcmpW( LDAP_PAGED_RESULT_OID_STRING_W, ctrls[i]->ldctl_oid ))
control = ctrls[i];
}
+ if (!control) return WLDAP32_LDAP_CONTROL_NOT_FOUND;
- if (!control)
- 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;
- }
+ if (!(ber = WLDAP32_ber_init( &control->ldctl_value ))) 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, &cookieU );
- if (tag == LBER_ERROR)
+ vec[0] = *cookie;
+ vec[1] = 0;
+ tag = WLDAP32_ber_scanf( ber, (char *)"{iV}", count, vec );
+ if (tag == WLDAP32_LBER_ERROR)
ret = WLDAP32_LDAP_DECODING_ERROR;
else
ret = WLDAP32_LDAP_SUCCESS;
- heap_free( cookieU );
- ber_free( ber, 1 );
-
-#endif
+ WLDAP32_ber_free( ber, 1 );
return ret;
}
-ULONG CDECL ldap_search_abandon_page( WLDAP32_LDAP *ld, PLDAPSearch search )
+ULONG CDECL ldap_search_abandon_page( WLDAP32_LDAP *ld, LDAPSearch *search )
{
-#ifdef HAVE_LDAP
LDAPControlW **ctrls;
TRACE( "(%p, %p)\n", ld, search );
@@ -357,91 +281,70 @@ 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_cookieW)
- heap_free( search->cookie );
+ if (search->cookie && search->cookie != &null_cookieW) heap_free( search->cookie );
heap_free( search );
return WLDAP32_LDAP_SUCCESS;
-
-#else
- return WLDAP32_LDAP_NOT_SUPPORTED;
-#endif
}
-PLDAPSearch CDECL ldap_search_init_pageA( WLDAP32_LDAP *ld, PCHAR dn, ULONG scope,
- PCHAR filter, PCHAR attrs[], ULONG attrsonly, PLDAPControlA *serverctrls,
- PLDAPControlA *clientctrls, ULONG timelimit, ULONG sizelimit, PLDAPSortKeyA *sortkeys )
+LDAPSearch * CDECL ldap_search_init_pageA( WLDAP32_LDAP *ld, char *dn, ULONG scope, char *filter, char **attrs,
+ ULONG attrsonly, LDAPControlA **serverctrls, LDAPControlA **clientctrls, ULONG timelimit, ULONG sizelimit,
+ LDAPSortKeyA **sortkeys )
{
- FIXME( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_a(dn),
- scope, debugstr_a(filter), attrs, attrsonly );
+ FIXME( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n", ld, debugstr_a(dn), scope,
+ debugstr_a(filter), attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, sortkeys );
return NULL;
}
-PLDAPSearch CDECL ldap_search_init_pageW( WLDAP32_LDAP *ld, PWCHAR dn, ULONG scope,
- PWCHAR filter, PWCHAR attrs[], ULONG attrsonly, PLDAPControlW *serverctrls,
- PLDAPControlW *clientctrls, ULONG timelimit, ULONG sizelimit, PLDAPSortKeyW *sortkeys )
+LDAPSearch * CDECL ldap_search_init_pageW( WLDAP32_LDAP *ld, WCHAR *dn, ULONG scope, WCHAR *filter, WCHAR **attrs,
+ ULONG attrsonly, LDAPControlW **serverctrls, LDAPControlW **clientctrls, ULONG timelimit, ULONG sizelimit,
+ LDAPSortKeyW **sortkeys )
{
-#ifdef HAVE_LDAP
LDAPSearch *search;
DWORD i, len;
- TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n",
- ld, debugstr_w(dn), scope, debugstr_w(filter), attrs, attrsonly,
- serverctrls, clientctrls, timelimit, sizelimit, sortkeys );
+ TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n", ld, debugstr_w(dn), scope,
+ debugstr_w(filter), attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, sortkeys );
- search = heap_alloc_zero( sizeof(*search) );
- if (!search)
+ if (!(search = heap_alloc_zero( sizeof(*search) )))
{
ld->ld_errno = WLDAP32_LDAP_NO_MEMORY;
return NULL;
}
- if (dn)
- {
- search->dn = strdupW( dn );
- if (!search->dn) goto fail;
- }
- if (filter)
- {
- search->filter = strdupW( filter );
- if (!search->filter) goto fail;
- }
- if (attrs)
- {
- search->attrs = strarraydupW( attrs );
- if (!search->attrs) goto fail;
- }
+ if (dn && !(search->dn = strdupW( dn ))) goto fail;
+ if (filter && !(search->filter = strdupW( filter ))) goto fail;
+ if (attrs && !(search->attrs = strarraydupW( attrs ))) goto fail;
len = serverctrls ? controlarraylenW( serverctrls ) : 0;
- search->serverctrls = heap_alloc( sizeof(LDAPControl *) * (len + 2) );
- if (!search->serverctrls) goto fail;
+ if (!(search->serverctrls = heap_alloc( sizeof(LDAPControlW *) * (len + 2) ))) goto fail;
search->serverctrls[0] = NULL; /* reserve 0 for page control */
for (i = 0; i < len; i++)
{
- search->serverctrls[i + 1] = controldupW( serverctrls[i] );
- if (!search->serverctrls[i + 1]) goto fail;
+ if (!(search->serverctrls[i + 1] = controldupW( serverctrls[i] )))
+ {
+ for (; i > 0; i--) controlfreeW( search->serverctrls[i] );
+ goto fail;
+ }
}
search->serverctrls[len + 1] = NULL;
- if (clientctrls)
+ if (clientctrls && !(search->clientctrls = controlarraydupW( clientctrls )))
{
- search->clientctrls = controlarraydupW( clientctrls );
- if (!search->clientctrls) goto fail;
+ for (i = 0; i < len; i++) controlfreeW( search->serverctrls[i] );
+ goto fail;
}
- search->scope = scope;
- search->attrsonly = attrsonly;
- search->timeout.tv_sec = timelimit;
+ search->scope = scope;
+ search->attrsonly = attrsonly;
+ search->timeout.tv_sec = timelimit;
search->timeout.tv_usec = 0;
- search->sizelimit = sizelimit;
- search->cookie = NULL;
-
+ search->sizelimit = sizelimit;
+ search->cookie = NULL;
return search;
fail:
ldap_search_abandon_page( ld, search );
ld->ld_errno = WLDAP32_LDAP_NO_MEMORY;
-
-#endif
return NULL;
}
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 32ed3f5a266..e488db954c8 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -40,6 +40,8 @@
#define WLDAP32_LDAP_SCOPE_ONELEVEL 0x01
#define WLDAP32_LDAP_SCOPE_SUBTREE 0x02
+#define WLDAP32_LBER_USE_DER 0x01
+
typedef enum {
WLDAP32_LDAP_SUCCESS = 0x00,
WLDAP32_LDAP_UNWILLING_TO_PERFORM = 0x35,
@@ -312,6 +314,14 @@ typedef struct ldap_apifeature_infoW
int ldapaif_version;
} LDAPAPIFeatureInfoW;
+WLDAP32_BerElement * CDECL WLDAP32_ber_alloc_t(int);
+void CDECL WLDAP32_ber_bvfree(BERVAL *);
+int CDECL WLDAP32_ber_flatten(WLDAP32_BerElement *, BERVAL **);
+void CDECL WLDAP32_ber_free(WLDAP32_BerElement *, int);
+WLDAP32_BerElement * CDECL WLDAP32_ber_init(BERVAL *);
+int WINAPIV WLDAP32_ber_printf(WLDAP32_BerElement *, char *, ...);
+ULONG WINAPIV WLDAP32_ber_scanf(WLDAP32_BerElement *, char *, ...);
+
WLDAP32_LDAP * CDECL cldap_openA(PCHAR,ULONG);
WLDAP32_LDAP * CDECL cldap_openW(PWCHAR,ULONG);
ULONG CDECL WLDAP32_ldap_abandon(WLDAP32_LDAP*,ULONG);
@@ -614,6 +624,26 @@ static inline char **strarrayWtoU( WCHAR **strarray )
return strarrayU;
}
+static inline WCHAR **strarraydupW( WCHAR **strarray )
+{
+ WCHAR **strarrayW = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(WCHAR *) * (strarraylenW( strarray ) + 1);
+ if ((strarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ WCHAR **p = strarray;
+ WCHAR **q = strarrayW;
+
+ while (*p) *q++ = strdupW( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayW;
+}
+
static inline char *strWtoA( const WCHAR *str )
{
char *ret = NULL;
@@ -1161,6 +1191,52 @@ static inline DWORD controlarraylenU( LDAPControlU **controlarray )
return p - controlarray;
}
+static inline LDAPControlW *controldupW( LDAPControlW *control )
+{
+ LDAPControlW *controlW;
+ DWORD len = control->ldctl_value.bv_len;
+ char *val = NULL;
+
+ if (control->ldctl_value.bv_val)
+ {
+ if (!(val = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return NULL;
+ memcpy( val, control->ldctl_value.bv_val, len );
+ }
+
+ if (!(controlW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlW) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlW->ldctl_oid = strdupW( control->ldctl_oid );
+ controlW->ldctl_value.bv_len = len;
+ controlW->ldctl_value.bv_val = val;
+ controlW->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlW;
+}
+
+static inline LDAPControlW **controlarraydupW( LDAPControlW **controlarray )
+{
+ LDAPControlW **controlarrayW = NULL;
+ DWORD size;
+
+ if (controlarray)
+ {
+ size = sizeof(LDAPControlW *) * (controlarraylenW( controlarray ) + 1);
+ if ((controlarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPControlW **p = controlarray;
+ LDAPControlW **q = controlarrayW;
+
+ while (*p) *q++ = controldupW( *p++ );
+ *q = NULL;
+ }
+ }
+ return controlarrayW;
+}
+
static inline WCHAR *strUtoW( const char *str )
{
WCHAR *ret = NULL;
--
2.30.2
More information about the wine-devel
mailing list