Hoping somebody can help me...

#1
Folks,

This is quite a bit out of the range of "normal" questions on this forum, but I don't know where else to find the answer(s). I have a program that used "NtOpenSymbolicLinkObject" and "NtQuerySymbolicLinkObject" to determine if two given directories were really the same directory because it is very important that the program knows this (the program is a cleanup utility that deletes files in one directory tree that are in another directory tree - and if two directories in the the two directory trees are really the same directory, the results could be disasterous. (I use symbolic links a lot.)) I am reasonably sure (but not totally so) that these functions worked for me in the past, but they are definitely not working now and the (limited!) documentation I can find on the internet says they may stop working at any time because Microsoft is dropping support for them. (I was using Vista when I added this functionality to the program and am using Windows 7 now.) (I know how to resolve junctions.) In particular, Rex, I seem to recall that you made a reference at some time in the not-too-distant past about finding another way to get this functionality (I don't remember the context), and you clearly know how to do this because the "dir" command displays where symbolic links "point" to. If I am right about this could you (or somebody) please tell me how to do it? I consider this not working to be a major flaw in the program as it now stands, (If it makes any difference, it is a C++ program.) And, on a related but far less critical task, do you know any way to get the disk address of a file? If two files on the same logical drive have the same disk address, it would mean that either some parent directories in each file's directory tree are really the same directory (junctioned or symbolically linked), or (more important for my purposes) that the there is a hardlink linking the two files together. Any insight I could get into these matters would be greatly appreciated!!!

Thanking you in advance,

- Dan Mathew
[email protected]
 
#2
On Wed, 19 May 2010 02:58:00 -0400, [email protected]
<> wrote:

|And, on a related but far less critical task, do you know any way to get the disk address of a file? If two files on the same logical drive have the same disk address, it would mean that either some parent directories in each file's directory tree are really the same directory (junctioned or symbolically linked), or (more important for my purposes) that the there is a hardlink linking the two files together.


_stat/_wstat ... they give inodes.

--
- Vince
 
#3
For uniqueness, I use the BY_HANDLE_FILE_INFORMATION structure returned
by GetFileInformationByHandle:

"The identifier (low and high parts) and the volume serial number uniquely
identify a file on a single computer. To determine whether two open handles
represent the same file, combine the identifier and the volume serial number
for each file and compare them."

To display the junction targets you could use something like the pseudo-C
code below, cleaned up a bunch:

static BOOL PrintJunctionResolution
(char * cpFilename,
WIN32_FIND_DATA const *fdpFindFileData)
{
HANDLE hFilenameOpen = INVALID_HANDLE_VALUE;
struct
{
REPARSE_GUID_DATA_BUFFER rgdb;
byte data[4096];
} rgdb;
DWORD lpBytesReturned;

if ((fdpFindFileData->dwFileAttributes &
(FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY)) ! (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY))
{
return FALSE;
}

hFilenameOpen = CreateFile(
cpFilename,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);


if (
!DeviceIoControl
(
(HANDLE) hFilenameOpen, // handle to file or directory
FSCTL_GET_REPARSE_POINT, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
(LPVOID) &rgdb, // output buffer
sizeof(rgdb), // size of output buffer
(LPDWORD) &lpBytesReturned, // number of bytes returned
NULL // OVERLAPPED structure
)
)
{
return FALSE;
}
// Note the .DataBuffer is not char but WCHAR.
printf(" [%S]", rgdb.rgdb.GenericReparseBuffer.DataBuffer);
}


On Wed, May 19, 2010 at 1:09 AM, vefatica <> wrote:


> On Wed, 19 May 2010 02:58:00 -0400, [email protected]
> <> wrote:
>
> |And, on a related but far less critical task, do you know any way to get
> the disk address of a file? If two files on the same logical drive have the
> same disk address, it would mean that either some parent directories in each
> file's directory tree are really the same directory (junctioned or
> symbolically linked), or (more important for my purposes) that the there is
> a hardlink linking the two files together.
>
>
> _stat/_wstat ... they give inodes.
>
> --
> - Vince
>
>
>
>
>


--
Jim Cook
2010 Sundays: 4/4, 6/6, 8/8, 10/10, 12/12 and 5/9, 9/5, 7/11, 11/7.
Next year they're Monday.
 
#4
On Wed, 19 May 2010 02:58:00 -0400, [email protected]
<> wrote:

|And, on a related but far less critical task, do you know any way to get the disk address of a file? If two files on the same logical drive have the same disk address, it would mean that either some parent directories in each file's directory tree are really the same directory (junctioned or symbolically linked), or (more important for my purposes) that the there is a hardlink linking the two files together.


