TCC failing to read recursive symlinks

Aug 23, 2010
688
9
Code:
@ECHO OFF
ECHO ECHO ===^^^> Called as ^%0 > 0.btm
MKLINK /A 1.btm 0.btm
MKLINK /A 2.btm 1.btm
DO F IN /L 2 1 0
  DIR /B %F.btm
  CALL %F.btm
ENDDO
DEL /Q ?.btm

Code:
[…]$ testlinks.btm
Symbolic link created for 1.btm <<===>> …\0.btm
Symbolic link created for 2.btm <<===>> …\1.btm
2.btm […\1.btm]
1.btm […\0.btm]
===> Called as 1.btm
0.btm
===> Called as 0.btm
 
Aug 23, 2010
688
9
Argue as you wish, this is not normal program behavior and I know no way to exhibit it, short of manually resolving links. Which is absolutely unnecessary, unless you want to specifically operate on the link itself.

Also, I don't understand your last message.
 
Aug 23, 2010
688
9
What will that do?
It will open the file for reading…
I've tried a number of ways to replicate the TCC behavior with the tools at hand, to no avail.
Even a program written in Delphi 7 over 13 years ago has absolutely no issues reading through symlinks.
 
May 20, 2008
12,167
133
Syracuse, NY, USA
Argue as you wish, this is not normal program behavior and I know no way to exhibit it, short of manually resolving links. Which is absolutely unnecessary, unless you want to specifically operate on the link itself.

Also, I don't understand your last message.
2.btm IS a link to 1.btm.
 
May 20, 2008
12,167
133
Syracuse, NY, USA
It will open the file for reading…
I've tried a number of ways to replicate the TCC behavior with the tools at hand, to no avail.
Even a program written in Delphi 7 over 13 years ago has absolutely no issues reading through symlinks.
TCC resolves the link OK, it just doesn't try to recurse when you ask what the link points to.

Code:
2018-03-25  19:54              25  0.btm
2018-03-25  19:54     <SYMLINK>    1.btm [V:\0.btm]
2018-03-25  19:54     <SYMLINK>    2.btm [V:\1.btm]

Code:
v:\> do i=0 to 2 ( type %i.btm )
ECHO ===^> Called as %0
ECHO ===^> Called as %0
ECHO ===^> Called as %0
 
May 20, 2008
12,167
133
Syracuse, NY, USA
I tried GetFinalPathNameByHandle() in a little plugin (re-using the name "@IPOW"). It won't do everything @TRUENAME needs, but it does follow a chain of symbolic links and even sees through SUBSTs.
Code:
v:\> subst | grep V:
V:\: => H:\work

v:\> echo %@ipow[2.btm]
\\?\H:\work\0.btm

v:\> echo %@ipow[v:\2.btm]
\\?\H:\work\0.btm

And, FWIW, @TRUENAME also does not follow a chain of symbolic links.
Code:
v:\> echo %@truename[v:\2.btm]
V:\1.btm

v:\> echo %@truename[v:\1.btm]
V:\0.btm
 
Aug 23, 2010
688
9
2.btm IS a link to 1.btm.
Of course. Where did I say the contrary?
TCC resolves the link OK, it just doesn't try to recurse when you ask what the link points to.
wat
You don't friggin' need to do anything specific to open a file. You don't even need to know that symlinks exist.
OS will do everything for you.
And, FWIW, @TRUENAME also does not follow a chain of symbolic links.
@TRUENAME is fundamentally broken. Don't use it. Don't rely on its behavior.
 
May 20, 2008
12,167
133
Syracuse, NY, USA
Then I missed the point of your original post ... sorry. I thought you were pointing out that TCC doesn't give 0.btm as the target of 2.btm.

Now I see what's happening (and your original point). If I try to execute 2.btm, I get nothing.
 

rconn

Administrator
Staff member
May 14, 2008
12,556
167
It's Windows that's failing, not TCC. TCC is querying (recursively) the reparse point for the file size (via a DeviceIoControl API call) so it can allocate the .BTM buffer, but the API is returning 0. So TCC thinks the batch file is empty, and executing it returns the (expected) result of nothing.

Easy workaround: use .CMD files instead of .BTM.
 
Aug 23, 2010
688
9
I don't understand your problem, sorry.

Delphi 7. Year 2002. Several years before file symlinks introduction in Windows Vista.
Code:
program LinksTest;
{$APPTYPE CONSOLE}
{$D-}

uses
  Windows;

var
  f: hFile;
  pHandleInfo: _BY_HANDLE_FILE_INFORMATION;

begin
  f := CreateFile(PChar(ParamStr(1)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

  if GetFileInformationByHandle(f, pHandleInfo) then begin
    WriteLn(ParamStr(1), ': ', pHandleInfo.nFileSizeLow);
  end;

end.
Works like a charm. No magic required at all.
 
May 20, 2008
12,167
133
Syracuse, NY, USA
Curious ... why DeviceIoControl?

When I have 2.btm ==> 1.btm ==> 0.btm, CreateFile(L"v:\\2.btm, ...) sees right through the links and using the returned HANDLE, GetFileSizeEx gives the size of 0.btm and ReadFile reads 0.btm
 

rconn

Administrator
Staff member
May 14, 2008
12,556
167
Curious ... why DeviceIoControl?

When I have 2.btm ==> 1.btm ==> 0.btm, CreateFile(L"v:\\2.btm, ...) sees right through the links and using the returned HANDLE, GetFileSizeEx gives the size of 0.btm and ReadFile reads 0.btm

Because TCC needs far more info about the reparse point than is available with CreateFile or GetFileSizeEx.
 
May 20, 2008
12,167
133
Syracuse, NY, USA
Because TCC needs far more info about the reparse point than is available with CreateFile or GetFileSizeEx.
Admitted: I'm naive. But what, other than the size and content, does TCC need to run a batch file? If Windows automatically gives TCC the ultimate target, why does TCC even care if the file name given is the name of a reparse point?
 
Aug 23, 2010
688
9
This is supposedly(?) fixed(?) in 22.0.42.

At least I'm unable to exhibit the issue in the environment where I observed it previously.
 
May 20, 2008
12,167
133
Syracuse, NY, USA
This is supposedly(?) fixed(?) in 22.0.42.

At least I'm unable to exhibit the issue in the environment where I observed it previously.
It doesn't look any better here.
Code:
v:\> MKLINK /A 1.btm 0.btm
Symbolic link created for 1.btm <<===>> V:\0.btm

v:\> MKLINK /A 2.btm 1.btm
Symbolic link created for 2.btm <<===>> V:\1.btm

v:\> d ?.btm
2018-03-26  21:45          11,591  0.btm
2018-05-26  13:28     <SYMLINK>    1.btm [V:\0.btm]
2018-05-26  13:28     <SYMLINK>    2.btm [V:\1.btm]

v:\> ver

TCC  22.00.42   Windows 7 [Version 6.1.7601]
 
Aug 23, 2010
688
9
Original problem was that I was unable to run scripts from 2-level symlink. (dev.env -> staging ->> deployed apps)
Directory listing you show is correct as far as directory listing goes.
 
May 20, 2008
12,167
133
Syracuse, NY, USA
Original problem was that I was unable to run scripts from 2-level symlink. (dev.env -> staging ->> deployed apps)
Directory listing you show is correct as far as directory listing goes.
Yes, that's better. I had forgotten the original problem.
 

Similar threads