This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: faked inode numbers on network drives



On Sun, 27 Nov 2005, Corinna Vinschen wrote:


And I ask why such an assumption is necessary at all.
In the Windows API there is a function GetVolumeInformation
which is supported from Win95 on and reports FILE_SUPPORTS_OBJECT_IDS
when inode numbers are valid.

Nope. Object IDs are not inode numbers. I suggest reading on object IDs in MSDN.

Thanks, and sorry for not being thorough enough before writing the mail.


Is there a reason for not using this? GetVolumeInformation is already
used in several other places within cygwin.

Samba reports FS_PERSISTENT_ACLS, but the way has_acls() is treated in case of CYGWIN=nosmbntsec (the default) disables its usage. I think I found a bug though, which might explain inconsistent behaviour. I'm looking into it.

But using FILE_SUPPORTS_OBJECT_IDS is definitely incorrect.  And, just
as a side note, the Samba version I'm using (3.0.20a) does not report
that it supports FILE_SUPPORTS_OBJECT_IDS.  The flags value returned
from GetVolumeInformation:

 11 == 0xb == FILE_CASE_SENSITIVE_SEARCH
              | FILE_CASE_PRESERVED_NAMES
              | FILE_PERSISTENT_ACLS

Ok. I now wrote and executed a small program which shows the inode numbers returned by GetFileInformationByHandle() to see which inode numbers are definitely non-sense and which could be real ones.
(Because of GetVolumePathName() used for brevity, this program only runs on >=W2K.)


On a W2K box, I tested several file systems, local and remote.
Here are the results:

     ino_h       ino_l  link    fsname  file
   2883584       82115     1      NTFS  C:\local_harddisk\testfile
   4161736        2070     2      NTFS  T:\samba3_share\testfile
   6881280       20695     1      NTFS  P:\w2k3_share\testfile
         0  -465645560     1     FAT32  W:\win98_share\testfile1
         0  -467871288     1     FAT32  W:\win98_share\testfile2
         0         568     1      CDFS  E:\local_cdrom\testfile1
         0         516     1      CDFS  E:\local_cdrom\testfile2
         0      258336     1       FAT  G:\local_usbstick\testfile1
         0      254880     1       FAT  G:\local_usbstick\testfile2

(samba reports the device number as low part of the inode number, and the real ext2 fs inode number as high part, which is bad for interix/sfu, as it only shows the low part as inode number. I just reported this as samba bug 3287, see https://bugzilla.samba.org/show_bug.cgi?id=3287 )

For the Win98 share, one gets random numbers on each call. The other numbers are constant, at least between reboots. (I didn't yet test after reboot.)

Based on these results, I could think of the following:

if (running on nt) {
    if (local drive) {
       return inode number by GetFileInformationByHandle();
    } else if (remote drive) {
       if (FS=="NTFS") {
          return inode number by GetFileInformationByHandle();
       } else {
          return faked inode number;
       }
    } else {
       return faked inode number;
    }
}


Martin




#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

void printerror()
{
  DWORD msgid = GetLastError();
  _TCHAR msg[1024];
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, msgid, 0, msg, sizeof(msg), NULL);
  _tprintf(_T("Could not open file (error %d): %s\n"), msgid, msg);
}

int _tmain(int argc, _TCHAR* argv[])
{
  _tprintf(_T("     ino_h       ino_l  link    fsname  file\n"));

  for (int i = 1; i < argc; i++) {
    HANDLE fh = CreateFile(
      argv[i],
      GENERIC_READ,
      FILE_SHARE_READ,
      NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      NULL
    );
    if (fh == INVALID_HANDLE_VALUE) { printerror(); continue; }

    BY_HANDLE_FILE_INFORMATION fi;
    memset(&fi, 0, sizeof(fi));

    BOOL res = GetFileInformationByHandle(fh, &fi);
    if (!res) { printerror(); continue;	}

    _TCHAR volpath[1024];
    res = GetVolumePathName( argv[i], volpath, sizeof(volpath) );
    if (!res) { printerror(); continue;	}

    _TCHAR fsname[100];
    res = GetVolumeInformation( volpath, NULL, 0, NULL, NULL, NULL, fsname, sizeof(fsname) );
    if (!res) { printerror(); continue;	}

    _tprintf(_T("%10d  %10d  %4d  %8s  %s\n"),
      fi.nFileIndexHigh, fi.nFileIndexLow, fi.nNumberOfLinks, fsname, argv[i]);

    CloseHandle(fh);
  }
  return 0;
}


-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]