winenas.drv: Add workaround for INT64 type too.
[wine] / dlls / wldap32 / wldap32.h
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 /* A set of helper functions to convert LDAP data structures
22  * to and from ansi (A), wide character (W) and utf8 (U) encodings.
23  */
24
25 static inline char *strdupU( const char *src )
26 {
27     char *dst;
28
29     if (!src) return NULL;
30     dst = HeapAlloc( GetProcessHeap(), 0, (strlen( src ) + 1) * sizeof(char) );
31     if (dst)
32         strcpy( dst, src );
33     return dst;
34 }
35
36 static inline LPWSTR strAtoW( LPCSTR str )
37 {
38     LPWSTR ret = NULL;
39     if (str)
40     {
41         DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
42         if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
43             MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
44     }
45     return ret;
46 }
47
48 static inline LPSTR strWtoA( LPCWSTR str )
49 {
50     LPSTR ret = NULL;
51     if (str)
52     {
53         DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
54         if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
55             WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
56     }
57     return ret;
58 }
59
60 static inline char *strWtoU( LPCWSTR str )
61 {
62     LPSTR ret = NULL;
63     if (str)
64     {
65         DWORD len = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
66         if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
67             WideCharToMultiByte( CP_UTF8, 0, str, -1, ret, len, NULL, NULL );
68     }
69     return ret;
70 }
71
72 static inline LPWSTR strUtoW( char *str )
73 {
74     LPWSTR ret = NULL;
75     if (str)
76     {
77         DWORD len = MultiByteToWideChar( CP_UTF8, 0, str, -1, NULL, 0 );
78         if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
79             MultiByteToWideChar( CP_UTF8, 0, str, -1, ret, len );
80     }
81     return ret;
82 }
83
84 static inline void strfreeA( LPSTR str )
85 {
86     HeapFree( GetProcessHeap(), 0, str );
87 }
88
89 static inline void strfreeW( LPWSTR str )
90 {
91     HeapFree( GetProcessHeap(), 0, str );
92 }
93
94 static inline void strfreeU( char *str )
95 {
96     HeapFree( GetProcessHeap(), 0, str );
97 }
98
99 static inline DWORD strarraylenA( LPSTR *strarray )
100 {
101     LPSTR *p = strarray;
102     while (*p) p++;
103     return p - strarray;
104 }
105
106 static inline DWORD strarraylenW( LPWSTR *strarray )
107 {
108     LPWSTR *p = strarray;
109     while (*p) p++;
110     return p - strarray;
111 }
112
113 static inline DWORD strarraylenU( char **strarray )
114 {
115     char **p = strarray;
116     while (*p) p++;
117     return p - strarray;
118 }
119
120 static inline LPWSTR *strarrayAtoW( LPSTR *strarray )
121 {
122     LPWSTR *strarrayW = NULL;
123     DWORD size;
124
125     if (strarray)
126     {
127         size  = sizeof(WCHAR*) * (strarraylenA( strarray ) + 1);
128         strarrayW = HeapAlloc( GetProcessHeap(), 0, size );
129
130         if (strarrayW)
131         {
132             LPSTR *p = strarray;
133             LPWSTR *q = strarrayW;
134
135             while (*p) *q++ = strAtoW( *p++ );
136             *q = NULL;
137         }
138     }
139     return strarrayW;
140 }
141
142 static inline LPSTR *strarrayWtoA( LPWSTR *strarray )
143 {
144     LPSTR *strarrayA = NULL;
145     DWORD size;
146
147     if (strarray)
148     {
149         size = sizeof(LPSTR) * (strarraylenW( strarray ) + 1);
150         strarrayA = HeapAlloc( GetProcessHeap(), 0, size );
151
152         if (strarrayA)
153         {
154             LPWSTR *p = strarray;
155             LPSTR *q = strarrayA;
156
157             while (*p) *q++ = strWtoA( *p++ );
158             *q = NULL;
159         }
160     }
161     return strarrayA;
162 }
163
164 static inline char **strarrayWtoU( LPWSTR *strarray )
165 {
166     char **strarrayU = NULL;
167     DWORD size;
168
169     if (strarray)
170     {
171         size = sizeof(char*) * (strarraylenW( strarray ) + 1);
172         strarrayU = HeapAlloc( GetProcessHeap(), 0, size );
173
174         if (strarrayU)
175         {
176             LPWSTR *p = strarray;
177             char **q = strarrayU;
178
179             while (*p) *q++ = strWtoU( *p++ );
180             *q = NULL;
181         }
182     }
183     return strarrayU;
184 }
185
186 static inline LPWSTR *strarrayUtoW( char **strarray )
187 {
188     LPWSTR *strarrayW = NULL;
189     DWORD size;
190
191     if (strarray)
192     {
193         size = sizeof(WCHAR*) * (strarraylenU( strarray ) + 1);
194         strarrayW = HeapAlloc( GetProcessHeap(), 0, size );
195
196         if (strarrayW)
197         {
198             char **p = strarray;
199             LPWSTR *q = strarrayW;
200
201             while (*p) *q++ = strUtoW( *p++ );
202             *q = NULL;
203         }
204     }
205     return strarrayW;
206 }
207
208 static inline void strarrayfreeA( LPSTR *strarray )
209 {
210     if (strarray)
211     {
212         LPSTR *p = strarray;
213         while (*p) strfreeA( *p++ );
214         HeapFree( GetProcessHeap(), 0, strarray );
215     }
216 }
217
218 static inline void strarrayfreeW( LPWSTR *strarray )
219 {
220     if (strarray)
221     {
222         LPWSTR *p = strarray;
223         while (*p) strfreeW( *p++ );
224         HeapFree( GetProcessHeap(), 0, strarray );
225     }
226 }
227
228 static inline void strarrayfreeU( char **strarray )
229 {
230     if (strarray)
231     {
232         char **p = strarray;
233         while (*p) strfreeU( *p++ );
234         HeapFree( GetProcessHeap(), 0, strarray );
235     }
236 }
237
238 #ifdef HAVE_LDAP
239
240 static inline struct berval *bvdup( struct berval *bv )
241 {
242     struct berval *berval;
243     DWORD size = sizeof(struct berval) + bv->bv_len;
244
245     berval = HeapAlloc( GetProcessHeap(), 0, size );
246     if (berval)
247     {
248         char *val = (char *)berval + sizeof(struct berval);
249
250         berval->bv_len = bv->bv_len;
251         berval->bv_val = val;
252         memcpy( val, bv->bv_val, bv->bv_len );
253     }
254     return berval;
255 }
256
257 static inline DWORD bvarraylen( struct berval **bv )
258 {
259     struct berval **p = bv;
260     while (*p) p++;
261     return p - bv;
262 }
263
264 static inline struct berval **bvarraydup( struct berval **bv )
265 {
266     struct berval **berval = NULL;
267     DWORD size;
268
269     if (bv)
270     {
271         size = sizeof(struct berval *) * (bvarraylen( bv ) + 1);
272         berval = HeapAlloc( GetProcessHeap(), 0, size );
273
274         if (berval)
275         {
276             struct berval **p = bv;
277             struct berval **q = berval;
278
279             while (*p) *q++ = bvdup( *p++ );
280             *q = NULL;
281         }
282     }
283     return berval;
284 }
285
286 static inline void bvarrayfree( struct berval **bv )
287 {
288     struct berval **p = bv;
289     while (*p) HeapFree( GetProcessHeap(), 0, *p++ );
290     HeapFree( GetProcessHeap(), 0, bv );
291 }
292
293 static inline LDAPModW *modAtoW( LDAPModA *mod )
294 {
295     LDAPModW *modW;
296
297     modW = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPModW) );
298     if (modW)
299     {
300         modW->mod_op = mod->mod_op;
301         modW->mod_type = strAtoW( mod->mod_type );
302
303         if (mod->mod_op & LDAP_MOD_BVALUES)
304             modW->mod_vals.modv_bvals = bvarraydup( mod->mod_vals.modv_bvals );
305         else
306             modW->mod_vals.modv_strvals = strarrayAtoW( mod->mod_vals.modv_strvals );
307     }
308     return modW;
309 }
310
311 static inline LDAPMod *modWtoU( LDAPModW *mod )
312 {
313     LDAPMod *modU;
314
315     modU = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPMod) );
316     if (modU)
317     {
318         modU->mod_op = mod->mod_op;
319         modU->mod_type = strWtoU( mod->mod_type );
320
321         if (mod->mod_op & LDAP_MOD_BVALUES)
322             modU->mod_vals.modv_bvals = bvarraydup( mod->mod_vals.modv_bvals );
323         else
324             modU->mod_vals.modv_strvals = strarrayWtoU( mod->mod_vals.modv_strvals );
325     }
326     return modU;
327 }
328
329 static inline void modfreeW( LDAPModW *mod )
330 {
331     if (mod->mod_op & LDAP_MOD_BVALUES)
332         bvarrayfree( mod->mod_vals.modv_bvals );
333     else
334         strarrayfreeW( mod->mod_vals.modv_strvals );
335     HeapFree( GetProcessHeap(), 0, mod );
336 }
337
338 static inline void modfreeU( LDAPMod *mod )
339 {
340     if (mod->mod_op & LDAP_MOD_BVALUES)
341         bvarrayfree( mod->mod_vals.modv_bvals );
342     else
343         strarrayfreeU( mod->mod_vals.modv_strvals );
344     HeapFree( GetProcessHeap(), 0, mod );
345 }
346
347 static inline DWORD modarraylenA( LDAPModA **modarray )
348 {
349     LDAPModA **p = modarray;
350     while (*p) p++;
351     return p - modarray;
352 }
353
354 static inline DWORD modarraylenW( LDAPModW **modarray )
355 {
356     LDAPModW **p = modarray;
357     while (*p) p++;
358     return p - modarray;
359 }
360
361 static inline LDAPModW **modarrayAtoW( LDAPModA **modarray )
362 {
363     LDAPModW **modarrayW = NULL;
364     DWORD size;
365
366     if (modarray)
367     {
368         size = sizeof(LDAPModW*) * (modarraylenA( modarray ) + 1);
369         modarrayW = HeapAlloc( GetProcessHeap(), 0, size );
370
371         if (modarrayW)
372         {
373             LDAPModA **p = modarray;
374             LDAPModW **q = modarrayW;
375
376             while (*p) *q++ = modAtoW( *p++ );
377             *q = NULL;
378         }
379     }
380     return modarrayW;
381 }
382
383 static inline LDAPMod **modarrayWtoU( LDAPModW **modarray )
384 {
385     LDAPMod **modarrayU = NULL;
386     DWORD size;
387
388     if (modarray)
389     {
390         size = sizeof(LDAPMod*) * (modarraylenW( modarray ) + 1);
391         modarrayU = HeapAlloc( GetProcessHeap(), 0, size );
392
393         if (modarrayU)
394         {
395             LDAPModW **p = modarray;
396             LDAPMod **q = modarrayU;
397
398             while (*p) *q++ = modWtoU( *p++ );
399             *q = NULL;
400         }
401     }
402     return modarrayU;
403 }
404
405 static inline void modarrayfreeW( LDAPModW **modarray )
406 {
407     if (modarray)
408     {
409         LDAPModW **p = modarray;
410         while (*p) modfreeW( *p++ );
411         HeapFree( GetProcessHeap(), 0, modarray );
412     }
413 }
414
415 static inline void modarrayfreeU( LDAPMod **modarray )
416 {
417     if (modarray)
418     {
419         LDAPMod **p = modarray;
420         while (*p) modfreeU( *p++ );
421         HeapFree( GetProcessHeap(), 0, modarray );
422     }
423 }
424
425 static inline LDAPControlW *controlAtoW( LDAPControlA *control )
426 {
427     LDAPControlW *controlW;
428     DWORD len = control->ldctl_value.bv_len;
429     char *val = NULL;
430
431     if (control->ldctl_value.bv_val)
432     {
433         val = HeapAlloc( GetProcessHeap(), 0, len );
434         if (!val) return NULL;
435         memcpy( val, control->ldctl_value.bv_val, len );
436     }
437
438     controlW = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPControlW) );
439     if (!controlW)
440     {
441         HeapFree( GetProcessHeap(), 0, val );
442         return NULL;
443     }
444
445     controlW->ldctl_oid = strAtoW( control->ldctl_oid );
446     controlW->ldctl_value.bv_len = len; 
447     controlW->ldctl_value.bv_val = val; 
448     controlW->ldctl_iscritical = control->ldctl_iscritical;
449
450     return controlW;
451 }
452
453 static inline LDAPControlA *controlWtoA( LDAPControlW *control )
454 {
455     LDAPControlA *controlA;
456     DWORD len = control->ldctl_value.bv_len;
457     char *val = NULL;
458
459     if (control->ldctl_value.bv_val)
460     {
461         val = HeapAlloc( GetProcessHeap(), 0, len );
462         if (!val) return NULL;
463         memcpy( val, control->ldctl_value.bv_val, len );
464     }
465
466     controlA = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPControlA) );
467     if (!controlA)
468     {
469         HeapFree( GetProcessHeap(), 0, val );
470         return NULL;
471     }
472
473     controlA->ldctl_oid = strWtoA( control->ldctl_oid );
474     controlA->ldctl_value.bv_len = len; 
475     controlA->ldctl_value.bv_val = val;
476     controlA->ldctl_iscritical = control->ldctl_iscritical;
477
478     return controlA;
479 }
480
481 static inline LDAPControl *controlWtoU( LDAPControlW *control )
482 {
483     LDAPControl *controlU;
484     DWORD len = control->ldctl_value.bv_len;
485     char *val = NULL;
486
487     if (control->ldctl_value.bv_val)
488     {
489         val = HeapAlloc( GetProcessHeap(), 0, len );
490         if (!val) return NULL;
491         memcpy( val, control->ldctl_value.bv_val, len );
492     }
493
494     controlU = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPControl) );
495     if (!controlU)
496     {
497         HeapFree( GetProcessHeap(), 0, val );
498         return NULL;
499     }
500
501     controlU->ldctl_oid = strWtoU( control->ldctl_oid );
502     controlU->ldctl_value.bv_len = len; 
503     controlU->ldctl_value.bv_val = val; 
504     controlU->ldctl_iscritical = control->ldctl_iscritical;
505
506     return controlU;
507 }
508
509 static inline LDAPControlW *controlUtoW( LDAPControl *control )
510 {
511     LDAPControlW *controlW;
512     DWORD len = control->ldctl_value.bv_len;
513     char *val = NULL;
514
515     if (control->ldctl_value.bv_val)
516     {
517         val = HeapAlloc( GetProcessHeap(), 0, len );
518         if (!val) return NULL;
519         memcpy( val, control->ldctl_value.bv_val, len );
520     }
521
522     controlW = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPControlW) );
523     if (!controlW)
524     {
525         HeapFree( GetProcessHeap(), 0, val );
526         return NULL;
527     }
528
529     controlW->ldctl_oid = strUtoW( control->ldctl_oid );
530     controlW->ldctl_value.bv_len = len; 
531     controlW->ldctl_value.bv_val = val; 
532     controlW->ldctl_iscritical = control->ldctl_iscritical;
533  
534     return controlW;
535 }
536
537 static inline void controlfreeA( LDAPControlA *control )
538 {
539     if (control)
540     {
541         strfreeA( control->ldctl_oid );
542         HeapFree( GetProcessHeap(), 0, control->ldctl_value.bv_val );
543         HeapFree( GetProcessHeap(), 0, control );
544     }
545 }
546
547 static inline void controlfreeW( LDAPControlW *control )
548 {
549     if (control)
550     {
551         strfreeW( control->ldctl_oid );
552         HeapFree( GetProcessHeap(), 0, control->ldctl_value.bv_val );
553         HeapFree( GetProcessHeap(), 0, control );
554     }
555 }
556
557 static inline void controlfreeU( LDAPControl *control )
558 {
559     if (control)
560     {
561         strfreeU( control->ldctl_oid );
562         HeapFree( GetProcessHeap(), 0, control->ldctl_value.bv_val );
563         HeapFree( GetProcessHeap(), 0, control );
564     }
565 }
566
567 static inline DWORD controlarraylenA( LDAPControlA **controlarray )
568 {
569     LDAPControlA **p = controlarray;
570     while (*p) p++;
571     return p - controlarray;
572 }
573
574 static inline DWORD controlarraylenW( LDAPControlW **controlarray )
575 {
576     LDAPControlW **p = controlarray;
577     while (*p) p++;
578     return p - controlarray;
579 }
580
581 static inline DWORD controlarraylenU( LDAPControl **controlarray )
582 {
583     LDAPControl **p = controlarray;
584     while (*p) p++;
585     return p - controlarray;
586 }
587
588 static inline LDAPControlW **controlarrayAtoW( LDAPControlA **controlarray )
589 {
590     LDAPControlW **controlarrayW = NULL;
591     DWORD size;
592
593     if (controlarray)
594     {
595         size = sizeof(LDAPControlW*) * (controlarraylenA( controlarray ) + 1);
596         controlarrayW = HeapAlloc( GetProcessHeap(), 0, size );
597
598         if (controlarrayW)
599         {
600             LDAPControlA **p = controlarray;
601             LDAPControlW **q = controlarrayW;
602
603             while (*p) *q++ = controlAtoW( *p++ );
604             *q = NULL;
605         }
606     }
607     return controlarrayW;
608 }
609
610 static inline LDAPControlA **controlarrayWtoA( LDAPControlW **controlarray )
611 {
612     LDAPControlA **controlarrayA = NULL;
613     DWORD size;
614
615     if (controlarray)
616     {
617         size = sizeof(LDAPControl*) * (controlarraylenW( controlarray ) + 1);
618         controlarrayA = HeapAlloc( GetProcessHeap(), 0, size );
619
620         if (controlarrayA)
621         {
622             LDAPControlW **p = controlarray;
623             LDAPControlA **q = controlarrayA;
624
625             while (*p) *q++ = controlWtoA( *p++ );
626             *q = NULL;
627         }
628     }
629     return controlarrayA;
630 }
631
632 static inline LDAPControl **controlarrayWtoU( LDAPControlW **controlarray )
633 {
634     LDAPControl **controlarrayU = NULL;
635     DWORD size;
636
637     if (controlarray)
638     {
639         size = sizeof(LDAPControl*) * (controlarraylenW( controlarray ) + 1);
640         controlarrayU = HeapAlloc( GetProcessHeap(), 0, size );
641
642         if (controlarrayU)
643         {
644             LDAPControlW **p = controlarray;
645             LDAPControl **q = controlarrayU;
646
647             while (*p) *q++ = controlWtoU( *p++ );
648             *q = NULL;
649         }
650     }
651     return controlarrayU;
652 }
653
654 static inline LDAPControlW **controlarrayUtoW( LDAPControl **controlarray )
655 {
656     LDAPControlW **controlarrayW = NULL;
657     DWORD size;
658
659     if (controlarray)
660     {
661         size = sizeof(LDAPControlW*) * (controlarraylenU( controlarray ) + 1);
662         controlarrayW = HeapAlloc( GetProcessHeap(), 0, size );
663
664         if (controlarrayW)
665         {
666             LDAPControl **p = controlarray;
667             LDAPControlW **q = controlarrayW;
668
669             while (*p) *q++ = controlUtoW( *p++ );
670             *q = NULL;
671         }
672     }
673     return controlarrayW;
674 }
675
676 static inline void controlarrayfreeA( LDAPControlA **controlarray )
677 {
678     if (controlarray)
679     {
680         LDAPControlA **p = controlarray;
681         while (*p) controlfreeA( *p++ );
682         HeapFree( GetProcessHeap(), 0, controlarray );
683     }
684 }
685
686 static inline void controlarrayfreeW( LDAPControlW **controlarray )
687 {
688     if (controlarray)
689     {
690         LDAPControlW **p = controlarray;
691         while (*p) controlfreeW( *p++ );
692         HeapFree( GetProcessHeap(), 0, controlarray );
693     }
694 }
695
696 static inline void controlarrayfreeU( LDAPControl **controlarray )
697 {
698     if (controlarray)
699     {
700         LDAPControl **p = controlarray;
701         while (*p) controlfreeU( *p++ );
702         HeapFree( GetProcessHeap(), 0, controlarray );
703     }
704 }
705
706 static inline LDAPSortKeyW *sortkeyAtoW( LDAPSortKeyA *sortkey )
707 {
708     LDAPSortKeyW *sortkeyW;
709
710     sortkeyW = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPSortKeyW) );
711     if (sortkeyW)
712     {
713         sortkeyW->sk_attrtype = strAtoW( sortkey->sk_attrtype );
714         sortkeyW->sk_matchruleoid = strAtoW( sortkey->sk_matchruleoid );
715         sortkeyW->sk_reverseorder = sortkey->sk_reverseorder;
716     }
717     return sortkeyW;
718 }
719
720 static inline LDAPSortKeyA *sortkeyWtoA( LDAPSortKeyW *sortkey )
721 {
722     LDAPSortKeyA *sortkeyA;
723
724     sortkeyA = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPSortKeyA) );
725     if (sortkeyA)
726     {
727         sortkeyA->sk_attrtype = strWtoA( sortkey->sk_attrtype );
728         sortkeyA->sk_matchruleoid = strWtoA( sortkey->sk_matchruleoid );
729         sortkeyA->sk_reverseorder = sortkey->sk_reverseorder;
730     }
731     return sortkeyA;
732 }
733
734 static inline LDAPSortKey *sortkeyWtoU( LDAPSortKeyW *sortkey )
735 {
736     LDAPSortKey *sortkeyU;
737
738     sortkeyU = HeapAlloc( GetProcessHeap(), 0, sizeof(LDAPSortKey) );
739     if (sortkeyU)
740     {
741         sortkeyU->attributeType = strWtoU( sortkey->sk_attrtype );
742         sortkeyU->orderingRule = strWtoU( sortkey->sk_matchruleoid );
743         sortkeyU->reverseOrder = sortkey->sk_reverseorder;
744     }
745     return sortkeyU;
746 }
747
748 static inline void sortkeyfreeA( LDAPSortKeyA *sortkey )
749 {
750     if (sortkey)
751     {
752         strfreeA( sortkey->sk_attrtype );
753         strfreeA( sortkey->sk_matchruleoid );
754         HeapFree( GetProcessHeap(), 0, sortkey );
755     }
756 }
757
758 static inline void sortkeyfreeW( LDAPSortKeyW *sortkey )
759 {
760     if (sortkey)
761     {
762         strfreeW( sortkey->sk_attrtype );
763         strfreeW( sortkey->sk_matchruleoid );
764         HeapFree( GetProcessHeap(), 0, sortkey );
765     }
766 }
767
768 static inline void sortkeyfreeU( LDAPSortKey *sortkey )
769 {
770     if (sortkey)
771     {
772         strfreeU( sortkey->attributeType );
773         strfreeU( sortkey->orderingRule );
774         HeapFree( GetProcessHeap(), 0, sortkey );
775     }
776 }
777
778 static inline DWORD sortkeyarraylenA( LDAPSortKeyA **sortkeyarray )
779 {
780     LDAPSortKeyA **p = sortkeyarray;
781     while (*p) p++;
782     return p - sortkeyarray;
783 }
784
785 static inline DWORD sortkeyarraylenW( LDAPSortKeyW **sortkeyarray )
786 {
787     LDAPSortKeyW **p = sortkeyarray;
788     while (*p) p++;
789     return p - sortkeyarray;
790 }
791
792 static inline LDAPSortKeyW **sortkeyarrayAtoW( LDAPSortKeyA **sortkeyarray )
793 {
794     LDAPSortKeyW **sortkeyarrayW = NULL;
795     DWORD size;
796
797     if (sortkeyarray)
798     {
799         size = sizeof(LDAPSortKeyW*) * (sortkeyarraylenA( sortkeyarray ) + 1);
800         sortkeyarrayW = HeapAlloc( GetProcessHeap(), 0, size );
801
802         if (sortkeyarrayW)
803         {
804             LDAPSortKeyA **p = sortkeyarray;
805             LDAPSortKeyW **q = sortkeyarrayW;
806
807             while (*p) *q++ = sortkeyAtoW( *p++ );
808             *q = NULL;
809         }
810     }
811     return sortkeyarrayW;
812 }
813
814 static inline LDAPSortKey **sortkeyarrayWtoU( LDAPSortKeyW **sortkeyarray )
815 {
816     LDAPSortKey **sortkeyarrayU = NULL;
817     DWORD size;
818
819     if (sortkeyarray)
820     {
821         size = sizeof(LDAPSortKey*) * (sortkeyarraylenW( sortkeyarray ) + 1);
822         sortkeyarrayU = HeapAlloc( GetProcessHeap(), 0, size );
823
824         if (sortkeyarrayU)
825         {
826             LDAPSortKeyW **p = sortkeyarray;
827             LDAPSortKey **q = sortkeyarrayU;
828
829             while (*p) *q++ = sortkeyWtoU( *p++ );
830             *q = NULL;
831         }
832     }
833     return sortkeyarrayU;
834 }
835
836 static inline void sortkeyarrayfreeW( LDAPSortKeyW **sortkeyarray )
837 {
838     if (sortkeyarray)
839     {
840         LDAPSortKeyW **p = sortkeyarray;
841         while (*p) sortkeyfreeW( *p++ );
842         HeapFree( GetProcessHeap(), 0, sortkeyarray );
843     }
844 }
845
846 static inline void sortkeyarrayfreeU( LDAPSortKey **sortkeyarray )
847 {
848     if (sortkeyarray)
849     {
850         LDAPSortKey **p = sortkeyarray;
851         while (*p) sortkeyfreeU( *p++ );
852         HeapFree( GetProcessHeap(), 0, sortkeyarray );
853     }
854 }
855
856 #endif /* HAVE_LDAP */