wldap32: Implement some page handling functions.
[wine] / dlls / wldap32 / misc.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include "wine/port.h"
24 #include "wine/debug.h"
25
26 #include <stdarg.h>
27 #include <stdio.h>
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winnls.h"
32
33 #ifdef HAVE_LDAP_H
34 #include <ldap.h>
35 #else
36 #define LDAP_SUCCESS        0x00
37 #define LDAP_NOT_SUPPORTED  0x5c
38 #endif
39
40 #include "winldap_private.h"
41 #include "wldap32.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
44
45 ULONG WLDAP32_ldap_abandon( WLDAP32_LDAP *ld, ULONG msgid )
46 {
47     ULONG ret = LDAP_NOT_SUPPORTED;
48 #ifdef HAVE_LDAP
49
50     TRACE( "(%p, 0x%08lx)\n", ld, msgid );
51
52     if (!ld) return ~0UL;
53     ret = ldap_abandon_ext( ld, msgid, NULL, NULL );
54
55 #endif
56     return ret;
57 }
58
59 ULONG ldap_check_filterA( WLDAP32_LDAP *ld, PCHAR filter )
60 {
61     ULONG ret;
62     WCHAR *filterW = NULL;
63
64     TRACE( "(%p, %s)\n", ld, debugstr_a(filter) );
65
66     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
67
68     if (filter) {
69         filterW = strAtoW( filter );
70         if (!filterW) return WLDAP32_LDAP_NO_MEMORY;
71     }
72
73     ret = ldap_check_filterW( ld, filterW );
74
75     strfreeW( filterW );
76     return ret;
77 }
78
79 ULONG ldap_check_filterW( WLDAP32_LDAP *ld, PWCHAR filter )
80 {
81     TRACE( "(%p, %s)\n", ld, debugstr_w(filter) );
82
83     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
84     return LDAP_SUCCESS; /* FIXME: do some checks */
85 }
86
87 ULONG ldap_cleanup( HANDLE instance )
88 {
89     TRACE( "(%p)\n", instance );
90     return LDAP_SUCCESS;
91 }
92
93 WLDAP32_LDAP *ldap_conn_from_msg( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *res )
94 {
95     TRACE( "(%p, %p)\n", ld, res );
96
97     if (!ld || !res) return NULL;
98     return ld; /* FIXME: not always correct */
99 }
100
101 ULONG WLDAP32_ldap_count_entries( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *res )
102 {
103     ULONG ret = LDAP_NOT_SUPPORTED;
104 #ifdef HAVE_LDAP
105
106     TRACE( "(%p, %p)\n", ld, res );
107
108     if (!ld) return ~0UL;
109     ret = ldap_count_entries( ld, res );
110
111 #endif
112     return ret;
113 }
114
115 ULONG WLDAP32_ldap_count_references( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *res )
116 {
117     ULONG ret = LDAP_NOT_SUPPORTED;
118 #ifdef HAVE_LDAP_COUNT_REFERENCES
119
120     TRACE( "(%p, %p)\n", ld, res );
121
122     if (!ld) return 0;
123     ret = ldap_count_references( ld, res );
124
125 #endif
126     return ret;
127 }
128
129 static ULONG get_escape_size( PCHAR src, ULONG srclen )
130 {
131     ULONG i, size = 0;
132
133     if (src)
134     {
135         for (i = 0; i < srclen; i++)
136         {
137             if ((src[i] >= '0' && src[i] <= '9') ||
138                 (src[i] >= 'A' && src[i] <= 'Z') ||
139                 (src[i] >= 'a' && src[i] <= 'z'))
140                 size++;
141             else
142                 size += 3;
143         }
144     }
145     return size + 1;
146 }
147
148 static void escape_filter_element( PCHAR src, ULONG srclen, PCHAR dst )
149 {
150     ULONG i;
151     char fmt[] = "\\%02X";
152     char *d = dst;
153
154     for (i = 0; i < srclen; i++)
155     {
156         if ((src[i] >= '0' && src[i] <= '9') ||
157             (src[i] >= 'A' && src[i] <= 'Z') ||
158             (src[i] >= 'a' && src[i] <= 'z'))
159             *d++ = src[i];
160         else
161         {
162             sprintf( d, fmt, (unsigned char)src[i] );
163             d += 3;
164         }
165     }
166     *++d = 0;
167 }
168
169 ULONG ldap_escape_filter_elementA( PCHAR src, ULONG srclen, PCHAR dst, ULONG dstlen )
170 {
171     ULONG len;
172
173     TRACE( "(%p, 0x%08lx, %p, 0x%08lx)\n", src, srclen, dst, dstlen );
174
175     len = get_escape_size( src, srclen );
176     if (!dst) return len;
177
178     if (!src || dstlen < len)
179         return WLDAP32_LDAP_PARAM_ERROR;
180     else
181     {
182         escape_filter_element( src, srclen, dst );
183         return LDAP_SUCCESS;
184     }
185 }
186
187 ULONG ldap_escape_filter_elementW( PCHAR src, ULONG srclen, PWCHAR dst, ULONG dstlen )
188 {
189     ULONG len;
190
191     TRACE( "(%p, 0x%08lx, %p, 0x%08lx)\n", src, srclen, dst, dstlen );
192
193     len = get_escape_size( src, srclen );
194     if (!dst) return len;
195
196     /* no matter what you throw at it, this is what native returns */
197     return WLDAP32_LDAP_PARAM_ERROR;
198 }
199
200 PCHAR ldap_first_attributeA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry,
201     WLDAP32_BerElement** ptr )
202 {
203     PCHAR ret = NULL;
204 #ifdef HAVE_LDAP
205     WCHAR *retW;
206
207     TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
208
209     if (!ld || !entry) return NULL;
210     retW = ldap_first_attributeW( ld, entry, ptr );
211
212     ret = strWtoA( retW );
213     ldap_memfreeW( retW );
214
215 #endif
216     return ret;
217 }
218
219 PWCHAR ldap_first_attributeW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry,
220     WLDAP32_BerElement** ptr )
221 {
222     PWCHAR ret = NULL;
223 #ifdef HAVE_LDAP
224     char *retU;
225
226     TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
227
228     if (!ld || !entry) return NULL;
229     retU = ldap_first_attribute( ld, entry, ptr );
230
231     ret = strUtoW( retU );
232     ldap_memfree( retU );
233
234 #endif
235     return ret;
236 }
237
238 WLDAP32_LDAPMessage *WLDAP32_ldap_first_entry( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *res )
239 {
240 #ifdef HAVE_LDAP
241
242     TRACE( "(%p, %p)\n", ld, res );
243
244     if (!ld || !res) return NULL;
245     return ldap_first_entry( ld, res );
246
247 #endif
248     return NULL;
249 }
250
251 WLDAP32_LDAPMessage *WLDAP32_ldap_first_reference( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *res )
252 {
253 #ifdef HAVE_LDAP_FIRST_REFERENCE
254
255     TRACE( "(%p, %p)\n", ld, res );
256
257     if (!ld) return NULL;
258     return ldap_first_reference( ld, res );
259
260 #endif
261     return NULL;
262 }
263
264 void ldap_memfreeA( PCHAR block )
265 {
266     TRACE( "(%p)\n", block );
267     strfreeA( block );
268 }
269
270 void ldap_memfreeW( PWCHAR block )
271 {
272     TRACE( "(%p)\n", block );
273     strfreeW( block );
274 }
275
276 ULONG WLDAP32_ldap_msgfree( WLDAP32_LDAPMessage *res )
277 {
278     ULONG ret = LDAP_SUCCESS;
279 #ifdef HAVE_LDAP
280
281     TRACE( "(%p)\n", res );
282     ldap_msgfree( res );
283
284 #endif
285     return ret;
286 }
287
288 PCHAR ldap_next_attributeA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry,
289     WLDAP32_BerElement *ptr )
290 {
291     PCHAR ret = NULL;
292 #ifdef HAVE_LDAP
293     WCHAR *retW;
294
295     TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
296
297     if (!ld || !entry || !ptr) return NULL;
298     retW = ldap_next_attributeW( ld, entry, ptr );
299
300     ret = strWtoA( retW );
301     ldap_memfreeW( retW );
302
303 #endif
304     return ret;
305 }
306
307 PWCHAR ldap_next_attributeW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry,
308     WLDAP32_BerElement *ptr )
309 {
310     PWCHAR ret = NULL;
311 #ifdef HAVE_LDAP
312     char *retU;
313
314     TRACE( "(%p, %p, %p)\n", ld, entry, ptr );
315
316     if (!ld || !entry || !ptr) return NULL;
317     retU = ldap_next_attribute( ld, entry, ptr );
318
319     ret = strUtoW( retU );
320     ldap_memfree( retU );
321
322 #endif
323     return ret;
324 }
325
326 WLDAP32_LDAPMessage *WLDAP32_ldap_next_entry( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry )
327 {
328 #ifdef HAVE_LDAP
329
330     TRACE( "(%p, %p)\n", ld, entry );
331
332     if (!ld || !entry) return NULL;
333     return ldap_next_entry( ld, entry );
334
335 #endif
336     return NULL;
337 }
338
339 WLDAP32_LDAPMessage *WLDAP32_ldap_next_reference( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry )
340 {
341 #ifdef HAVE_LDAP_NEXT_REFERENCE
342
343     TRACE( "(%p, %p)\n", ld, entry );
344
345     if (!ld || !entry) return NULL;
346     return ldap_next_reference( ld, entry );
347
348 #endif
349     return NULL;
350 }
351
352 ULONG WLDAP32_ldap_result( WLDAP32_LDAP *ld, ULONG msgid, ULONG all,
353     struct l_timeval *timeout, WLDAP32_LDAPMessage **res )
354 {
355     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
356 #ifdef HAVE_LDAP
357
358     TRACE( "(%p, 0x%08lx, 0x%08lx, %p, %p)\n", ld, msgid, all, timeout, res );
359
360     if (!ld || !res || msgid == ~0UL) return ~0UL;
361     ret = ldap_result( ld, msgid, all, (struct timeval *)timeout, res );
362
363 #endif
364     return ret;
365 }
366
367 int LdapUnicodeToUTF8( LPCWSTR src, int srclen, LPSTR dst, int dstlen )
368 {
369     return WideCharToMultiByte( CP_UTF8, 0, src, srclen, dst, dstlen, NULL, NULL );
370 }
371
372 int LdapUTF8ToUnicode( LPCSTR src, int srclen, LPWSTR dst, int dstlen )
373 {
374     return MultiByteToWideChar( CP_UTF8, 0, src, srclen, dst, dstlen );
375 }