1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
/* dl_win32.xs
*
* Platform: Win32 (Windows NT/Windows 95)
* Author: Wei-Yuen Tan (wyt@hip.com)
* Created: A warm day in June, 1995
*
* Modified:
* August 23rd 1995 - rewritten after losing everything when I
* wiped off my NT partition (eek!)
*/
/* Porting notes:
I merely took Paul's dl_dlopen.xs, took out extraneous stuff and
replaced the appropriate SunOS calls with the corresponding Win32
calls.
*/
#define WIN32_LEAN_AND_MEAN
#ifdef __GNUC__
#define Win32_Winsock
#endif
#include <windows.h>
#include <string.h>
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "win32.h"
#include "XSUB.h"
typedef struct {
SV * x_error_sv;
} my_cxtx_t; /* this *must* be named my_cxtx_t */
#define DL_CXT_EXTRA /* ask for dl_cxtx to be defined in dlutils.c */
#include "dlutils.c" /* SaveError() etc */
#define dl_error_sv (dl_cxtx.x_error_sv)
static char *
OS_Error_String(pTHX)
{
dMY_CXT;
DWORD err = GetLastError();
STRLEN len;
if (!dl_error_sv)
dl_error_sv = newSVpvn("",0);
PerlProc_GetOSError(dl_error_sv,err);
return SvPV(dl_error_sv,len);
}
static void
dl_private_init(pTHX)
{
(void)dl_generic_private_init(aTHX);
}
/*
This function assumes the list staticlinkmodules
will be formed from package names with '::' replaced
with '/'. Thus Win32::OLE is in the list as Win32/OLE
*/
static int
dl_static_linked(char *filename)
{
const char * const *p;
char *ptr, *hptr;
static const char subStr[] = "/auto/";
char szBuffer[MAX_PATH];
/* avoid buffer overflow when called with invalid filenames */
if (strlen(filename) >= sizeof(szBuffer))
return 0;
/* change all the '\\' to '/' */
strcpy(szBuffer, filename);
for(ptr = szBuffer; ptr = strchr(ptr, '\\'); ++ptr)
*ptr = '/';
/* delete the file name */
ptr = strrchr(szBuffer, '/');
if(ptr != NULL)
*ptr = '\0';
/* remove leading lib path */
ptr = strstr(szBuffer, subStr);
if(ptr != NULL)
ptr += sizeof(subStr)-1;
else
ptr = szBuffer;
for (p = staticlinkmodules; *p;p++) {
if (hptr = strstr(ptr, *p)) {
/* found substring, need more detailed check if module name match */
if (hptr==ptr) {
return strcmp(ptr, *p)==0;
}
if (hptr[strlen(*p)] == 0)
return hptr[-1]=='/';
}
};
return 0;
}
MODULE = DynaLoader PACKAGE = DynaLoader
BOOT:
(void)dl_private_init(aTHX);
void
dl_load_file(filename,flags=0)
char * filename
int flags
PREINIT:
void *retv;
CODE:
{
DLDEBUG(1,PerlIO_printf(Perl_debug_log,"dl_load_file(%s):\n", filename));
if (dl_static_linked(filename) == 0) {
retv = PerlProc_DynaLoad(filename);
}
else
retv = (void*) Win_GetModuleHandle(NULL);
DLDEBUG(2,PerlIO_printf(Perl_debug_log," libref=%x\n", retv));
ST(0) = sv_newmortal() ;
if (retv == NULL)
SaveError(aTHX_ "load_file:%s",
OS_Error_String(aTHX)) ;
else
sv_setiv( ST(0), (IV)retv);
}
int
dl_unload_file(libref)
void * libref
CODE:
DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_unload_file(%lx):\n", PTR2ul(libref)));
RETVAL = FreeLibrary(libref);
if (!RETVAL)
SaveError(aTHX_ "unload_file:%s", OS_Error_String(aTHX)) ;
DLDEBUG(2,PerlIO_printf(Perl_debug_log, " retval = %d\n", RETVAL));
OUTPUT:
RETVAL
void
dl_find_symbol(libhandle, symbolname)
void * libhandle
char * symbolname
PREINIT:
void *retv;
CODE:
DLDEBUG(2,PerlIO_printf(Perl_debug_log,"dl_find_symbol(handle=%x, symbol=%s)\n",
libhandle, symbolname));
retv = (void*) GetProcAddress((HINSTANCE) libhandle, symbolname);
DLDEBUG(2,PerlIO_printf(Perl_debug_log," symbolref = %x\n", retv));
ST(0) = sv_newmortal() ;
if (retv == NULL)
SaveError(aTHX_ "find_symbol:%s",
OS_Error_String(aTHX)) ;
else
sv_setiv( ST(0), (IV)retv);
void
dl_undef_symbols()
CODE:
# These functions should not need changing on any platform:
void
dl_install_xsub(perl_name, symref, filename="$Package")
char * perl_name
void * symref
char * filename
CODE:
DLDEBUG(2,PerlIO_printf(Perl_debug_log,"dl_install_xsub(name=%s, symref=%x)\n",
perl_name, symref));
ST(0) = sv_2mortal(newRV((SV*)newXS(perl_name,
(void(*)(pTHX_ CV *))symref,
filename)));
char *
dl_error()
CODE:
dMY_CXT;
RETVAL = dl_last_error;
OUTPUT:
RETVAL
#if defined(USE_ITHREADS)
void
CLONE(...)
CODE:
MY_CXT_CLONE;
PERL_UNUSED_VAR(items);
/* MY_CXT_CLONE just does a memcpy on the whole structure, so to avoid
* using Perl variables that belong to another thread, we create our
* own for this thread.
*/
MY_CXT.x_dl_last_error = newSVpvn("", 0);
#endif
# end.
|