_stat/_wstat ... they give inodes.

--
- Vince
Vince,

Sorry it took me so long to get back to you, but for unknown reasons I was unable to log on to this forum for a couple of days (Rex fixed this), and thank you for your response. However, when I looked into these functions more deeply (on the web at http://msdn.microsoft.com/en-us/library/ at: 14h5k7ff(VS.71).aspx (I had to split-up the URL because this website abbreviated it) I found the following:




<DT>st_ino: Number of the information node (the inode) for the file (UNIX-specific). On UNIX file systems, the inode describes the file date and time stamps, permissions, and content. When files are hard-linked to one another, they share the same inode. The inode, and therefore st_ino, has no meaning in the FAT, HPFS, or NTFS file systems. (Bold and italics mine.) <DT>


<DT>And I could not find any fields in the structure that related to the rough NTFS equivalent of the UNIX inode. Just thought you might want to know...

- Dan





</DT>
 
#5
For uniqueness, I use the BY_HANDLE_FILE_INFORMATION structure returned
by GetFileInformationByHandle:

...

{
return FALSE;
}
// Note the .DataBuffer is not char but WCHAR.
printf(" [%S]", rgdb.rgdb.GenericReparseBuffer.DataBuffer);
}

...

Jim Cook
2010 Sundays: 4/4, 6/6, 8/8, 10/10, 12/12 and 5/9, 9/5, 7/11, 11/7.
Next year they're Monday.
Jim,

Thank you for your response! Sorry this took so long, but I was unable to log on to this website for a couple of days for unknown (to me!) reasons; Rex fixed this for me. But back to the point: This code was a very good start but not the complete solution. If you are interested in the "complete solution", send me an e-mail at [email protected] and I'll reply with the complete final (fully tested and working!) code (it's a self-contained function) as an attachment. (I'm not attaching it to this posting to avoid taking up space on this site for something that is probably irrelevant to most people.)

- Dan
 
#6
On Wed, 26 May 2010 03:39:59 -0400, mathewsdw <> wrote:

|<DT>*st_ino: *Number of the information node [...]

When I thought of inodes, I was confused, looked them up and came to those "C"
functions I mentioned. What I was really thinking of were the nFileIndexHigh
and nFileIndexLow members of BY_HANDLE_FILE_INFORMATION which Jim Cook mentioned
I dealt with them about 6 years ago in an FSTAT.EXE program that I might have
incorporated into a TCC plugin (could still do that). I had even used the term
"inode" (see below). Anyway, I'm glad Jim got it right and set you on the right
track.

g:\projects\listlinks\release> fstat
Syntax: FSTAT.EXE filename options

Options (appear in the order specified)

/A attributes
/S size
/Tx local date/time [x = (c)reate, (w)rite, (a)ccess]
/Fx like /T but UTC seconds since 1980-01-01 00:00:00
/I inode
/N number of links
/L list links

Attributes: A archived C compressed E encrypted
H hidden I content indexed O offline
R read-only T temporary


g:\projects\listlinks\release> fstat d:\tc11\tcc.exe /a /s /tc /tw /ta /i /n /l
AI
107248
2010-04-23 09:29:40
2010-04-23 09:29:40
2010-05-26 09:57:38
004C:2A90:07D8:2763
1
d:\TC11\tcc.exe
--
- Vince
 
#7
I'm sure you're aware of this but here's another example of using what I had (wrongly) called "inodes".

v:\> fstat d:\tc11\Plugins\4utils.dll /i
78FB:8D8F:0001:001E

v:\> fstat d:\tcmd10\Plugins\4utils.dll /i
78FB:8D8F:0001:001E

They are indeed the same file, being on a volume which is mounted on several "plugins" mount points.
 
#8
----- Original Message -----
From: "vefatica" <>
To: <[email protected]>
Sent: 2010. May 26., Wednesday 10.22
Subject: RE: [Support-t-1980] Re: Hoping somebody can help me...



> I'm sure you're aware of this but here's another example of using what I
> had (wrongly) called "inodes".
>
> v:\> fstat d:\tc11\Plugins\4utils.dll /i
> 78FB:8D8F:0001:001E
>
> v:\> fstat d:\tcmd10\Plugins\4utils.dll /i
> 78FB:8D8F:0001:001E
>
> They are indeed the same file, being on a volume which is mounted on
> several "plugins" mount points.
Isn't this the same value returned by the @INODE[] variable function? It's
what I have been using for years to verify two or more directory entries are
hard linked to represent the same file body.

IIRC, the OP was not asking how you obtain the file identifier in TCC, but
directly from the MS APIs, which is why I did not respond.
--
Steve