Welcome!

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

SignUp Now!

How to? @IsSubst

samintz

Scott Mintz
May
1,582
27
Dan,

Your message seems to have vanished. Here's my reply to it anyway:
-=-=-=-=-=-=-

I think there may be something in the tips & techniques section on this. However I use this approach:
Code:
[R:] function IsSubst=`%@if[%@index[%@execstr[do d in /p subst (echos %%@left[1,%%d])],%@left[1,%1]] NE -1,1,0]`
 
 
[R:] echo %@IsSubst[C:]
0
 
[R:] echo %@IsSubst[%_CWD]
1


While the above function works, it's not efficient in that it reruns SUBST every time it is invoked. That's good if your SUBST'ed drive list changes often. It might be better to assign the output to an environment variable and use that.

Code:
unset /q sl & do d in /p subst (set sl=%[sl]%@left[1,%d])
function IsSubst=`%@if[%@index[%sl,%@left[1,%1]] NE -1,1,0]`

FWIW, on my system I have drives QRTVWYZ subst'ed.

-Scott
 
Thank you, Scott. However, what you've told me is that there isn't any way (as far as you ( :) ) know) to do it other than by invoking the "Subst" command (program), and that is specifically what I was trying to avoid. (My present "solution", while not identical, was very similar to yours, including using the "@ExecStr" function to invoke "Subst"). However, I like your idea better, I think, because I was doing the "Do /P" in a batch file (which is what I was "@ExecStr"ing); I didn't realize you could put that directly in "@ExecStr" argument itself! Really neat, and thank you! But the whole point was to really not have to invoke the "Subst" program at all. (Which I fully admit may be nothing more than a rather silly performance consideration; but I've always written my code (quite successfully in the "old days", I might add), with "performance" being a top consideration. And maybe that's just silly in today's world; but 35+ year-old habits are hard to break! :))

- Dan
 
But the whole point was to really not have to invoke the "Subst" program at all.)

I haven't tried it myself, but my good friend Google suggests that QueryDosDevice() might be useful for this purpose. (Possibly you could call it using %@WINAPI?)
 
Thank you, Charles, it does seem to be worth investigating. However, in my initial trials, I haven't been able to figure out how to actually use it from the documentation of the @WinAPI (and QueryDosDevice) function(s) and I unfortunately I have (many!) more important things to do at the moment.

- Dan
 
I haven't tried it myself, but my good friend Google suggests that QueryDosDevice() might be useful for this purpose. (Possibly you could call it using %@WINAPI?)
Yes, that'll work.

Code:
v:\> echo %@winapi[kernel32.dll,QueryDosDeviceW,"s:",BUFFER,260]
\??\Z:\Windows\system32
 
v:\> echo %@winapi[kernel32.dll,QueryDosDeviceW,"v:",BUFFER,260]
\??\E:\workplace

It also resolves network mapped drives.

Code:
v:\> echo %@winapi[kernel32.dll,QueryDosDeviceW,"y:",BUFFER,260]
\Device\LanmanRedirector\;Y:000000000001d6b6\lucky\e$
 
Thank you also, Vince. It would have probably taken me many hours (if not days) to figure that out on my own! Boy, the combination of you guys and this bulletin board are truly wonderful!!!! :)
 
I haven't been able to figure out how to actually use it from the documentation of the @WinAPI (and QueryDosDevice) function(s).

After naming the DLL and the function, you specify the arguments expected by the function. At MS there's online documentation of all the Win32 functions. QueryDosDevice() expects three params, a device name (input, a string), a place to store the name of the target (output), and the length of that place. In this case, QueryDosDevice's second parameter should be BUFFER (literally). That causes TCC to send a pointer to a buffer where QDD can write the name of the target. I'm confident that that buffer is pretty big (Rex, how big?). I said (below) the buffer size was only 260 because that's MAX_PATH and I figured that QDD would think it sufficient.

If you use BUFFER with @WINAPI, @WINAPI will return the contents of that buffer. Otherwise, @WINAPI will return the function's return value (typically an integer type).

Code:
v:\> echo %@winapi[kernel32.dll,QueryDosDevice,"v:",BUFFER,260]
\??\E:\workplace
 
I've now got it fully implemented and working (after my usual "exhaustive" testing :)), so thank you all very much!

- Dan

P. S. And I even wrote a function to identify what the subst'd drive is "pointing" to!
 
How about simply
Code:
function issubst=`%@if[%@left[2,%1] eq %@left[2,%@truename[%1]],0,1]`
 
Thank you, Dave, I'm really laughing as I type this! :) This is yet another indication that TCC has so many capabilities that it would seem that virtually no human being (other than maybe Rex, himself!) can keep track of them all! And what is even more humorous in my case, I've got a rather old function/routine (as in years; a small batch file invoked via @ExecStr and if I knew how to write "recursive" functions in TCC - which I don't and I do not think even can be done - would simply be a function) that will fully resolve (i.e., resolve any name passed to it to it's "ultimate" target - independent of how many subst'd drives, symlinks and/or junctions are involved) by repeatedly invoking @TrueName until nothing changes. Funny! (Like I've said before, my bad memory is not a joke!)

- Dan
 
So using the @WinApi function, the IsSubst function can be created like this:

Code:
function IsSubst=`%@inc[%@index[%@winapi[kernel32.dll,QueryDosDevice,"%1",BUFFER,260],\??\]]`

That will return 1 if the first characters of the QueryDosDevice call match "\??\" and 0 otherwise.

-Scott
 
Scott,

Your are correct, of course, when you say that that is a very good way to use the "@WinAPI" function that was mentioned previously, but since all I really needed to know in my application was whether or not the drive letter was subst'd at all, the "@TrueName" function is a better idea (to me, at least!) because it doesn't rely on anything outside of TCC. And the "TrueTrueName" subroutine I mentioned above is probably a better idea in the "general" case because it can handle literally anything and not just subst'd drives. (Boy, it's truly a wonderful and amazing thing to me how brilliant people who answer questions on this bulletin board are!!! :))

- Dan
 
So using the @WinApi function, the IsSubst function can be created like this:

Code:
function IsSubst=`%@inc[%@index[%@winapi[kernel32.dll,QueryDosDevice,"%1",BUFFER,260],\??\]]`

Thie slightly simpler form below seems to work on WinXP SP3:
Code:
      function IsSubst=`%@if["%@left[4,%@winapi[kernel32.dll,QueryDosDevice,"%1",BUFFER,260]]" EQC "\??\",1,0]`
It, too, returns 1 if the first characters of the QueryDosDevice call match "\??\" and 0 otherwise.
 
Thank you, Joe, but I don't need it (at least at the moment! But maybe I might in the future...). But yet another indication that virtually no one other than Rex, himself, can keep track of it all (although maybe you can since you managed to both see this and remember it!!! :) )

- Dan
 
Back
Top