From b38bba3aea186cf7f05e45334a96afe25078da16 Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Sat, 5 Apr 2008 23:22:41 +0000 Subject: * win/tclWinFile.c: (WinSymLinkDirectory): Fixed a problem that Tcl was creating an NTFS junction point (IO_REPARSE_TAG_MOUNT_POINT) but filling in the union member for a Vista symbolic link. We had gotten away with this error because the union member (SymbolicLinkReparseBuffer) was misdefined in this file and in the 'winnt.h' in early versions of MinGW. MinGW 3.4.2 has the correct definition of SymbolicLinkReparseBuffer, exposing the mismatch, and making tests cmdAH-19.4.1, fCmd-28.*, and filename-11.* fail. --- ChangeLog | 12 ++++++++++++ win/tclWinFile.c | 34 +++++++++++++++++----------------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5aae64a..9bc846f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-04-05 Kevin B. Kenny + + * win/tclWinFile.c: (WinSymLinkDirectory): Fixed a problem that + Tcl was creating an NTFS junction point (IO_REPARSE_TAG_MOUNT_POINT) + but filling in the union member for a Vista symbolic link. + We had gotten away with this error because the union member + (SymbolicLinkReparseBuffer) was misdefined in this file + and in the 'winnt.h' in early versions of MinGW. MinGW 3.4.2 + has the correct definition of SymbolicLinkReparseBuffer, exposing + the mismatch, and making tests cmdAH-19.4.1, fCmd-28.*, and + filename-11.* fail. + 2008-04-04 Andreas Kupries * tests/io.test (io-53.9): Added testcase for [Bug 780533], based diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 66ecdf8..4a909f3 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinFile.c,v 1.95 2007/12/13 15:28:44 dgp Exp $ + * RCS: @(#) $Id: tclWinFile.c,v 1.95.2.1 2008/04/05 23:22:41 kennykb Exp $ */ /* #define _WIN32_WINNT 0x0500 */ @@ -123,6 +123,7 @@ typedef struct _REPARSE_DATA_BUFFER { WORD SubstituteNameLength; WORD PrintNameOffset; WORD PrintNameLength; + ULONG Flags; WCHAR PathBuffer[1]; } SymbolicLinkReparseBuffer; struct { @@ -445,18 +446,18 @@ WinSymLinkDirectory( memset(reparseBuffer, 0, sizeof(DUMMY_REPARSE_BUFFER)); reparseBuffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength = + reparseBuffer->MountPointReparseBuffer.SubstituteNameLength = wcslen(nativeTarget) * sizeof(WCHAR); reparseBuffer->Reserved = 0; - reparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength = 0; - reparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset = - reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength + reparseBuffer->MountPointReparseBuffer.PrintNameLength = 0; + reparseBuffer->MountPointReparseBuffer.PrintNameOffset = + reparseBuffer->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR); - memcpy(reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer, nativeTarget, + memcpy(reparseBuffer->MountPointReparseBuffer.PathBuffer, nativeTarget, sizeof(WCHAR) - + reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength); + + reparseBuffer->MountPointReparseBuffer.SubstituteNameLength); reparseBuffer->ReparseDataLength = - reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength+12; + reparseBuffer->MountPointReparseBuffer.SubstituteNameLength+12; return NativeWriteReparse(linkDirPath, reparseBuffer); } @@ -604,12 +605,12 @@ WinReadLinkDirectory( */ offset = 0; - if (reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[0] == L'\\') { + if (reparseBuffer->MountPointReparseBuffer.PathBuffer[0] == L'\\') { /* * Check whether this is a mounted volume. */ - if (wcsncmp(reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer, + if (wcsncmp(reparseBuffer->MountPointReparseBuffer.PathBuffer, L"\\??\\Volume{",11) == 0) { char drive; @@ -618,7 +619,7 @@ WinReadLinkDirectory( * to fix here. It doesn't seem very well documented. */ - reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[1]=L'\\'; + reparseBuffer->MountPointReparseBuffer.PathBuffer[1]=L'\\'; /* * Check if a corresponding drive letter exists, and use that @@ -626,7 +627,7 @@ WinReadLinkDirectory( */ drive = TclWinDriveLetterForVolMountPoint( - reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer); + reparseBuffer->MountPointReparseBuffer.PathBuffer); if (drive != -1) { char driveSpec[3] = { '\0', ':', '\0' @@ -649,14 +650,14 @@ WinReadLinkDirectory( */ goto invalidError; - } else if (wcsncmp(reparseBuffer->SymbolicLinkReparseBuffer + } else if (wcsncmp(reparseBuffer->MountPointReparseBuffer .PathBuffer, L"\\\\?\\",4) == 0) { /* * Strip off the prefix. */ offset = 4; - } else if (wcsncmp(reparseBuffer->SymbolicLinkReparseBuffer + } else if (wcsncmp(reparseBuffer->MountPointReparseBuffer .PathBuffer, L"\\??\\",4) == 0) { /* * Strip off the prefix. @@ -667,8 +668,8 @@ WinReadLinkDirectory( } Tcl_WinTCharToUtf((const char *) - reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer, - (int) reparseBuffer->SymbolicLinkReparseBuffer + reparseBuffer->MountPointReparseBuffer.PathBuffer, + (int) reparseBuffer->MountPointReparseBuffer .SubstituteNameLength, &ds); copy = Tcl_DStringValue(&ds)+offset; @@ -775,7 +776,6 @@ NativeWriteReparse( TclWinConvertError(GetLastError()); return -1; } - hFile = (*tclWinProcs->createFileProc)(linkDirPath, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); -- cgit v0.12