diff options
Diffstat (limited to 'win/tclWinFile.c')
-rw-r--r-- | win/tclWinFile.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 7586af1..bb9de9c 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -149,6 +149,8 @@ typedef struct { * Other typedefs required by this code. */ +typedef BOOL WINAPI (CreateHardLinkProc)(const TCHAR *, + const TCHAR *, LPSECURITY_ATTRIBUTES); static time_t ToCTime(FILETIME fileTime); static void FromCTime(time_t posixTime, FILETIME *fileTime); @@ -254,7 +256,23 @@ WinLink( */ if (linkAction & TCL_CREATE_HARD_LINK) { - if (CreateHardLink(linkSourcePath, linkTargetPath, NULL)) { + static int initialized = 0; + static CreateHardLinkProc *pCreateHardLink = NULL; + + if (!initialized) { + HMODULE dllH = GetModuleHandle(TEXT("KERNEL32")); + + initialized = 1; + if (dllH != NULL) { + pCreateHardLink = (CreateHardLinkProc *) + GetProcAddress(dllH, "CreateHardLinkW"); + } + } + if (pCreateHardLink == NULL) { + SetLastError(ERROR_NOT_SUPPORTED); + } + if ((pCreateHardLink != NULL) && + pCreateHardLink(linkSourcePath, linkTargetPath, NULL)) { /* * Success! */ @@ -1450,19 +1468,19 @@ TclpGetUserHome( domain = strchr(name, '@'); if (domain != NULL) { Tcl_DStringInit(&ds); - wName = Tcl_UtfToUniCharDString(domain + 1, -1, &ds); + wName = (WCHAR *) Tcl_WinUtfToTChar(domain + 1, -1, &ds); badDomain = NetGetDCName(NULL, wName, (LPBYTE *) wDomainPtr); Tcl_DStringFree(&ds); nameLen = domain - name; } if (badDomain == 0) { Tcl_DStringInit(&ds); - wName = Tcl_UtfToUniCharDString(name, nameLen, &ds); + wName = (WCHAR *) Tcl_WinUtfToTChar(name, nameLen, &ds); if (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) uiPtrPtr) == 0) { wHomeDir = uiPtr->usri1_home_dir; if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) { - Tcl_UniCharToUtfDString(wHomeDir, lstrlenW(wHomeDir), - bufferPtr); + Tcl_WinTCharToUtf((TCHAR *) wHomeDir, wcslen(wHomeDir) * + sizeof (WCHAR), bufferPtr); } else { /* * User exists but has no home dir. Return @@ -1473,7 +1491,7 @@ TclpGetUserHome( for (i = 0; i < size; ++i){ if (buf[i] == '\\') buf[i] = '/'; } - Tcl_UniCharToUtfDString(buf, size-1, bufferPtr); + Tcl_WinTCharToUtf(buf, (size-1) * sizeof (WCHAR), bufferPtr); Tcl_DStringAppend(bufferPtr, "/", -1); Tcl_DStringAppend(bufferPtr, name, -1); } @@ -1980,21 +1998,21 @@ NativeStat( if (GetFileInformationByHandle(fileHandle,&data) != TRUE) { fileType = GetFileType(fileHandle); - CloseHandle(fileHandle); + CloseHandle(fileHandle); if (fileType != FILE_TYPE_CHAR && fileType != FILE_TYPE_DISK) { - Tcl_SetErrno(ENOENT); - return -1; - } + Tcl_SetErrno(ENOENT); + return -1; + } /* Mock up the expected structure */ memset(&data, 0, sizeof(data)); statPtr->st_atime = 0; statPtr->st_mtime = 0; statPtr->st_ctime = 0; } else { - CloseHandle(fileHandle); - statPtr->st_atime = ToCTime(data.ftLastAccessTime); - statPtr->st_mtime = ToCTime(data.ftLastWriteTime); - statPtr->st_ctime = ToCTime(data.ftCreationTime); + CloseHandle(fileHandle); + statPtr->st_atime = ToCTime(data.ftLastAccessTime); + statPtr->st_mtime = ToCTime(data.ftLastWriteTime); + statPtr->st_ctime = ToCTime(data.ftCreationTime); } attr = data.dwFileAttributes; statPtr->st_size = ((Tcl_WideInt) data.nFileSizeLow) | @@ -2975,7 +2993,13 @@ TclNativeCreateNativeRep( * 0xC0 0x80 (== overlong NUL). See bug [3118489]: NUL in filenames */ len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, 0, 0); if (len==0) { - goto done; + if (GetLastError() == ERROR_INVALID_FLAGS) { + /* Win NT/2000? */ + len = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0); + } + if (len==0) { + goto done; + } } } /* Overallocate 6 chars, making some room for extended paths */ @@ -2983,7 +3007,12 @@ TclNativeCreateNativeRep( if (nativePathPtr==0) { goto done; } - MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, nativePathPtr, len+1); + if ((MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, + nativePathPtr, len+1) == 0) && + (GetLastError() == ERROR_INVALID_FLAGS)) { + /* Win NT/2000? */ + MultiByteToWideChar(CP_UTF8, 0, str, -1, nativePathPtr, len+1); + } /* ** If path starts with "//?/" or "\\?\" (extended path), translate ** any slashes to backslashes but leave the '?' intact |