diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | win/tclWinFile.c | 34 |
2 files changed, 29 insertions, 17 deletions
@@ -1,3 +1,15 @@ +2008-04-05 Kevin B. Kenny <kennykb@acm.org> + + * 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 <andreask@activestate.com> * tests/io.test (io-53.9): Added testcase for [Bug 780533], based diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 66ecdf8..f5f8d5d 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.96 2008/04/05 23:25:15 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); |