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