static HINSTANCE hInstance; /* HINSTANCE of this DLL. */
static int platformId; /* Running under NT, or 95/98? */
+#ifdef HAVE_NO_SEH
+static void *ESP;
+static void *EBP;
+#endif /* HAVE_NO_SEH */
+
/*
* The following function tables are used to dispatch to either the
* wide-character or multi-byte versions of the operating system calls,
WCHAR *, TCHAR **)) SearchPathA,
(BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryA,
(BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesA,
+ NULL,
+ NULL,
};
static TclWinProcs unicodeProcs = {
WCHAR *, TCHAR **)) SearchPathW,
(BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryW,
(BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesW,
+ NULL,
+ NULL,
};
TclWinProcs *tclWinProcs;
-Tcl_Encoding tclWinTCharEncoding;
+static Tcl_Encoding tclWinTCharEncoding;
/*
* The following declaration is for the VC++ DLL entry point.
BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
LPVOID reserved);
-/* CYGNUS LOCAL */
-#ifdef __CYGWIN__0
-/* CYGWIN requires an impure pointer variable, which must be
- explicitly initialized when the DLL starts up. */
-struct _reent *_impure_ptr;
-extern struct _reent __declspec(dllimport) reent_data;
-#endif
-/* END CYGNUS LOCAL */
#ifdef __WIN32__
#ifndef STATIC_BUILD
DWORD reason; /* Reason this function is being called. */
LPVOID reserved; /* Not used. */
{
- /* CYGNUS LOCAL */
-#ifdef __CYGWIN__0
- /* Cygwin requires the impure data pointer to be initialized
- when the DLL starts up. */
- _impure_ptr = &reent_data;
-#endif
- /* END CYGNUS LOCAL */
-
switch (reason) {
case DLL_PROCESS_ATTACH:
TclWinInit(hInst);
int
TclpCheckStackSpace()
{
+ int retval = 0;
+
/*
* We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD
* bytes of stack space left. alloca() is cheap on windows; basically
* exception if the stack pointer is set below the bottom of the stack.
*/
-#ifndef __GNUC__
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "movl %esp, _ESP" "\n\t"
+ "movl %ebp, _EBP");
+
+ __asm__ __volatile__ (
+ "pushl $__except_checkstackspace_handler" "\n\t"
+ "pushl %fs:0" "\n\t"
+ "mov %esp, %fs:0");
+#else
__try {
+#endif /* HAVE_NO_SEH */
alloca(TCL_WIN_STACK_THRESHOLD);
- return 1;
- /* CYGNUS LOCAL */
- } __except (1) {}
+ retval = 1;
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "jmp checkstackspace_pop" "\n"
+ "checkstackspace_reentry:" "\n\t"
+ "movl _ESP, %esp" "\n\t"
+ "movl _EBP, %ebp");
+
+ __asm__ __volatile__ (
+ "checkstackspace_pop:" "\n\t"
+ "mov (%esp), %eax" "\n\t"
+ "mov %eax, %fs:0" "\n\t"
+ "add $8, %esp");
#else
- return alloca(TCL_WIN_STACK_THRESHOLD) != NULL;
-#endif
+ } __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
- return 0;
+ /*
+ * Avoid using control flow statements in the SEH guarded block!
+ */
+ return retval;
}
-
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_checkstackspace_handler(
+ struct _EXCEPTION_RECORD *ExceptionRecord,
+ void *EstablisherFrame,
+ struct _CONTEXT *ContextRecord,
+ void *DispatcherContext)
+{
+ __asm__ __volatile__ (
+ "jmp checkstackspace_reentry");
+ return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
\f
/*
*----------------------------------------------------------------------
* tclWinProcs structure to dispatch to either the wide-character
* or multi-byte versions of the operating system calls, depending
* on whether Unicode is the system encoding.
+ *
+ * As well as this, we can also try to load in some additional
+ * procs which may/may not be present depending on the current
+ * Windows version (e.g. Win95 will not have the procs below).
*
* Results:
* None.
if (wide) {
tclWinProcs = &unicodeProcs;
tclWinTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
+ if (tclWinProcs->getFileAttributesExProc == NULL) {
+ HINSTANCE hInstance = LoadLibraryA("kernel32");
+ if (hInstance != NULL) {
+ tclWinProcs->getFileAttributesExProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
+ LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExW");
+ tclWinProcs->createHardLinkProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
+ LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
+ "CreateHardLinkW");
+ FreeLibrary(hInstance);
+ }
+ }
} else {
tclWinProcs = &asciiProcs;
tclWinTCharEncoding = NULL;
+ if (tclWinProcs->getFileAttributesExProc == NULL) {
+ HINSTANCE hInstance = LoadLibraryA("kernel32");
+ if (hInstance != NULL) {
+ tclWinProcs->getFileAttributesExProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
+ LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExA");
+ tclWinProcs->createHardLinkProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
+ LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
+ "CreateHardLinkA");
+ FreeLibrary(hInstance);
+ }
+ }
}
}
\f
return Tcl_ExternalToUtfDString(tclWinTCharEncoding,
(CONST char *) string, len, dsPtr);
}
-
-
-