Hi all,
I've been doing some experimentation today and discovered another twist
in the story
which relates to cygwin - so I forward this on to cygwin-user list, also.
I have been testing the code below against symlinks created
in cygwin64 (I'm running win7 64-bit; I have mingw/msys, msys2 (64), and
cygwin64 installations).
My code hadn't detected symlink files but all of thesymlinks I was trying
were cygwin64.
I created some symlinks natively, using an ln.exe (from
http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html)
and using mklink.exe; these links *-do show up-* as reparse points in my
detection scheme 3), (but 2) should also work) described below.
The links I couldn't detect earlier were created by cygwin install
procedure, i.e. cygwin64/lib/noX has two files and
two symlinks pointing to the files: fstat_win32 below didn't find a
FILE_ATTRIBUTE_REPARSE_POINT in its mask.
Nevertheless, cygwin and msys2 "ls -la" commands show a symlink. They work
like a symlink should.
So the question becomes, "why do cygwin symlinks look different, and how
can a user program detect this attribute?
(I've edited the original message to correct the lstat call )
On Wed, Jan 14, 2015 at 9:33 AM, Greg Jung <[email protected]> wrote:
> Hi Folks,
> I've been trying to program a recognition of NTFS symbolic link files;
> What I;ve gleaned
> from MSDN procedures don't seem to work. Below are coded three methods
>
> 1) (untested) open file and call GetFileInformationByHandleEx. I can't
> get winbase.h header definitions recognized
> 2) GetFileAttributes() works ok for Junctions doesn't recognize symlink
> files
> 3) FindFirstEx . same result as 2)
>
> There must be a way, since cygwin 'ls -a' and msys2 'ls -a' commands will
> show links.
>
> in the calling routine, I modify result of stat() (from glibc, I take it)
> from with system calls:
> #ifdef _WIN32
> int addlink = 0;
> fstat_win32(filename.c_str(), addlink);
> int actStat = stat(filename.c_str(), &statStruct);
> if( addlink != 0) cout << " addlink came back " << endl;
> statStruct.st_mode |= addlink;
> #else
> int actStat = lstat( filename.c_str(), &statStruct);
> #endif
>
> where fstat_win32 now has a graveyard full of attempts: ( When a directory
> link is encountered, however, the test succeeeds.)
>
> void fstat_win32(const string& filepath, int& st_mode)
> {
> DWORD dwattrib, reparsetag;
> DString st;
> st=filepath;
> #if 1
> //
> // This method has not been tested: it will not compile -
> GetFileInformationByHandleEx
> // does not get through from the winbase.h header
> //
> HANDLE hFile;
> BOOL success;
> DWORD fattrib[2];
> hFile = CreateFile( (TCHAR *)st.c_str(),
> FILE_GENERIC_READ,
> FILE_SHARE_READ | FILE_SHARE_WRITE,
> 0,
> OPEN_EXISTING,
> FILE_FLAG_OPEN_REPARSE_POINT,
> 0);
> if (hFile == INVALID_HANDLE_VALUE) {
> CloseHandle(hFile);
> cout << " stat_win32: could not open " + st << endl;
> return;
> }
> else {
> success = GetFileInformationByHandleEx( hFile,
> FileAttributeTagInfo,
> &fattrib,
> sizeof(fattrib));
> dwattrib = fattrib[0];
> reparsetag = fattrib[1];
> }
> CloseHandle(hFile);
>
> // dwattrib = GetFileAttributes( (TCHAR *)st.c_str()); // This doesn't
> work to find symlinks
> if( (dwattrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0 ) {
> st_mode |= S_IFLNK;
> cout << " fstat_win32: symbolic link detected and flagged!! " <<
> filepath ;
> }
> else st_mode=0;
> #elif 0
> DWORD dwlen;
> HANDLE hFind;
> BOOL foundnext;
> WIN32_FIND_DATA FindFileData;
> // This doesn't work to find symlinks
> hFind = FindFirstFileEx( (TCHAR *) st.c_str(),
> FindExInfoStandard,
> &FindFileData,
> FindExSearchNameMatch, NULL, 0);
> if (hFind == INVALID_HANDLE_VALUE)
> return;
> dwattrib = FindFileData.dwFileAttributes;
> if( (dwattrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0 ) {
> st_mode |= S_IFLNK;
> cout << " fstat_win32: symbolic link detected and flagged!! " <<
> filepath ;
> dwattrib = FindFileData.dwReserved0;
> // IO_REPARSE_TAG_SYMLINK _MOUNT_POINT etc.
> }
> FindClose(hFind);
> #endif
> return;
> }
>
>
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public