wininet/tests: Improve error reporting in a couple of tests.
[wine] / dlls / wldap32 / value.c
1 /*
2  * WLDAP32 - LDAP support for Wine
3  *
4  * Copyright 2005 Hans Leidekker
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdarg.h>
25 #ifdef HAVE_LDAP_H
26 #include <ldap.h>
27 #endif
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winnls.h"
32
33 #include "winldap_private.h"
34 #include "wldap32.h"
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
38
39 /***********************************************************************
40  *      ldap_count_values_len     (WLDAP32.@)
41  *
42  * Count the number of values in an array of berval structures.
43  *
44  * PARAMS
45  *  vals  [I] Pointer to an array of berval structures.
46  *
47  * RETURNS
48  *  Success: The number of values counted.
49  *  Failure: 0
50  *
51  * NOTES
52  *  Call ldap_count_values_len with the result of a call to
53  *  ldap_get_values_len.
54  */
55 ULONG CDECL WLDAP32_ldap_count_values_len( struct WLDAP32_berval **vals )
56 {
57     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
58 #ifdef HAVE_LDAP
59
60     TRACE( "(%p)\n", vals );
61     ret = ldap_count_values_len( (struct berval **)vals );
62
63 #endif
64     return ret;
65 }
66
67 /***********************************************************************
68  *      ldap_count_valuesA     (WLDAP32.@)
69  *
70  * See ldap_count_valuesW.
71  */
72 ULONG CDECL ldap_count_valuesA( PCHAR *vals )
73 {
74     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
75 #ifdef HAVE_LDAP
76     WCHAR **valsW = NULL;
77
78     TRACE( "(%p)\n", vals );
79
80     if (!vals) return 0;
81
82     valsW = strarrayAtoW( vals );
83     if (!valsW) return WLDAP32_LDAP_NO_MEMORY;
84
85     ret = ldap_count_valuesW( valsW );
86     strarrayfreeW( valsW );
87
88 #endif
89     return ret;
90 }
91
92 /***********************************************************************
93  *      ldap_count_valuesW     (WLDAP32.@)
94  *
95  * Count the number of values in a string array.
96  *
97  * PARAMS
98  *  vals  [I] Pointer to an array of strings.
99  *
100  * RETURNS
101  *  Success: The number of values counted.
102  *  Failure: 0
103  *
104  * NOTES
105  *  Call ldap_count_valuesW with the result of a call to
106  *  ldap_get_valuesW.
107  */
108 ULONG CDECL ldap_count_valuesW( PWCHAR *vals )
109 {
110     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
111 #ifdef HAVE_LDAP
112     WCHAR **p = vals;
113
114     TRACE( "(%p)\n", vals );
115
116     if (!vals) return 0;
117
118     ret = 0;
119     while (*p++) ret++;
120
121 #endif
122     return ret;
123 }
124
125 /***********************************************************************
126  *      ldap_get_valuesA     (WLDAP32.@)
127  *
128  * See ldap_get_valuesW.
129  */
130 PCHAR * CDECL ldap_get_valuesA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry, PCHAR attr )
131 {
132     PCHAR *ret = NULL;
133 #ifdef HAVE_LDAP
134     WCHAR *attrW = NULL, **retW;
135
136     TRACE( "(%p, %p, %s)\n", ld, entry, debugstr_a(attr) );
137
138     if (!ld || !entry || !attr) return NULL;
139
140     attrW = strAtoW( attr );
141     if (!attrW) return NULL;
142
143     retW = ldap_get_valuesW( ld, entry, attrW );
144
145     ret = strarrayWtoA( retW );
146     ldap_value_freeW( retW );
147     strfreeW( attrW );
148
149 #endif
150     return ret;
151 }
152
153 #ifdef HAVE_LDAP
154 static char *bv2str( struct berval *bv )
155 {
156     char *str = NULL;
157     unsigned int len = bv->bv_len;
158
159     str = HeapAlloc( GetProcessHeap(), 0, len + 1 );
160     if (str)
161     {
162         memcpy( str, bv->bv_val, len );
163         str[len] = '\0';
164     }
165     return str;
166 }
167
168 static char **bv2str_array( struct berval **bv )
169 {
170     unsigned int len = 0, i = 0;
171     struct berval **p = bv;
172     char **str;
173
174     while (*p)
175     {
176         len++;
177         p++;
178     }
179     str = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(char *) );
180     if (!str) return NULL;
181
182     p = bv;
183     while (*p)
184     {
185         str[i] = bv2str( *p );
186         if (!str[i])
187         {
188             while (i > 0) HeapFree( GetProcessHeap(), 0, str[--i] );
189             HeapFree( GetProcessHeap(), 0, str );
190             return NULL;
191         } 
192         i++;
193         p++; 
194     }
195     str[i] = NULL;
196     return str;
197 }
198 #endif
199
200 /***********************************************************************
201  *      ldap_get_valuesW     (WLDAP32.@)
202  *
203  * Retrieve string values for a given attribute.
204  *
205  * PARAMS
206  *  ld     [I] Pointer to an LDAP context.
207  *  entry  [I] Entry to retrieve values from.
208  *  attr   [I] Attribute to retrieve values for.
209  *
210  * RETURNS
211  *  Success: Pointer to a character array holding the values.
212  *  Failure: NULL
213  *
214  * NOTES
215  *  Call ldap_get_valuesW with the result of a call to
216  *  ldap_first_entry or ldap_next_entry. Free the returned
217  *  array with a call to ldap_value_freeW.
218  */
219 PWCHAR * CDECL ldap_get_valuesW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry, PWCHAR attr )
220 {
221     PWCHAR *ret = NULL;
222 #ifdef HAVE_LDAP
223     char *attrU = NULL, **retU;
224     struct berval **bv;
225
226     TRACE( "(%p, %p, %s)\n", ld, entry, debugstr_w(attr) );
227
228     if (!ld || !entry || !attr) return NULL;
229
230     attrU = strWtoU( attr );
231     if (!attrU) return NULL;
232
233     bv = ldap_get_values_len( ld, entry, attrU );
234
235     retU = bv2str_array( bv );
236     ret = strarrayUtoW( retU );
237
238     ldap_value_free_len( bv );
239     strarrayfreeU( retU );
240     strfreeU( attrU );
241
242 #endif
243     return ret;
244 }
245
246 /***********************************************************************
247  *      ldap_get_values_lenA     (WLDAP32.@)
248  *
249  * See ldap_get_values_lenW.
250  */
251 struct WLDAP32_berval ** CDECL ldap_get_values_lenA( WLDAP32_LDAP *ld,
252     WLDAP32_LDAPMessage *message, PCHAR attr )
253 {
254 #ifdef HAVE_LDAP
255     WCHAR *attrW = NULL;
256     struct WLDAP32_berval **ret;
257
258     TRACE( "(%p, %p, %s)\n", ld, message, debugstr_a(attr) );
259
260     if (!ld || !message || !attr) return NULL;
261
262     attrW = strAtoW( attr );
263     if (!attrW) return NULL;
264
265     ret = ldap_get_values_lenW( ld, message, attrW );
266
267     strfreeW( attrW );
268     return ret;
269
270 #else
271     return NULL;
272 #endif
273 }
274
275 /***********************************************************************
276  *      ldap_get_values_lenW     (WLDAP32.@)
277  *
278  * Retrieve binary values for a given attribute.
279  *
280  * PARAMS
281  *  ld      [I] Pointer to an LDAP context.
282  *  message [I] Entry to retrieve values from.
283  *  attr    [I] Attribute to retrieve values for.
284  *
285  * RETURNS
286  *  Success: Pointer to a berval array holding the values.
287  *  Failure: NULL
288  *
289  * NOTES
290  *  Call ldap_get_values_lenW with the result of a call to
291  *  ldap_first_entry or ldap_next_entry. Free the returned
292  *  array with a call to ldap_value_free_len.
293  */
294 struct WLDAP32_berval ** CDECL ldap_get_values_lenW( WLDAP32_LDAP *ld,
295     WLDAP32_LDAPMessage *message, PWCHAR attr )
296 {
297 #ifdef HAVE_LDAP
298     char *attrU = NULL;
299     struct berval **ret;
300
301     TRACE( "(%p, %p, %s)\n", ld, message, debugstr_w(attr) );
302
303     if (!ld || !message || !attr) return NULL;
304
305     attrU = strWtoU( attr );
306     if (!attrU) return NULL;
307
308     ret = ldap_get_values_len( ld, message, attrU );
309
310     strfreeU( attrU );
311     return (struct WLDAP32_berval **)ret;
312
313 #else
314     return NULL;
315 #endif
316 }
317
318 /***********************************************************************
319  *      ldap_value_free_len     (WLDAP32.@)
320  *
321  * Free an array of berval structures.
322  *
323  * PARAMS
324  *  vals  [I] Array of berval structures.
325  *
326  * RETURNS
327  *  Success: LDAP_SUCCESS
328  *  Failure: An LDAP error code.
329  */
330 ULONG CDECL WLDAP32_ldap_value_free_len( struct WLDAP32_berval **vals )
331 {
332 #ifdef HAVE_LDAP
333
334     TRACE( "(%p)\n", vals );
335     ldap_value_free_len( (struct berval **)vals );
336
337 #endif
338     return WLDAP32_LDAP_SUCCESS;
339 }
340
341 /***********************************************************************
342  *      ldap_value_freeA     (WLDAP32.@)
343  *
344  * See ldap_value_freeW.
345  */
346 ULONG CDECL ldap_value_freeA( PCHAR *vals )
347 {
348     TRACE( "(%p)\n", vals );
349
350     strarrayfreeA( vals );
351     return WLDAP32_LDAP_SUCCESS;
352 }
353
354 /***********************************************************************
355  *      ldap_value_freeW     (WLDAP32.@)
356  *
357  * Free an array of string values.
358  *
359  * PARAMS
360  *  vals  [I] Array of string values.
361  *
362  * RETURNS
363  *  Success: LDAP_SUCCESS
364  *  Failure: An LDAP error code.
365  */
366 ULONG CDECL ldap_value_freeW( PWCHAR *vals )
367 {
368     TRACE( "(%p)\n", vals );
369
370     strarrayfreeW( vals );
371     return WLDAP32_LDAP_SUCCESS;
372 }