Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2021
- 70 participants
- 697 discussions
[PATCH 4/5] wldap32: Move support for compare functions to the Unix library.
by Hans Leidekker 14 Apr '21
by Hans Leidekker 14 Apr '21
14 Apr '21
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/compare.c | 355 ++++++++++-------------------------------
dlls/wldap32/libldap.c | 17 ++
dlls/wldap32/libldap.h | 8 +
3 files changed, 108 insertions(+), 272 deletions(-)
diff --git a/dlls/wldap32/compare.c b/dlls/wldap32/compare.c
index c725aa3a715..7a366572dc9 100644
--- a/dlls/wldap32/compare.c
+++ b/dlls/wldap32/compare.c
@@ -18,56 +18,33 @@
* 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
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#endif
/***********************************************************************
* ldap_compareA (WLDAP32.@)
*
* See ldap_compareW.
*/
-ULONG CDECL ldap_compareA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
+ULONG CDECL ldap_compareA( WLDAP32_LDAP *ld, char *dn, char *attr, char *value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = ~0u;
WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
- ret = ~0u;
-
- TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr),
- debugstr_a(value) );
+ TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr), debugstr_a(value) );
if (!ld || !attr) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
-
- attrW = strAtoW( attr );
- if (!attrW) goto exit;
-
- if (value) {
- valueW = strAtoW( value );
- if (!valueW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (!(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
ret = ldap_compareW( ld, dnW, attrW, valueW );
@@ -75,8 +52,6 @@ exit:
strfreeW( dnW );
strfreeW( attrW );
strfreeW( valueW );
-
-#endif
return ret;
}
@@ -95,51 +70,15 @@ exit:
* Success: Message ID of the compare operation.
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_compareW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
+ULONG CDECL ldap_compareW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- struct berval val = { 0, NULL };
- int msg;
-
- ret = ~0u;
-
- TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr),
- debugstr_w(value) );
-
- if (!ld || !attr) return ~0u;
-
- 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;
-
- val.bv_len = strlen( valueU );
- val.bv_val = valueU;
- }
+ ULONG msg, ret;
- ret = ldap_compare_ext( ld->ld, dn ? dnU : "", attrU, &val, NULL, NULL, &msg );
+ TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value) );
- if (ret == LDAP_SUCCESS)
- ret = msg;
- else
- ret = ~0u;
-
-exit:
- strfreeU( dnU );
- strfreeU( attrU );
- strfreeU( valueU );
-
-#endif
- return ret;
+ ret = ldap_compare_extW( ld, dn, attr, value, NULL, NULL, NULL, &msg );
+ if (ret == WLDAP32_LDAP_SUCCESS) return msg;
+ return ~0u;
}
/***********************************************************************
@@ -147,46 +86,26 @@ exit:
*
* See ldap_compare_extW.
*/
-ULONG CDECL ldap_compare_extA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
- struct WLDAP32_berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls,
+ULONG CDECL ldap_compare_extA( WLDAP32_LDAP *ld, char *dn, char *attr, char *value,
+ struct WLDAP32_berval *data, LDAPControlA **serverctrls, LDAPControlA **clientctrls,
ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
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 );
+ 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;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attr && !(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
- ret = ldap_compare_extW( ld, dnW, attrW, valueW, data,
- serverctrlsW, clientctrlsW, message );
+ ret = ldap_compare_extW( ld, dnW, attrW, valueW, data, serverctrlsW, clientctrlsW, message );
exit:
strfreeW( dnW );
@@ -194,8 +113,6 @@ exit:
strfreeW( valueW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -223,62 +140,45 @@ exit:
* both are non-NULL, data will be used. The serverctrls and clientctrls
* parameters are optional and should be set to NULL if not used.
*/
-ULONG CDECL ldap_compare_extW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
- struct WLDAP32_berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls,
- ULONG *message )
+ULONG CDECL ldap_compare_extW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value,
+ struct WLDAP32_berval *data, LDAPControlW **serverctrls, LDAPControlW **clientctrls, ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval val = { 0, NULL };
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU *dataU = NULL, val = { 0, NULL };
- 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 );
+ 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;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (!(attrU = strWtoU( attr ))) goto exit;
+ if (!data)
+ {
+ if (value)
+ {
+ if (!(valueU = strWtoU( value ))) goto exit;
val.bv_len = strlen( valueU );
val.bv_val = valueU;
}
}
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ else if (!(dataU = bervalWtoU( data ))) goto exit;
- ret = map_error( ldap_compare_ext( ld->ld, dn ? dnU : "", attrU, data ? (struct berval *)data : &val,
- serverctrlsU, clientctrlsU, (int *)message ));
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+ ret = map_error( ldap_funcs->ldap_compare_ext( ld->ld, dnU, attrU, dataU ? dataU : &val, serverctrlsU,
+ clientctrlsU, message ) );
exit:
strfreeU( dnU );
strfreeU( attrU );
strfreeU( valueU );
+ bvfreeU( dataU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -287,45 +187,25 @@ exit:
*
* See ldap_compare_ext_sW.
*/
-ULONG CDECL ldap_compare_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
- struct WLDAP32_berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
+ULONG CDECL ldap_compare_ext_sA( WLDAP32_LDAP *ld, char *dn, char *attr, char *value,
+ struct WLDAP32_berval *data, LDAPControlA **serverctrls, LDAPControlA **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
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 );
+ 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;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attr && !(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
- ret = ldap_compare_ext_sW( ld, dnW, attrW, valueW, data, serverctrlsW,
- clientctrlsW );
+ ret = ldap_compare_ext_sW( ld, dnW, attrW, valueW, data, serverctrlsW, clientctrlsW );
exit:
strfreeW( dnW );
@@ -333,8 +213,6 @@ exit:
strfreeW( valueW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -361,61 +239,44 @@ exit:
* both are non-NULL, data will be used. The serverctrls and clientctrls
* parameters are optional and should be set to NULL if not used.
*/
-ULONG CDECL ldap_compare_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
- struct WLDAP32_berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
+ULONG CDECL ldap_compare_ext_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value,
+ struct WLDAP32_berval *data, LDAPControlW **serverctrls, LDAPControlW **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval val = { 0, NULL };
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU *dataU = NULL, val = { 0, 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 );
+ 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;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (attr && !(attrU = strWtoU( attr ))) goto exit;
+ if (!data)
+ {
+ if (value)
+ {
+ if (!(valueU = strWtoU( value ))) goto exit;
val.bv_len = strlen( valueU );
val.bv_val = valueU;
}
}
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ else if (!(dataU = bervalWtoU( data ))) goto exit;
- ret = map_error( ldap_compare_ext_s( ld->ld, dn ? dnU : "", attr ? attrU : "",
- data ? (struct berval *)data : &val,
- serverctrlsU, clientctrlsU ));
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+ ret = map_error( ldap_funcs->ldap_compare_ext_s( ld->ld, dnU, attrU, dataU ? dataU : &val, serverctrlsU,
+ clientctrlsU ) );
exit:
strfreeU( dnU );
strfreeU( attrU );
strfreeU( valueU );
+ bvfreeU( dataU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -426,29 +287,16 @@ exit:
*/
ULONG CDECL ldap_compare_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
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) );
+ 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;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attr && !(attrW = strAtoW( attr ))) goto exit;
+ if (value && !(valueW = strAtoW( value ))) goto exit;
ret = ldap_compare_sW( ld, dnW, attrW, valueW );
@@ -456,8 +304,6 @@ exit:
strfreeW( dnW );
strfreeW( attrW );
strfreeW( valueW );
-
-#endif
return ret;
}
@@ -476,43 +322,8 @@ exit:
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_compare_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
+ULONG CDECL ldap_compare_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *attr, WCHAR *value )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL, *attrU = NULL, *valueU = NULL;
- struct berval val = { 0, 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;
-
- val.bv_len = strlen( valueU );
- val.bv_val = valueU;
- }
-
- ret = map_error( ldap_compare_ext_s( ld->ld, dn ? dnU : "", attr ? attrU : "", &val, NULL, NULL ));
-
-exit:
- strfreeU( dnU );
- strfreeU( attrU );
- strfreeU( valueU );
-
-#endif
- return ret;
+ TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value) );
+ return ldap_compare_ext_sW( ld, dn, attr, value, NULL, NULL, NULL );
}
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
index 380c589257b..0ddd4035514 100644
--- a/dlls/wldap32/libldap.c
+++ b/dlls/wldap32/libldap.c
@@ -309,6 +309,21 @@ int CDECL wrap_ldap_add_ext_s( void *ld, const char *dn, LDAPModU **attrs, LDAPC
(LDAPControl **)clientctrls );
}
+int CDECL wrap_ldap_compare_ext( void *ld, const char *dn, const char *attrs, struct bervalU *value,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls, ULONG *msg )
+{
+ int dummy;
+ return ldap_compare_ext( ld, dn ? dn : "", attrs ? attrs : "", (struct berval *)value,
+ (LDAPControl **)serverctrls, (LDAPControl **)clientctrls, msg ? (int *)msg : &dummy );
+}
+
+int CDECL wrap_ldap_compare_ext_s( void *ld, const char *dn, const char *attrs, struct bervalU *value,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+ return ldap_compare_ext_s( ld, dn ? dn : "", attrs ? attrs : "", (struct berval *)value,
+ (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
void CDECL wrap_ldap_memfree( void *ptr )
{
return ldap_memfree( ptr );
@@ -375,6 +390,8 @@ static const struct ldap_funcs funcs =
wrap_ber_scanf,
wrap_ldap_add_ext,
wrap_ldap_add_ext_s,
+ wrap_ldap_compare_ext,
+ wrap_ldap_compare_ext_s,
wrap_ldap_memfree,
wrap_ldap_sasl_bind,
wrap_ldap_sasl_bind_s,
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
index 9b4f941d677..0fa1c7e5671 100644
--- a/dlls/wldap32/libldap.h
+++ b/dlls/wldap32/libldap.h
@@ -94,6 +94,10 @@ extern int CDECL wrap_ldap_add_ext(void *, const char *, LDAPModU **, LDAPContro
ULONG *) DECLSPEC_HIDDEN;
extern int CDECL wrap_ldap_add_ext_s(void *, const char *, LDAPModU **, LDAPControlU **,
LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_compare_ext(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, ULONG *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_compare_ext_s(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **) DECLSPEC_HIDDEN;
extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN;
extern int CDECL wrap_ldap_sasl_bind(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
LDAPControlU **, int *) DECLSPEC_HIDDEN;
@@ -122,6 +126,10 @@ struct ldap_funcs
int (CDECL *ldap_add_ext)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
int (CDECL *ldap_add_ext_s)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
+ int (CDECL *ldap_compare_ext)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, ULONG *);
+ int (CDECL *ldap_compare_ext_s)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **);
void (CDECL *ldap_memfree)(void *);
int (CDECL *ldap_sasl_bind)(void *, const char *, const char *, struct bervalU *, LDAPControlU **, LDAPControlU **,
int *);
--
2.30.2
1
0
[PATCH 3/5] wldap32: Move support for bind functions to the Unix library.
by Hans Leidekker 14 Apr '21
by Hans Leidekker 14 Apr '21
14 Apr '21
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/bind.c | 419 ++++++++++-----------------------
dlls/wldap32/libldap.c | 58 ++++-
dlls/wldap32/libldap.h | 52 +++-
dlls/wldap32/main.c | 6 +-
dlls/wldap32/option.c | 6 +-
dlls/wldap32/winldap_private.h | 2 +-
6 files changed, 234 insertions(+), 309 deletions(-)
diff --git a/dlls/wldap32/bind.c b/dlls/wldap32/bind.c
index 1498dc49fe6..0078b532e66 100644
--- a/dlls/wldap32/bind.c
+++ b/dlls/wldap32/bind.c
@@ -18,63 +18,40 @@
* 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
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "rpc.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "wine/heap.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#endif
/***********************************************************************
* ldap_bindA (WLDAP32.@)
*
* See ldap_bindW.
*/
-ULONG CDECL ldap_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
+ULONG CDECL ldap_bindA( WLDAP32_LDAP *ld, char *dn, char *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *credW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
if (!ld) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (cred) {
- credW = strAtoW( cred );
- if (!credW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (cred && !(credW = strAtoW( cred ))) goto exit;
ret = ldap_bindW( ld, dnW, credW, method );
exit:
strfreeW( dnW );
strfreeW( credW );
-
-#endif
return ret;
}
@@ -96,36 +73,28 @@ exit:
* NOTES
* Only LDAP_AUTH_SIMPLE is supported (just like native).
*/
-ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
+ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *credU = NULL;
- struct berval pwd = { 0, NULL };
+ struct bervalU pwd = { 0, NULL };
int msg;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
if (!ld) return ~0u;
- if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (cred) {
- credU = strWtoU( cred );
- if (!credU) goto exit;
+ if (method != WLDAP32_LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (cred)
+ {
+ if (!(credU = strWtoU( cred ))) goto exit;
pwd.bv_len = strlen( credU );
pwd.bv_val = credU;
}
- ret = ldap_sasl_bind( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
-
- if (ret == LDAP_SUCCESS)
+ ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, 0, &pwd, NULL, NULL, &msg ) );
+ if (ret == WLDAP32_LDAP_SUCCESS)
ret = msg;
else
ret = ~0u;
@@ -133,8 +102,6 @@ ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
exit:
strfreeU( dnU );
strfreeU( credU );
-
-#endif
return ret;
}
@@ -143,30 +110,23 @@ exit:
*
* See ldap_bind_sW.
*/
-ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
+ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, char *dn, char *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *credW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (cred) {
- if (method == LDAP_AUTH_SIMPLE)
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (cred)
+ {
+ if (method == WLDAP32_LDAP_AUTH_SIMPLE)
{
- credW = strAtoW( cred );
- if (!credW) goto exit;
+ if (!(credW = strAtoW( cred ))) goto exit;
}
- else
- credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
+ else credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
}
ret = ldap_bind_sW( ld, dnW, credW, method );
@@ -174,24 +134,19 @@ ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
exit:
strfreeW( dnW );
if (credW != (WCHAR *)cred) strfreeW( credW );
-
-#endif
return ret;
}
-#ifdef HAVE_LDAP
-
-static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *interact )
+int CDECL sasl_interact_cb( void *ld, unsigned flags, void *defaults, void *interact )
{
-#ifdef HAVE_SASL_SASL_H
SEC_WINNT_AUTH_IDENTITY_A *id = defaults;
- sasl_interact_t *sasl = interact;
+ struct sasl_interactU *sasl = interact;
- TRACE( "%p,%08x,%p,%p\n", ld, flags, defaults, interact );
+ TRACE( "(%p, 0x%08x, %p, %p)\n", ld, flags, defaults, interact );
while (sasl->id != SASL_CB_LIST_END)
{
- TRACE("sasl->id = %04lx\n", sasl->id);
+ TRACE( "sasl->id = %04lx\n", sasl->id );
if (sasl->id == SASL_CB_GETREALM)
{
@@ -208,19 +163,12 @@ static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *intera
sasl->result = id->Password;
sasl->len = id->PasswordLength;
}
-
sasl++;
}
- return LDAP_SUCCESS;
-#else
- FIXME( "%p,%08x,%p,%p: stub\n", ld, flags, defaults, interact );
- return LDAP_SUCCESS;
-#endif /* HAVE_SASL_SASL_H */
+ return WLDAP32_LDAP_SUCCESS;
}
-#endif /* HAVE_LDAP */
-
/***********************************************************************
* ldap_bind_sW (WLDAP32.@)
*
@@ -236,36 +184,27 @@ static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *intera
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
+ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *credU = NULL;
- struct berval pwd = { 0, NULL };
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ struct bervalU pwd = { 0, NULL };
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (method == LDAP_AUTH_SIMPLE)
+ if (method == WLDAP32_LDAP_AUTH_SIMPLE)
{
- if (dn)
- {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
if (cred)
{
- credU = strWtoU( cred );
- if (!credU) goto exit;
-
+ if (!(credU = strWtoU( cred ))) goto exit;
pwd.bv_len = strlen( credU );
pwd.bv_val = credU;
}
- ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, 0, &pwd, NULL, NULL, NULL ) );
}
else if (method == WLDAP32_LDAP_AUTH_NEGOTIATE)
{
@@ -274,7 +213,6 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)cred;
memset( &idU, 0, sizeof(idU) );
-
if (id)
{
if (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
@@ -283,19 +221,17 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
idW.Domain = (unsigned short *)strnAtoW( (char *)id->Domain, id->DomainLength, &idW.DomainLength );
idW.User = (unsigned short *)strnAtoW( (char *)id->User, id->UserLength, &idW.UserLength );
idW.Password = (unsigned short *)strnAtoW( (char *)id->Password, id->PasswordLength, &idW.PasswordLength );
-
id = &idW;
}
-
idU.Domain = (unsigned char *)strnWtoU( id->Domain, id->DomainLength, &idU.DomainLength );
idU.User = (unsigned char *)strnWtoU( id->User, id->UserLength, &idU.UserLength );
idU.Password = (unsigned char *)strnWtoU( id->Password, id->PasswordLength, &idU.PasswordLength );
}
- ret = map_error( ldap_sasl_interactive_bind_s( ld->ld,
- NULL /* server will ignore DN anyway */,
- NULL /* query supportedSASLMechanisms */,
- NULL, NULL, LDAP_SASL_QUIET, sasl_interact, &idU ));
+ ret = map_error( ldap_funcs->ldap_sasl_interactive_bind_s( ld->ld,
+ NULL /* server will ignore DN anyway */,
+ NULL /* query supportedSASLMechanisms */,
+ NULL, NULL, 2 /* LDAP_SASL_QUIET */, &idU ) );
if (id && (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI))
{
@@ -317,8 +253,6 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
exit:
strfreeU( dnU );
strfreeU( credU );
-
-#endif
return ret;
}
@@ -327,37 +261,23 @@ exit:
*
* See ldap_sasl_bindW.
*/
-ULONG CDECL ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn,
- const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
- PLDAPControlA *clientctrls, int *message )
+ULONG CDECL ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
+ LDAPControlA **serverctrls, LDAPControlA **clientctrls, int *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW, *mechanismW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
debugstr_a(mechanism), cred, serverctrls, clientctrls, message );
if (!ld || !dn || !mechanism || !cred || !message)
return WLDAP32_LDAP_PARAM_ERROR;
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
-
- mechanismW = strAtoW( mechanism );
- if (!mechanismW) goto exit;
-
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (!(dnW = strAtoW( dn ))) goto exit;
+ if (!(mechanismW = strAtoW( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_sasl_bindW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, message );
@@ -366,8 +286,6 @@ exit:
strfreeW( mechanismW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -383,7 +301,7 @@ exit:
* cred [I] Credentials.
* serverctrls [I] Array of LDAP server controls.
* clientctrls [I] Array of LDAP client controls.
- * message [O] Message ID of the bind operation.
+ * message [O] Message ID of the bind operation.
*
* RETURNS
* Success: LDAP_SUCCESS
@@ -393,17 +311,13 @@ exit:
* The serverctrls and clientctrls parameters are optional and should
* be set to NULL if not used.
*/
-ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
- const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
- PLDAPControlW *clientctrls, int *message )
+ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn, const PWCHAR mechanism, const BERVAL *cred,
+ LDAPControlW **serverctrls, LDAPControlW **clientctrls, int *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU, *mechanismU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval credU;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU credU;
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
debugstr_w(mechanism), cred, serverctrls, clientctrls, message );
@@ -411,34 +325,21 @@ ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
if (!ld || !dn || !mechanism || !cred || !message)
return WLDAP32_LDAP_PARAM_ERROR;
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
-
- mechanismU = strWtoU( mechanism );
- if (!mechanismU) goto exit;
-
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ if (!(dnU = strWtoU( dn ))) goto exit;
+ if (!(mechanismU = strWtoU( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
credU.bv_len = cred->bv_len;
credU.bv_val = cred->bv_val;
- ret = map_error( ldap_sasl_bind( ld->ld, dnU, mechanismU, &credU,
- serverctrlsU, clientctrlsU, message ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, mechanismU, &credU, serverctrlsU, clientctrlsU, message ) );
exit:
strfreeU( dnU );
strfreeU( mechanismU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -447,37 +348,23 @@ exit:
*
* See ldap_sasl_bind_sW.
*/
-ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn,
- const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
- PLDAPControlA *clientctrls, PBERVAL *serverdata )
+ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
+ LDAPControlA **serverctrls, LDAPControlA **clientctrls, BERVAL **serverdata )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW, *mechanismW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
debugstr_a(mechanism), cred, serverctrls, clientctrls, serverdata );
if (!ld || !dn || !mechanism || !cred || !serverdata)
return WLDAP32_LDAP_PARAM_ERROR;
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
-
- mechanismW = strAtoW( mechanism );
- if (!mechanismW) goto exit;
-
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (!(dnW = strAtoW( dn ))) goto exit;
+ if (!(mechanismW = strAtoW( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_sasl_bind_sW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, serverdata );
@@ -486,8 +373,6 @@ exit:
strfreeW( mechanismW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -514,16 +399,13 @@ exit:
* be set to NULL if not used.
*/
ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
- const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
- PLDAPControlW *clientctrls, PBERVAL *serverdata )
+ const PWCHAR mechanism, const BERVAL *cred, LDAPControlW **serverctrls,
+ LDAPControlW **clientctrls, BERVAL **serverdata )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU, *mechanismU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- struct berval credU;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+ struct bervalU *dataU, credU;
TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
debugstr_w(mechanism), cred, serverctrls, clientctrls, serverdata );
@@ -531,34 +413,28 @@ ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
if (!ld || !dn || !mechanism || !cred || !serverdata)
return WLDAP32_LDAP_PARAM_ERROR;
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
-
- mechanismU = strWtoU( mechanism );
- if (!mechanismU) goto exit;
-
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
+ if (!(dnU = strWtoU( dn ))) goto exit;
+ if (!(mechanismU = strWtoU( mechanism ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
credU.bv_len = cred->bv_len;
credU.bv_val = cred->bv_val;
- ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, mechanismU, &credU,
- serverctrlsU, clientctrlsU, (struct berval **)serverdata ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, mechanismU, &credU, serverctrlsU, clientctrlsU, &dataU ) );
+ if (ret == WLDAP32_LDAP_SUCCESS)
+ {
+ BERVAL *ptr;
+ if (!(ptr = bervalUtoW( dataU ))) ret = WLDAP32_LDAP_NO_MEMORY;
+ else *serverdata = ptr;
+ ldap_funcs->ber_bvfree( dataU );
+ }
exit:
strfreeU( dnU );
strfreeU( mechanismU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -567,34 +443,23 @@ exit:
*
* See ldap_simple_bindW.
*/
-ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
+ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, char *dn, char *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *passwdW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
if (!ld) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (passwd) {
- passwdW = strAtoW( passwd );
- if (!passwdW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
ret = ldap_simple_bindW( ld, dnW, passwdW );
exit:
strfreeW( dnW );
strfreeW( passwdW );
-
-#endif
return ret;
}
@@ -613,37 +478,29 @@ exit:
* Failure: An LDAP error code.
*
* NOTES
- * Set dn and passwd to NULL to bind as an anonymous user.
+ * Set dn and passwd to NULL to bind as an anonymous user.
*/
-ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
+ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *passwdU = NULL;
- struct berval pwd = { 0, NULL };
+ struct bervalU pwd = { 0, NULL };
int msg;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
if (!ld) return ~0u;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (passwd) {
- passwdU = strWtoU( passwd );
- if (!passwdU) goto exit;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (passwd)
+ {
+ if (!(passwdU = strWtoU( passwd ))) goto exit;
pwd.bv_len = strlen( passwdU );
pwd.bv_val = passwdU;
}
- ret = ldap_sasl_bind( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
-
- if (ret == LDAP_SUCCESS)
+ ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, 0, &pwd, NULL, NULL, &msg ) );
+ if (ret == WLDAP32_LDAP_SUCCESS)
ret = msg;
else
ret = ~0u;
@@ -651,8 +508,6 @@ ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
exit:
strfreeU( dnU );
strfreeU( passwdU );
-
-#endif
return ret;
}
@@ -661,34 +516,23 @@ exit:
*
* See ldap_simple_bind_sW.
*/
-ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
+ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, char *dn, char *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL, *passwdW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (passwd) {
- passwdW = strAtoW( passwd );
- if (!passwdW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
ret = ldap_simple_bind_sW( ld, dnW, passwdW );
exit:
strfreeW( dnW );
strfreeW( passwdW );
-
-#endif
return ret;
}
@@ -707,40 +551,31 @@ exit:
* Failure: An LDAP error code.
*
* NOTES
- * Set dn and passwd to NULL to bind as an anonymous user.
+ * Set dn and passwd to NULL to bind as an anonymous user.
*/
-ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
+ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *passwd )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL, *passwdU = NULL;
- struct berval pwd = { 0, NULL };
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ struct bervalU pwd = { 0, NULL };
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (passwd) {
- passwdU = strWtoU( passwd );
- if (!passwdU) goto exit;
-
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (passwd)
+ {
+ if (!(passwdU = strWtoU( passwd ))) goto exit;
pwd.bv_len = strlen( passwdU );
pwd.bv_val = passwdU;
}
- ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
+ ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, 0, &pwd, NULL, NULL, NULL ) );
exit:
strfreeU( dnU );
strfreeU( passwdU );
-
-#endif
return ret;
}
@@ -758,22 +593,16 @@ exit:
*/
ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
TRACE( "(%p)\n", ld );
- if (ld)
- {
- ret = map_error( ldap_unbind_ext( ld->ld, NULL, NULL ));
- if ( ld->ld_server_ctrls )
- ldap_value_free_len( ld->ld_server_ctrls );
- heap_free( ld );
- }
- else
- ret = WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+ ret = map_error( ldap_funcs->ldap_unbind_ext( ld->ld, NULL, NULL ));
+ if (ld->ld_server_ctrls) ldap_funcs->ldap_value_free_len( ld->ld_server_ctrls );
-#endif
+ heap_free( ld );
return ret;
}
@@ -791,21 +620,15 @@ ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
*/
ULONG CDECL WLDAP32_ldap_unbind_s( WLDAP32_LDAP *ld )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
TRACE( "(%p)\n", ld );
- if (ld)
- {
- ret = map_error( ldap_unbind_ext_s( ld->ld, NULL, NULL ));
- if ( ld->ld_server_ctrls )
- ldap_value_free_len( ld->ld_server_ctrls );
- heap_free( ld );
- }
- else
- ret = WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+ ret = map_error( ldap_funcs->ldap_unbind_ext_s( ld->ld, NULL, NULL ) );
+ if (ld->ld_server_ctrls) ldap_funcs->ldap_value_free_len( ld->ld_server_ctrls );
-#endif
+ heap_free( ld );
return ret;
}
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
index 3436cffc4a1..380c589257b 100644
--- a/dlls/wldap32/libldap.c
+++ b/dlls/wldap32/libldap.c
@@ -52,6 +52,8 @@ C_ASSERT( sizeof(LDAPVLVInfoU) == sizeof(LDAPVLVInfo) );
static LDAPMod *nullattrs[] = { NULL };
+static const struct ldap_callbacks *callbacks;
+
void * CDECL wrap_ber_alloc_t( int options )
{
return ber_alloc_t( options );
@@ -292,7 +294,7 @@ int WINAPIV wrap_ber_scanf( void *ber, char *fmt, ... )
return ret;
}
-int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+int CDECL wrap_ldap_add_ext( void *ld, const char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
LDAPControlU **clientctrls, ULONG *msg )
{
int dummy;
@@ -300,7 +302,7 @@ int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU
(LDAPControl **)clientctrls, msg ? (int *)msg : &dummy );
}
-int CDECL wrap_ldap_add_ext_s( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+int CDECL wrap_ldap_add_ext_s( void *ld, const char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
LDAPControlU **clientctrls )
{
return ldap_add_ext_s( ld, dn ? dn : "", attrs ? (LDAPMod **)attrs : nullattrs, (LDAPControl **)serverctrls,
@@ -312,6 +314,51 @@ void CDECL wrap_ldap_memfree( void *ptr )
return ldap_memfree( ptr );
}
+int CDECL wrap_ldap_sasl_bind( void *ld, const char *dn, const char *mech, struct bervalU *cred,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls, int *msgid )
+{
+ return ldap_sasl_bind( ld, dn, mech, (struct berval *)cred, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls, msgid );
+}
+
+int CDECL wrap_ldap_sasl_bind_s( void *ld, const char *dn, const char *mech, struct bervalU *cred,
+ LDAPControlU **serverctrls, LDAPControlU **clientctrls, struct bervalU **servercred )
+{
+ return ldap_sasl_bind_s( ld, dn, mech, (struct berval *)cred, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls, (struct berval **)servercred );
+}
+
+static int wrap_sasl_interact( LDAP *ld, unsigned int flags, void *defaults, void *interact )
+{
+#ifdef HAVE_SASL_SASL_H
+ C_ASSERT( sizeof(struct sasl_interactU) == sizeof(struct sasl_interact) );
+ return callbacks->sasl_interact( ld, flags, defaults, interact );
+#endif
+ return -1;
+}
+
+int CDECL wrap_ldap_sasl_interactive_bind_s( void *ld, const char *dn, const char *mech, LDAPControlU **serverctrls,
+ LDAPControlU **clientctrls, unsigned int flags, void *defaults )
+{
+ return ldap_sasl_interactive_bind_s( ld, dn, mech, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls, flags,
+ wrap_sasl_interact, defaults );
+}
+
+int CDECL wrap_ldap_unbind_ext( void *ld, LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+ return ldap_unbind_ext( ld, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
+int CDECL wrap_ldap_unbind_ext_s( void *ld, LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+ return ldap_unbind_ext_s( ld, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
+void CDECL wrap_ldap_value_free_len( struct bervalU **values )
+{
+ ldap_value_free_len( (struct berval **)values );
+}
+
static const struct ldap_funcs funcs =
{
wrap_ber_alloc_t,
@@ -329,11 +376,18 @@ static const struct ldap_funcs funcs =
wrap_ldap_add_ext,
wrap_ldap_add_ext_s,
wrap_ldap_memfree,
+ wrap_ldap_sasl_bind,
+ wrap_ldap_sasl_bind_s,
+ wrap_ldap_sasl_interactive_bind_s,
+ wrap_ldap_unbind_ext,
+ wrap_ldap_unbind_ext_s,
+ wrap_ldap_value_free_len,
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
{
if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+ callbacks = ptr_in;
*(const struct ldap_funcs **)ptr_out = &funcs;
return STATUS_SUCCESS;
}
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
index 4ca90d298a0..9b4f941d677 100644
--- a/dlls/wldap32/libldap.h
+++ b/dlls/wldap32/libldap.h
@@ -60,6 +60,23 @@ typedef struct
void *ldvlv_extradata;
} LDAPVLVInfoU;
+#ifndef SASL_CB_LIST_END
+#define SASL_CB_LIST_END 0
+#define SASL_CB_USER 0x4001
+#define SASL_CB_PASS 0x4004
+#define SASL_CB_GETREALM 0x4008
+#endif
+
+typedef struct sasl_interactU
+{
+ unsigned long id;
+ const char *challenge;
+ const char *prompt;
+ const char *defresult;
+ const void *result;
+ unsigned int len;
+} sasl_interact_tU;
+
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;
@@ -73,9 +90,20 @@ extern unsigned int CDECL wrap_ber_skip_tag(void *, unsigned int *) DECLSPEC_HID
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 int CDECL wrap_ldap_add_ext(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **,
+ ULONG *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_add_ext_s(void *, const char *, LDAPModU **, LDAPControlU **,
+ LDAPControlU **) DECLSPEC_HIDDEN;
extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_bind(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, int *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_bind_s(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, struct bervalU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_interactive_bind_s(void *, const char *, const char *, LDAPControlU **,
+ LDAPControlU **, unsigned int, void *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_unbind_ext(void *, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_unbind_ext_s(void *, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ldap_value_free_len(struct bervalU **) DECLSPEC_HIDDEN;
struct ldap_funcs
{
@@ -92,9 +120,25 @@ struct ldap_funcs
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 **);
+ int (CDECL *ldap_add_ext)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
+ int (CDECL *ldap_add_ext_s)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
void (CDECL *ldap_memfree)(void *);
+ int (CDECL *ldap_sasl_bind)(void *, const char *, const char *, struct bervalU *, LDAPControlU **, LDAPControlU **,
+ int *);
+ int (CDECL *ldap_sasl_bind_s)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+ LDAPControlU **, struct bervalU **);
+ int (CDECL *ldap_sasl_interactive_bind_s)(void *, const char *, const char *, LDAPControlU **, LDAPControlU **,
+ unsigned int, void *);
+ int (CDECL *ldap_unbind_ext)(void *, LDAPControlU **, LDAPControlU **);
+ int (CDECL *ldap_unbind_ext_s)(void *, LDAPControlU **, LDAPControlU **);
+ void (CDECL *ldap_value_free_len)(struct bervalU **);
+};
+
+extern int CDECL sasl_interact_cb(void *, unsigned int, void *, void *) DECLSPEC_HIDDEN;
+
+struct ldap_callbacks
+{
+ int (CDECL *sasl_interact)(void *, unsigned int, void *, void *);
};
extern const struct ldap_funcs *ldap_funcs;
diff --git a/dlls/wldap32/main.c b/dlls/wldap32/main.c
index 55a08c9bad5..c2fdf30f820 100644
--- a/dlls/wldap32/main.c
+++ b/dlls/wldap32/main.c
@@ -31,6 +31,10 @@ HINSTANCE hwldap32;
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
const struct ldap_funcs *ldap_funcs = NULL;
+const struct ldap_callbacks ldap_callbacks =
+{
+ sasl_interact_cb
+};
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
@@ -41,7 +45,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_ATTACH:
hwldap32 = hinst;
DisableThreadLibraryCalls( hinst );
- if (__wine_init_unix_lib( hinst, reason, NULL, &ldap_funcs ))
+ if (__wine_init_unix_lib( hinst, reason, &ldap_callbacks, &ldap_funcs ))
ERR( "No libldap support, expect problems\n" );
break;
}
diff --git a/dlls/wldap32/option.c b/dlls/wldap32/option.c
index 388432a442c..8398dff67e4 100644
--- a/dlls/wldap32/option.c
+++ b/dlls/wldap32/option.c
@@ -416,8 +416,8 @@ static BOOL query_supported_server_ctrls( WLDAP32_LDAP *ld )
{
ULONG count, i;
- ld->ld_server_ctrls = ldap_get_values_len( ld->ld, entry, attrs[0] );
- count = ldap_count_values_len( ld->ld_server_ctrls );
+ ld->ld_server_ctrls = (struct bervalU **)ldap_get_values_len( ld->ld, entry, attrs[0] );
+ count = ldap_count_values_len( (struct berval **)ld->ld_server_ctrls );
for (i = 0; i < count; i++)
TRACE("%u: %s\n", i, debugstr_an( ld->ld_server_ctrls[i]->bv_val, ld->ld_server_ctrls[i]->bv_len ));
}
@@ -435,7 +435,7 @@ static BOOL is_supported_server_ctrls( WLDAP32_LDAP *ld, LDAPControl **ctrls )
return TRUE; /* can't verify, let the server handle it on next query */
user_count = controlarraylenU( ctrls );
- server_count = ldap_count_values_len( ld->ld_server_ctrls );
+ server_count = ldap_count_values_len( (struct berval **)ld->ld_server_ctrls );
for (n = 0; n < user_count; n++)
{
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 22e981cb26d..20fc676c7e2 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -144,7 +144,7 @@ typedef struct wldap32
ULONG ld_refhoplimit;
ULONG ld_options;
/* internal LDAP context */
- struct berval **ld_server_ctrls;
+ struct bervalU **ld_server_ctrls;
void *ld;
} WLDAP32_LDAP, *WLDAP32_PLDAP;
--
2.30.2
1
0
[PATCH 2/5] wldap32: Move support for ber functions to the Unix library.
by Hans Leidekker 14 Apr '21
by Hans Leidekker 14 Apr '21
14 Apr '21
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/ber.c | 348 ++++++++++++++-------------------
dlls/wldap32/libldap.c | 260 ++++++++++++++++++++++++
dlls/wldap32/libldap.h | 28 +++
dlls/wldap32/misc.c | 28 ++-
dlls/wldap32/winldap_private.h | 22 +++
include/winber.h | 6 +
6 files changed, 477 insertions(+), 215 deletions(-)
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 <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#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 */
--
2.30.2
1
0
[PATCH 1/5] wldap32: Move support for add functions to a new Unix library.
by Hans Leidekker 14 Apr '21
by Hans Leidekker 14 Apr '21
14 Apr '21
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/Makefile.in | 1 +
dlls/wldap32/add.c | 274 ++--------
dlls/wldap32/init.c | 10 +-
dlls/wldap32/libldap.c | 81 +++
dlls/wldap32/libldap.h | 72 +++
dlls/wldap32/main.c | 12 +-
dlls/wldap32/winldap_private.h | 910 ++++++++++++++++++++++++++++++++-
dlls/wldap32/wldap32.h | 30 +-
8 files changed, 1137 insertions(+), 253 deletions(-)
create mode 100644 dlls/wldap32/libldap.c
create mode 100644 dlls/wldap32/libldap.h
diff --git a/dlls/wldap32/Makefile.in b/dlls/wldap32/Makefile.in
index 7dc2984c5aa..18a37151f99 100644
--- a/dlls/wldap32/Makefile.in
+++ b/dlls/wldap32/Makefile.in
@@ -15,6 +15,7 @@ C_SRCS = \
error.c \
extended.c \
init.c \
+ libldap.c \
main.c \
misc.c \
modify.c \
diff --git a/dlls/wldap32/add.c b/dlls/wldap32/add.c
index 0d0c8bfa117..cce7726a241 100644
--- a/dlls/wldap32/add.c
+++ b/dlls/wldap32/add.c
@@ -18,62 +18,39 @@
* 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
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "winldap_private.h"
-#ifdef HAVE_LDAP
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-static LDAPMod *nullattrs[] = { NULL };
-#endif
-
/***********************************************************************
* ldap_addA (WLDAP32.@)
*
* See ldap_addW.
*/
-ULONG CDECL ldap_addA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[] )
+ULONG CDECL ldap_addA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), attrs );
if (!ld) return ~0u;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
ret = ldap_addW( ld, dnW, attrsW );
exit:
strfreeW( dnW );
modarrayfreeW( attrsW );
-
-#endif
return ret;
}
@@ -97,42 +74,15 @@ exit:
* the operation. Cancel the operation by calling ldap_abandon
* with the message ID.
*/
-ULONG CDECL ldap_addW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[] )
+ULONG CDECL ldap_addW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL;
- LDAPMod **attrsU = NULL;
- int msg;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
+ ULONG ret, msg;
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), attrs );
- if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
-
- ret = ldap_add_ext( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs, NULL, NULL, &msg );
-
- if (ret == LDAP_SUCCESS)
- ret = msg;
- else
- ret = ~0u;
-
-exit:
- strfreeU( dnU );
- modarrayfreeU( attrsU );
-
-#endif
- return ret;
+ ret = ldap_add_extW( ld, dn, attrs, NULL, NULL, &msg );
+ if (ret == WLDAP32_LDAP_SUCCESS) return msg;
+ return ~0u;
}
/***********************************************************************
@@ -140,38 +90,22 @@ exit:
*
* See ldap_add_extW.
*/
-ULONG CDECL ldap_add_extA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[],
- PLDAPControlA *serverctrls, PLDAPControlA *clientctrls, ULONG *message )
+ULONG CDECL ldap_add_extA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs, LDAPControlA **serverctrls,
+ LDAPControlA **clientctrls, ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn), attrs,
- serverctrls, clientctrls, message );
+ TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn), attrs, serverctrls, clientctrls, message );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_add_extW( ld, dnW, attrsW, serverctrlsW, clientctrlsW, message );
@@ -180,8 +114,6 @@ exit:
modarrayfreeW( attrsW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -208,50 +140,30 @@ exit:
* the operation. The serverctrls and clientctrls parameters are
* optional and should be set to NULL if not used.
*/
-ULONG CDECL ldap_add_extW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[],
- PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG *message )
+ULONG CDECL ldap_add_extW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs, LDAPControlW **serverctrls,
+ LDAPControlW **clientctrls, ULONG *message )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL;
- LDAPMod **attrsU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
- int dummy;
+ LDAPModU **attrsU = NULL;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), attrs,
- serverctrls, clientctrls, message );
+ TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), attrs, serverctrls, clientctrls, message );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
-
- ret = map_error( ldap_add_ext( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs, serverctrlsU,
- clientctrlsU, message ? (int *)message : &dummy ));
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (attrs && !(attrsU = modarrayWtoU( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+
+ ret = map_error( ldap_funcs->ldap_add_ext( ld->ld, dnU, attrsU, serverctrlsU, clientctrlsU, message ) );
exit:
strfreeU( dnU );
modarrayfreeU( attrsU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -260,38 +172,22 @@ exit:
*
* See ldap_add_ext_sW.
*/
-ULONG CDECL ldap_add_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[],
- PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
+ULONG CDECL ldap_add_ext_sA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs, LDAPControlA **serverctrls,
+ LDAPControlA **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_a(dn), attrs,
- serverctrls, clientctrls );
+ TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_a(dn), attrs, serverctrls, clientctrls );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
- if (serverctrls) {
- serverctrlsW = controlarrayAtoW( serverctrls );
- if (!serverctrlsW) goto exit;
- }
- if (clientctrls) {
- clientctrlsW = controlarrayAtoW( clientctrls );
- if (!clientctrlsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
ret = ldap_add_ext_sW( ld, dnW, attrsW, serverctrlsW, clientctrlsW );
@@ -300,8 +196,6 @@ exit:
modarrayfreeW( attrsW );
controlarrayfreeW( serverctrlsW );
controlarrayfreeW( clientctrlsW );
-
-#endif
return ret;
}
@@ -326,49 +220,30 @@ exit:
* The serverctrls and clientctrls parameters are optional and
* should be set to NULL if not used.
*/
-ULONG CDECL ldap_add_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[],
- PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
+ULONG CDECL ldap_add_ext_sW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs, LDAPControlW **serverctrls,
+ LDAPControlW **clientctrls )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
char *dnU = NULL;
- LDAPMod **attrsU = NULL;
- LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
+ LDAPModU **attrsU = NULL;
+ LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
- TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_w(dn), attrs,
- serverctrls, clientctrls );
+ TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_w(dn), attrs, serverctrls, clientctrls );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
- if (serverctrls) {
- serverctrlsU = controlarrayWtoU( serverctrls );
- if (!serverctrlsU) goto exit;
- }
- if (clientctrls) {
- clientctrlsU = controlarrayWtoU( clientctrls );
- if (!clientctrlsU) goto exit;
- }
-
- ret = map_error( ldap_add_ext_s( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs,
- serverctrlsU, clientctrlsU ));
+ if (dn && !(dnU = strWtoU( dn ))) goto exit;
+ if (attrs && !(attrsU = modarrayWtoU( attrs ))) goto exit;
+ if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+ if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
+
+ ret = map_error( ldap_funcs->ldap_add_ext_s( ld->ld, dnU, attrsU, serverctrlsU, clientctrlsU ) );
exit:
strfreeU( dnU );
modarrayfreeU( attrsU );
controlarrayfreeU( serverctrlsU );
controlarrayfreeU( clientctrlsU );
-
-#endif
return ret;
}
@@ -377,35 +252,24 @@ exit:
*
* See ldap_add_sW.
*/
-ULONG CDECL ldap_add_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *attrs[] )
+ULONG CDECL ldap_add_sA( WLDAP32_LDAP *ld, char *dn, LDAPModA **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret = WLDAP32_LDAP_NO_MEMORY;
WCHAR *dnW = NULL;
LDAPModW **attrsW = NULL;
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), attrs );
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnW = strAtoW( dn );
- if (!dnW) goto exit;
- }
- if (attrs) {
- attrsW = modarrayAtoW( attrs );
- if (!attrsW) goto exit;
- }
+ if (dn && !(dnW = strAtoW( dn ))) goto exit;
+ if (attrs && !(attrsW = modarrayAtoW( attrs ))) goto exit;
ret = ldap_add_sW( ld, dnW, attrsW );
exit:
strfreeW( dnW );
modarrayfreeW( attrsW );
-
-#endif
return ret;
}
@@ -424,34 +288,8 @@ exit:
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_add_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[] )
+ULONG CDECL ldap_add_sW( WLDAP32_LDAP *ld, WCHAR *dn, LDAPModW **attrs )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
- char *dnU = NULL;
- LDAPMod **attrsU = NULL;
-
- ret = WLDAP32_LDAP_NO_MEMORY;
-
TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), attrs );
-
- if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
-
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
- }
- if (attrs) {
- attrsU = modarrayWtoU( attrs );
- if (!attrsU) goto exit;
- }
-
- ret = map_error( ldap_add_ext_s( ld->ld, dn ? dnU : "", attrs ? attrsU : nullattrs, NULL, NULL ));
-
-exit:
- strfreeU( dnU );
- modarrayfreeU( attrsU );
-
-#endif
- return ret;
+ return ldap_add_ext_sW( ld, dn, attrs, NULL, NULL );
}
diff --git a/dlls/wldap32/init.c b/dlls/wldap32/init.c
index 0072ede6772..6586caa0ef5 100644
--- a/dlls/wldap32/init.c
+++ b/dlls/wldap32/init.c
@@ -128,11 +128,11 @@ static BOOL has_ldap_scheme( char *url )
static char *join_hostnames( const char *scheme, char **hostnames, ULONG portnumber )
{
char *res, *p, *q, **v;
- unsigned int i = 0, size = 0;
+ unsigned int i = 0, size = 0;
static const char sep[] = " ", fmt[] = ":%d";
char port[7];
- sprintf( port, fmt, portnumber );
+ sprintf( port, fmt, portnumber );
for (v = hostnames; *v; v++)
{
@@ -147,7 +147,7 @@ static char *join_hostnames( const char *scheme, char **hostnames, ULONG portnum
size += strlen( *v );
- if (!strchr( q, ':' ))
+ if (!strchr( q, ':' ))
size += strlen( port );
i++;
@@ -212,7 +212,7 @@ static WLDAP32_LDAP *create_context( const char *url )
ld = heap_alloc_zero( sizeof( *ld ));
if (!ld) return NULL;
- if (ldap_initialize( &ld->ld, url ) != LDAP_SUCCESS)
+ if (ldap_initialize( (LDAP **)&ld->ld, url ) != LDAP_SUCCESS)
{
heap_free( ld );
return NULL;
@@ -307,7 +307,7 @@ exit:
/***********************************************************************
* ldap_connect (WLDAP32.@)
*
- * Connect to an LDAP server.
+ * Connect to an LDAP server.
*
* PARAMS
* ld [I] Pointer to an LDAP context.
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
new file mode 100644
index 00000000000..0372206062a
--- /dev/null
+++ b/dlls/wldap32/libldap.c
@@ -0,0 +1,81 @@
+/*
+ * Unix interface for libldap
+ *
+ * Copyright 2021 Hans Leidekker for CodeWeavers
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+
+#ifdef HAVE_LDAP
+#include <stdarg.h>
+#ifdef HAVE_LDAP_H
+# include <ldap.h>
+#endif
+#ifdef HAVE_SASL_SASL_H
+# include <sasl/sasl.h>
+#endif
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+#include "winbase.h"
+
+#include "wine/debug.h"
+#include "winldap_private.h"
+
+C_ASSERT( sizeof(BerValueU) == sizeof(BerValue) );
+C_ASSERT( sizeof(LDAPModU) == sizeof(LDAPMod) );
+C_ASSERT( sizeof(LDAPControlU) == sizeof(LDAPControl) );
+C_ASSERT( sizeof(LDAPSortKeyU) == sizeof(LDAPSortKey) );
+C_ASSERT( sizeof(LDAPVLVInfoU) == sizeof(LDAPVLVInfo) );
+
+static LDAPMod *nullattrs[] = { NULL };
+
+int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+ LDAPControlU **clientctrls, ULONG *msg )
+{
+ int dummy;
+ return ldap_add_ext( ld, dn ? dn : "", attrs ? (LDAPMod **)attrs : nullattrs, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls, msg ? (int *)msg : &dummy );
+}
+
+int CDECL wrap_ldap_add_ext_s( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+ LDAPControlU **clientctrls )
+{
+ return ldap_add_ext_s( ld, dn ? dn : "", attrs ? (LDAPMod **)attrs : nullattrs, (LDAPControl **)serverctrls,
+ (LDAPControl **)clientctrls );
+}
+
+static const struct ldap_funcs funcs =
+{
+ wrap_ldap_add_ext,
+ wrap_ldap_add_ext_s,
+};
+
+NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
+{
+ if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+ *(const struct ldap_funcs **)ptr_out = &funcs;
+ return STATUS_SUCCESS;
+}
+
+#endif /* HAVE_LDAP */
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
new file mode 100644
index 00000000000..d9d833cdcb8
--- /dev/null
+++ b/dlls/wldap32/libldap.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2021 Hans Leidekker for CodeWeavers
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* compatible with structures defined in ldap.h */
+typedef struct bervalU
+{
+ unsigned long bv_len;
+ char *bv_val;
+} BerValueU;
+
+typedef struct
+{
+ int mod_op;
+ char *mod_type;
+ union
+ {
+ char **modv_strvals;
+ struct bervalU **modv_bvals;
+ } mod_vals;
+} LDAPModU;
+
+typedef struct
+{
+ char *ldctl_oid;
+ struct bervalU ldctl_value;
+ char ldctl_iscritical;
+} LDAPControlU;
+
+typedef struct
+{
+ char *attributeType;
+ char *orderingRule;
+ int reverseOrder;
+} LDAPSortKeyU;
+
+typedef struct
+{
+ int ldvlv_version;
+ int ldvlv_before_count;
+ int ldvlv_after_count;
+ int ldvlv_offset;
+ int ldvlv_count;
+ struct bervalU *ldvlv_attrvalue;
+ struct bervalU *ldvlv_context;
+ void *ldvlv_extradata;
+} LDAPVLVInfoU;
+
+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;
+
+struct ldap_funcs
+{
+ int (CDECL *ldap_add_ext)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
+ int (CDECL *ldap_add_ext_s)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
+};
+
+extern const struct ldap_funcs *ldap_funcs;
diff --git a/dlls/wldap32/main.c b/dlls/wldap32/main.c
index ce9e60367b9..55a08c9bad5 100644
--- a/dlls/wldap32/main.c
+++ b/dlls/wldap32/main.c
@@ -18,18 +18,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-
-#include "wine/debug.h"
#include <stdarg.h>
-
#include "windef.h"
+#include "winternl.h"
#include "winbase.h"
+#include "wine/debug.h"
+#include "libldap.h"
+
HINSTANCE hwldap32;
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
+const struct ldap_funcs *ldap_funcs = NULL;
+
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
TRACE( "(%p, %d, %p)\n", hinst, reason, reserved );
@@ -39,6 +41,8 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_ATTACH:
hwldap32 = hinst;
DisableThreadLibraryCalls( hinst );
+ if (__wine_init_unix_lib( hinst, reason, NULL, &ldap_funcs ))
+ ERR( "No libldap support, expect problems\n" );
break;
}
return TRUE;
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 8cd546b88b5..d0583c61f50 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -22,6 +22,11 @@
* native headers.
*/
+#include <assert.h>
+#include "winternl.h"
+#include "winnls.h"
+#include "libldap.h"
+
typedef enum {
WLDAP32_LDAP_SUCCESS = 0x00,
WLDAP32_LDAP_UNWILLING_TO_PERFORM = 0x35,
@@ -101,7 +106,9 @@ typedef struct berelement
#define WLDAP32_LDAP_OPT_SECURITY_CONTEXT 0x99
#define WLDAP32_LDAP_OPT_ROOTDSE_CACHE 0x9a
-#define WLDAP32_LDAP_AUTH_NEGOTIATE 0x486
+#define WLDAP32_LDAP_AUTH_SIMPLE 0x80
+#define WLDAP32_LDAP_AUTH_SASL 0x83
+#define WLDAP32_LDAP_AUTH_NEGOTIATE 0x486
typedef struct WLDAP32_berval
{
@@ -111,9 +118,6 @@ typedef struct WLDAP32_berval
typedef struct wldap32
{
-#ifdef HAVE_LDAP
- LDAP *ld;
-#endif
struct
{
UINT_PTR sb_sd;
@@ -137,7 +141,9 @@ typedef struct wldap32
ULONG ld_cldaptimeout;
ULONG ld_refhoplimit;
ULONG ld_options;
+ /* internal LDAP context */
struct berval **ld_server_ctrls;
+ void *ld;
} WLDAP32_LDAP, *WLDAP32_PLDAP;
typedef struct ldapmodA {
@@ -424,10 +430,10 @@ ULONG CDECL ldap_rename_ext_sA(WLDAP32_LDAP*,PCHAR,PCHAR,PCHAR,INT,PLDAPControlA
ULONG CDECL ldap_rename_ext_sW(WLDAP32_LDAP*,PWCHAR,PWCHAR,PWCHAR,INT,PLDAPControlW*,PLDAPControlW*);
ULONG CDECL WLDAP32_ldap_result(WLDAP32_LDAP*,ULONG,ULONG,struct l_timeval*,WLDAP32_LDAPMessage**);
ULONG CDECL WLDAP32_ldap_result2error(WLDAP32_LDAP*,WLDAP32_LDAPMessage*,ULONG);
-ULONG CDECL ldap_sasl_bindA(WLDAP32_LDAP*,const PCHAR,const PCHAR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,int*);
-ULONG CDECL ldap_sasl_bindW(WLDAP32_LDAP*,const PWCHAR,const PWCHAR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,int*);
-ULONG CDECL ldap_sasl_bind_sA(WLDAP32_LDAP*,const PCHAR,const PCHAR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,PBERVAL*);
-ULONG CDECL ldap_sasl_bind_sW(WLDAP32_LDAP*,const PWCHAR,const PWCHAR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,PBERVAL*);
+ULONG CDECL ldap_sasl_bindA(WLDAP32_LDAP*,const PSTR,const PSTR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,int*);
+ULONG CDECL ldap_sasl_bindW(WLDAP32_LDAP*,const PWSTR,const PWSTR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,int*);
+ULONG CDECL ldap_sasl_bind_sA(WLDAP32_LDAP*,const PSTR,const PSTR,const BERVAL*,PLDAPControlA*,PLDAPControlA*,PBERVAL*);
+ULONG CDECL ldap_sasl_bind_sW(WLDAP32_LDAP*,const PWSTR,const PWSTR,const BERVAL*,PLDAPControlW*,PLDAPControlW*,PBERVAL*);
ULONG CDECL ldap_search_abandon_page(WLDAP32_PLDAP,PLDAPSearch);
ULONG CDECL ldap_searchA(WLDAP32_LDAP*,PCHAR,ULONG,PCHAR,PCHAR[],ULONG);
ULONG CDECL ldap_searchW(WLDAP32_LDAP*,PWCHAR,ULONG,PWCHAR,PWCHAR[],ULONG);
@@ -473,3 +479,891 @@ ULONG CDECL LdapGetLastError(void);
ULONG CDECL LdapMapErrorToWin32(ULONG);
int CDECL LdapUnicodeToUTF8(LPCWSTR,int,LPSTR,int);
int CDECL LdapUTF8ToUnicode(LPCSTR,int,LPWSTR,int);
+
+ULONG map_error( int ) DECLSPEC_HIDDEN;
+
+static inline char *strdupU( const char *src )
+{
+ char *dst;
+ if (!src) return NULL;
+ if ((dst = RtlAllocateHeap( GetProcessHeap(), 0, (strlen( src ) + 1) * sizeof(char) ))) strcpy( dst, src );
+ return dst;
+}
+
+#ifndef HAVE_LDAP
+static inline WCHAR *strdupW( const WCHAR *src )
+{
+ WCHAR *dst;
+ if (!src) return NULL;
+ if ((dst = RtlAllocateHeap( GetProcessHeap(), 0, (lstrlenW( src ) + 1) * sizeof(WCHAR) ))) lstrcpyW( dst, src );
+ return dst;
+}
+
+static inline char *strWtoU( const WCHAR *str )
+{
+ char *ret = NULL;
+ if (str)
+ {
+ int len = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len )))
+ WideCharToMultiByte( CP_UTF8, 0, str, -1, ret, len, NULL, NULL );
+ }
+ return ret;
+}
+
+static inline char *strnWtoU( const WCHAR *str, DWORD in_len, DWORD *out_len )
+{
+ char *ret = NULL;
+ *out_len = 0;
+ if (str)
+ {
+ DWORD len = WideCharToMultiByte( CP_UTF8, 0, str, in_len, NULL, 0, NULL, NULL );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len + 1 )))
+ {
+ WideCharToMultiByte( CP_UTF8, 0, str, in_len, ret, len, NULL, NULL );
+ ret[len] = 0;
+ *out_len = len;
+ }
+ }
+ return ret;
+}
+
+static inline void strfreeU( char *str )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, str );
+}
+
+static inline WCHAR *strAtoW( const char *str )
+{
+ WCHAR *ret = NULL;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
+ }
+ return ret;
+}
+
+static inline void strfreeW( WCHAR *str )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, str );
+}
+
+static inline WCHAR *strnAtoW( const char *str, DWORD in_len, DWORD *out_len )
+{
+ WCHAR *ret = NULL;
+ *out_len = 0;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, str, in_len, NULL, 0 );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
+ {
+ MultiByteToWideChar( CP_ACP, 0, str, in_len, ret, len );
+ ret[len] = 0;
+ *out_len = len;
+ }
+ }
+ return ret;
+}
+
+static inline DWORD bvarraylenW( struct WLDAP32_berval **bv )
+{
+ struct WLDAP32_berval **p = bv;
+ while (*p) p++;
+ return p - bv;
+}
+
+static inline DWORD strarraylenW( WCHAR **strarray )
+{
+ WCHAR **p = strarray;
+ while (*p) p++;
+ return p - strarray;
+}
+
+static inline char **strarrayWtoU( WCHAR **strarray )
+{
+ char **strarrayU = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(char *) * (strarraylenW( strarray ) + 1);
+ if ((strarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ WCHAR **p = strarray;
+ char **q = strarrayU;
+
+ while (*p) *q++ = strWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayU;
+}
+
+static inline char *strWtoA( const WCHAR *str )
+{
+ char *ret = NULL;
+ if (str)
+ {
+ DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len )))
+ WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
+ }
+ return ret;
+}
+
+static inline char **strarrayWtoA( WCHAR **strarray )
+{
+ char **strarrayA = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(char *) * (strarraylenW( strarray ) + 1);
+ if ((strarrayA = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ WCHAR **p = strarray;
+ char **q = strarrayA;
+
+ while (*p) *q++ = strWtoA( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayA;
+}
+
+#define WLDAP32_LDAP_MOD_BVALUES 0x80
+
+static inline DWORD modarraylenW( LDAPModW **modarray )
+{
+ LDAPModW **p = modarray;
+ while (*p) p++;
+ return p - modarray;
+}
+
+static inline struct bervalU *bervalWtoU( const struct WLDAP32_berval *bv )
+{
+ struct bervalU *berval;
+ DWORD size = sizeof(*berval) + bv->bv_len;
+
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, 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 bervalU **bv )
+{
+ struct bervalU **p = bv;
+ while (*p) p++;
+ return p - bv;
+}
+
+static inline struct WLDAP32_berval *bervalUtoW( const struct bervalU *bv )
+{
+ struct WLDAP32_berval *berval;
+ DWORD size = sizeof(*berval) + bv->bv_len;
+
+ assert( bv->bv_len <= ~0u );
+
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, 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 struct WLDAP32_berval **bvarrayUtoW( struct bervalU **bv )
+{
+ struct WLDAP32_berval **berval = NULL;
+ DWORD size;
+
+ if (bv)
+ {
+ size = sizeof(*berval) * (bvarraylenU( bv ) + 1);
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ struct bervalU **p = bv;
+ struct WLDAP32_berval **q = berval;
+
+ while (*p) *q++ = bervalUtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return berval;
+}
+
+static inline void bvfreeU( struct bervalU *berval )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, berval );
+}
+
+static inline struct bervalU **bvarrayWtoU( struct WLDAP32_berval **bv )
+{
+ struct bervalU **berval = NULL;
+ DWORD size;
+
+ if (bv)
+ {
+ size = sizeof(*berval) * (bvarraylenW( bv ) + 1);
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ struct WLDAP32_berval **p = bv;
+ struct bervalU **q = berval;
+
+ while (*p) *q++ = bervalWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return berval;
+}
+
+static inline LDAPModU *modWtoU( const LDAPModW *mod )
+{
+ LDAPModU *modU;
+
+ if ((modU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPModU) )))
+ {
+ modU->mod_op = mod->mod_op;
+ modU->mod_type = strWtoU( mod->mod_type );
+
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ modU->mod_vals.modv_bvals = bvarrayWtoU( mod->mod_vals.modv_bvals );
+ else
+ modU->mod_vals.modv_strvals = strarrayWtoU( mod->mod_vals.modv_strvals );
+ }
+ return modU;
+}
+
+static inline LDAPModU **modarrayWtoU( LDAPModW **modarray )
+{
+ LDAPModU **modarrayU = NULL;
+ DWORD size;
+
+ if (modarray)
+ {
+ size = sizeof(LDAPModU *) * (modarraylenW( modarray ) + 1);
+ if ((modarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPModW **p = modarray;
+ LDAPModU **q = modarrayU;
+
+ while (*p) *q++ = modWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return modarrayU;
+}
+
+static inline void bvarrayfreeU( struct bervalU **bv )
+{
+ struct bervalU **p = bv;
+ while (*p) RtlFreeHeap( GetProcessHeap(), 0, *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, bv );
+}
+
+static inline void strarrayfreeU( char **strarray )
+{
+ if (strarray)
+ {
+ char **p = strarray;
+ while (*p) strfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, strarray );
+ }
+}
+
+static inline void modfreeU( LDAPModU *mod )
+{
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ bvarrayfreeU( mod->mod_vals.modv_bvals );
+ else
+ strarrayfreeU( mod->mod_vals.modv_strvals );
+ RtlFreeHeap( GetProcessHeap(), 0, mod );
+}
+
+static inline void modarrayfreeU( LDAPModU **modarray )
+{
+ if (modarray)
+ {
+ LDAPModU **p = modarray;
+ while (*p) modfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, modarray );
+ }
+}
+
+static inline DWORD modarraylenA( LDAPModA **modarray )
+{
+ LDAPModA **p = modarray;
+ while (*p) p++;
+ return p - modarray;
+}
+
+static inline struct WLDAP32_berval *bervalWtoW( const struct WLDAP32_berval *bv )
+{
+ struct WLDAP32_berval *berval;
+ DWORD size = sizeof(*berval) + bv->bv_len;
+
+ if ((berval = RtlAllocateHeap( GetProcessHeap(), 0, 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 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 = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ struct WLDAP32_berval **p = bv;
+ struct WLDAP32_berval **q = berval;
+
+ while (*p) *q++ = bervalWtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return berval;
+}
+
+static inline DWORD strarraylenA( char **strarray )
+{
+ char **p = strarray;
+ while (*p) p++;
+ return p - strarray;
+}
+
+static inline WCHAR **strarrayAtoW( char **strarray )
+{
+ WCHAR **strarrayW = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(WCHAR *) * (strarraylenA( strarray ) + 1);
+ if ((strarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char **p = strarray;
+ WCHAR **q = strarrayW;
+
+ while (*p) *q++ = strAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayW;
+}
+
+static inline LDAPModW *modAtoW( const LDAPModA *mod )
+{
+ LDAPModW *modW;
+
+ if ((modW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPModW) )))
+ {
+ modW->mod_op = mod->mod_op;
+ modW->mod_type = strAtoW( mod->mod_type );
+
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ modW->mod_vals.modv_bvals = bvarrayWtoW( mod->mod_vals.modv_bvals );
+ else
+ modW->mod_vals.modv_strvals = strarrayAtoW( mod->mod_vals.modv_strvals );
+ }
+ return modW;
+}
+
+static inline LDAPModW **modarrayAtoW( LDAPModA **modarray )
+{
+ LDAPModW **modarrayW = NULL;
+ DWORD size;
+
+ if (modarray)
+ {
+ size = sizeof(LDAPModW *) * (modarraylenA( modarray ) + 1);
+ if ((modarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPModA **p = modarray;
+ LDAPModW **q = modarrayW;
+
+ while (*p) *q++ = modAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return modarrayW;
+}
+
+static inline void bvarrayfreeW( struct WLDAP32_berval **bv )
+{
+ struct WLDAP32_berval **p = bv;
+ while (*p) RtlFreeHeap( GetProcessHeap(), 0, *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, bv );
+}
+
+static inline void strarrayfreeW( WCHAR **strarray )
+{
+ if (strarray)
+ {
+ WCHAR **p = strarray;
+ while (*p) strfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, strarray );
+ }
+}
+
+static inline void modfreeW( LDAPModW *mod )
+{
+ if (mod->mod_op & WLDAP32_LDAP_MOD_BVALUES)
+ bvarrayfreeW( mod->mod_vals.modv_bvals );
+ else
+ strarrayfreeW( mod->mod_vals.modv_strvals );
+ RtlFreeHeap( GetProcessHeap(), 0, mod );
+}
+
+static inline void modarrayfreeW( LDAPModW **modarray )
+{
+ if (modarray)
+ {
+ LDAPModW **p = modarray;
+ while (*p) modfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, modarray );
+ }
+}
+
+static inline DWORD controlarraylenA( LDAPControlA **controlarray )
+{
+ LDAPControlA **p = controlarray;
+ while (*p) p++;
+ return p - controlarray;
+}
+
+static inline LDAPControlW *controlAtoW( const LDAPControlA *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 = strAtoW( 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 **controlarrayAtoW( LDAPControlA **controlarray )
+{
+ LDAPControlW **controlarrayW = NULL;
+ DWORD size;
+
+ if (controlarray)
+ {
+ size = sizeof(LDAPControlW *) * (controlarraylenA( controlarray ) + 1);
+ if ((controlarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPControlA **p = controlarray;
+ LDAPControlW **q = controlarrayW;
+
+ while (*p) *q++ = controlAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return controlarrayW;
+}
+
+static inline void controlfreeW( LDAPControlW *control )
+{
+ if (control)
+ {
+ strfreeW( control->ldctl_oid );
+ RtlFreeHeap( GetProcessHeap(), 0, control->ldctl_value.bv_val );
+ RtlFreeHeap( GetProcessHeap(), 0, control );
+ }
+}
+
+static inline void controlarrayfreeW( LDAPControlW **controlarray )
+{
+ if (controlarray)
+ {
+ LDAPControlW **p = controlarray;
+ while (*p) controlfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, controlarray );
+ }
+}
+
+static inline DWORD controlarraylenW( LDAPControlW **controlarray )
+{
+ LDAPControlW **p = controlarray;
+ while (*p) p++;
+ return p - controlarray;
+}
+
+static inline LDAPControlA *controlWtoA( const LDAPControlW *control )
+{
+ LDAPControlA *controlA;
+ 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 (!(controlA = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlA) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlA->ldctl_oid = strWtoA( control->ldctl_oid );
+ controlA->ldctl_value.bv_len = len;
+ controlA->ldctl_value.bv_val = val;
+ controlA->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlA;
+}
+
+static inline void strfreeA( char *str )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, str );
+}
+
+static inline void controlfreeA( LDAPControlA *control )
+{
+ if (control)
+ {
+ strfreeA( control->ldctl_oid );
+ RtlFreeHeap( GetProcessHeap(), 0, control->ldctl_value.bv_val );
+ RtlFreeHeap( GetProcessHeap(), 0, control );
+ }
+}
+
+static inline void controlarrayfreeA( LDAPControlA **controlarray )
+{
+ if (controlarray)
+ {
+ LDAPControlA **p = controlarray;
+ while (*p) controlfreeA( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, controlarray );
+ }
+}
+
+static inline LDAPControlU *controlWtoU( const LDAPControlW *control )
+{
+ LDAPControlU *controlU;
+ 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 (!(controlU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlU) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlU->ldctl_oid = strWtoU( control->ldctl_oid );
+ controlU->ldctl_value.bv_len = len;
+ controlU->ldctl_value.bv_val = val;
+ controlU->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlU;
+}
+
+static inline LDAPControlU **controlarrayWtoU( LDAPControlW **controlarray )
+{
+ LDAPControlU **controlarrayU = NULL;
+ DWORD size;
+
+ if (controlarray)
+ {
+ size = sizeof(LDAPControlU *) * (controlarraylenW( controlarray ) + 1);
+ if ((controlarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPControlW **p = controlarray;
+ LDAPControlU **q = controlarrayU;
+
+ while (*p) *q++ = controlWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return controlarrayU;
+}
+
+static inline void controlfreeU( LDAPControlU *control )
+{
+ if (control)
+ {
+ strfreeU( control->ldctl_oid );
+ RtlFreeHeap( GetProcessHeap(), 0, control->ldctl_value.bv_val );
+ RtlFreeHeap( GetProcessHeap(), 0, control );
+ }
+}
+
+static inline void controlarrayfreeU( LDAPControlU **controlarray )
+{
+ if (controlarray)
+ {
+ LDAPControlU **p = controlarray;
+ while (*p) controlfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, controlarray );
+ }
+}
+
+static inline DWORD controlarraylenU( LDAPControlU **controlarray )
+{
+ LDAPControlU **p = controlarray;
+ while (*p) p++;
+ return p - controlarray;
+}
+
+static inline WCHAR *strUtoW( const char *str )
+{
+ WCHAR *ret = NULL;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_UTF8, 0, str, -1, NULL, 0 );
+ if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ MultiByteToWideChar( CP_UTF8, 0, str, -1, ret, len );
+ }
+ return ret;
+}
+
+static inline DWORD strarraylenU( char **strarray )
+{
+ char **p = strarray;
+ while (*p) p++;
+ return p - strarray;
+}
+
+static inline WCHAR **strarrayUtoW( char **strarray )
+{
+ WCHAR **strarrayW = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(WCHAR *) * (strarraylenU( strarray ) + 1);
+ if ((strarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ char **p = strarray;
+ WCHAR **q = strarrayW;
+
+ while (*p) *q++ = strUtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayW;
+}
+
+static inline LDAPControlW *controlUtoW( const LDAPControlU *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 = strUtoW( 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 DWORD sortkeyarraylenA( LDAPSortKeyA **sortkeyarray )
+{
+ LDAPSortKeyA **p = sortkeyarray;
+ while (*p) p++;
+ return p - sortkeyarray;
+}
+
+static inline LDAPSortKeyW *sortkeyAtoW( const LDAPSortKeyA *sortkey )
+{
+ LDAPSortKeyW *sortkeyW;
+
+ if ((sortkeyW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPSortKeyW) )))
+ {
+ sortkeyW->sk_attrtype = strAtoW( sortkey->sk_attrtype );
+ sortkeyW->sk_matchruleoid = strAtoW( sortkey->sk_matchruleoid );
+ sortkeyW->sk_reverseorder = sortkey->sk_reverseorder;
+ }
+ return sortkeyW;
+}
+
+static inline LDAPSortKeyW **sortkeyarrayAtoW( LDAPSortKeyA **sortkeyarray )
+{
+ LDAPSortKeyW **sortkeyarrayW = NULL;
+ DWORD size;
+
+ if (sortkeyarray)
+ {
+ size = sizeof(LDAPSortKeyW *) * (sortkeyarraylenA( sortkeyarray ) + 1);
+ if ((sortkeyarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPSortKeyA **p = sortkeyarray;
+ LDAPSortKeyW **q = sortkeyarrayW;
+
+ while (*p) *q++ = sortkeyAtoW( *p++ );
+ *q = NULL;
+ }
+ }
+ return sortkeyarrayW;
+}
+
+static inline void sortkeyfreeW( LDAPSortKeyW *sortkey )
+{
+ if (sortkey)
+ {
+ strfreeW( sortkey->sk_attrtype );
+ strfreeW( sortkey->sk_matchruleoid );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkey );
+ }
+}
+
+static inline void sortkeyarrayfreeW( LDAPSortKeyW **sortkeyarray )
+{
+ if (sortkeyarray)
+ {
+ LDAPSortKeyW **p = sortkeyarray;
+ while (*p) sortkeyfreeW( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkeyarray );
+ }
+}
+
+static inline DWORD sortkeyarraylenW( LDAPSortKeyW **sortkeyarray )
+{
+ LDAPSortKeyW **p = sortkeyarray;
+ while (*p) p++;
+ return p - sortkeyarray;
+}
+
+static inline LDAPSortKeyU *sortkeyWtoU( const LDAPSortKeyW *sortkey )
+{
+ LDAPSortKeyU *sortkeyU;
+
+ if ((sortkeyU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPSortKeyU) )))
+ {
+ sortkeyU->attributeType = strWtoU( sortkey->sk_attrtype );
+ sortkeyU->orderingRule = strWtoU( sortkey->sk_matchruleoid );
+ sortkeyU->reverseOrder = sortkey->sk_reverseorder;
+ }
+ return sortkeyU;
+}
+
+static inline LDAPSortKeyU **sortkeyarrayWtoU( LDAPSortKeyW **sortkeyarray )
+{
+ LDAPSortKeyU **sortkeyarrayU = NULL;
+ DWORD size;
+
+ if (sortkeyarray)
+ {
+ size = sizeof(LDAPSortKeyU *) * (sortkeyarraylenW( sortkeyarray ) + 1);
+ if ((sortkeyarrayU = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPSortKeyW **p = sortkeyarray;
+ LDAPSortKeyU **q = sortkeyarrayU;
+
+ while (*p) *q++ = sortkeyWtoU( *p++ );
+ *q = NULL;
+ }
+ }
+ return sortkeyarrayU;
+}
+
+static inline void sortkeyfreeU( LDAPSortKeyU *sortkey )
+{
+ if (sortkey)
+ {
+ strfreeU( sortkey->attributeType );
+ strfreeU( sortkey->orderingRule );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkey );
+ }
+}
+
+static inline void sortkeyarrayfreeU( LDAPSortKeyU **sortkeyarray )
+{
+ if (sortkeyarray)
+ {
+ LDAPSortKeyU **p = sortkeyarray;
+ while (*p) sortkeyfreeU( *p++ );
+ RtlFreeHeap( GetProcessHeap(), 0, sortkeyarray );
+ }
+}
+
+static inline LDAPVLVInfoU *vlvinfoWtoU( const WLDAP32_LDAPVLVInfo *info )
+{
+ LDAPVLVInfoU *infoU;
+
+ if ((infoU = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*infoU) )))
+ {
+ infoU->ldvlv_version = info->ldvlv_version;
+ infoU->ldvlv_before_count = info->ldvlv_before_count;
+ infoU->ldvlv_after_count = info->ldvlv_after_count;
+ infoU->ldvlv_offset = info->ldvlv_offset;
+ infoU->ldvlv_count = info->ldvlv_count;
+ if (!(infoU->ldvlv_attrvalue = bervalWtoU( info->ldvlv_attrvalue )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, infoU );
+ return NULL;
+ }
+ if (!(infoU->ldvlv_context = bervalWtoU( info->ldvlv_context )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, infoU->ldvlv_attrvalue );
+ RtlFreeHeap( GetProcessHeap(), 0, infoU );
+ return NULL;
+ }
+ infoU->ldvlv_extradata = info->ldvlv_extradata;
+ }
+ return infoU;
+}
+
+static inline void vlvinfofreeU( LDAPVLVInfoU *info )
+{
+ RtlFreeHeap( GetProcessHeap(), 0, info->ldvlv_attrvalue );
+ RtlFreeHeap( GetProcessHeap(), 0, info->ldvlv_context );
+ RtlFreeHeap( GetProcessHeap(), 0, info );
+}
+#endif
diff --git a/dlls/wldap32/wldap32.h b/dlls/wldap32/wldap32.h
index 5b099c9fabc..17132ff80c1 100644
--- a/dlls/wldap32/wldap32.h
+++ b/dlls/wldap32/wldap32.h
@@ -30,14 +30,7 @@ ULONG map_error( int ) DECLSPEC_HIDDEN;
* to and from ansi (A), wide character (W) and utf8 (U) encodings.
*/
-static inline char *strdupU( const char *src )
-{
- char *dst;
- if (!src) return NULL;
- if ((dst = heap_alloc( (strlen( src ) + 1) * sizeof(char) ))) strcpy( dst, src );
- return dst;
-}
-
+#ifdef HAVE_LDAP
static inline WCHAR *strdupW( const WCHAR *src )
{
WCHAR *dst;
@@ -264,16 +257,6 @@ static inline LPWSTR *strarraydupW( LPWSTR *strarray )
return strarrayW;
}
-static inline void strarrayfreeA( LPSTR *strarray )
-{
- if (strarray)
- {
- LPSTR *p = strarray;
- while (*p) strfreeA( *p++ );
- heap_free( strarray );
- }
-}
-
static inline void strarrayfreeW( LPWSTR *strarray )
{
if (strarray)
@@ -316,6 +299,17 @@ static inline void bvarrayfreeW( struct WLDAP32_berval **bv )
while (*p) heap_free( *p++ );
heap_free( bv );
}
+#endif
+
+static inline void strarrayfreeA( LPSTR *strarray )
+{
+ if (strarray)
+ {
+ LPSTR *p = strarray;
+ while (*p) strfreeA( *p++ );
+ heap_free( strarray );
+ }
+}
#ifdef HAVE_LDAP
--
2.30.2
1
0
14 Apr '21
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/dc.c | 12 +-----------
dlls/gdi32/driver.c | 13 ++++++++++++-
dlls/gdi32/enhmfdrv/dc.c | 4 +++-
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 830fabf6e78..eb9dbf85668 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -1922,17 +1922,7 @@ DWORD WINAPI SetLayout(HDC hdc, DWORD layout)
if (dc)
{
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetLayout );
- layout = physdev->funcs->pSetLayout( physdev, layout );
- if (layout != GDI_ERROR)
- {
- oldlayout = dc->layout;
- dc->layout = layout;
- if (layout != oldlayout)
- {
- if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
- DC_UpdateXforms( dc );
- }
- }
+ oldlayout = physdev->funcs->pSetLayout( physdev, layout );
release_dc_ptr( dc );
}
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 09b051cd6fa..a2ebd018bca 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -795,7 +795,18 @@ static void CDECL nulldrv_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
static DWORD CDECL nulldrv_SetLayout( PHYSDEV dev, DWORD layout )
{
- return layout;
+ DC *dc = get_nulldrv_dc( dev );
+ DWORD old_layout;
+
+ old_layout = dc->layout;
+ dc->layout = layout;
+ if (layout != old_layout)
+ {
+ if (layout & LAYOUT_RTL) dc->MapMode = MM_ANISOTROPIC;
+ DC_UpdateXforms( dc );
+ }
+
+ return old_layout;
}
static BOOL CDECL nulldrv_SetDeviceGammaRamp( PHYSDEV dev, void *ramp )
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index 2a749418829..72b6afeee8b 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -334,12 +334,14 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{
+ PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
EMRSETLAYOUT emr;
emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr);
emr.iMode = layout;
- return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR;
+ if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR;
+ return next->funcs->pSetLayout( next, layout );
}
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
--
2.27.0
1
0
14 Apr '21
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/tests/metafile.c | 51 +++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 9340e20444a..e2592988cea 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5023,6 +5023,56 @@ static void test_emf_AlphaBlend(void)
ReleaseDC(0, hdc);
}
+static void test_emf_text_extends(void)
+{
+ static const XFORM xform = {0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f};
+ HFONT font, old_font, old_font2;
+ LOGFONTW logfont = {0};
+ HENHMETAFILE emf;
+ SIZE size, size2;
+ HDC dc, emf_dc;
+ BOOL ret;
+
+ dc = GetDC(0);
+ emf_dc = CreateEnhMetaFileW(dc, NULL, NULL, NULL);
+ ok(!!emf_dc, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+
+ logfont.lfWeight = FW_NORMAL;
+ logfont.lfHeight = 20;
+ lstrcpyW(logfont.lfFaceName, L"Tahoma");
+ font = CreateFontIndirectW(&logfont);
+ ok(!!font, "CreateFontIndirectW failed, error %d\n", GetLastError());
+
+ old_font = SelectObject(dc, font);
+ old_font2 = SelectObject(emf_dc, font);
+
+ ret = SetGraphicsMode(dc, GM_ADVANCED);
+ ok(ret, "SetGraphicsMode failed, error %d\n", GetLastError());
+ ret = SetGraphicsMode(emf_dc, GM_ADVANCED);
+ ok(ret, "SetGraphicsMode failed, error %d\n", GetLastError());
+
+ ret = ModifyWorldTransform(dc, &xform, MWT_RIGHTMULTIPLY);
+ ok(ret, "ModifyWorldTransform failed, error %d\n", GetLastError());
+ ret = ModifyWorldTransform(emf_dc, &xform, MWT_RIGHTMULTIPLY);
+ ok(ret, "ModifyWorldTransform failed, error %d\n", GetLastError());
+
+ ret = GetTextExtentPoint32W(dc, L"W", 1, &size);
+ ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
+ ret = GetTextExtentPoint32W(emf_dc, L"W", 1, &size2);
+ ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
+todo_wine
+ ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d\n",
+ size.cx, size.cy, size2.cx, size2.cy);
+
+ SelectObject(emf_dc, old_font2);
+ SelectObject(dc, old_font);
+ DeleteObject(font);
+ emf = CloseEnhMetaFile(emf_dc);
+ ok(!!emf, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ DeleteEnhMetaFile(emf);
+ ReleaseDC(0, dc);
+}
+
START_TEST(metafile)
{
init_function_pointers();
@@ -5041,6 +5091,7 @@ START_TEST(metafile)
test_emf_PolyPolyline();
test_emf_GradientFill();
test_emf_WorldTransform();
+ test_emf_text_extends();
/* For win-format metafiles (mfdrv) */
test_mf_SaveDC();
--
2.27.0
1
0
14 Apr '21
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/tests/metafile.c | 713 +++++++++++++++++++++++++++++++++++-
1 file changed, 712 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 648e9369803..ec9c7894574 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -991,7 +991,7 @@ static void test_mf_SaveDC(void)
/* with the nominal results. */
/* Maximum size of sample metafiles in bytes. */
-#define MF_BUFSIZE 1024
+#define MF_BUFSIZE 2048
/* 8x8 bitmap data for a pattern brush */
static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
@@ -4315,6 +4315,716 @@ static void test_emf_WorldTransform(void)
}
}
+static const unsigned char EMF_ALPHABLEND_1BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_4BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x68, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_8BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0x88, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xa4, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x28, 0x04, 0x00, 0x00, 0x94, 0x04, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_16BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x03, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0x03, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xe0, 0x07, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_16BIT_555[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_24BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa8, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_32BIT_888[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_32BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xe0, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static void test_emf_AlphaBlend(void)
+{
+ static const XFORM xform = {0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
+ static const BLENDFUNCTION blend = {AC_SRC_OVER, 0, 128, 0};
+ static const int bitmap_width = 4, bitmap_height = 4;
+ unsigned char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
+ BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
+ HDC hdc, hdc_emf, hdc_emf2, hdc_bitmap;
+ HBITMAP hbitmap, old_hbitmap;
+ HENHMETAFILE hemf, hemf2;
+ int ret, test_idx;
+ char comment[64];
+ void *bits;
+
+ static const struct
+ {
+ WORD bpp;
+ WORD compression;
+ const void *bits;
+ size_t bits_count;
+ DWORD used_color_count;
+ DWORD color_count;
+ RGBQUAD colors[3];
+ }
+ tests[] =
+ {
+ {1, BI_RGB, EMF_ALPHABLEND_1BIT, sizeof(EMF_ALPHABLEND_1BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {4, BI_RGB, EMF_ALPHABLEND_4BIT, sizeof(EMF_ALPHABLEND_4BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {8, BI_RGB, EMF_ALPHABLEND_8BIT, sizeof(EMF_ALPHABLEND_8BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {16, BI_RGB, EMF_ALPHABLEND_16BIT_555, sizeof(EMF_ALPHABLEND_16BIT_555)},
+ {24, BI_RGB, EMF_ALPHABLEND_24BIT, sizeof(EMF_ALPHABLEND_24BIT)},
+ {32, BI_RGB, EMF_ALPHABLEND_32BIT_888, sizeof(EMF_ALPHABLEND_32BIT_888)},
+ {16, BI_BITFIELDS, EMF_ALPHABLEND_16BIT, sizeof(EMF_ALPHABLEND_16BIT), 0, 3, {{0x00, 0xf8, 0x00}, {0xe0, 0x07, 0x00}, {0x1f, 0x00, 0x00}}},
+ {32, BI_BITFIELDS, EMF_ALPHABLEND_32BIT, sizeof(EMF_ALPHABLEND_32BIT), 0, 3, {{0x00, 0x00, 0xff}, {0xe0, 0xff, 0x00}, {0xff, 0x00, 0x00}}},
+ };
+
+ hdc = GetDC(0);
+
+ /* Test that source DC cannot be an enhanced metafile */
+ hdc_emf = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+ hdc_emf2 = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf2, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+
+ ret = GdiAlphaBlend(hdc_emf, 0, 0, 1, 1, hdc_emf2, 0, 0, 1, 1, blend);
+ ok(!ret, "GdiAlphaBlend succeeded\n");
+
+ hemf2 = CloseEnhMetaFile(hdc_emf2);
+ ok(!!hemf2, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ hemf = CloseEnhMetaFile(hdc_emf);
+ ok(!!hemf, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ DeleteEnhMetaFile(hemf2);
+ DeleteEnhMetaFile(hemf);
+
+ /* Test AlphaBlend with different format of bitmaps */
+ for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx)
+ {
+ memset(bmi_buffer, 0, sizeof(bmi_buffer));
+ bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
+ bmi->bmiHeader.biHeight = bitmap_width;
+ bmi->bmiHeader.biWidth = bitmap_height;
+ bmi->bmiHeader.biBitCount = tests[test_idx].bpp;
+ bmi->bmiHeader.biPlanes = 1;
+ bmi->bmiHeader.biCompression = tests[test_idx].compression;
+ bmi->bmiHeader.biClrUsed = tests[test_idx].used_color_count;
+ memcpy(bmi->bmiColors, tests[test_idx].colors, sizeof(RGBQUAD) * tests[test_idx].color_count);
+
+ hbitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
+ ok(!!hbitmap, "Test %d: CreateDIBSection failed, error %d\n", test_idx, GetLastError());
+ hdc_bitmap = CreateCompatibleDC(hdc);
+ ok(!!hdc_bitmap, "Test %d: CreateCompatibleDC failed, error %d\n", test_idx, GetLastError());
+ old_hbitmap = SelectObject(hdc_bitmap, hbitmap);
+
+ SetBkColor(hdc_bitmap, RGB(0xff, 0xff, 0xff));
+ ret = SetGraphicsMode(hdc_bitmap, GM_ADVANCED);
+ ok(ret, "Test %d: SetGraphicsMode failed, error %d\n", test_idx, GetLastError());
+ ret = SetWorldTransform(hdc_bitmap, &xform);
+ ok(ret, "Test %d: SetWorldTransform failed, error %d\n", test_idx, GetLastError());
+ ret = SetMapMode(hdc_bitmap, MM_ANISOTROPIC);
+ ok(ret, "Test %d: SetMapMode failed, error %d\n", test_idx, GetLastError());
+ ret = SetWindowOrgEx(hdc_bitmap, 0, 0, NULL);
+ ok(ret, "Test %d: SetWindowOrgEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetWindowExtEx(hdc_bitmap, 400, 400, NULL);
+ ok(ret, "Test %d: SetWindowExtEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetViewportOrgEx(hdc_bitmap, 0, 0, NULL);
+ ok(ret, "Test %d: SetViewportOrgEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetViewportExtEx(hdc_bitmap, bitmap_width, bitmap_height, NULL);
+ ok(ret, "Test %d: SetViewportExtEx failed, error %d\n", test_idx, GetLastError());
+
+ hdc_emf = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf, "Test %d: CreateEnhMetaFileW failed, error %d\n", test_idx, GetLastError());
+
+ ret = BitBlt(hdc_emf, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, WHITENESS);
+ ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
+ ret = BitBlt(hdc_bitmap, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, BLACKNESS);
+ ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
+ ret = GdiAlphaBlend(hdc_emf, 0, 0, bitmap_width, bitmap_height, hdc_bitmap, 0, 0, 400, 400, blend);
+ todo_wine
+ ok(ret, "Test %d: GdiAlphaBlend failed, error %d\n", test_idx, GetLastError());
+
+ hemf = CloseEnhMetaFile(hdc_emf);
+ ok(!!hemf, "Test %d: CloseEnhMetaFile failed, %d\n", test_idx, GetLastError());
+
+ sprintf(comment, "test_emf_AlphaBlend() test %d", test_idx);
+ if (ret)
+ ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
+ if (ret)
+ {
+ dump_emf_bits(hemf, comment);
+ dump_emf_records(hemf, comment);
+ }
+
+ DeleteEnhMetaFile(hemf);
+ SelectObject(hdc_bitmap, old_hbitmap);
+ DeleteDC(hdc_bitmap);
+ DeleteObject(hbitmap);
+ }
+
+ ReleaseDC(0, hdc);
+}
+
START_TEST(metafile)
{
init_function_pointers();
@@ -4323,6 +5033,7 @@ START_TEST(metafile)
test_ExtTextOut();
test_ExtTextOutScale();
test_SaveDC();
+ test_emf_AlphaBlend();
test_emf_BitBlt();
test_emf_DCBrush();
test_emf_ExtTextOut_on_path();
--
2.27.0
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
tools/winedump/emf.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/winedump/emf.c b/tools/winedump/emf.c
index d5630f6812b..2f54f73153b 100644
--- a/tools/winedump/emf.c
+++ b/tools/winedump/emf.c
@@ -325,7 +325,30 @@ static int dump_emfrecord(void)
}
EMRCASE(EMR_BITBLT);
- EMRCASE(EMR_STRETCHBLT);
+
+ case EMR_STRETCHBLT:
+ {
+ const EMRSTRETCHBLT *blt = PRD(offset, sizeof(*blt));
+ const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)((const unsigned char *)blt + blt->offBmiSrc);
+
+ printf("%-20s %08x\n", "EMR_STRETCHBLT", length);
+ printf("bounds (%d,%d - %d,%d) dst %d,%d %dx%d src %d,%d %dx%d rop %#x xform (%f, %f, %f, %f, %f, %f)\n"
+ "bk_color %#x usage %#x bmi_offset %#x bmi_size %#x bits_offset %#x bits_size %#x\n",
+ blt->rclBounds.left, blt->rclBounds.top, blt->rclBounds.right, blt->rclBounds.bottom,
+ blt->xDest, blt->yDest, blt->cxDest, blt->cyDest,
+ blt->xSrc, blt->ySrc, blt->cxSrc, blt->cySrc, blt->dwRop,
+ blt->xformSrc.eM11, blt->xformSrc.eM12, blt->xformSrc.eM21,
+ blt->xformSrc.eM22, blt->xformSrc.eDx, blt->xformSrc.eDy,
+ blt->crBkColorSrc, blt->iUsageSrc, blt->offBmiSrc, blt->cbBmiSrc,
+ blt->offBitsSrc, blt->cbBitsSrc);
+ printf("BITMAPINFOHEADER biSize %#x biWidth %d biHeight %d biPlanes %d biBitCount %d biCompression %#x\n"
+ "biSizeImage %#x biXPelsPerMeter %d biYPelsPerMeter %d biClrUsed %#x biClrImportant %#x\n",
+ bmih->biSize, bmih->biWidth, bmih->biHeight, bmih->biPlanes, bmih->biBitCount,
+ bmih->biCompression, bmih->biSizeImage, bmih->biXPelsPerMeter, bmih->biYPelsPerMeter,
+ bmih->biClrUsed, bmih->biClrImportant);
+ break;
+ }
+
EMRCASE(EMR_MASKBLT);
EMRCASE(EMR_PLGBLT);
EMRCASE(EMR_SETDIBITSTODEVICE);
--
2.27.0
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
tools/winedump/emf.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/winedump/emf.c b/tools/winedump/emf.c
index d44f7a806a5..d5630f6812b 100644
--- a/tools/winedump/emf.c
+++ b/tools/winedump/emf.c
@@ -397,7 +397,30 @@ static int dump_emfrecord(void)
EMRCASE(EMR_COLORCORRECTPALETTE);
EMRCASE(EMR_SETICMPROFILEA);
EMRCASE(EMR_SETICMPROFILEW);
- EMRCASE(EMR_ALPHABLEND);
+
+ case EMR_ALPHABLEND:
+ {
+ const EMRALPHABLEND *blend = PRD(offset, sizeof(*blend));
+ const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)((const unsigned char *)blend + blend->offBmiSrc);
+
+ printf("%-20s %08x\n", "EMR_ALPHABLEND", length);
+ printf("bounds (%d,%d - %d,%d) dst %d,%d %dx%d src %d,%d %dx%d rop %#x xform (%f, %f, %f, %f, %f, %f)\n"
+ "bk_color %#x usage %#x bmi_offset %#x bmi_size %#x bits_offset %#x bits_size %#x\n",
+ blend->rclBounds.left, blend->rclBounds.top, blend->rclBounds.right, blend->rclBounds.bottom,
+ blend->xDest, blend->yDest, blend->cxDest, blend->cyDest,
+ blend->xSrc, blend->ySrc, blend->cxSrc, blend->cySrc, blend->dwRop,
+ blend->xformSrc.eM11, blend->xformSrc.eM12, blend->xformSrc.eM21,
+ blend->xformSrc.eM22, blend->xformSrc.eDx, blend->xformSrc.eDy,
+ blend->crBkColorSrc, blend->iUsageSrc, blend->offBmiSrc, blend->cbBmiSrc,
+ blend->offBitsSrc, blend->cbBitsSrc);
+ printf("BITMAPINFOHEADER biSize %#x biWidth %d biHeight %d biPlanes %d biBitCount %d biCompression %#x\n"
+ "biSizeImage %#x biXPelsPerMeter %d biYPelsPerMeter %d biClrUsed %#x biClrImportant %#x\n",
+ bmih->biSize, bmih->biWidth, bmih->biHeight, bmih->biPlanes, bmih->biBitCount,
+ bmih->biCompression, bmih->biSizeImage, bmih->biXPelsPerMeter, bmih->biYPelsPerMeter,
+ bmih->biClrUsed, bmih->biClrImportant);
+ break;
+ }
+
EMRCASE(EMR_SETLAYOUT);
EMRCASE(EMR_TRANSPARENTBLT);
EMRCASE(EMR_RESERVED_117);
--
2.27.0
1
0
[PATCH 1/3] ntoskrnl: Remove the device from the root device list in IRP_MN_REMOVE_DEVICE.
by Zebediah Figura 14 Apr '21
by Zebediah Figura 14 Apr '21
14 Apr '21
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/ntoskrnl.exe/pnp.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c
index 0d9d816e3c0..095344b1073 100644
--- a/dlls/ntoskrnl.exe/pnp.c
+++ b/dlls/ntoskrnl.exe/pnp.c
@@ -955,10 +955,13 @@ static NTSTATUS WINAPI pnp_manager_device_pnp( DEVICE_OBJECT *device, IRP *irp )
break;
case IRP_MN_START_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
- case IRP_MN_REMOVE_DEVICE:
/* Nothing to do. */
irp->IoStatus.u.Status = STATUS_SUCCESS;
break;
+ case IRP_MN_REMOVE_DEVICE:
+ list_remove( &root_device->entry );
+ irp->IoStatus.u.Status = STATUS_SUCCESS;
+ break;
case IRP_MN_QUERY_CAPABILITIES:
irp->IoStatus.u.Status = STATUS_SUCCESS;
break;
--
2.30.2
2
3