summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--win/tclWinFile.c34
2 files changed, 29 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index c2642b5..daf5103 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);