diff options
Diffstat (limited to 'win/tclWin32Dll.c')
-rw-r--r-- | win/tclWin32Dll.c | 578 |
1 files changed, 125 insertions, 453 deletions
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 6c863b9..7972862 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -12,16 +12,9 @@ */ #include "tclWinInt.h" - -#ifndef TCL_NO_STACK_CHECK -/* - * The following functions implement stack depth checking - */ -typedef struct ThreadSpecificData { - int *stackBound; /* The current stack boundary */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; -#endif /* TCL_NO_STACK_CHECK */ +#if defined(HAVE_INTRIN_H) +# include <intrin.h> +#endif /* * The following data structures are used when loading the thunking library @@ -35,7 +28,7 @@ typedef BOOL (WINAPI UTREGISTER)(HANDLE hModule, LPCSTR SixteenBitDLL, LPCSTR InitName, LPCSTR ProcName, UT32PROC **ThirtyTwoBitThunk, FARPROC UT32Callback, LPVOID Buff); -typedef VOID (WINAPI UTUNREGISTER)(HANDLE hModule); +typedef void (WINAPI UTUNREGISTER)(HANDLE hModule); /* * The following variables keep track of information about this DLL on a @@ -71,150 +64,80 @@ typedef struct EXCEPTION_REGISTRATION { #define cpuid __asm __emit 0fh __asm __emit 0a2h #endif +static Tcl_Encoding winTCharEncoding = NULL; + /* - * The following function tables are used to dispatch to either the - * wide-character or multi-byte versions of the operating system calls, - * depending on whether the Unicode calls are available. + * The following function table is used to dispatch to wide-character + * versions of the operating system calls. */ -static TclWinProcs asciiProcs = { - 0, - - (BOOL (WINAPI *)(CONST TCHAR *, LPDCB)) BuildCommDCBA, - (TCHAR *(WINAPI *)(TCHAR *)) CharLowerA, - (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *, BOOL)) CopyFileA, - (BOOL (WINAPI *)(CONST TCHAR *, LPSECURITY_ATTRIBUTES)) CreateDirectoryA, - (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *, - DWORD, DWORD, HANDLE)) CreateFileA, - (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, - LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *, - LPSTARTUPINFOA, LPPROCESS_INFORMATION)) CreateProcessA, - (BOOL (WINAPI *)(CONST TCHAR *)) DeleteFileA, - (HANDLE (WINAPI *)(CONST TCHAR *, WIN32_FIND_DATAT *)) FindFirstFileA, - (BOOL (WINAPI *)(HANDLE, WIN32_FIND_DATAT *)) FindNextFileA, - (BOOL (WINAPI *)(WCHAR *, LPDWORD)) GetComputerNameA, - (DWORD (WINAPI *)(DWORD, WCHAR *)) GetCurrentDirectoryA, - (DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesA, - (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *, - TCHAR **)) GetFullPathNameA, - (DWORD (WINAPI *)(HMODULE, WCHAR *, int)) GetModuleFileNameA, - (DWORD (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD)) GetShortPathNameA, - (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique, - WCHAR *)) GetTempFileNameA, - (DWORD (WINAPI *)(DWORD, WCHAR *)) GetTempPathA, - (BOOL (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD, - WCHAR *, DWORD)) GetVolumeInformationA, - (HINSTANCE (WINAPI *)(CONST TCHAR *, HANDLE, DWORD)) LoadLibraryExA, - (TCHAR (WINAPI *)(WCHAR *, CONST TCHAR *)) lstrcpyA, - (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *)) MoveFileA, - (BOOL (WINAPI *)(CONST TCHAR *)) RemoveDirectoryA, - (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD, - 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 - * mandatory in recent Tcl releases. - */ - - NULL, - NULL, - /* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _utime, */ - NULL, - NULL, - /* getLongPathNameProc */ - NULL, - /* Security SDK - not available on 95,98,ME */ - NULL, NULL, NULL, NULL, NULL, NULL, - /* ReadConsole and WriteConsole */ - (BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsoleA, - (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleA, - (BOOL (WINAPI *)(LPTSTR, LPDWORD)) GetUserNameA -}; - -static TclWinProcs unicodeProcs = { +static const TclWinProcs winProcs = { 1, - - (BOOL (WINAPI *)(CONST TCHAR *, LPDCB)) BuildCommDCBW, - (TCHAR *(WINAPI *)(TCHAR *)) CharLowerW, - (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *, BOOL)) CopyFileW, - (BOOL (WINAPI *)(CONST TCHAR *, LPSECURITY_ATTRIBUTES)) CreateDirectoryW, - (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *, - DWORD, DWORD, HANDLE)) CreateFileW, - (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, - LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *, - LPSTARTUPINFOA, LPPROCESS_INFORMATION)) CreateProcessW, - (BOOL (WINAPI *)(CONST TCHAR *)) DeleteFileW, - (HANDLE (WINAPI *)(CONST TCHAR *, WIN32_FIND_DATAT *)) FindFirstFileW, - (BOOL (WINAPI *)(HANDLE, WIN32_FIND_DATAT *)) FindNextFileW, - (BOOL (WINAPI *)(WCHAR *, LPDWORD)) GetComputerNameW, - (DWORD (WINAPI *)(DWORD, WCHAR *)) GetCurrentDirectoryW, - (DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesW, - (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *, - TCHAR **)) GetFullPathNameW, - (DWORD (WINAPI *)(HMODULE, WCHAR *, int)) GetModuleFileNameW, - (DWORD (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD)) GetShortPathNameW, - (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique, - WCHAR *)) GetTempFileNameW, - (DWORD (WINAPI *)(DWORD, WCHAR *)) GetTempPathW, - (BOOL (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD, - WCHAR *, DWORD)) GetVolumeInformationW, - (HINSTANCE (WINAPI *)(CONST TCHAR *, HANDLE, DWORD)) LoadLibraryExW, - (TCHAR (WINAPI *)(WCHAR *, CONST TCHAR *)) lstrcpyW, - (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *)) MoveFileW, - (BOOL (WINAPI *)(CONST TCHAR *)) RemoveDirectoryW, - (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD, - 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 - * mandatory in recent Tcl releases. - */ - - NULL, - NULL, - /* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _wutime, */ - NULL, - NULL, - /* getLongPathNameProc */ - NULL, - /* Security SDK - will be filled in on NT,XP,2000,2003 */ - NULL, NULL, NULL, NULL, NULL, NULL, + (BOOL (WINAPI *)(const TCHAR *, LPDCB)) BuildCommDCB, + (TCHAR *(WINAPI *)(TCHAR *)) CharLower, + (BOOL (WINAPI *)(const TCHAR *, const TCHAR *, BOOL)) CopyFile, + (BOOL (WINAPI *)(const TCHAR *, LPSECURITY_ATTRIBUTES)) CreateDirectory, + (HANDLE (WINAPI *)(const TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *, + DWORD, DWORD, HANDLE)) CreateFile, + (BOOL (WINAPI *)(const TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, const TCHAR *, + LPSTARTUPINFO, LPPROCESS_INFORMATION)) CreateProcess, + (BOOL (WINAPI *)(const TCHAR *)) DeleteFile, + (HANDLE (WINAPI *)(const TCHAR *, WIN32_FIND_DATAT *)) FindFirstFile, + (BOOL (WINAPI *)(HANDLE, WIN32_FIND_DATAT *)) FindNextFile, + (BOOL (WINAPI *)(TCHAR *, LPDWORD)) GetComputerName, + (DWORD (WINAPI *)(DWORD, TCHAR *)) GetCurrentDirectory, + (DWORD (WINAPI *)(const TCHAR *)) GetFileAttributes, + (DWORD (WINAPI *)(const TCHAR *, DWORD nBufferLength, TCHAR *, + TCHAR **)) GetFullPathName, + (DWORD (WINAPI *)(const TCHAR *, TCHAR *, DWORD)) GetShortPathName, + (UINT (WINAPI *)(const TCHAR *, const TCHAR *, UINT uUnique, + TCHAR *)) GetTempFileName, + (DWORD (WINAPI *)(DWORD, TCHAR *)) GetTempPath, + (BOOL (WINAPI *)(const TCHAR *, TCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD, + TCHAR *, DWORD)) GetVolumeInformation, + (HINSTANCE (WINAPI *)(const TCHAR *, HANDLE, DWORD)) LoadLibraryEx, + (BOOL (WINAPI *)(const TCHAR *, const TCHAR *)) MoveFile, + (BOOL (WINAPI *)(const TCHAR *)) RemoveDirectory, + (DWORD (WINAPI *)(const TCHAR *, const TCHAR *, const TCHAR *, DWORD, + TCHAR *, TCHAR **)) SearchPath, + (BOOL (WINAPI *)(const TCHAR *)) SetCurrentDirectory, + (BOOL (WINAPI *)(const TCHAR *, DWORD)) SetFileAttributes, + (BOOL (WINAPI *)(const TCHAR *, GET_FILEEX_INFO_LEVELS, + LPVOID)) GetFileAttributesEx, + (BOOL (WINAPI *)(const TCHAR *, const TCHAR*, + LPSECURITY_ATTRIBUTES)) CreateHardLink, + (HANDLE (WINAPI *)(const TCHAR*, UINT, LPVOID, UINT, + LPVOID, DWORD)) FindFirstFileEx, + (BOOL (WINAPI *)(const TCHAR*, TCHAR*, + DWORD)) GetVolumeNameForVolumeMountPoint, + (DWORD (WINAPI *)(const TCHAR*, TCHAR*, + DWORD)) GetLongPathName, + /* Security SDK */ + (BOOL (WINAPI *)(LPCTSTR, SECURITY_INFORMATION, + PSECURITY_DESCRIPTOR, DWORD, LPDWORD)) GetFileSecurity, + (BOOL (WINAPI *) (SECURITY_IMPERSONATION_LEVEL)) ImpersonateSelf, + (BOOL (WINAPI *) (HANDLE, DWORD, BOOL, PHANDLE)) OpenThreadToken, + (BOOL (WINAPI *) (void)) RevertToSelf, + (void (WINAPI *) (PDWORD, PGENERIC_MAPPING)) MapGenericMask, + (BOOL (WINAPI *)(PSECURITY_DESCRIPTOR, HANDLE, DWORD, + PGENERIC_MAPPING, PPRIVILEGE_SET, LPDWORD, LPDWORD, LPBOOL)) AccessCheck, /* ReadConsole and WriteConsole */ - (BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsoleW, - (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleW, - (BOOL (WINAPI *)(LPTSTR, LPDWORD)) GetUserNameW + (BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsole, + (BOOL (WINAPI *)(HANDLE, const void*, DWORD, LPDWORD, LPVOID)) WriteConsole, + (BOOL (WINAPI *)(LPTSTR, LPDWORD)) GetUserName, + (const TCHAR *(*)(const char *, int, Tcl_DString *)) Tcl_WinUtfToTChar, + (const char *(*)(const TCHAR *, int, Tcl_DString *)) Tcl_WinTCharToUtf }; -TclWinProcs *tclWinProcs; -static Tcl_Encoding tclWinTCharEncoding; +const TclWinProcs *const tclWinProcs = &winProcs; -#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. - */ - -BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, - LPVOID reserved) __attribute__ ((noinline)); -#else /* * The following declaration is for the VC++ DLL entry point. */ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved); -#endif /* HAVE_NO_SEH */ /* * The following structure and linked list is to allow us to map between @@ -223,8 +146,8 @@ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, */ typedef struct MountPointMap { - CONST WCHAR *volumeName; /* Native wide string volume name. */ - char driveLetter; /* Drive letter corresponding to the volume + const TCHAR *volumeName; /* Native wide string volume name. */ + TCHAR driveLetter; /* Drive letter corresponding to the volume * name. */ struct MountPointMap *nextPtr; /* Pointer to next structure in list, or @@ -243,8 +166,6 @@ TCL_DECLARE_MUTEX(mountPointMap) * We will need this below. */ -extern Tcl_FSDupInternalRepProc TclNativeDupInternalRep; - #ifdef __WIN32__ #ifndef STATIC_BUILD @@ -287,10 +208,7 @@ DllEntryPoint( * 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." + * Initializes most rudimentary Windows bits. * *---------------------------------------------------------------------- */ @@ -301,105 +219,16 @@ DllMain( DWORD reason, /* Reason this function is being called. */ LPVOID reserved) /* Not used. */ { -#if defined(HAVE_NO_SEH) && !defined(_WIN64) - EXCEPTION_REGISTRATION registration; -#endif - switch (reason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInst); TclWinInit(hInst); return TRUE; - 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. + * DLL_PROCESS_DETACH is unnecessary as the user should call + * Tcl_Finalize explicitly before unloading Tcl. */ - -#if defined(HAVE_NO_SEH) && !defined(_WIN64) - __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 -#ifndef HAVE_NO_SEH - __try { -#endif - Tcl_Finalize(); -#ifndef HAVE_NO_SEH - } __except (EXCEPTION_EXECUTE_HANDLER) { - /* empty handler body. */ - } -#endif -#endif - - break; } return TRUE; @@ -457,15 +286,18 @@ TclWinInit( 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 or Win9x, so just in case someone manages + * to get a runtime there, make sure they know that. */ if (platformId == VER_PLATFORM_WIN32s) { Tcl_Panic("Win32s is not a supported platform"); } + if (platformId == VER_PLATFORM_WIN32_WINDOWS) { + Tcl_Panic("Windows 9x is not a supported platform"); + } - tclWinProcs = &asciiProcs; + TclWinResetInterfaces(); } /* @@ -478,9 +310,10 @@ TclWinInit( * * Results: * The return value is one of: - * VER_PLATFORM_WIN32s Win32s on Windows 3.1. (not supported) - * VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95, 98, ME. - * VER_PLATFORM_WIN32_NT Win32 on Windows NT, 2000, XP + * VER_PLATFORM_WIN32s Win32s on Windows 3.1 (not supported) + * VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95, 98, ME (not supported) + * VER_PLATFORM_WIN32_NT Win32 on Windows NT, 2000, XP + * VER_PLATFORM_WIN32_CE Win32 on Windows CE * * Side effects: * None. @@ -526,83 +359,6 @@ TclWinNoBackslash( } /* - *---------------------------------------------------------------------- - * - * TclpGetStackParams -- - * - * Determine the stack params for the current thread: in which - * direction does the stack grow, and what is the stack lower (resp. - * upper) bound for safe invocation of a new command? This is used to - * cache the values needed for an efficient computation of - * TclpCheckStackSpace() when the interp is known. - * - * Results: - * Returns 1 if the stack grows down, in which case a stack lower bound - * is stored at stackBoundPtr. If the stack grows up, 0 is returned and - * an upper bound is stored at stackBoundPtr. If a bound cannot be - * determined NULL is stored at stackBoundPtr. - * - *---------------------------------------------------------------------- - */ - -#ifndef TCL_NO_STACK_CHECK -int -TclpGetCStackParams( - int **stackBoundPtr) -{ - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - SYSTEM_INFO si; /* The system information, used to - * determine the page size */ - MEMORY_BASIC_INFORMATION mbi; - /* The information about the memory - * area in which the stack resides */ - - if (!tsdPtr->stackBound - || ((UINT_PTR)&tsdPtr < (UINT_PTR)tsdPtr->stackBound)) { - - /* - * Either we haven't determined the stack bound in this thread, - * or else we've overflowed the bound that we previously - * determined. We need to find a new stack bound from - * Windows. - */ - - GetSystemInfo(&si); - if (VirtualQuery((LPCVOID) &tsdPtr, &mbi, sizeof(mbi)) == 0) { - - /* For some reason, the system didn't let us query the - * stack size. Nevertheless, we got here and haven't - * blown up yet. Don't update the calculated stack bound. - * If there is no calculated stack bound yet, set it to - * the base of the current page of stack. */ - - if (!tsdPtr->stackBound) { - tsdPtr->stackBound = - (int*) ((UINT_PTR)(&tsdPtr) - & ~ (UINT_PTR)(si.dwPageSize - 1)); - } - - } else { - - /* The allocation base of the stack segment has to be advanced - * by one page (to allow for the guard page maintained in the - * C runtime) and then by TCL_WIN_STACK_THRESHOLD (to allow - * for the amount of stack that Tcl needs). - */ - - tsdPtr->stackBound = - (int*) ((UINT_PTR)(mbi.AllocationBase) - + (UINT_PTR)(si.dwPageSize) - + TCL_WIN_STACK_THRESHOLD); - } - } - *stackBoundPtr = tsdPtr->stackBound; - return 1; -} -#endif - - -/* *--------------------------------------------------------------------------- * * TclWinSetInterfaces -- @@ -630,107 +386,17 @@ TclWinSetInterfaces( int wide) /* Non-zero to use wide interfaces, 0 * otherwise. */ { - Tcl_FreeEncoding(tclWinTCharEncoding); + TclWinResetInterfaces(); 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); - } - } - } 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); - } - } + winTCharEncoding = Tcl_GetEncoding(NULL, "unicode"); } } /* *--------------------------------------------------------------------------- * - * TclWinResetInterfaceEncodings -- + * TclWinEncodingsCleanup -- * * Called during finalization to free up any encodings we use. The * tclWinProcs-> look up table is still ok to use after this call, @@ -750,13 +416,11 @@ TclWinSetInterfaces( */ void -TclWinResetInterfaceEncodings(void) +TclWinEncodingsCleanup(void) { MountPointMap *dlIter, *dlIter2; - if (tclWinTCharEncoding != NULL) { - Tcl_FreeEncoding(tclWinTCharEncoding); - tclWinTCharEncoding = NULL; - } + + TclWinResetInterfaces(); /* * Clean up the mount point map. @@ -766,8 +430,8 @@ TclWinResetInterfaceEncodings(void) dlIter = driveLetterLookup; while (dlIter != NULL) { dlIter2 = dlIter->nextPtr; - ckfree((char*)dlIter->volumeName); - ckfree((char*)dlIter); + ckfree(dlIter->volumeName); + ckfree(dlIter); dlIter = dlIter2; } Tcl_MutexUnlock(&mountPointMap); @@ -793,7 +457,10 @@ TclWinResetInterfaceEncodings(void) void TclWinResetInterfaces(void) { - tclWinProcs = &asciiProcs; + if (winTCharEncoding != NULL) { + Tcl_FreeEncoding(winTCharEncoding); + winTCharEncoding = NULL; + } } /* @@ -820,11 +487,11 @@ TclWinResetInterfaces(void) char TclWinDriveLetterForVolMountPoint( - CONST WCHAR *mountPoint) + const TCHAR *mountPoint) { MountPointMap *dlIter, *dlPtr2; - WCHAR Target[55]; /* Target of mount at mount point */ - WCHAR drive[4] = { L'A', L':', L'\\', L'\0' }; + TCHAR Target[55]; /* Target of mount at mount point */ + TCHAR drive[4] = TEXT("A:\\"); /* * Detect the volume mounted there. Unfortunately, there is no simple way @@ -835,28 +502,28 @@ TclWinDriveLetterForVolMountPoint( Tcl_MutexLock(&mountPointMap); dlIter = driveLetterLookup; while (dlIter != NULL) { - if (wcscmp(dlIter->volumeName, mountPoint) == 0) { + if (_tcscmp(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'); + drive[0] = (TCHAR) dlIter->driveLetter; /* * 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) { + if (GetVolumeNameForVolumeMountPoint(drive, + Target, 55) != 0) { + if (_tcscmp(dlIter->volumeName, Target) == 0) { /* * Nothing has changed. */ Tcl_MutexUnlock(&mountPointMap); - return dlIter->driveLetter; + return (char) dlIter->driveLetter; } } @@ -883,8 +550,8 @@ TclWinDriveLetterForVolMountPoint( * Now dlPtr2 points to the structure to free. */ - ckfree((char*)dlPtr2->volumeName); - ckfree((char*)dlPtr2); + ckfree(dlPtr2->volumeName); + ckfree(dlPtr2); /* * Restart the loop - we could try to be clever and continue half @@ -907,23 +574,23 @@ TclWinDriveLetterForVolMountPoint( * Try to read the volume mount point and see where it points. */ - if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive, - (TCHAR*)Target, 55) != 0) { + if (GetVolumeNameForVolumeMountPoint(drive, + Target, 55) != 0) { int alreadyStored = 0; for (dlIter = driveLetterLookup; dlIter != NULL; dlIter = dlIter->nextPtr) { - if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) { + if (_tcscmp(dlIter->volumeName, Target) == 0) { alreadyStored = 1; break; } } if (!alreadyStored) { - dlPtr2 = (MountPointMap *) ckalloc(sizeof(MountPointMap)); + dlPtr2 = ckalloc(sizeof(MountPointMap)); dlPtr2->volumeName = TclNativeDupInternalRep(Target); - dlPtr2->driveLetter = 'A' + (drive[0] - L'A'); + dlPtr2->driveLetter = (char) drive[0]; dlPtr2->nextPtr = driveLetterLookup; - driveLetterLookup = dlPtr2; + driveLetterLookup = dlPtr2; } } } @@ -934,9 +601,9 @@ TclWinDriveLetterForVolMountPoint( for (dlIter = driveLetterLookup; dlIter != NULL; dlIter = dlIter->nextPtr) { - if (wcscmp(dlIter->volumeName, mountPoint) == 0) { + if (_tcscmp(dlIter->volumeName, mountPoint) == 0) { Tcl_MutexUnlock(&mountPointMap); - return dlIter->driveLetter; + return (char) dlIter->driveLetter; } } @@ -945,11 +612,11 @@ TclWinDriveLetterForVolMountPoint( * 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 = ckalloc(sizeof(MountPointMap)); + dlPtr2->volumeName = TclNativeDupInternalRep((ClientData) mountPoint); dlPtr2->driveLetter = -1; dlPtr2->nextPtr = driveLetterLookup; - driveLetterLookup = dlPtr2; + driveLetterLookup = dlPtr2; Tcl_MutexUnlock(&mountPointMap); return -1; } @@ -1006,27 +673,27 @@ TclWinDriveLetterForVolMountPoint( TCHAR * Tcl_WinUtfToTChar( - CONST char *string, /* Source string in UTF-8. */ + 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, + return (TCHAR *) Tcl_UtfToExternalDString(winTCharEncoding, string, len, dsPtr); } char * Tcl_WinTCharToUtf( - CONST TCHAR *string, /* Source string in Unicode when running NT, + 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); + return Tcl_ExternalToUtfDString(winTCharEncoding, + (const char *) string, len, dsPtr); } /* @@ -1054,11 +721,16 @@ TclWinCPUID( { int status = TCL_ERROR; -#if defined(__GNUC__) +#if defined(HAVE_INTRIN_H) && defined(_WIN64) + + __cpuid(regsPtr, index); + status = TCL_OK; + +#elif defined(__GNUC__) # if defined(_WIN64) /* * Execute the CPUID instruction with the given index, and store results - * off 'regsPtr'. + * off 'regPtr'. */ __asm__ __volatile__( |