diff options
author | Andy Polyakov <appro@openssl.org> | 2005-06-05 18:13:38 +0000 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2005-06-05 18:13:38 +0000 |
commit | 7ed876533aa7c8e721836c25cef737c3643f5e55 (patch) | |
tree | 3978ef9d2c18ec4e176bbf4b7e0c0517202fb012 /crypto/dso/dso_win32.c | |
parent | b2d91a69133e5b8e546f5316f1005e6553194d81 (diff) |
New function, DSO_pathbyaddr, to find pathname for loaded shared object
by an address within it. Tested on Linux, Solaris, IRIX, Tru64, Darwin,
HP-UX, Win32, few BSD flavors...
Diffstat (limited to 'crypto/dso/dso_win32.c')
-rw-r--r-- | crypto/dso/dso_win32.c | 125 |
1 files changed, 122 insertions, 3 deletions
diff --git a/crypto/dso/dso_win32.c b/crypto/dso/dso_win32.c index e6eaa99005..96ccd4b7ee 100644 --- a/crypto/dso/dso_win32.c +++ b/crypto/dso/dso_win32.c @@ -85,6 +85,7 @@ static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg); static char *win32_name_converter(DSO *dso, const char *filename); static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2); +static int win32_pathbyaddr(void *addr,char *path,int sz); static const char *openssl_strnchr(const char *string, int c, size_t len); @@ -103,7 +104,8 @@ static DSO_METHOD dso_meth_win32 = { win32_name_converter, win32_merger, NULL, /* init */ - NULL /* finish */ + NULL, /* finish */ + win32_pathbyaddr }; DSO_METHOD *DSO_METHOD_win32(void) @@ -127,7 +129,7 @@ static int win32_load(DSO *dso) DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME); goto err; } - h = LoadLibrary(filename); + h = LoadLibraryA(filename); if(h == NULL) { DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED); @@ -593,5 +595,122 @@ static const char *openssl_strnchr(const char *string, int c, size_t len) return NULL; } +#include <tlhelp32.h> +#ifdef _WIN32_WCE +# if _WIN32_WCE < 300 +static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName) + { + WCHAR lpProcNameW[64]; + int i; + + for (i=0;lpProcName[i] && i<64;i++) + lpProcNameW[i] = (WCHAR)lpProcName[i]; + if (i==64) return NULL; + lpProcNameW[i] = 0; + + return GetProcAddressW(hModule,lpProcNameW); + } +# endif +# undef GetProcAddress +# define GetProcAddress GetProcAddressA +# define DLLNAME "TOOLHELP.DLL" +#else +# ifdef MODULEENTRY32 +# undef MODULEENTRY32 /* unmask the ASCII version! */ +# endif +# define DLLNAME "KERNEL32.DLL" +#endif + +typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD); +typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE); +typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *); -#endif /* OPENSSL_SYS_WIN32 */ +static int win32_pathbyaddr(void *addr,char *path,int sz) + { + HMODULE dll; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 me32; + CREATETOOLHELP32SNAPSHOT create_snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + MODULE32 module_first, module_next; + int len; + + if (addr == NULL) addr = win32_pathbyaddr; + + dll = LoadLibrary(TEXT(DLLNAME)); + if (dll == NULL) + { + DSOerr(DSO_F_PATHBYADDR,DSO_R_UNSUPPORTED); + return -1; + } + + create_snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(dll,"CreateToolhelp32Snapshot"); + if (create_snap == NULL) + { + DSOerr(DSO_F_PATHBYADDR,DSO_R_UNSUPPORTED); + return -1; + } + /* We take the rest for granted... */ +#ifdef _WIN32_WCE + close_snap = (CLOSETOOLHELP32SNAPSHOT) + GetProcAddress(dll,"CloseToolhelp32Snapshot"); +#else + close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle; +#endif + module_first = (MODULE32)GetProcAddress(dll,"Module32First"); + module_next = (MODULE32)GetProcAddress(dll,"Module32Next"); + + hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0); + if( hModuleSnap == INVALID_HANDLE_VALUE ) + { + FreeLibrary(dll); + DSOerr(DSO_F_PATHBYADDR,DSO_R_UNSUPPORTED); + return -1; + } + + me32.dwSize = sizeof(me32); + + if(!(*module_first)(hModuleSnap,&me32)) + { + (*close_snap)(hModuleSnap); + FreeLibrary(dll); + DSOerr(DSO_F_PATHBYADDR,DSO_R_FAILURE); + return -1; + } + + do { + if ((BYTE *)addr >= me32.modBaseAddr && + (BYTE *)addr < me32.modBaseAddr+me32.modBaseSize) + { + (*close_snap)(hModuleSnap); + FreeLibrary(dll); +#ifdef _WIN32_WCE +# if _WIN32_WCE >= 101 + return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1, + path,sz,NULL,NULL); +# else + len = (int)wcslen(me32.szExePath); + if (sz <= 0) return len+1; + if (len >= sz) len=sz-1; + for(i=0;i<len;i++) + path[i] = (char)me32.szExePath[i]; + path[len++] = 0; + return len; +# endif +#else + len = (int)strlen(me32.szExePath); + if (sz <= 0) return len+1; + if (len >= sz) len=sz-1; + memcpy(path,me32.szExePath,len); + path[len++] = 0; + return len; +#endif + } + } while((*module_next)(hModuleSnap, &me32)); + + (*close_snap)(hModuleSnap); + FreeLibrary(dll); + return 0; + } +#endif /* DSO_WIN32 */ |