summaryrefslogtreecommitdiffstats
path: root/win/tclWin32Dll.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tclWin32Dll.c')
-rw-r--r--win/tclWin32Dll.c1220
1 files changed, 636 insertions, 584 deletions
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index 0fe1b52..ce54eee 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -1,22 +1,23 @@
/*
* tclWin32Dll.c --
*
- * This file contains the DLL entry point.
+ * This file contains the DLL entry point and other low-level bit bashing
+ * code that needs inline assembly.
*
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWin32Dll.c,v 1.45 2005/06/06 20:54:18 kennykb Exp $
+ * RCS: @(#) $Id: tclWin32Dll.c,v 1.46 2005/07/24 22:56:46 dkf Exp $
*/
#include "tclWinInt.h"
/*
- * The following data structures are used when loading the thunking
- * library for execing child processes under Win32s.
+ * The following data structures are used when loading the thunking library
+ * for execing child processes under Win32s.
*/
typedef DWORD (WINAPI UT32PROC)(LPVOID lpBuff, DWORD dwUserDefined,
@@ -29,40 +30,37 @@ typedef BOOL (WINAPI UTREGISTER)(HANDLE hModule, LPCSTR SixteenBitDLL,
typedef VOID (WINAPI UTUNREGISTER)(HANDLE hModule);
/*
- * The following variables keep track of information about this DLL
- * on a per-instance basis. Each time this DLL is loaded, it gets its own
- * new data segment with its own copy of all static and global information.
+ * The following variables keep track of information about this DLL on a
+ * per-instance basis. Each time this DLL is loaded, it gets its own new data
+ * segment with its own copy of all static and global information.
*/
static HINSTANCE hInstance; /* HINSTANCE of this DLL. */
static int platformId; /* Running under NT, or 95/98? */
#ifdef HAVE_NO_SEH
-
/*
- * Unlike Borland and Microsoft, we don't register exception handlers
- * by pushing registration records onto the runtime stack. Instead, we
- * register them by creating an EXCEPTION_REGISTRATION within the activation
- * record.
+ * Unlike Borland and Microsoft, we don't register exception handlers by
+ * pushing registration records onto the runtime stack. Instead, we register
+ * them by creating an EXCEPTION_REGISTRATION within the activation record.
*/
typedef struct EXCEPTION_REGISTRATION {
- struct EXCEPTION_REGISTRATION* link;
- EXCEPTION_DISPOSITION (*handler)( struct _EXCEPTION_RECORD*, void*,
- struct _CONTEXT*, void* );
- void* ebp;
- void* esp;
+ struct EXCEPTION_REGISTRATION *link;
+ EXCEPTION_DISPOSITION (*handler)(
+ struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
+ void *ebp;
+ void *esp;
int status;
} EXCEPTION_REGISTRATION;
-
#endif
/*
- * VC++ 5.x has no 'cpuid' assembler instruction, so we
- * must emulate it
+ * VC++ 5.x has no 'cpuid' assembler instruction, so we must emulate it
*/
-#if defined(_MSC_VER) && ( _MSC_VER <= 1100 )
-#define cpuid __asm __emit 0fh __asm __emit 0a2h
+
+#if defined(_MSC_VER) && (_MSC_VER <= 1100)
+#define cpuid __asm __emit 0fh __asm __emit 0a2h
#endif
/*
@@ -106,13 +104,15 @@ static TclWinProcs asciiProcs = {
WCHAR *, TCHAR **)) SearchPathA,
(BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryA,
(BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesA,
+
/*
* The three NULL function pointers will only be set when
- * Tcl_FindExecutable is called. If you don't ever call that
- * function, the application will crash whenever WinTcl tries to call
- * functions through these null pointers. That is not a bug in Tcl
- * -- Tcl_FindExecutable is obligatory in recent Tcl releases.
+ * Tcl_FindExecutable is called. If you don't ever call that function, the
+ * application will crash whenever WinTcl tries to call functions through
+ * these null pointers. That is not a bug in Tcl - Tcl_FindExecutable is
+ * mandatory in recent Tcl releases.
*/
+
NULL,
NULL,
/* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _utime, */
@@ -157,13 +157,15 @@ static TclWinProcs unicodeProcs = {
WCHAR *, TCHAR **)) SearchPathW,
(BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryW,
(BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesW,
+
/*
* The three NULL function pointers will only be set when
- * Tcl_FindExecutable is called. If you don't ever call that
- * function, the application will crash whenever WinTcl tries to call
- * functions through these null pointers. That is not a bug in Tcl
- * -- Tcl_FindExecutable is obligatory in recent Tcl releases.
+ * Tcl_FindExecutable is called. If you don't ever call that function, the
+ * application will crash whenever WinTcl tries to call functions through
+ * these null pointers. That is not a bug in Tcl - Tcl_FindExecutable is
+ * mandatory in recent Tcl releases.
*/
+
NULL,
NULL,
/* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _wutime, */
@@ -176,64 +178,63 @@ static TclWinProcs unicodeProcs = {
TclWinProcs *tclWinProcs;
static Tcl_Encoding tclWinTCharEncoding;
-
#ifdef HAVE_NO_SEH
-
-/* Need to add noinline flag to DllMain declaration so that gcc -O3
- * does not inline asm code into DllEntryPoint and cause a
- * compile time error because of redefined local labels.
+/*
+ * Need to add noinline flag to DllMain declaration so that gcc -O3 does not
+ * inline asm code into DllEntryPoint and cause a compile time error because
+ * of redefined local labels.
*/
BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
- LPVOID reserved)
- __attribute__ ((noinline));
-
+ LPVOID reserved) __attribute__ ((noinline));
#else
-
/*
* The following declaration is for the VC++ DLL entry point.
*/
BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
- LPVOID reserved);
+ LPVOID reserved);
#endif /* HAVE_NO_SEH */
-
/*
* The following structure and linked list is to allow us to map between
- * volume mount points and drive letters on the fly (no Win API exists
- * for this).
+ * volume mount points and drive letters on the fly (no Win API exists for
+ * this).
*/
+
typedef struct MountPointMap {
- CONST WCHAR* volumeName; /* Native wide string volume name */
- char driveLetter; /* Drive letter corresponding to
- * the volume name. */
- struct MountPointMap* nextPtr; /* Pointer to next structure in list,
- * or NULL */
+ CONST WCHAR *volumeName; /* Native wide string volume name. */
+ char driveLetter; /* Drive letter corresponding to the volume
+ * name. */
+ struct MountPointMap *nextPtr;
+ /* Pointer to next structure in list, or
+ * NULL. */
} MountPointMap;
/*
- * This is the head of the linked list, which is protected by the
- * mutex which follows, for thread-enabled builds.
+ * This is the head of the linked list, which is protected by the mutex which
+ * follows, for thread-enabled builds.
*/
+
MountPointMap *driveLetterLookup = NULL;
TCL_DECLARE_MUTEX(mountPointMap)
-/* We will need this below */
+/*
+ * We will need this below.
+ */
+
extern Tcl_FSDupInternalRepProc TclNativeDupInternalRep;
#ifdef __WIN32__
#ifndef STATIC_BUILD
-
/*
*----------------------------------------------------------------------
*
* DllEntryPoint --
*
- * This wrapper function is used by Borland to invoke the
- * initialization code for Tcl. It simply calls the DllMain
- * routine.
+ * This wrapper function is used by Borland to invoke the initialization
+ * code for Tcl. It simply calls the DllMain routine.
*
* Results:
* See DllMain.
@@ -258,21 +259,22 @@ DllEntryPoint(hInst, reason, reserved)
*
* DllMain --
*
- * This routine is called by the VC++ C run time library init
- * code, or the DllEntryPoint routine. It is responsible for
- * initializing various dynamically loaded libraries.
+ * This routine is called by the VC++ C run time library init code, or
+ * the DllEntryPoint routine. It is responsible for initializing various
+ * dynamically loaded libraries.
*
* Results:
* TRUE on sucess, FALSE on failure.
*
* Side effects:
- * Establishes 32-to-16 bit thunk and initializes sockets library.
- * This might call some sycronization functions, but MSDN
- * documentation states: "Waiting on synchronization objects in
- * DllMain can cause a deadlock."
+ * Establishes 32-to-16 bit thunk and initializes sockets library. This
+ * might call some sycronization functions, but MSDN documentation
+ * states: "Waiting on synchronization objects in DllMain can cause a
+ * deadlock."
*
*----------------------------------------------------------------------
*/
+
BOOL APIENTRY
DllMain(hInst, reason, reserved)
HINSTANCE hInst; /* Library instance handle. */
@@ -291,76 +293,79 @@ DllMain(hInst, reason, reserved)
case DLL_PROCESS_DETACH:
/*
- * Protect the call to Tcl_Finalize. The OS could be unloading
- * us from an exception handler and the state of the stack might
- * be unstable.
+ * Protect the call to Tcl_Finalize. The OS could be unloading us from
+ * an exception handler and the state of the stack might be unstable.
*/
+
#ifdef HAVE_NO_SEH
- __asm__ __volatile__ (
-
- /*
- * Construct an EXCEPTION_REGISTRATION to protect the
- * call to Tcl_Finalize
- */
- "leal %[registration], %%edx" "\n\t"
- "movl %%fs:0, %%eax" "\n\t"
- "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
- "leal 1f, %%eax" "\n\t"
- "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
- "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
- "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
- "movl %[error], 0x10(%%edx)" "\n\t" /* status */
-
- /*
- * Link the EXCEPTION_REGISTRATION on the chain
- */
- "movl %%edx, %%fs:0" "\n\t"
-
- /*
- * Call Tcl_Finalize
- */
- "call _Tcl_Finalize" "\n\t"
-
- /*
- * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION
- * and store a TCL_OK status
- */
-
- "movl %%fs:0, %%edx" "\n\t"
- "movl %[ok], %%eax" "\n\t"
- "movl %%eax, 0x10(%%edx)" "\n\t"
- "jmp 2f" "\n"
-
- /*
- * Come here on an exception. Get the EXCEPTION_REGISTRATION
- * that we previously put on the chain.
- */
-
- "1:" "\t"
- "movl %%fs:0, %%edx" "\n\t"
- "movl 0x8(%%edx), %%edx" "\n"
-
-
- /*
- * Come here however we exited. Restore context from the
- * EXCEPTION_REGISTRATION in case the stack is unbalanced.
- */
-
- "2:" "\t"
- "movl 0xc(%%edx), %%esp" "\n\t"
- "movl 0x8(%%edx), %%ebp" "\n\t"
- "movl 0x0(%%edx), %%eax" "\n\t"
- "movl %%eax, %%fs:0" "\n\t"
-
- :
- /* No outputs */
- :
- [registration] "m" (registration),
- [ok] "i" (TCL_OK),
- [error] "i" (TCL_ERROR)
- :
- "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
- );
+ __asm__ __volatile__ (
+
+ /*
+ * Construct an EXCEPTION_REGISTRATION to protect the call to
+ * Tcl_Finalize
+ */
+
+ "leal %[registration], %%edx" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
+ "leal 1f, %%eax" "\n\t"
+ "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
+ "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
+ "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
+ "movl %[error], 0x10(%%edx)" "\n\t" /* status */
+
+ /*
+ * Link the EXCEPTION_REGISTRATION on the chain
+ */
+
+ "movl %%edx, %%fs:0" "\n\t"
+
+ /*
+ * Call Tcl_Finalize
+ */
+
+ "call _Tcl_Finalize" "\n\t"
+
+ /*
+ * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION
+ * and store a TCL_OK status
+ */
+
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl %[ok], %%eax" "\n\t"
+ "movl %%eax, 0x10(%%edx)" "\n\t"
+ "jmp 2f" "\n"
+
+ /*
+ * Come here on an exception. Get the EXCEPTION_REGISTRATION that
+ * we previously put on the chain.
+ */
+
+ "1:" "\t"
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%edx" "\n"
+
+
+ /*
+ * Come here however we exited. Restore context from the
+ * EXCEPTION_REGISTRATION in case the stack is unbalanced.
+ */
+
+ "2:" "\t"
+ "movl 0xc(%%edx), %%esp" "\n\t"
+ "movl 0x8(%%edx), %%ebp" "\n\t"
+ "movl 0x0(%%edx), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+
+ :
+ /* No outputs */
+ :
+ [registration] "m" (registration),
+ [ok] "i" (TCL_OK),
+ [error] "i" (TCL_ERROR)
+ :
+ "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
+ );
#else /* HAVE_NO_SEH */
__try {
@@ -375,7 +380,6 @@ DllMain(hInst, reason, reserved)
return TRUE;
}
-
#endif /* !STATIC_BUILD */
#endif /* __WIN32__ */
@@ -429,8 +433,8 @@ TclWinInit(hInst)
platformId = os.dwPlatformId;
/*
- * We no longer support Win32s, so just in case someone manages to
- * get a runtime there, make sure they know that.
+ * We no longer support Win32s, so just in case someone manages to get a
+ * runtime there, make sure they know that.
*/
if (platformId == VER_PLATFORM_WIN32s) {
@@ -445,8 +449,8 @@ TclWinInit(hInst)
*
* TclWinGetPlatformId --
*
- * Determines whether running under NT, 95, or Win32s, to allow
- * runtime conditional code.
+ * Determines whether running under NT, 95, or Win32s, to allow runtime
+ * conditional code.
*
* Results:
* The return value is one of:
@@ -502,8 +506,8 @@ TclWinNoBackslash(
*
* TclpCheckStackSpace --
*
- * Detect if we are about to blow the stack. Called before an
- * evaluation can happen when nesting depth is checked.
+ * Detect if we are about to blow the stack. Called before an evaluation
+ * can happen when nesting depth is checked.
*
* Results:
* 1 if there is enough stack space to continue; 0 if not.
@@ -524,95 +528,98 @@ 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
- * it just subtracts from the stack pointer causing the OS to throw an
- * exception if the stack pointer is set below the bottom of the stack.
+ * We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD bytes
+ * of stack space left. alloca() is cheap on windows; basically it just
+ * subtracts from the stack pointer causing the OS to throw an exception
+ * if the stack pointer is set below the bottom of the stack.
*/
#ifdef HAVE_NO_SEH
__asm__ __volatile__ (
- /*
- * Construct an EXCEPTION_REGISTRATION to protect the
- * call to __alloca
- */
- "leal %[registration], %%edx" "\n\t"
- "movl %%fs:0, %%eax" "\n\t"
- "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
- "leal 1f, %%eax" "\n\t"
- "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
- "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
- "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
- "movl %[error], 0x10(%%edx)" "\n\t" /* status */
-
- /*
- * Link the EXCEPTION_REGISTRATION on the chain
- */
- "movl %%edx, %%fs:0" "\n\t"
-
- /*
- * Attempt a call to __alloca, to determine whether there's
- * sufficient memory to be had.
- */
-
- "movl %[size], %%eax" "\n\t"
- "pushl %%eax" "\n\t"
- "call __alloca" "\n\t"
-
- /*
- * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION
- * and store a TCL_OK status
- */
- "movl %%fs:0, %%edx" "\n\t"
- "movl %[ok], %%eax" "\n\t"
- "movl %%eax, 0x10(%%edx)" "\n\t"
- "jmp 2f" "\n"
-
- /*
- * Come here on an exception. Get the EXCEPTION_REGISTRATION
- * that we previously put on the chain.
- */
- "1:" "\t"
- "movl %%fs:0, %%edx" "\n\t"
- "movl 0x8(%%edx), %%edx" "\n\t"
-
- /*
- * Come here however we exited. Restore context from the
- * EXCEPTION_REGISTRATION in case the stack is unbalanced.
- */
-
- "2:" "\t"
- "movl 0xc(%%edx), %%esp" "\n\t"
- "movl 0x8(%%edx), %%ebp" "\n\t"
- "movl 0x0(%%edx), %%eax" "\n\t"
- "movl %%eax, %%fs:0" "\n\t"
-
- :
- /* No outputs */
- :
- [registration] "m" (registration),
- [ok] "i" (TCL_OK),
- [error] "i" (TCL_ERROR),
- [size] "i" (TCL_WIN_STACK_THRESHOLD)
- :
- "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
- );
+ /*
+ * Construct an EXCEPTION_REGISTRATION to protect the call to __alloca
+ */
+
+ "leal %[registration], %%edx" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
+ "leal 1f, %%eax" "\n\t"
+ "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
+ "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
+ "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
+ "movl %[error], 0x10(%%edx)" "\n\t" /* status */
+
+ /*
+ * Link the EXCEPTION_REGISTRATION on the chain
+ */
+
+ "movl %%edx, %%fs:0" "\n\t"
+
+ /*
+ * Attempt a call to __alloca, to determine whether there's sufficient
+ * memory to be had.
+ */
+
+ "movl %[size], %%eax" "\n\t"
+ "pushl %%eax" "\n\t"
+ "call __alloca" "\n\t"
+
+ /*
+ * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION and
+ * store a TCL_OK status
+ */
+
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl %[ok], %%eax" "\n\t"
+ "movl %%eax, 0x10(%%edx)" "\n\t"
+ "jmp 2f" "\n"
+
+ /*
+ * Come here on an exception. Get the EXCEPTION_REGISTRATION that we
+ * previously put on the chain.
+ */
+
+ "1:" "\t"
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%edx" "\n\t"
+
+ /*
+ * Come here however we exited. Restore context from the
+ * EXCEPTION_REGISTRATION in case the stack is unbalanced.
+ */
+
+ "2:" "\t"
+ "movl 0xc(%%edx), %%esp" "\n\t"
+ "movl 0x8(%%edx), %%ebp" "\n\t"
+ "movl 0x0(%%edx), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+
+ :
+ /* No outputs */
+ :
+ [registration] "m" (registration),
+ [ok] "i" (TCL_OK),
+ [error] "i" (TCL_ERROR),
+ [size] "i" (TCL_WIN_STACK_THRESHOLD)
+ :
+ "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
+ );
retval = (registration.status == TCL_OK);
#else /* !HAVE_NO_SEH */
__try {
#ifdef HAVE_ALLOCA_GCC_INLINE
- __asm__ __volatile__ (
- "movl %0, %%eax" "\n\t"
- "call __alloca" "\n\t"
- :
- : "i"(TCL_WIN_STACK_THRESHOLD)
- : "%eax");
+ __asm__ __volatile__ (
+ "movl %0, %%eax" "\n\t"
+ "call __alloca" "\n\t"
+ :
+ : "i"(TCL_WIN_STACK_THRESHOLD)
+ : "%eax");
#else
- alloca(TCL_WIN_STACK_THRESHOLD);
+ alloca(TCL_WIN_STACK_THRESHOLD);
#endif /* HAVE_ALLOCA_GCC_INLINE */
- retval = 1;
+ retval = 1;
} __except (EXCEPTION_EXECUTE_HANDLER) {}
#endif /* HAVE_NO_SEH */
@@ -624,123 +631,123 @@ TclpCheckStackSpace()
*
* TclWinSetInterfaces --
*
- * A helper proc that allows the test library to change the
- * 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).
+ * A helper proc that allows the test library to change the 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.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
void
TclWinSetInterfaces(
- int wide) /* Non-zero to use wide interfaces, 0
- * otherwise. */
+ int wide) /* Non-zero to use wide interfaces, 0
+ * otherwise. */
{
Tcl_FreeEncoding(tclWinTCharEncoding);
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");
- tclWinProcs->findFirstFileExProc =
- (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
- LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
- "FindFirstFileExW");
- tclWinProcs->getVolumeNameForVMPProc =
- (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetVolumeNameForVolumeMountPointW");
- tclWinProcs->getLongPathNameProc =
- (DWORD (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetLongPathNameW");
- FreeLibrary(hInstance);
- }
- hInstance = LoadLibraryA("advapi32");
- if (hInstance != NULL) {
- tclWinProcs->getFileSecurityProc = (BOOL (WINAPI *)(
- LPCTSTR lpFileName,
- SECURITY_INFORMATION RequestedInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength,
- LPDWORD lpnLengthNeeded)) GetProcAddress(hInstance,
- "GetFileSecurityW");
- tclWinProcs->impersonateSelfProc = (BOOL (WINAPI *) (
- SECURITY_IMPERSONATION_LEVEL ImpersonationLevel))
- GetProcAddress(hInstance, "ImpersonateSelf");
- tclWinProcs->openThreadTokenProc = (BOOL (WINAPI *) (
- HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf,
- PHANDLE TokenHandle)) GetProcAddress(hInstance,
- "OpenThreadToken");
- tclWinProcs->revertToSelfProc = (BOOL (WINAPI *) (void))
- GetProcAddress(hInstance, "RevertToSelf");
- tclWinProcs->mapGenericMaskProc = (VOID (WINAPI *) (
- PDWORD AccessMask, PGENERIC_MAPPING GenericMapping))
- GetProcAddress(hInstance, "MapGenericMask");
- tclWinProcs->accessCheckProc = (BOOL (WINAPI *)(
- PSECURITY_DESCRIPTOR pSecurityDescriptor,
- HANDLE ClientToken, DWORD DesiredAccess,
- PGENERIC_MAPPING GenericMapping,
- PPRIVILEGE_SET PrivilegeSet,
- LPDWORD PrivilegeSetLength,
- LPDWORD GrantedAccess,
- LPBOOL AccessStatus)) GetProcAddress(hInstance,
- "AccessCheck");
- FreeLibrary(hInstance);
- }
- }
+ 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");
+ tclWinProcs->findFirstFileExProc =
+ (HANDLE (WINAPI *)(CONST TCHAR*, UINT, LPVOID, UINT,
+ LPVOID, DWORD)) GetProcAddress(hInstance,
+ "FindFirstFileExW");
+ tclWinProcs->getVolumeNameForVMPProc =
+ (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance,
+ "GetVolumeNameForVolumeMountPointW");
+ tclWinProcs->getLongPathNameProc =
+ (DWORD (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance, "GetLongPathNameW");
+ FreeLibrary(hInstance);
+ }
+ hInstance = LoadLibraryA("advapi32");
+ if (hInstance != NULL) {
+ tclWinProcs->getFileSecurityProc = (BOOL (WINAPI *)(
+ LPCTSTR lpFileName,
+ SECURITY_INFORMATION RequestedInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ DWORD nLength, LPDWORD lpnLengthNeeded))
+ GetProcAddress(hInstance, "GetFileSecurityW");
+ tclWinProcs->impersonateSelfProc = (BOOL (WINAPI *) (
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel))
+ GetProcAddress(hInstance, "ImpersonateSelf");
+ tclWinProcs->openThreadTokenProc = (BOOL (WINAPI *) (
+ HANDLE ThreadHandle, DWORD DesiredAccess,
+ BOOL OpenAsSelf, PHANDLE TokenHandle))
+ GetProcAddress(hInstance, "OpenThreadToken");
+ tclWinProcs->revertToSelfProc = (BOOL (WINAPI *) (void))
+ GetProcAddress(hInstance, "RevertToSelf");
+ tclWinProcs->mapGenericMaskProc = (VOID (WINAPI *) (
+ PDWORD AccessMask, PGENERIC_MAPPING GenericMapping))
+ GetProcAddress(hInstance, "MapGenericMask");
+ tclWinProcs->accessCheckProc = (BOOL (WINAPI *)(
+ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ HANDLE ClientToken, DWORD DesiredAccess,
+ PGENERIC_MAPPING GenericMapping,
+ PPRIVILEGE_SET PrivilegeSet,
+ LPDWORD PrivilegeSetLength, LPDWORD GrantedAccess,
+ LPBOOL AccessStatus)) GetProcAddress(hInstance,
+ "AccessCheck");
+ 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");
- tclWinProcs->findFirstFileExProc = NULL;
- tclWinProcs->getLongPathNameProc = NULL;
- /*
- * The 'findFirstFileExProc' function exists on some
- * of 95/98/ME, but it seems not to work as anticipated.
- * Therefore we don't set this function pointer. The
- * relevant code will fall back on a slower approach
- * using the normal findFirstFileProc.
- *
- * (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
- * LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
- * "FindFirstFileExA");
- */
- tclWinProcs->getVolumeNameForVMPProc =
- (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetVolumeNameForVolumeMountPointA");
- FreeLibrary(hInstance);
- }
- }
+ 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");
+ tclWinProcs->findFirstFileExProc = NULL;
+ tclWinProcs->getLongPathNameProc = NULL;
+ /*
+ * The 'findFirstFileExProc' function exists on some of
+ * 95/98/ME, but it seems not to work as anticipated.
+ * Therefore we don't set this function pointer. The relevant
+ * code will fall back on a slower approach using the normal
+ * findFirstFileProc.
+ *
+ * (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
+ * LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
+ * "FindFirstFileExA");
+ */
+ tclWinProcs->getVolumeNameForVMPProc =
+ (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance,
+ "GetVolumeNameForVolumeMountPointA");
+ FreeLibrary(hInstance);
+ }
+ }
}
}
@@ -749,39 +756,43 @@ TclWinSetInterfaces(
*
* TclWinResetInterfaceEncodings --
*
- * Called during finalization to free up any encodings we use.
- * The tclWinProcs-> look up table is still ok to use after
- * this call, provided no encoding conversion is required.
+ * Called during finalization to free up any encodings we use. The
+ * tclWinProcs-> look up table is still ok to use after this call,
+ * provided no encoding conversion is required.
*
- * We also clean up any memory allocated in our mount point
- * map which is used to follow certain kinds of symlinks.
- * That code should never be used once encodings are taken
- * down.
- *
+ * We also clean up any memory allocated in our mount point map which is
+ * used to follow certain kinds of symlinks. That code should never be
+ * used once encodings are taken down.
+ *
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
+
void
TclWinResetInterfaceEncodings()
{
MountPointMap *dlIter, *dlIter2;
if (tclWinTCharEncoding != NULL) {
- Tcl_FreeEncoding(tclWinTCharEncoding);
- tclWinTCharEncoding = NULL;
+ Tcl_FreeEncoding(tclWinTCharEncoding);
+ tclWinTCharEncoding = NULL;
}
- /* Clean up the mount point map */
+
+ /*
+ * Clean up the mount point map.
+ */
+
Tcl_MutexLock(&mountPointMap);
dlIter = driveLetterLookup;
while (dlIter != NULL) {
- dlIter2 = dlIter->nextPtr;
- ckfree((char*)dlIter->volumeName);
- ckfree((char*)dlIter);
- dlIter = dlIter2;
+ dlIter2 = dlIter->nextPtr;
+ ckfree((char*)dlIter->volumeName);
+ ckfree((char*)dlIter);
+ dlIter = dlIter2;
}
Tcl_MutexUnlock(&mountPointMap);
}
@@ -791,15 +802,15 @@ TclWinResetInterfaceEncodings()
*
* TclWinResetInterfaces --
*
- * Called during finalization to reset us to a safe state for reuse.
- * After this call, it is best not to use the tclWinProcs-> look
- * up table since it is likely to be different to what is expected.
+ * Called during finalization to reset us to a safe state for reuse.
+ * After this call, it is best not to use the tclWinProcs-> look up table
+ * since it is likely to be different to what is expected.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
@@ -814,121 +825,149 @@ TclWinResetInterfaces()
*
* TclWinDriveLetterForVolMountPoint
*
- * Unfortunately, Windows provides no easy way at all to get hold
- * of the drive letter for a volume mount point, but we need that
- * information to understand paths correctly. So, we have to
- * build an associated array to find these correctly, and allow
- * quick and easy lookup from volume mount points to drive letters.
+ * Unfortunately, Windows provides no easy way at all to get hold of the
+ * drive letter for a volume mount point, but we need that information to
+ * understand paths correctly. So, we have to build an associated array
+ * to find these correctly, and allow quick and easy lookup from volume
+ * mount points to drive letters.
*
- * We assume here that we are running on a system for which the wide
- * character interfaces are used, which is valid for Win 2000 and WinXP
- * which are the only systems on which this function will ever be called.
+ * We assume here that we are running on a system for which the wide
+ * character interfaces are used, which is valid for Win 2000 and WinXP
+ * which are the only systems on which this function will ever be called.
*
- * Result: the drive letter, or -1 if no drive letter corresponds to
- * the given mount point.
+ * Result:
+ * The drive letter, or -1 if no drive letter corresponds to the given
+ * mount point.
*
*--------------------------------------------------------------------
*/
+
char
TclWinDriveLetterForVolMountPoint(CONST WCHAR *mountPoint)
{
MountPointMap *dlIter, *dlPtr2;
- WCHAR Target[55]; /* Target of mount at mount point */
+ WCHAR Target[55]; /* Target of mount at mount point */
WCHAR drive[4] = { L'A', L':', L'\\', L'\0' };
/*
- * Detect the volume mounted there. Unfortunately, there is no
- * simple way to map a unique volume name to a DOS drive letter.
- * So, we have to build an associative array.
+ * Detect the volume mounted there. Unfortunately, there is no simple way
+ * to map a unique volume name to a DOS drive letter. So, we have to build
+ * an associative array.
*/
Tcl_MutexLock(&mountPointMap);
dlIter = driveLetterLookup;
while (dlIter != NULL) {
- if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
- /*
- * We need to check whether this information is
- * still valid, since either the user or various
- * programs could have adjusted the mount points on
- * the fly.
- */
- drive[0] = L'A' + (dlIter->driveLetter - 'A');
- /* Try to read the volume mount point and see where it points */
- if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
- (TCHAR*)Target, 55) != 0) {
- if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
- /* Nothing has changed */
- Tcl_MutexUnlock(&mountPointMap);
- return dlIter->driveLetter;
- }
- }
- /*
- * If we reach here, unfortunately, this mount point is
- * no longer valid at all
- */
- if (driveLetterLookup == dlIter) {
- dlPtr2 = dlIter;
- driveLetterLookup = dlIter->nextPtr;
- } else {
- for (dlPtr2 = driveLetterLookup;
- dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
- if (dlPtr2->nextPtr == dlIter) {
- dlPtr2->nextPtr = dlIter->nextPtr;
- dlPtr2 = dlIter;
- break;
- }
- }
- }
- /* Now dlPtr2 points to the structure to free */
- ckfree((char*)dlPtr2->volumeName);
- ckfree((char*)dlPtr2);
- /*
- * Restart the loop --- we could try to be clever
- * and continue half way through, but the logic is a
- * bit messy, so it's cleanest just to restart
- */
- dlIter = driveLetterLookup;
- continue;
- }
- dlIter = dlIter->nextPtr;
+ if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
+ /*
+ * We need to check whether this information is still valid, since
+ * either the user or various programs could have adjusted the
+ * mount points on the fly.
+ */
+
+ drive[0] = L'A' + (dlIter->driveLetter - 'A');
+
+ /*
+ * Try to read the volume mount point and see where it points.
+ */
+
+ if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
+ (TCHAR*)Target, 55) != 0) {
+ if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
+ /*
+ * Nothing has changed.
+ */
+
+ Tcl_MutexUnlock(&mountPointMap);
+ return dlIter->driveLetter;
+ }
+ }
+
+ /*
+ * If we reach here, unfortunately, this mount point is no longer
+ * valid at all.
+ */
+
+ if (driveLetterLookup == dlIter) {
+ dlPtr2 = dlIter;
+ driveLetterLookup = dlIter->nextPtr;
+ } else {
+ for (dlPtr2 = driveLetterLookup;
+ dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
+ if (dlPtr2->nextPtr == dlIter) {
+ dlPtr2->nextPtr = dlIter->nextPtr;
+ dlPtr2 = dlIter;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Now dlPtr2 points to the structure to free.
+ */
+
+ ckfree((char*)dlPtr2->volumeName);
+ ckfree((char*)dlPtr2);
+
+ /*
+ * Restart the loop - we could try to be clever and continue half
+ * way through, but the logic is a bit messy, so it's cleanest
+ * just to restart.
+ */
+
+ dlIter = driveLetterLookup;
+ continue;
+ }
+ dlIter = dlIter->nextPtr;
}
- /* We couldn't find it, so we must iterate over the letters */
+ /*
+ * We couldn't find it, so we must iterate over the letters.
+ */
for (drive[0] = L'A'; drive[0] <= L'Z'; drive[0]++) {
- /* Try to read the volume mount point and see where it points */
- if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
- (TCHAR*)Target, 55) != 0) {
- int alreadyStored = 0;
- for (dlIter = driveLetterLookup; dlIter != NULL;
- dlIter = dlIter->nextPtr) {
- if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
- alreadyStored = 1;
- break;
- }
- }
- if (!alreadyStored) {
- dlPtr2 = (MountPointMap*) ckalloc(sizeof(MountPointMap));
- dlPtr2->volumeName = TclNativeDupInternalRep(Target);
- dlPtr2->driveLetter = 'A' + (drive[0] - L'A');
- dlPtr2->nextPtr = driveLetterLookup;
- driveLetterLookup = dlPtr2;
- }
- }
+ /*
+ * Try to read the volume mount point and see where it points.
+ */
+
+ if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
+ (TCHAR*)Target, 55) != 0) {
+ int alreadyStored = 0;
+
+ for (dlIter = driveLetterLookup; dlIter != NULL;
+ dlIter = dlIter->nextPtr) {
+ if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
+ alreadyStored = 1;
+ break;
+ }
+ }
+ if (!alreadyStored) {
+ dlPtr2 = (MountPointMap *) ckalloc(sizeof(MountPointMap));
+ dlPtr2->volumeName = TclNativeDupInternalRep(Target);
+ dlPtr2->driveLetter = 'A' + (drive[0] - L'A');
+ dlPtr2->nextPtr = driveLetterLookup;
+ driveLetterLookup = dlPtr2;
+ }
+ }
}
- /* Try again */
+
+ /*
+ * Try again.
+ */
+
for (dlIter = driveLetterLookup; dlIter != NULL;
- dlIter = dlIter->nextPtr) {
- if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
- Tcl_MutexUnlock(&mountPointMap);
- return dlIter->driveLetter;
- }
+ dlIter = dlIter->nextPtr) {
+ if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
+ Tcl_MutexUnlock(&mountPointMap);
+ return dlIter->driveLetter;
+ }
}
+
/*
- * The volume doesn't appear to correspond to a drive letter -- we
- * remember that fact and store '-1' so we don't have to look it
- * up each time.
+ * The volume doesn't appear to correspond to a drive letter - we remember
+ * that fact and store '-1' so we don't have to look it up each time.
*/
+
dlPtr2 = (MountPointMap*) ckalloc(sizeof(MountPointMap));
dlPtr2->volumeName = TclNativeDupInternalRep((ClientData)mountPoint);
dlPtr2->driveLetter = -1;
@@ -943,78 +982,74 @@ TclWinDriveLetterForVolMountPoint(CONST WCHAR *mountPoint)
*
* Tcl_WinUtfToTChar, Tcl_WinTCharToUtf --
*
- * Convert between UTF-8 and Unicode when running Windows NT or
- * the current ANSI code page when running Windows 95.
- *
- * On Mac, Unix, and Windows 95, all strings exchanged between Tcl
- * and the OS are "char" oriented. We need only one Tcl_Encoding to
- * convert between UTF-8 and the system's native encoding. We use
- * NULL to represent that encoding.
- *
- * On NT, some strings exchanged between Tcl and the OS are "char"
- * oriented, while others are in Unicode. We need two Tcl_Encoding
- * APIs depending on whether we are targeting a "char" or Unicode
- * interface.
- *
- * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an
- * encoding of NULL should always used to convert between UTF-8
- * and the system's "char" oriented encoding. The following two
- * functions are used in Windows-specific code to convert between
- * UTF-8 and Unicode strings (NT) or "char" strings(95). This saves
- * you the trouble of writing the following type of fragment over and
- * over:
- *
- * if (running NT) {
- * encoding <- Tcl_GetEncoding("unicode");
- * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
- * Tcl_FreeEncoding(encoding);
- * } else {
- * nativeBuffer <- UtfToExternal(NULL, utfBuffer);
- * }
- *
- * By convention, in Windows a TCHAR is a character in the ANSI code
- * page on Windows 95, a Unicode character on Windows NT. If you
- * plan on targeting a Unicode interfaces when running on NT and a
- * "char" oriented interface while running on 95, these functions
- * should be used. If you plan on targetting the same "char"
- * oriented function on both 95 and NT, use Tcl_UtfToExternal()
- * with an encoding of NULL.
+ * Convert between UTF-8 and Unicode when running Windows NT or the
+ * current ANSI code page when running Windows 95.
+ *
+ * On Mac, Unix, and Windows 95, all strings exchanged between Tcl and
+ * the OS are "char" oriented. We need only one Tcl_Encoding to convert
+ * between UTF-8 and the system's native encoding. We use NULL to
+ * represent that encoding.
+ *
+ * On NT, some strings exchanged between Tcl and the OS are "char"
+ * oriented, while others are in Unicode. We need two Tcl_Encoding APIs
+ * depending on whether we are targeting a "char" or Unicode interface.
+ *
+ * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an encoding of
+ * NULL should always used to convert between UTF-8 and the system's
+ * "char" oriented encoding. The following two functions are used in
+ * Windows-specific code to convert between UTF-8 and Unicode strings
+ * (NT) or "char" strings(95). This saves you the trouble of writing the
+ * following type of fragment over and over:
+ *
+ * if (running NT) {
+ * encoding <- Tcl_GetEncoding("unicode");
+ * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
+ * Tcl_FreeEncoding(encoding);
+ * } else {
+ * nativeBuffer <- UtfToExternal(NULL, utfBuffer);
+ * }
+ *
+ * By convention, in Windows a TCHAR is a character in the ANSI code page
+ * on Windows 95, a Unicode character on Windows NT. If you plan on
+ * targeting a Unicode interfaces when running on NT and a "char"
+ * oriented interface while running on 95, these functions should be
+ * used. If you plan on targetting the same "char" oriented function on
+ * both 95 and NT, use Tcl_UtfToExternal() with an encoding of NULL.
*
* Results:
- * The result is a pointer to the string in the desired target
- * encoding. Storage for the result string is allocated in
- * dsPtr; the caller must call Tcl_DStringFree() when the result
- * is no longer needed.
+ * The result is a pointer to the string in the desired target encoding.
+ * Storage for the result string is allocated in dsPtr; the caller must
+ * call Tcl_DStringFree() when the result is no longer needed.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
TCHAR *
Tcl_WinUtfToTChar(string, len, dsPtr)
- CONST char *string; /* Source string in UTF-8. */
- int len; /* Source string length in bytes, or < 0 for
- * strlen(). */
- Tcl_DString *dsPtr; /* Uninitialized or free DString in which
- * the converted string is stored. */
+ CONST char *string; /* Source string in UTF-8. */
+ int len; /* Source string length in bytes, or < 0 for
+ * strlen(). */
+ Tcl_DString *dsPtr; /* Uninitialized or free DString in which the
+ * converted string is stored. */
{
return (TCHAR *) Tcl_UtfToExternalDString(tclWinTCharEncoding,
- string, len, dsPtr);
+ string, len, dsPtr);
}
char *
Tcl_WinTCharToUtf(string, len, dsPtr)
- CONST TCHAR *string; /* Source string in Unicode when running
- * NT, ANSI when running 95. */
- int len; /* Source string length in bytes, or < 0 for
- * platform-specific string length. */
- Tcl_DString *dsPtr; /* Uninitialized or free DString in which
- * the converted string is stored. */
+ CONST TCHAR *string; /* Source string in Unicode when running NT,
+ * ANSI when running 95. */
+ int len; /* Source string length in bytes, or < 0 for
+ * platform-specific string length. */
+ Tcl_DString *dsPtr; /* Uninitialized or free DString in which the
+ * converted string is stored. */
{
return Tcl_ExternalToUtfDString(tclWinTCharEncoding,
- (CONST char *) string, len, dsPtr);
+ (CONST char *) string, len, dsPtr);
}
/*
@@ -1022,112 +1057,115 @@ Tcl_WinTCharToUtf(string, len, dsPtr)
*
* TclWinCPUID --
*
- * Get CPU ID information on an Intel box under Windows
+ * Get CPU ID information on an Intel box under Windows
*
* Results:
- * Returns TCL_OK if successful, TCL_ERROR if CPUID is not
- * supported or fails.
+ * Returns TCL_OK if successful, TCL_ERROR if CPUID is not supported or
+ * fails.
*
* Side effects:
- * If successful, stores EAX, EBX, ECX and EDX registers after
- * the CPUID instruction in the four integers designated by 'regsPtr'
+ * If successful, stores EAX, EBX, ECX and EDX registers after the CPUID
+ * instruction in the four integers designated by 'regsPtr'
*
*----------------------------------------------------------------------
*/
int
-TclWinCPUID( unsigned int index, /* Which CPUID value to retrieve */
- unsigned int * regsPtr ) /* Registers after the CPUID */
+TclWinCPUID(
+ unsigned int index, /* Which CPUID value to retrieve. */
+ unsigned int *regsPtr) /* Registers after the CPUID. */
{
-
#ifdef HAVE_NO_SEH
EXCEPTION_REGISTRATION registration;
#endif
int status = TCL_ERROR;
#if defined(__GNUC__) && !defined(_WIN64)
-
/*
- * Execute the CPUID instruction with the given index, and
- * store results off 'regPtr'.
+ * Execute the CPUID instruction with the given index, and store results
+ * off 'regPtr'.
*/
- __asm__ __volatile__ (
+ __asm__ __volatile__(
+ /*
+ * Construct an EXCEPTION_REGISTRATION to protect the CPUID
+ * instruction (early 486's don't have CPUID)
+ */
+
+ "leal %[registration], %%edx" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
+ "leal 1f, %%eax" "\n\t"
+ "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
+ "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
+ "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
+ "movl %[error], 0x10(%%edx)" "\n\t" /* status */
+
+ /*
+ * Link the EXCEPTION_REGISTRATION on the chain
+ */
+
+ "movl %%edx, %%fs:0" "\n\t"
- /*
- * Construct an EXCEPTION_REGISTRATION to protect the
- * CPUID instruction (early 486's don't have CPUID)
- */
- "leal %[registration], %%edx" "\n\t"
- "movl %%fs:0, %%eax" "\n\t"
- "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
- "leal 1f, %%eax" "\n\t"
- "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
- "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
- "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
- "movl %[error], 0x10(%%edx)" "\n\t" /* status */
-
- /*
- * Link the EXCEPTION_REGISTRATION on the chain
- */
- "movl %%edx, %%fs:0" "\n\t"
-
- /*
- * Do the CPUID instruction, and save the results in
- * the 'regsPtr' area
- */
-
- "movl %[rptr], %%edi" "\n\t"
- "movl %[index], %%eax" "\n\t"
- "cpuid" "\n\t"
- "movl %%eax, 0x0(%%edi)" "\n\t"
- "movl %%ebx, 0x4(%%edi)" "\n\t"
- "movl %%ecx, 0x8(%%edi)" "\n\t"
- "movl %%edx, 0xc(%%edi)" "\n\t"
-
- /*
- * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION
- * and store a TCL_OK status
- */
- "movl %%fs:0, %%edx" "\n\t"
- "movl %[ok], %%eax" "\n\t"
- "movl %%eax, 0x10(%%edx)" "\n\t"
- "jmp 2f" "\n"
-
- /*
- * Come here on an exception. Get the EXCEPTION_REGISTRATION
- * that we previously put on the chain.
- */
- "1:" "\t"
- "movl %%fs:0, %%edx" "\n\t"
- "movl 0x8(%%edx), %%edx" "\n\t"
-
- /*
- * Come here however we exited. Restore context from the
- * EXCEPTION_REGISTRATION in case the stack is unbalanced.
- */
-
- "2:" "\t"
- "movl 0xc(%%edx), %%esp" "\n\t"
- "movl 0x8(%%edx), %%ebp" "\n\t"
- "movl 0x0(%%edx), %%eax" "\n\t"
- "movl %%eax, %%fs:0" "\n\t"
-
- :
- /* No outputs */
- :
- [index] "m" (index),
- [rptr] "m" (regsPtr),
- [registration] "m" (registration),
- [ok] "i" (TCL_OK),
- [error] "i" (TCL_ERROR)
- :
- "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory" );
+ /*
+ * Do the CPUID instruction, and save the results in the 'regsPtr'
+ * area.
+ */
+
+ "movl %[rptr], %%edi" "\n\t"
+ "movl %[index], %%eax" "\n\t"
+ "cpuid" "\n\t"
+ "movl %%eax, 0x0(%%edi)" "\n\t"
+ "movl %%ebx, 0x4(%%edi)" "\n\t"
+ "movl %%ecx, 0x8(%%edi)" "\n\t"
+ "movl %%edx, 0xc(%%edi)" "\n\t"
+
+ /*
+ * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION and
+ * store a TCL_OK status.
+ */
+
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl %[ok], %%eax" "\n\t"
+ "movl %%eax, 0x10(%%edx)" "\n\t"
+ "jmp 2f" "\n"
+
+ /*
+ * Come here on an exception. Get the EXCEPTION_REGISTRATION that we
+ * previously put on the chain.
+ */
+
+ "1:" "\t"
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%edx" "\n\t"
+
+ /*
+ * Come here however we exited. Restore context from the
+ * EXCEPTION_REGISTRATION in case the stack is unbalanced.
+ */
+
+ "2:" "\t"
+ "movl 0xc(%%edx), %%esp" "\n\t"
+ "movl 0x8(%%edx), %%ebp" "\n\t"
+ "movl 0x0(%%edx), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+
+ :
+ /* No outputs */
+ :
+ [index] "m" (index),
+ [rptr] "m" (regsPtr),
+ [registration] "m" (registration),
+ [ok] "i" (TCL_OK),
+ [error] "i" (TCL_ERROR)
+ :
+ "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
status = registration.status;
#elif defined(_MSC_VER) && !defined(_WIN64)
-
- /* Define a structure in the stack frame to hold the registers */
+ /*
+ * Define a structure in the stack frame to hold the registers.
+ */
struct {
DWORD dw0;
@@ -1137,39 +1175,53 @@ TclWinCPUID( unsigned int index, /* Which CPUID value to retrieve */
} regs;
regs.dw0 = index;
- /* Execute the CPUID instruction and save regs in the stack frame */
+ /*
+ * Execute the CPUID instruction and save regs in the stack frame.
+ */
_try {
_asm {
push ebx
push ecx
push edx
- mov eax, regs.dw0
+ mov eax, regs.dw0
cpuid
- mov regs.dw0, eax
- mov regs.dw1, ebx
- mov regs.dw2, ecx
- mov regs.dw3, edx
- pop edx
- pop ecx
- pop ebx
+ mov regs.dw0, eax
+ mov regs.dw1, ebx
+ mov regs.dw2, ecx
+ mov regs.dw3, edx
+ pop edx
+ pop ecx
+ pop ebx
}
- /* Copy regs back out to the caller */
+ /*
+ * Copy regs back out to the caller.
+ */
- regsPtr[0]=regs.dw0;
- regsPtr[1]=regs.dw1;
- regsPtr[2]=regs.dw2;
- regsPtr[3]=regs.dw3;
+ regsPtr[0] = regs.dw0;
+ regsPtr[1] = regs.dw1;
+ regsPtr[2] = regs.dw2;
+ regsPtr[3] = regs.dw3;
status = TCL_OK;
- } __except( EXCEPTION_EXECUTE_HANDLER ) {
+ } __except(EXCEPTION_EXECUTE_HANDLER) {
+ /* do nothing */
}
#else
- /* Don't know how to do assembly code for
- * this compiler and/or architecture */
+ /*
+ * Don't know how to do assembly code for this compiler and/or
+ * architecture.
+ */
#endif
return status;
}
-
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */