mfmediaengine: Remove vertical flipping of video frames.
[wine.git] / dlls / wldap32 / misc.c
blob697f1d3ad5e80f5fdbebb7ed0780b6aac3e81196
1 /*
2 * WLDAP32 - LDAP support for Wine
4 * Copyright 2005 Hans Leidekker
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.
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.
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
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnls.h"
26 #include "winldap.h"
28 #include "wine/debug.h"
29 #include "winldap_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
33 /***********************************************************************
34 * ldap_abandon (WLDAP32.@)
36 * Cancel an asynchronous operation.
38 * PARAMS
39 * ld [I] Pointer to an LDAP context.
40 * msgid [I] ID of the operation to cancel.
42 * RETURNS
43 * Success: LDAP_SUCCESS
44 * Failure: An LDAP error code.
46 ULONG CDECL ldap_abandon( LDAP *ld, ULONG msgid )
48 TRACE( "(%p, %#lx)\n", ld, msgid );
50 if (!ld) return ~0u;
51 else
53 struct ldap_abandon_ext_params params = { CTX(ld), msgid };
54 return map_error( LDAP_CALL( ldap_abandon_ext, &params ));
58 /***********************************************************************
59 * ldap_check_filterA (WLDAP32.@)
61 * See ldap_check_filterW.
63 ULONG CDECL ldap_check_filterA( LDAP *ld, char *filter )
65 ULONG ret;
66 WCHAR *filterW = NULL;
68 TRACE( "(%p, %s)\n", ld, debugstr_a(filter) );
70 if (!ld) return LDAP_PARAM_ERROR;
71 if (filter && !(filterW = strAtoW( filter ))) return LDAP_NO_MEMORY;
73 ret = ldap_check_filterW( ld, filterW );
75 free( filterW );
76 return ret;
79 /***********************************************************************
80 * ldap_check_filterW (WLDAP32.@)
82 * Check filter syntax.
84 * PARAMS
85 * ld [I] Pointer to an LDAP context.
86 * filter [I] Filter string.
88 * RETURNS
89 * Success: LDAP_SUCCESS
90 * Failure: An LDAP error code.
92 ULONG CDECL ldap_check_filterW( LDAP *ld, WCHAR *filter )
94 TRACE( "(%p, %s)\n", ld, debugstr_w(filter) );
96 if (!ld) return LDAP_PARAM_ERROR;
97 return LDAP_SUCCESS; /* FIXME: do some checks */
100 /***********************************************************************
101 * ldap_cleanup (WLDAP32.@)
103 ULONG CDECL ldap_cleanup( HANDLE instance )
105 TRACE( "(%p)\n", instance );
106 return LDAP_SUCCESS;
109 /***********************************************************************
110 * ldap_conn_from_msg (WLDAP32.@)
112 * Get the LDAP context for a given message.
114 * PARAMS
115 * ld [I] Pointer to an LDAP context.
116 * res [I] LDAP message.
118 * RETURNS
119 * Success: Pointer to an LDAP context.
120 * Failure: NULL
122 LDAP * CDECL ldap_conn_from_msg( LDAP *ld, LDAPMessage *res )
124 TRACE( "(%p, %p)\n", ld, res );
126 if (!ld || !res) return NULL;
127 return ld; /* FIXME: not always correct */
130 /***********************************************************************
131 * ldap_count_entries (WLDAP32.@)
133 * Count the number of entries returned from a search.
135 * PARAMS
136 * ld [I] Pointer to an LDAP context.
137 * res [I] LDAP message.
139 * RETURNS
140 * Success: The number of entries.
141 * Failure: ~0u
143 ULONG CDECL ldap_count_entries( LDAP *ld, LDAPMessage *res )
145 TRACE( "(%p, %p)\n", ld, res );
147 if (!ld) return ~0u;
148 else
150 struct ldap_count_entries_params params = { CTX(ld), MSG(res) };
151 return LDAP_CALL( ldap_count_entries, &params );
155 /***********************************************************************
156 * ldap_count_references (WLDAP32.@)
158 * Count the number of references returned from a search.
160 * PARAMS
161 * ld [I] Pointer to an LDAP context.
162 * res [I] LDAP message.
164 * RETURNS
165 * Success: The number of references.
166 * Failure: ~0u
168 ULONG CDECL ldap_count_references( LDAP *ld, LDAPMessage *res )
170 TRACE( "(%p, %p)\n", ld, res );
172 if (!ld) return 0;
173 else
175 struct ldap_count_references_params params = { CTX(ld), MSG(res) };
176 return LDAP_CALL( ldap_count_references, &params );
180 static ULONG get_escape_size( PCHAR src, ULONG srclen )
182 ULONG i, size = 0;
184 if (src)
186 for (i = 0; i < srclen; i++)
188 if ((src[i] >= '0' && src[i] <= '9') ||
189 (src[i] >= 'A' && src[i] <= 'Z') ||
190 (src[i] >= 'a' && src[i] <= 'z'))
191 size++;
192 else
193 size += 3;
196 return size + 1;
199 static void escape_filter_element( char *src, ULONG srclen, char *dst )
201 ULONG i;
202 static const char fmt[] = "\\%02X";
203 char *d = dst;
205 for (i = 0; i < srclen; i++)
207 if ((src[i] >= '0' && src[i] <= '9') ||
208 (src[i] >= 'A' && src[i] <= 'Z') ||
209 (src[i] >= 'a' && src[i] <= 'z'))
210 *d++ = src[i];
211 else
212 d += sprintf( d, fmt, (unsigned char)src[i] );
214 *++d = 0;
217 /***********************************************************************
218 * ldap_escape_filter_elementA (WLDAP32.@)
220 * See ldap_escape_filter_elementW.
222 ULONG CDECL ldap_escape_filter_elementA( char *src, ULONG srclen, char *dst, ULONG dstlen )
224 ULONG len = get_escape_size( src, srclen );
226 TRACE( "(%p, %#lx, %p, %#lx)\n", src, srclen, dst, dstlen );
228 if (!dst) return len;
229 if (!src || dstlen < len) return LDAP_PARAM_ERROR;
231 escape_filter_element( src, srclen, dst );
232 return LDAP_SUCCESS;
235 /***********************************************************************
236 * ldap_escape_filter_elementW (WLDAP32.@)
238 * Escape binary data for safe passing in filters.
240 * PARAMS
241 * src [I] Filter element to be escaped.
242 * srclen [I] Length in bytes of the filter element.
243 * dst [O] Destination buffer for the escaped filter element.
244 * dstlen [I] Length in bytes of the destination buffer.
246 * RETURNS
247 * Success: LDAP_SUCCESS
248 * Failure: An LDAP error code.
250 ULONG CDECL ldap_escape_filter_elementW( char *src, ULONG srclen, WCHAR *dst, ULONG dstlen )
252 ULONG len = get_escape_size( src, srclen );
254 TRACE( "(%p, %#lx, %p, %#lx)\n", src, srclen, dst, dstlen );
256 if (!dst) return len;
258 /* no matter what you throw at it, this is what native returns */
259 return LDAP_PARAM_ERROR;
262 /***********************************************************************
263 * ldap_first_attributeA (WLDAP32.@)
265 * See ldap_first_attributeW.
267 char * CDECL ldap_first_attributeA( LDAP *ld, LDAPMessage *entry, BerElement **ber )
269 char *ret = NULL;
270 WCHAR *retW;
272 TRACE( "(%p, %p, %p)\n", ld, entry, ber );
274 if (!ld || !entry) return NULL;
276 retW = ldap_first_attributeW( ld, entry, ber );
277 if (retW)
279 ret = strWtoA( retW );
280 ldap_memfreeW( retW );
283 return ret;
286 /***********************************************************************
287 * ldap_first_attributeW (WLDAP32.@)
289 * Get the first attribute for a given entry.
291 * PARAMS
292 * ld [I] Pointer to an LDAP context.
293 * entry [I] Entry to retrieve attribute for.
294 * ptr [O] Position pointer.
296 * RETURNS
297 * Success: Name of the first attribute.
298 * Failure: NULL
300 * NOTES
301 * Use ldap_memfree to free the returned string.
303 WCHAR * CDECL ldap_first_attributeW( LDAP *ld, LDAPMessage *entry, BerElement **ptr )
305 WCHAR *ret = NULL;
306 BerElement *ber;
307 char *retU;
308 void *berU;
310 TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
312 if (ld && entry)
314 struct ldap_first_attribute_params params = { CTX(ld), MSG(entry), &berU, &retU };
315 LDAP_CALL( ldap_first_attribute, &params );
317 else return NULL;
319 if (retU && (ber = malloc( sizeof(*ber) )))
321 BER(ber) = (char *)berU;
322 *ptr = ber;
323 ret = strUtoW( retU );
326 LDAP_CALL( ldap_memfree, retU );
327 return ret;
330 /***********************************************************************
331 * ldap_first_entry (WLDAP32.@)
333 * Get the first entry from a result message.
335 * PARAMS
336 * ld [I] Pointer to an LDAP context.
337 * res [I] Search result message.
339 * RETURNS
340 * Success: The first entry.
341 * Failure: NULL
343 * NOTES
344 * The returned entry will be freed when the message is freed.
346 LDAPMessage * CDECL ldap_first_entry( LDAP *ld, LDAPMessage *res )
348 void *msgU;
350 TRACE( "(%p, %p)\n", ld, res );
352 if (ld && res)
354 struct ldap_first_entry_params params = { CTX(ld), MSG(res), &msgU };
355 if (!LDAP_CALL( ldap_first_entry, &params ))
357 assert( msgU == MSG(res) );
358 return res;
361 return NULL;
364 /***********************************************************************
365 * ldap_first_reference (WLDAP32.@)
367 * Get the first reference from a result message.
369 * PARAMS
370 * ld [I] Pointer to an LDAP context.
371 * res [I] Search result message.
373 * RETURNS
374 * Success: The first reference.
375 * Failure: NULL
377 LDAPMessage * CDECL ldap_first_reference( LDAP *ld, LDAPMessage *res )
379 void *msgU;
381 TRACE( "(%p, %p)\n", ld, res );
383 if (ld)
385 struct ldap_first_reference_params params = { CTX(ld), MSG(res), &msgU };
386 if (!LDAP_CALL( ldap_first_reference, &params ))
388 assert( msgU == MSG(res) );
389 return res;
392 return NULL;
395 /***********************************************************************
396 * ldap_memfreeA (WLDAP32.@)
398 * See ldap_memfreeW.
400 void CDECL ldap_memfreeA( char *block )
402 TRACE( "(%p)\n", block );
403 free( block );
406 /***********************************************************************
407 * ldap_memfreeW (WLDAP32.@)
409 * Free a block of memory.
411 * PARAMS
412 * block [I] Pointer to memory block to be freed.
414 void CDECL ldap_memfreeW( WCHAR *block )
416 TRACE( "(%p)\n", block );
417 free( block );
420 /***********************************************************************
421 * ldap_msgfree (WLDAP32.@)
423 * Free a message.
425 * PARAMS
426 * res [I] Message to be freed.
428 ULONG CDECL ldap_msgfree( LDAPMessage *res )
430 LDAPMessage *entry, *list = res;
432 TRACE( "(%p)\n", res );
434 if (!res) return LDAP_SUCCESS;
436 LDAP_CALL( ldap_msgfree, MSG(res) );
437 while (list)
439 entry = list;
440 list = entry->lm_next;
441 free( entry );
444 return LDAP_SUCCESS;
447 /***********************************************************************
448 * ldap_next_attributeA (WLDAP32.@)
450 * See ldap_next_attributeW.
452 char * CDECL ldap_next_attributeA( LDAP *ld, LDAPMessage *entry, BerElement *ptr )
454 char *ret = NULL;
455 WCHAR *retW;
457 TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
459 if (!ld || !entry || !ptr) return NULL;
461 retW = ldap_next_attributeW( ld, entry, ptr );
462 if (retW)
464 ret = strWtoA( retW );
465 ldap_memfreeW( retW );
468 return ret;
471 /***********************************************************************
472 * ldap_next_attributeW (WLDAP32.@)
474 * Get the next attribute for a given entry.
476 * PARAMS
477 * ld [I] Pointer to an LDAP context.
478 * entry [I] Entry to retrieve attribute for.
479 * ptr [I/O] Position pointer.
481 * RETURNS
482 * Success: The name of the next attribute.
483 * Failure: NULL
485 * NOTES
486 * Free the returned string after each iteration with ldap_memfree.
487 * When done iterating and when ptr != NULL, call ber_free( ptr, 0 ).
489 WCHAR * CDECL ldap_next_attributeW( LDAP *ld, LDAPMessage *entry, BerElement *ptr )
491 WCHAR *ret = NULL;
492 char *retU;
494 TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
496 if (ld && entry && ptr)
498 struct ldap_next_attribute_params params = { CTX(ld), MSG(entry), BER(ptr), &retU };
499 if (!LDAP_CALL( ldap_next_attribute, &params ))
501 ret = strUtoW( retU );
502 LDAP_CALL( ldap_memfree, retU );
505 return ret;
508 /***********************************************************************
509 * ldap_next_entry (WLDAP32.@)
511 * Get the next entry from a result message.
513 * PARAMS
514 * ld [I] Pointer to an LDAP context.
515 * entry [I] Entry returned by a previous call.
517 * RETURNS
518 * Success: The next entry.
519 * Failure: NULL
521 * NOTES
522 * The returned entry will be freed when the message is freed.
524 LDAPMessage * CDECL ldap_next_entry( LDAP *ld, LDAPMessage *entry )
526 LDAPMessage *msg = NULL;
527 void *msgU;
529 TRACE( "(%p, %p)\n", ld, entry );
531 if (!ld || !entry) return NULL;
533 if (entry->lm_next) return entry->lm_next;
534 else
536 struct ldap_next_entry_params params = { CTX(ld), MSG(entry), &msgU };
537 LDAP_CALL( ldap_next_entry, &params );
540 if (msgU && (msg = calloc( 1, sizeof(*msg) )))
542 MSG(msg) = msgU;
543 entry->lm_next = msg;
546 return msg;
549 /***********************************************************************
550 * ldap_next_reference (WLDAP32.@)
552 * Get the next reference from a result message.
554 * PARAMS
555 * ld [I] Pointer to an LDAP context.
556 * entry [I] Entry returned by a previous call.
558 * RETURNS
559 * Success: The next reference.
560 * Failure: NULL
562 * NOTES
563 * The returned entry will be freed when the message is freed.
565 LDAPMessage * CDECL ldap_next_reference( LDAP *ld, LDAPMessage *entry )
567 LDAPMessage *msg = NULL;
568 void *msgU;
570 TRACE( "(%p, %p)\n", ld, entry );
572 if (!ld || !entry) return NULL;
574 if (entry->lm_next) return entry->lm_next;
575 else
577 struct ldap_next_reference_params params = { CTX(ld), MSG(entry), &msgU };
578 LDAP_CALL( ldap_next_reference, &params );
580 if (msgU && (msg = calloc( 1, sizeof(*msg) )))
582 MSG(msg) = msgU;
583 entry->lm_next = msg;
586 return msg;
589 /***********************************************************************
590 * ldap_result (WLDAP32.@)
592 * Get the result of an asynchronous operation.
594 * PARAMS
595 * ld [I] Pointer to an LDAP context.
596 * msgid [I] Message ID of the operation.
597 * all [I] How many results should be returned?
598 * timeout [I] How long to wait for the results?
599 * res [O] Result message for the operation.
601 * RETURNS
602 * Success: One of the following values:
604 * LDAP_RES_ADD
605 * LDAP_RES_BIND
606 * LDAP_RES_COMPARE
607 * LDAP_RES_DELETE
608 * LDAP_RES_EXTENDED
609 * LDAP_RES_MODIFY
610 * LDAP_RES_MODRDN
611 * LDAP_RES_REFERRAL
612 * LDAP_RES_SEARCH_ENTRY
613 * LDAP_RES_SEARCH_RESULT
615 * Failure: ~0u
617 * This function returns 0 when the timeout has expired.
619 * NOTES
620 * A NULL timeout pointer causes the function to block waiting
621 * for results to arrive. A timeout value of 0 causes the function
622 * to immediately return any available results. Free returned results
623 * with ldap_msgfree.
625 ULONG CDECL ldap_result( LDAP *ld, ULONG msgid, ULONG all, struct l_timeval *timeout, LDAPMessage **res )
627 LDAPMessage *msg;
628 struct timevalU timeval;
629 void *msgU = NULL;
630 ULONG ret = ~0u;
632 TRACE( "(%p, %#lx, %#lx, %p, %p)\n", ld, msgid, all, timeout, res );
634 if (ld && res && msgid != ~0u)
636 struct ldap_result_params params = { CTX(ld), msgid, all, timeout ? &timeval : NULL, &msgU };
638 if (timeout)
640 timeval.tv_sec = timeout->tv_sec;
641 timeval.tv_usec = timeout->tv_usec;
644 ret = LDAP_CALL( ldap_result, &params );
646 if (msgU && (msg = calloc( 1, sizeof(*msg) )))
648 MSG(msg) = msgU;
649 *res = msg;
652 return ret;
655 /***********************************************************************
656 * LdapUnicodeToUTF8 (WLDAP32.@)
658 * Convert a wide character string to a UTF8 string.
660 * PARAMS
661 * src [I] Wide character string to convert.
662 * srclen [I] Size of string to convert, in characters.
663 * dst [O] Pointer to a buffer that receives the converted string.
664 * dstlen [I] Size of the destination buffer in characters.
666 * RETURNS
667 * The number of characters written into the destination buffer.
669 * NOTES
670 * Set dstlen to zero to ask for the required buffer size.
672 int CDECL LdapUnicodeToUTF8( const WCHAR *src, int srclen, char *dst, int dstlen )
674 return WideCharToMultiByte( CP_UTF8, 0, src, srclen, dst, dstlen, NULL, NULL );
677 /***********************************************************************
678 * LdapUTF8ToUnicode (WLDAP32.@)
680 * Convert a UTF8 string to a wide character string.
682 * PARAMS
683 * src [I] UTF8 string to convert.
684 * srclen [I] Size of string to convert, in characters.
685 * dst [O] Pointer to a buffer that receives the converted string.
686 * dstlen [I] Size of the destination buffer in characters.
688 * RETURNS
689 * The number of characters written into the destination buffer.
691 * NOTES
692 * Set dstlen to zero to ask for the required buffer size.
694 int CDECL LdapUTF8ToUnicode( const char *src, int srclen, WCHAR *dst, int dstlen )
696 return MultiByteToWideChar( CP_UTF8, 0, src, srclen, dst, dstlen );