X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdso%2Fdso_win32.c;h=d98a3e85f3921a51ce8c3086a1b0c96c2ab5b906;hp=4ce9a5d45c8cfb9ce3e1829be9f5c34b89a5d3b2;hb=9e9bececa9e9a89bf7b42a90c95b06eb3a2ee7a3;hpb=cbecb3ac3763f1179dc220a69d28e92f58e9443e diff --git a/crypto/dso/dso_win32.c b/crypto/dso/dso_win32.c index 4ce9a5d45c..d98a3e85f3 100644 --- a/crypto/dso/dso_win32.c +++ b/crypto/dso/dso_win32.c @@ -61,13 +61,56 @@ #include "cryptlib.h" #include -#ifndef OPENSSL_SYS_WIN32 +#if !defined(DSO_WIN32) DSO_METHOD *DSO_METHOD_win32(void) { return NULL; } #else +#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 + +static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName) + { + WCHAR *fnamw; + size_t len_0=strlen(lpLibFileName)+1,i; + +#ifdef _MSC_VER + fnamw = (WCHAR *)_alloca (len_0*sizeof(WCHAR)); +#else + fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR)); +#endif + if (fnamw == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + +#if defined(_WIN32_WCE) && _WIN32_WCE>=101 + if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0)) +#endif + for (i=0;idevice = start; result->devicelen = filename - start; @@ -319,10 +372,19 @@ static struct file_st *win32_splitter(DSO *dso, const char *filename, start = ++filename; result->dir = start; } + else if(position == IN_DEVICE) + { + position = IN_FILE; + filename++; + result->dir = start; + result->dirlen = filename - start; + start = filename; + } else { filename++; result->dirlen += filename - start; + start = filename; } break; case '\0': @@ -336,12 +398,19 @@ static struct file_st *win32_splitter(DSO *dso, const char *filename, { if (assume_last_is_dir) { - result->devicelen += filename - start; + if (position == IN_DEVICE) + { + result->dir = start; + result->dirlen = 0; + } + result->dirlen += + filename - start; } else { result->file = start; - result->filelen = filename - start; + result->filelen = + filename - start; } } } @@ -351,17 +420,17 @@ static struct file_st *win32_splitter(DSO *dso, const char *filename, break; } } - while(*filename); + while(last); if(!result->nodelen) result->node = NULL; - if(!result->devicelen) result->devicce = NULL; + if(!result->devicelen) result->device = NULL; if(!result->dirlen) result->dir = NULL; if(!result->filelen) result->file = NULL; return(result); } -static char *win32_joiner(DSO *dso, const file_st *file_split) +static char *win32_joiner(DSO *dso, const struct file_st *file_split) { int len = 0, offset = 0; char *result = NULL; @@ -369,7 +438,7 @@ static char *win32_joiner(DSO *dso, const file_st *file_split) if(!file_split) { - DSOerr(DSO_F_WIN32_MERGER, + DSOerr(DSO_F_WIN32_JOINER, ERR_R_PASSED_NULL_PARAMETER); return(NULL); } @@ -397,14 +466,14 @@ static char *win32_joiner(DSO *dso, const file_st *file_split) if(!len) { - DSOerr(DSO_F_WIN32_MERGER, DSO_R_EMPTY_FILE_STRUCTURE); + DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE); return(NULL); } result = OPENSSL_malloc(len + 1); if (!result) { - DSOerr(DSO_F_WIN32_MERGER, + DSOerr(DSO_F_WIN32_JOINER, ERR_R_MALLOC_FAILURE); return(NULL); } @@ -428,7 +497,7 @@ static char *win32_joiner(DSO *dso, const file_st *file_split) start = file_split->predir; while(file_split->predirlen > (start - file_split->predir)) { - const char *end = strnchr(start, '/', + const char *end = openssl_strnchr(start, '/', file_split->predirlen - (start - file_split->predir)); if(!end) end = start @@ -439,14 +508,17 @@ static char *win32_joiner(DSO *dso, const file_st *file_split) result[offset] = '\\'; offset++; start = end + 1; } +#if 0 /* Not needed, since the directory converter above already appeneded + a backslash */ if(file_split->predir && (file_split->dir || file_split->file)) { result[offset] = '\\'; offset++; } +#endif start = file_split->dir; while(file_split->dirlen > (start - file_split->dir)) { - const char *end = strnchr(start, '/', + const char *end = openssl_strnchr(start, '/', file_split->dirlen - (start - file_split->dir)); if(!end) end = start @@ -457,10 +529,13 @@ static char *win32_joiner(DSO *dso, const file_st *file_split) result[offset] = '\\'; offset++; start = end + 1; } +#if 0 /* Not needed, since the directory converter above already appeneded + a backslash */ if(file_split->dir && file_split->file) { result[offset] = '\\'; offset++; } +#endif strncpy(&result[offset], file_split->file, file_split->filelen); offset += file_split->filelen; result[offset] = '\0'; @@ -503,15 +578,15 @@ static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2 } else { - filespec1_split = win32_splitter(dso, filespec1, 1); + filespec1_split = win32_splitter(dso, filespec1, 0); if (!filespec1_split) { DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); return(NULL); } - filespec2_split = win32_splitter(dso, filespec2, 0); - if (!filespec1_split) + filespec2_split = win32_splitter(dso, filespec2, 1); + if (!filespec2_split) { DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); @@ -577,4 +652,190 @@ static char *win32_name_converter(DSO *dso, const char *filename) return(translated); } -#endif /* OPENSSL_SYS_WIN32 */ +static const char *openssl_strnchr(const char *string, int c, size_t len) + { + size_t i; + const char *p; + for (i = 0, p = string; i < len && *p; i++, p++) + { + if (*p == c) + return p; + } + return NULL; + } + +#include +#ifdef _WIN32_WCE +# 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 *); + +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) + { + union { int(*f)(void*,char*,int); void *p; } t = + { win32_pathbyaddr }; + addr = t.p; + } + + dll = LoadLibrary(TEXT(DLLNAME)); + if (dll == NULL) + { + DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED); + return -1; + } + + create_snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(dll,"CreateToolhelp32Snapshot"); + if (create_snap == NULL) + { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_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_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED); + return -1; + } + + me32.dwSize = sizeof(me32); + + if(!(*module_first)(hModuleSnap,&me32)) + { + (*close_snap)(hModuleSnap); + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_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= 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; + } + +static void *win32_globallookup(const char *name) + { + HMODULE dll; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 me32; + CREATETOOLHELP32SNAPSHOT create_snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + MODULE32 module_first, module_next; + FARPROC ret=NULL; + + dll = LoadLibrary(TEXT(DLLNAME)); + if (dll == NULL) + { + DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED); + return NULL; + } + + create_snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(dll,"CreateToolhelp32Snapshot"); + if (create_snap == NULL) + { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED); + return NULL; + } + /* 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_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED); + return NULL; + } + + me32.dwSize = sizeof(me32); + + if (!(*module_first)(hModuleSnap,&me32)) + { + (*close_snap)(hModuleSnap); + FreeLibrary(dll); + return NULL; + } + + do { + if (ret = GetProcAddress(me32.hModule,name)) + { + (*close_snap)(hModuleSnap); + FreeLibrary(dll); + return ret; + } + } while((*module_next)(hModuleSnap,&me32)); + + (*close_snap)(hModuleSnap); + FreeLibrary(dll); + return NULL; + } +#endif /* DSO_WIN32 */