[WLDAP32]
[reactos.git] / reactos / dll / win32 / wldap32 / ber.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
23 #include <stdarg.h>
24
25 #include <windef.h>
26 #include <winbase.h>
27 #include <winldap.h>
28
29 #include <wine/debug.h>
30 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
31
32 #ifndef LBER_ERROR
33 # define LBER_ERROR (~0U)
34 #endif
35
36 /***********************************************************************
37 * ber_alloc_t (WLDAP32.@)
38 *
39 * Allocate a berelement structure.
40 *
41 * PARAMS
42 * options [I] Must be LBER_USE_DER.
43 *
44 * RETURNS
45 * Success: Pointer to an allocated berelement structure.
46 * Failure: NULL
47 *
48 * NOTES
49 * Free the berelement structure with ber_free.
50 */
51 BerElement * CDECL WLDAP32_ber_alloc_t( INT options )
52 {
53 #ifdef HAVE_LDAP
54 return ber_alloc_t( options );
55 #else
56 return NULL;
57 #endif
58 }
59
60
61 /***********************************************************************
62 * ber_bvdup (WLDAP32.@)
63 *
64 * Copy a berval structure.
65 *
66 * PARAMS
67 * berval [I] Pointer to the berval structure to be copied.
68 *
69 * RETURNS
70 * Success: Pointer to a copy of the berval structure.
71 * Failure: NULL
72 *
73 * NOTES
74 * Free the copy with ber_bvfree.
75 */
76 BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval )
77 {
78 #ifdef HAVE_LDAP
79 return ber_bvdup( berval );
80 #else
81 return NULL;
82 #endif
83 }
84
85
86 /***********************************************************************
87 * ber_bvecfree (WLDAP32.@)
88 *
89 * Free an array of berval structures.
90 *
91 * PARAMS
92 * berval [I] Pointer to an array of berval structures.
93 *
94 * RETURNS
95 * Nothing.
96 *
97 * NOTES
98 * Use this function only to free an array of berval structures
99 * returned by a call to ber_scanf with a 'V' in the format string.
100 */
101 void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval )
102 {
103 #ifdef HAVE_LDAP
104 ber_bvecfree( berval );
105 #endif
106 }
107
108
109 /***********************************************************************
110 * ber_bvfree (WLDAP32.@)
111 *
112 * Free a berval structure.
113 *
114 * PARAMS
115 * berval [I] Pointer to a berval structure.
116 *
117 * RETURNS
118 * Nothing.
119 *
120 * NOTES
121 * Use this function only to free berval structures allocated by
122 * an LDAP API.
123 */
124 void CDECL WLDAP32_ber_bvfree( BERVAL *berval )
125 {
126 #ifdef HAVE_LDAP
127 ber_bvfree( berval );
128 #endif
129 }
130
131
132 /***********************************************************************
133 * ber_first_element (WLDAP32.@)
134 *
135 * Return the tag of the first element in a set or sequence.
136 *
137 * PARAMS
138 * berelement [I] Pointer to a berelement structure.
139 * len [O] Receives the length of the first element.
140 * opaque [O] Receives a pointer to a cookie.
141 *
142 * RETURNS
143 * Success: Tag of the first element.
144 * Failure: LBER_DEFAULT (no more data).
145 *
146 * NOTES
147 * len and cookie should be passed to ber_next_element.
148 */
149 ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR **opaque )
150 {
151 #ifdef HAVE_LDAP
152 return ber_first_element( berelement, len, opaque );
153 #else
154 return LBER_ERROR;
155 #endif
156 }
157
158
159 /***********************************************************************
160 * ber_flatten (WLDAP32.@)
161 *
162 * Flatten a berelement structure into a berval structure.
163 *
164 * PARAMS
165 * berelement [I] Pointer to a berelement structure.
166 * berval [O] Pointer to a berval structure.
167 *
168 * RETURNS
169 * Success: 0
170 * Failure: LBER_ERROR
171 *
172 * NOTES
173 * Free the berval structure with ber_bvfree.
174 */
175 INT CDECL WLDAP32_ber_flatten( BerElement *berelement, PBERVAL *berval )
176 {
177 #ifdef HAVE_LDAP
178 return ber_flatten( berelement, berval );
179 #else
180 return LBER_ERROR;
181 #endif
182 }
183
184
185 /***********************************************************************
186 * ber_free (WLDAP32.@)
187 *
188 * Free a berelement structure.
189 *
190 * PARAMS
191 * berelement [I] Pointer to the berelement structure to be freed.
192 * buf [I] Flag.
193 *
194 * RETURNS
195 * Nothing.
196 *
197 * NOTES
198 * Set buf to 0 if the berelement was allocated with ldap_first_attribute
199 * or ldap_next_attribute, otherwise set it to 1.
200 */
201 void CDECL WLDAP32_ber_free( BerElement *berelement, INT buf )
202 {
203 #ifdef HAVE_LDAP
204 ber_free( berelement, buf );
205 #endif
206 }
207
208
209 /***********************************************************************
210 * ber_init (WLDAP32.@)
211 *
212 * Initialise a berelement structure from a berval structure.
213 *
214 * PARAMS
215 * berval [I] Pointer to a berval structure.
216 *
217 * RETURNS
218 * Success: Pointer to a berelement structure.
219 * Failure: NULL
220 *
221 * NOTES
222 * Call ber_free to free the returned berelement structure.
223 */
224 BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
225 {
226 #ifdef HAVE_LDAP
227 return ber_init( berval );
228 #else
229 return NULL;
230 #endif
231 }
232
233
234 /***********************************************************************
235 * ber_next_element (WLDAP32.@)
236 *
237 * Return the tag of the next element in a set or sequence.
238 *
239 * PARAMS
240 * berelement [I] Pointer to a berelement structure.
241 * len [I/O] Receives the length of the next element.
242 * opaque [I/O] Pointer to a cookie.
243 *
244 * RETURNS
245 * Success: Tag of the next element.
246 * Failure: LBER_DEFAULT (no more data).
247 *
248 * NOTES
249 * len and cookie are initialized by ber_first_element and should
250 * be passed on in subsequent calls to ber_next_element.
251 */
252 ULONG CDECL WLDAP32_ber_next_element( BerElement *berelement, ULONG *len, CHAR *opaque )
253 {
254 #ifdef HAVE_LDAP
255 return ber_next_element( berelement, len, opaque );
256 #else
257 return LBER_ERROR;
258 #endif
259 }
260
261
262 /***********************************************************************
263 * ber_peek_tag (WLDAP32.@)
264 *
265 * Return the tag of the next element.
266 *
267 * PARAMS
268 * berelement [I] Pointer to a berelement structure.
269 * len [O] Receives the length of the next element.
270 *
271 * RETURNS
272 * Success: Tag of the next element.
273 * Failure: LBER_DEFAULT (no more data).
274 */
275 ULONG CDECL WLDAP32_ber_peek_tag( BerElement *berelement, ULONG *len )
276 {
277 #ifdef HAVE_LDAP
278 return ber_peek_tag( berelement, len );
279 #else
280 return LBER_ERROR;
281 #endif
282 }
283
284
285 /***********************************************************************
286 * ber_skip_tag (WLDAP32.@)
287 *
288 * Skip the current tag and return the tag of the next element.
289 *
290 * PARAMS
291 * berelement [I] Pointer to a berelement structure.
292 * len [O] Receives the length of the skipped element.
293 *
294 * RETURNS
295 * Success: Tag of the next element.
296 * Failure: LBER_DEFAULT (no more data).
297 */
298 ULONG CDECL WLDAP32_ber_skip_tag( BerElement *berelement, ULONG *len )
299 {
300 #ifdef HAVE_LDAP
301 return ber_skip_tag( berelement, len );
302 #else
303 return LBER_ERROR;
304 #endif
305 }
306
307
308 /***********************************************************************
309 * ber_printf (WLDAP32.@)
310 *
311 * Encode a berelement structure.
312 *
313 * PARAMS
314 * berelement [I/O] Pointer to a berelement structure.
315 * fmt [I] Format string.
316 * ... [I] Values to encode.
317 *
318 * RETURNS
319 * Success: Non-negative number.
320 * Failure: LBER_ERROR
321 *
322 * NOTES
323 * berelement must have been allocated with ber_alloc_t. This function
324 * can be called multiple times to append data.
325 */
326 INT CDECL WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... )
327 {
328 #ifdef HAVE_LDAP
329 __ms_va_list list;
330 int ret = 0;
331 char new_fmt[2];
332
333 new_fmt[1] = 0;
334 __ms_va_start( list, fmt );
335 while (*fmt)
336 {
337 new_fmt[0] = *fmt++;
338 switch(new_fmt[0])
339 {
340 case 'b':
341 case 'e':
342 case 'i':
343 {
344 int i = va_arg( list, int );
345 ret = ber_printf( berelement, new_fmt, i );
346 break;
347 }
348 case 'o':
349 case 's':
350 {
351 char *str = va_arg( list, char * );
352 ret = ber_printf( berelement, new_fmt, str );
353 break;
354 }
355 case 't':
356 {
357 unsigned int tag = va_arg( list, unsigned int );
358 ret = ber_printf( berelement, new_fmt, tag );
359 break;
360 }
361 case 'v':
362 {
363 char **array = va_arg( list, char ** );
364 ret = ber_printf( berelement, new_fmt, array );
365 break;
366 }
367 case 'V':
368 {
369 struct berval **array = va_arg( list, struct berval ** );
370 ret = ber_printf( berelement, new_fmt, array );
371 break;
372 }
373 case 'X':
374 {
375 char *str = va_arg( list, char * );
376 int len = va_arg( list, int );
377 new_fmt[0] = 'B'; /* 'X' is deprecated */
378 ret = ber_printf( berelement, new_fmt, str, len );
379 break;
380 }
381 case 'n':
382 case '{':
383 case '}':
384 case '[':
385 case ']':
386 ret = ber_printf( berelement, new_fmt );
387 break;
388 default:
389 FIXME( "Unknown format '%c'\n", new_fmt[0] );
390 ret = -1;
391 break;
392 }
393 if (ret == -1) break;
394 }
395 __ms_va_end( list );
396 return ret;
397 #else
398 return LBER_ERROR;
399 #endif
400 }
401
402
403 /***********************************************************************
404 * ber_scanf (WLDAP32.@)
405 *
406 * Decode a berelement structure.
407 *
408 * PARAMS
409 * berelement [I/O] Pointer to a berelement structure.
410 * fmt [I] Format string.
411 * ... [I] Pointers to values to be decoded.
412 *
413 * RETURNS
414 * Success: Non-negative number.
415 * Failure: LBER_ERROR
416 *
417 * NOTES
418 * berelement must have been allocated with ber_init. This function
419 * can be called multiple times to decode data.
420 */
421 INT CDECL WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... )
422 {
423 #ifdef HAVE_LDAP
424 __ms_va_list list;
425 int ret = 0;
426 char new_fmt[2];
427
428 new_fmt[1] = 0;
429 __ms_va_start( list, fmt );
430 while (*fmt)
431 {
432 new_fmt[0] = *fmt++;
433 switch(new_fmt[0])
434 {
435 case 'a':
436 {
437 char **ptr = va_arg( list, char ** );
438 ret = ber_scanf( berelement, new_fmt, ptr );
439 break;
440 }
441 case 'b':
442 case 'e':
443 case 'i':
444 {
445 int *i = va_arg( list, int * );
446 ret = ber_scanf( berelement, new_fmt, i );
447 break;
448 }
449 case 't':
450 {
451 unsigned int *tag = va_arg( list, unsigned int * );
452 ret = ber_scanf( berelement, new_fmt, tag );
453 break;
454 }
455 case 'v':
456 {
457 char ***array = va_arg( list, char *** );
458 ret = ber_scanf( berelement, new_fmt, array );
459 break;
460 }
461 case 'B':
462 {
463 char **str = va_arg( list, char ** );
464 int *len = va_arg( list, int * );
465 ret = ber_scanf( berelement, new_fmt, str, len );
466 break;
467 }
468 case 'O':
469 {
470 struct berval **ptr = va_arg( list, struct berval ** );
471 ret = ber_scanf( berelement, new_fmt, ptr );
472 break;
473 }
474 case 'V':
475 {
476 struct berval ***array = va_arg( list, struct berval *** );
477 ret = ber_scanf( berelement, new_fmt, array );
478 break;
479 }
480 case 'n':
481 case 'x':
482 case '{':
483 case '}':
484 case '[':
485 case ']':
486 ret = ber_scanf( berelement, new_fmt );
487 break;
488 default:
489 FIXME( "Unknown format '%c'\n", new_fmt[0] );
490 ret = -1;
491 break;
492 }
493 if (ret == -1) break;
494 }
495 __ms_va_end( list );
496 return ret;
497 #else
498 return LBER_ERROR;
499 #endif
500 }