1 /* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */ 2 /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL 3 * project 2000. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <stdio.h> 60 #include <string.h> 61 #include "cryptlib.h" 62 #include <openssl/dso.h> 63 64 #if !defined(DSO_WIN32) 65 DSO_METHOD *DSO_METHOD_win32(void) 66 { 67 return NULL; 68 } 69 #else 70 71 #ifdef _WIN32_WCE 72 # if _WIN32_WCE < 300 73 static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName) 74 { 75 WCHAR lpProcNameW[64]; 76 int i; 77 78 for (i=0;lpProcName[i] && i<64;i++) 79 lpProcNameW[i] = (WCHAR)lpProcName[i]; 80 if (i==64) return NULL; 81 lpProcNameW[i] = 0; 82 83 return GetProcAddressW(hModule,lpProcNameW); 84 } 85 # endif 86 # undef GetProcAddress 87 # define GetProcAddress GetProcAddressA 88 89 static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName) 90 { 91 WCHAR *fnamw; 92 size_t len_0=strlen(lpLibFileName)+1,i; 93 94 #ifdef _MSC_VER 95 fnamw = (WCHAR *)_alloca (len_0*sizeof(WCHAR)); 96 #else 97 fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR)); 98 #endif 99 if (fnamw == NULL) 100 { 101 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 102 return NULL; 103 } 104 105 #if defined(_WIN32_WCE) && _WIN32_WCE>=101 106 if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0)) 107 #endif 108 for (i=0;i<len_0;i++) fnamw[i]=(WCHAR)lpLibFileName[i]; 109 110 return LoadLibraryW(fnamw); 111 } 112 #endif 113 114 /* Part of the hack in "win32_load" ... */ 115 #define DSO_MAX_TRANSLATED_SIZE 256 116 117 static int win32_load(DSO *dso); 118 static int win32_unload(DSO *dso); 119 static void *win32_bind_var(DSO *dso, const char *symname); 120 static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname); 121 #if 0 122 static int win32_unbind_var(DSO *dso, char *symname, void *symptr); 123 static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); 124 static int win32_init(DSO *dso); 125 static int win32_finish(DSO *dso); 126 static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg); 127 #endif 128 static char *win32_name_converter(DSO *dso, const char *filename); 129 static char *win32_merger(DSO *dso, const char *filespec1, 130 const char *filespec2); 131 static int win32_pathbyaddr(void *addr,char *path,int sz); 132 static void *win32_globallookup(const char *name); 133 134 static const char *openssl_strnchr(const char *string, int c, size_t len); 135 136 static DSO_METHOD dso_meth_win32 = { 137 "OpenSSL 'win32' shared library method", 138 win32_load, 139 win32_unload, 140 win32_bind_var, 141 win32_bind_func, 142 /* For now, "unbind" doesn't exist */ 143 #if 0 144 NULL, /* unbind_var */ 145 NULL, /* unbind_func */ 146 #endif 147 NULL, /* ctrl */ 148 win32_name_converter, 149 win32_merger, 150 NULL, /* init */ 151 NULL, /* finish */ 152 win32_pathbyaddr, 153 win32_globallookup 154 }; 155 156 DSO_METHOD *DSO_METHOD_win32(void) 157 { 158 return(&dso_meth_win32); 159 } 160 161 /* For this DSO_METHOD, our meth_data STACK will contain; 162 * (i) a pointer to the handle (HINSTANCE) returned from 163 * LoadLibrary(), and copied. 164 */ 165 166 static int win32_load(DSO *dso) 167 { 168 HINSTANCE h = NULL, *p = NULL; 169 /* See applicable comments from dso_dl.c */ 170 char *filename = DSO_convert_filename(dso, NULL); 171 172 if(filename == NULL) 173 { 174 DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME); 175 goto err; 176 } 177 h = LoadLibraryA(filename); 178 if(h == NULL) 179 { 180 DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED); 181 ERR_add_error_data(3, "filename(", filename, ")"); 182 goto err; 183 } 184 p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE)); 185 if(p == NULL) 186 { 187 DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE); 188 goto err; 189 } 190 *p = h; 191 if(!sk_void_push(dso->meth_data, p)) 192 { 193 DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR); 194 goto err; 195 } 196 /* Success */ 197 dso->loaded_filename = filename; 198 return(1); 199 err: 200 /* Cleanup !*/ 201 if(filename != NULL) 202 OPENSSL_free(filename); 203 if(p != NULL) 204 OPENSSL_free(p); 205 if(h != NULL) 206 FreeLibrary(h); 207 return(0); 208 } 209 210 static int win32_unload(DSO *dso) 211 { 212 HINSTANCE *p; 213 if(dso == NULL) 214 { 215 DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); 216 return(0); 217 } 218 if(sk_void_num(dso->meth_data) < 1) 219 return(1); 220 p = sk_void_pop(dso->meth_data); 221 if(p == NULL) 222 { 223 DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE); 224 return(0); 225 } 226 if(!FreeLibrary(*p)) 227 { 228 DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED); 229 /* We should push the value back onto the stack in 230 * case of a retry. */ 231 sk_void_push(dso->meth_data, p); 232 return(0); 233 } 234 /* Cleanup */ 235 OPENSSL_free(p); 236 return(1); 237 } 238 239 /* Using GetProcAddress for variables? TODO: Check this out in 240 * the Win32 API docs, there's probably a variant for variables. */ 241 static void *win32_bind_var(DSO *dso, const char *symname) 242 { 243 HINSTANCE *ptr; 244 void *sym; 245 246 if((dso == NULL) || (symname == NULL)) 247 { 248 DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); 249 return(NULL); 250 } 251 if(sk_void_num(dso->meth_data) < 1) 252 { 253 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR); 254 return(NULL); 255 } 256 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); 257 if(ptr == NULL) 258 { 259 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE); 260 return(NULL); 261 } 262 sym = GetProcAddress(*ptr, symname); 263 if(sym == NULL) 264 { 265 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_SYM_FAILURE); 266 ERR_add_error_data(3, "symname(", symname, ")"); 267 return(NULL); 268 } 269 return(sym); 270 } 271 272 static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname) 273 { 274 HINSTANCE *ptr; 275 void *sym; 276 277 if((dso == NULL) || (symname == NULL)) 278 { 279 DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); 280 return(NULL); 281 } 282 if(sk_void_num(dso->meth_data) < 1) 283 { 284 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR); 285 return(NULL); 286 } 287 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); 288 if(ptr == NULL) 289 { 290 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE); 291 return(NULL); 292 } 293 sym = GetProcAddress(*ptr, symname); 294 if(sym == NULL) 295 { 296 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_SYM_FAILURE); 297 ERR_add_error_data(3, "symname(", symname, ")"); 298 return(NULL); 299 } 300 return((DSO_FUNC_TYPE)sym); 301 } 302 303 struct file_st 304 { 305 const char *node; int nodelen; 306 const char *device; int devicelen; 307 const char *predir; int predirlen; 308 const char *dir; int dirlen; 309 const char *file; int filelen; 310 }; 311 312 static struct file_st *win32_splitter(DSO *dso, const char *filename, 313 int assume_last_is_dir) 314 { 315 struct file_st *result = NULL; 316 enum { IN_NODE, IN_DEVICE, IN_FILE } position; 317 const char *start = filename; 318 char last; 319 320 if (!filename) 321 { 322 DSOerr(DSO_F_WIN32_SPLITTER,DSO_R_NO_FILENAME); 323 /*goto err;*/ 324 return(NULL); 325 } 326 327 result = OPENSSL_malloc(sizeof(struct file_st)); 328 if(result == NULL) 329 { 330 DSOerr(DSO_F_WIN32_SPLITTER, 331 ERR_R_MALLOC_FAILURE); 332 return(NULL); 333 } 334 335 memset(result, 0, sizeof(struct file_st)); 336 position = IN_DEVICE; 337 338 if((filename[0] == '\\' && filename[1] == '\\') 339 || (filename[0] == '/' && filename[1] == '/')) 340 { 341 position = IN_NODE; 342 filename += 2; 343 start = filename; 344 result->node = start; 345 } 346 347 do 348 { 349 last = filename[0]; 350 switch(last) 351 { 352 case ':': 353 if(position != IN_DEVICE) 354 { 355 DSOerr(DSO_F_WIN32_SPLITTER, 356 DSO_R_INCORRECT_FILE_SYNTAX); 357 /*goto err;*/ 358 OPENSSL_free(result); 359 return(NULL); 360 } 361 result->device = start; 362 result->devicelen = (int)(filename - start); 363 position = IN_FILE; 364 start = ++filename; 365 result->dir = start; 366 break; 367 case '\\': 368 case '/': 369 if(position == IN_NODE) 370 { 371 result->nodelen = (int)(filename - start); 372 position = IN_FILE; 373 start = ++filename; 374 result->dir = start; 375 } 376 else if(position == IN_DEVICE) 377 { 378 position = IN_FILE; 379 filename++; 380 result->dir = start; 381 result->dirlen = (int)(filename - start); 382 start = filename; 383 } 384 else 385 { 386 filename++; 387 result->dirlen += (int)(filename - start); 388 start = filename; 389 } 390 break; 391 case '\0': 392 if(position == IN_NODE) 393 { 394 result->nodelen = (int)(filename - start); 395 } 396 else 397 { 398 if(filename - start > 0) 399 { 400 if (assume_last_is_dir) 401 { 402 if (position == IN_DEVICE) 403 { 404 result->dir = start; 405 result->dirlen = 0; 406 } 407 result->dirlen += 408 (int)(filename - start); 409 } 410 else 411 { 412 result->file = start; 413 result->filelen = 414 (int)(filename - start); 415 } 416 } 417 } 418 break; 419 default: 420 filename++; 421 break; 422 } 423 } 424 while(last); 425 426 if(!result->nodelen) result->node = NULL; 427 if(!result->devicelen) result->device = NULL; 428 if(!result->dirlen) result->dir = NULL; 429 if(!result->filelen) result->file = NULL; 430 431 return(result); 432 } 433 434 static char *win32_joiner(DSO *dso, const struct file_st *file_split) 435 { 436 int len = 0, offset = 0; 437 char *result = NULL; 438 const char *start; 439 440 if(!file_split) 441 { 442 DSOerr(DSO_F_WIN32_JOINER, 443 ERR_R_PASSED_NULL_PARAMETER); 444 return(NULL); 445 } 446 if(file_split->node) 447 { 448 len += 2 + file_split->nodelen; /* 2 for starting \\ */ 449 if(file_split->predir || file_split->dir || file_split->file) 450 len++; /* 1 for ending \ */ 451 } 452 else if(file_split->device) 453 { 454 len += file_split->devicelen + 1; /* 1 for ending : */ 455 } 456 len += file_split->predirlen; 457 if(file_split->predir && (file_split->dir || file_split->file)) 458 { 459 len++; /* 1 for ending \ */ 460 } 461 len += file_split->dirlen; 462 if(file_split->dir && file_split->file) 463 { 464 len++; /* 1 for ending \ */ 465 } 466 len += file_split->filelen; 467 468 if(!len) 469 { 470 DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE); 471 return(NULL); 472 } 473 474 result = OPENSSL_malloc(len + 1); 475 if (!result) 476 { 477 DSOerr(DSO_F_WIN32_JOINER, 478 ERR_R_MALLOC_FAILURE); 479 return(NULL); 480 } 481 482 if(file_split->node) 483 { 484 strcpy(&result[offset], "\\\\"); offset += 2; 485 strncpy(&result[offset], file_split->node, 486 file_split->nodelen); offset += file_split->nodelen; 487 if(file_split->predir || file_split->dir || file_split->file) 488 { 489 result[offset] = '\\'; offset++; 490 } 491 } 492 else if(file_split->device) 493 { 494 strncpy(&result[offset], file_split->device, 495 file_split->devicelen); offset += file_split->devicelen; 496 result[offset] = ':'; offset++; 497 } 498 start = file_split->predir; 499 while(file_split->predirlen > (start - file_split->predir)) 500 { 501 const char *end = openssl_strnchr(start, '/', 502 file_split->predirlen - (start - file_split->predir)); 503 if(!end) 504 end = start 505 + file_split->predirlen 506 - (start - file_split->predir); 507 strncpy(&result[offset], start, 508 end - start); offset += (int)(end - start); 509 result[offset] = '\\'; offset++; 510 start = end + 1; 511 } 512 #if 0 /* Not needed, since the directory converter above already appeneded 513 a backslash */ 514 if(file_split->predir && (file_split->dir || file_split->file)) 515 { 516 result[offset] = '\\'; offset++; 517 } 518 #endif 519 start = file_split->dir; 520 while(file_split->dirlen > (start - file_split->dir)) 521 { 522 const char *end = openssl_strnchr(start, '/', 523 file_split->dirlen - (start - file_split->dir)); 524 if(!end) 525 end = start 526 + file_split->dirlen 527 - (start - file_split->dir); 528 strncpy(&result[offset], start, 529 end - start); offset += (int)(end - start); 530 result[offset] = '\\'; offset++; 531 start = end + 1; 532 } 533 #if 0 /* Not needed, since the directory converter above already appeneded 534 a backslash */ 535 if(file_split->dir && file_split->file) 536 { 537 result[offset] = '\\'; offset++; 538 } 539 #endif 540 strncpy(&result[offset], file_split->file, 541 file_split->filelen); offset += file_split->filelen; 542 result[offset] = '\0'; 543 return(result); 544 } 545 546 static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2) 547 { 548 char *merged = NULL; 549 struct file_st *filespec1_split = NULL; 550 struct file_st *filespec2_split = NULL; 551 552 if(!filespec1 && !filespec2) 553 { 554 DSOerr(DSO_F_WIN32_MERGER, 555 ERR_R_PASSED_NULL_PARAMETER); 556 return(NULL); 557 } 558 if (!filespec2) 559 { 560 merged = OPENSSL_malloc(strlen(filespec1) + 1); 561 if(!merged) 562 { 563 DSOerr(DSO_F_WIN32_MERGER, 564 ERR_R_MALLOC_FAILURE); 565 return(NULL); 566 } 567 strcpy(merged, filespec1); 568 } 569 else if (!filespec1) 570 { 571 merged = OPENSSL_malloc(strlen(filespec2) + 1); 572 if(!merged) 573 { 574 DSOerr(DSO_F_WIN32_MERGER, 575 ERR_R_MALLOC_FAILURE); 576 return(NULL); 577 } 578 strcpy(merged, filespec2); 579 } 580 else 581 { 582 filespec1_split = win32_splitter(dso, filespec1, 0); 583 if (!filespec1_split) 584 { 585 DSOerr(DSO_F_WIN32_MERGER, 586 ERR_R_MALLOC_FAILURE); 587 return(NULL); 588 } 589 filespec2_split = win32_splitter(dso, filespec2, 1); 590 if (!filespec2_split) 591 { 592 DSOerr(DSO_F_WIN32_MERGER, 593 ERR_R_MALLOC_FAILURE); 594 OPENSSL_free(filespec1_split); 595 return(NULL); 596 } 597 598 /* Fill in into filespec1_split */ 599 if (!filespec1_split->node && !filespec1_split->device) 600 { 601 filespec1_split->node = filespec2_split->node; 602 filespec1_split->nodelen = filespec2_split->nodelen; 603 filespec1_split->device = filespec2_split->device; 604 filespec1_split->devicelen = filespec2_split->devicelen; 605 } 606 if (!filespec1_split->dir) 607 { 608 filespec1_split->dir = filespec2_split->dir; 609 filespec1_split->dirlen = filespec2_split->dirlen; 610 } 611 else if (filespec1_split->dir[0] != '\\' 612 && filespec1_split->dir[0] != '/') 613 { 614 filespec1_split->predir = filespec2_split->dir; 615 filespec1_split->predirlen = filespec2_split->dirlen; 616 } 617 if (!filespec1_split->file) 618 { 619 filespec1_split->file = filespec2_split->file; 620 filespec1_split->filelen = filespec2_split->filelen; 621 } 622 623 merged = win32_joiner(dso, filespec1_split); 624 } 625 OPENSSL_free(filespec1_split); 626 OPENSSL_free(filespec2_split); 627 return(merged); 628 } 629 630 static char *win32_name_converter(DSO *dso, const char *filename) 631 { 632 char *translated; 633 int len, transform; 634 635 len = strlen(filename); 636 transform = ((strstr(filename, "/") == NULL) && 637 (strstr(filename, "\\") == NULL) && 638 (strstr(filename, ":") == NULL)); 639 if(transform) 640 /* We will convert this to "%s.dll" */ 641 translated = OPENSSL_malloc(len + 5); 642 else 643 /* We will simply duplicate filename */ 644 translated = OPENSSL_malloc(len + 1); 645 if(translated == NULL) 646 { 647 DSOerr(DSO_F_WIN32_NAME_CONVERTER, 648 DSO_R_NAME_TRANSLATION_FAILED); 649 return(NULL); 650 } 651 if(transform) 652 sprintf(translated, "%s.dll", filename); 653 else 654 sprintf(translated, "%s", filename); 655 return(translated); 656 } 657 658 static const char *openssl_strnchr(const char *string, int c, size_t len) 659 { 660 size_t i; 661 const char *p; 662 for (i = 0, p = string; i < len && *p; i++, p++) 663 { 664 if (*p == c) 665 return p; 666 } 667 return NULL; 668 } 669 670 #include <tlhelp32.h> 671 #ifdef _WIN32_WCE 672 # define DLLNAME "TOOLHELP.DLL" 673 #else 674 # ifdef MODULEENTRY32 675 # undef MODULEENTRY32 /* unmask the ASCII version! */ 676 # endif 677 # define DLLNAME "KERNEL32.DLL" 678 #endif 679 680 typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD); 681 typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE); 682 typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *); 683 684 static int win32_pathbyaddr(void *addr,char *path,int sz) 685 { 686 HMODULE dll; 687 HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 688 MODULEENTRY32 me32; 689 CREATETOOLHELP32SNAPSHOT create_snap; 690 CLOSETOOLHELP32SNAPSHOT close_snap; 691 MODULE32 module_first, module_next; 692 int len; 693 694 if (addr == NULL) 695 { 696 union { int(*f)(void*,char*,int); void *p; } t = 697 { win32_pathbyaddr }; 698 addr = t.p; 699 } 700 701 dll = LoadLibrary(TEXT(DLLNAME)); 702 if (dll == NULL) 703 { 704 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED); 705 return -1; 706 } 707 708 create_snap = (CREATETOOLHELP32SNAPSHOT) 709 GetProcAddress(dll,"CreateToolhelp32Snapshot"); 710 if (create_snap == NULL) 711 { 712 FreeLibrary(dll); 713 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED); 714 return -1; 715 } 716 /* We take the rest for granted... */ 717 #ifdef _WIN32_WCE 718 close_snap = (CLOSETOOLHELP32SNAPSHOT) 719 GetProcAddress(dll,"CloseToolhelp32Snapshot"); 720 #else 721 close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle; 722 #endif 723 module_first = (MODULE32)GetProcAddress(dll,"Module32First"); 724 module_next = (MODULE32)GetProcAddress(dll,"Module32Next"); 725 726 hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0); 727 if( hModuleSnap == INVALID_HANDLE_VALUE ) 728 { 729 FreeLibrary(dll); 730 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED); 731 return -1; 732 } 733 734 me32.dwSize = sizeof(me32); 735 736 if(!(*module_first)(hModuleSnap,&me32)) 737 { 738 (*close_snap)(hModuleSnap); 739 FreeLibrary(dll); 740 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_FAILURE); 741 return -1; 742 } 743 744 do { 745 if ((BYTE *)addr >= me32.modBaseAddr && 746 (BYTE *)addr < me32.modBaseAddr+me32.modBaseSize) 747 { 748 (*close_snap)(hModuleSnap); 749 FreeLibrary(dll); 750 #ifdef _WIN32_WCE 751 # if _WIN32_WCE >= 101 752 return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1, 753 path,sz,NULL,NULL); 754 # else 755 len = (int)wcslen(me32.szExePath); 756 if (sz <= 0) return len+1; 757 if (len >= sz) len=sz-1; 758 for(i=0;i<len;i++) 759 path[i] = (char)me32.szExePath[i]; 760 path[len++] = 0; 761 return len; 762 # endif 763 #else 764 len = (int)strlen(me32.szExePath); 765 if (sz <= 0) return len+1; 766 if (len >= sz) len=sz-1; 767 memcpy(path,me32.szExePath,len); 768 path[len++] = 0; 769 return len; 770 #endif 771 } 772 } while((*module_next)(hModuleSnap, &me32)); 773 774 (*close_snap)(hModuleSnap); 775 FreeLibrary(dll); 776 return 0; 777 } 778 779 static void *win32_globallookup(const char *name) 780 { 781 HMODULE dll; 782 HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 783 MODULEENTRY32 me32; 784 CREATETOOLHELP32SNAPSHOT create_snap; 785 CLOSETOOLHELP32SNAPSHOT close_snap; 786 MODULE32 module_first, module_next; 787 FARPROC ret=NULL; 788 789 dll = LoadLibrary(TEXT(DLLNAME)); 790 if (dll == NULL) 791 { 792 DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED); 793 return NULL; 794 } 795 796 create_snap = (CREATETOOLHELP32SNAPSHOT) 797 GetProcAddress(dll,"CreateToolhelp32Snapshot"); 798 if (create_snap == NULL) 799 { 800 FreeLibrary(dll); 801 DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED); 802 return NULL; 803 } 804 /* We take the rest for granted... */ 805 #ifdef _WIN32_WCE 806 close_snap = (CLOSETOOLHELP32SNAPSHOT) 807 GetProcAddress(dll,"CloseToolhelp32Snapshot"); 808 #else 809 close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle; 810 #endif 811 module_first = (MODULE32)GetProcAddress(dll,"Module32First"); 812 module_next = (MODULE32)GetProcAddress(dll,"Module32Next"); 813 814 hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0); 815 if( hModuleSnap == INVALID_HANDLE_VALUE ) 816 { 817 FreeLibrary(dll); 818 DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED); 819 return NULL; 820 } 821 822 me32.dwSize = sizeof(me32); 823 824 if (!(*module_first)(hModuleSnap,&me32)) 825 { 826 (*close_snap)(hModuleSnap); 827 FreeLibrary(dll); 828 return NULL; 829 } 830 831 do { 832 if ((ret = GetProcAddress(me32.hModule,name))) 833 { 834 (*close_snap)(hModuleSnap); 835 FreeLibrary(dll); 836 return ret; 837 } 838 } while((*module_next)(hModuleSnap,&me32)); 839 840 (*close_snap)(hModuleSnap); 841 FreeLibrary(dll); 842 return NULL; 843 } 844 #endif /* DSO_WIN32 */