+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 */