% file normalize "c:/Users/james/Application Data/Foo/Bar"
C:/Users/james/Application Data//Bar"
This is a big problem because the normalize code gets used by other
"file" operations so that for instance:
% file exists "c:/Users/james/Application Data/Foo/Bar/bar.txt"
0
will return 0 even if bar.txt exists and is readable.
The reason for the strange result in normalize is this code in
tclWinFile.c line 2542
/* Normal path */
WIN32_FIND_DATAW fData;
HANDLE handle;
handle = FindFirstFileW((WCHAR*)nativePath, &fData);
if (handle == INVALID_HANDLE_VALUE) {
/* This is usually the '/' in 'c:/' at end of string */
Tcl_DStringAppend(&dsNorm,(CONST char*)L"/", sizeof(WCHAR));
} else {
FindFirstFileW is going to fail here because the Application Data
directory has somewhat strange permissions on it presumably to stop
the unwary from venturing in there and mucking with something.
It seems to me this call is just trying to determine if the path
exists. In which case changing it to GetFileAttributesW would solve
the problem. I think.
Turning off UAC didn't seem to affect this either in case you were
wondering.
- James.
It might stem from the fact that it's a hidden directory. That causes
all sorts of problems with a number of Windows's APIs. (FWIW, this
works fine with 8.4.14 on XP, so this may be Vista-specific
oddness...)
Donal.
I see the same oddness on Vista 64bit. It's not just permissions
though; "Application Data" is what they call a 'junction point'.
It's supposed to make legacy paths available to pre-vista apps.
Anyway - using the vista-supplied 'dir' command or cygwin's 'ls'..
attempting to get a listing directly on:
c:/Users/someone/Application Data/ will fail to produce a listing
(file not found / no such file or directory)..
but you can use these tools to get listings below the junction point.
Tcl however doesn't seem to get past it. Using glob, you only get a
listing below that point if you fudge it by throwing in an extra
segment:
ie.. to see whats' in Foo you have to do this:
glob -dir c:/Users/someone/Application Data/Foo/Foo *
Tcl's 'open' also needs such a path fudge.
As dir & ls seem to cope.. I'm guessing Tcl may indeed need to be
adjusted somehow to handle these junction points.
Julian
RF
permission denied' :/
Also.. if it is a symbolic link equivalent glob doesn't yet know that:
using the '-types l' switch it doesn't show up in the list.
Actually I couldn't get a glob on c:/Users/someone to show
"Application Data" at all - tried the '-types' (b,c,d,f,l,p,s)
J
Further to that..
By default the various junction points seem to have the 'everyone'
group set to deny 'List folder / read data'
If you remove this permission entry then Tcl's 'file readlink' returns
the destination of the junction correctly:
e.g
%file readlink "C:/Users/someone/Application Data"
C:\Users\someone\AppData\Roaming
Now.. file normalize also works:
%file normalize "C:/Users/someone/Application Data/Foo/Bar"
C:/Users/someone/AppData/Roaming/Foo/Bar
So.. looks like Donals comment re permissions was basically on the
mark.
Unfortunately it's apparently not recommended to open up the
permissions on junction points like that.. besides which, it's not the
default and would be a pain,
so I don't know what the solution is.
J
Anyway.. the current default junction point interaction with Tcl seems
like it will break Tcl apps that happen to install things into classic
Microsoftish locations.
J
They're one of the equivalents, and closer to mount points than
symlinks. Vista has symlinks, too. But there's no exact equivalent
outside of NTFS.
--
Darren New / San Diego, CA, USA (PST)
I bet exercise equipment would be a lot more
expensive if we had evolved from starfish.
Has anyone tried tacking "/." on the end? As in
C:/yadda/Application Data/.
as the file name to use? I find that sometimes helps with UNIX-style
symlinks, but I don't have a Vista available to see if it makes any
difference in the behavior there.
It seems to make no difference.
Another very strange situation that arises though is the following:
(underlying path to test.txt is C:\Users\julz\AppData\Roaming\Microsoft
\test.txt)
(tcl8.5a7 on vista x64)
#tclsh session 1)
C:\Users>tclsh
%open "C:/Users/julz/Application Data/Microsoft/test.txt" r
couldn't open "C:/Users/julz/Application Data/Microsoft/test.txt":
no such file or directory
%open "C:/Users/julz/Application Data/Microsoft/Microsoft/
test.txt"
file331038
%exit
Now.. this time with an extra 'glob' call at the beginning:
#tclsh session 2)
C:\Users>tclsh
%glob -dir . *
./Administrator ./julz ./Public
%open "C:/Users/julz/Application Data/Microsoft/test.txt" r
file481058
%open "C:/Users/julz/Application Data/Microsoft/Microsoft/
test.txt" r
couldn't open "C:/Users/julz/Application Data/Microsoft/Microsoft/
test.txt": no such file or directory.
So.. whether or not we need to fudge the path.. depends on whether or
not there was a previous 'glob -dir . *' call??
I have no idea what's going on there.
Further testing.. we can replace 'glob -dir .*' with 'file
normalize .' (but not 'file normalize C:/Users')
and this will also allow unfudged access to the file.
Julian.
Tcl supports the older NTFS junction points with file link/file readlink.
Michael
One of the reasons for the strange perms of symlinks is to avoid that
legacy tools (like disk usage tools) count files more than once if they
follow the links.
See german Mag. IX, 07/2007, Pg. 116+, Author Kaczenski Nils
The files beyond the links (eg. on directory after the symlink) should
be accessible "normaly".
IMHO a curious handling of symlinks.
--
Gerhard Reithofer
Tech-EDV Support Forum - http://support.tech-edv.co.at
When it does fail it will construct a funny looking path (see the '//'
in my example). This code gets called in various places including
"file exists" and "file normalize" and possibly others.
I can probably suggest a patch if anybody is interested. It looks
fairly simple.
- James.
That would help, especially if done through the tracker mechanism on
sourceforge (stops it from getting lost). Thanks!
Donal.