Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

TCC failing to read recursive symlinks

Aug
717
10
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
 
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.
 
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.
 
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.
 
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
 
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
 
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.
 
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.
 
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.
 
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.
 
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
 
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.
 
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?
 
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.
 
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]
 
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.
 
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

Back
Top