windows - Getting a Folder ID C# -


i trying track files , folders through lifetime (they may moved or renamed). have done searching , found filesystemwatcher might popular way track files , folders, however, not work me application may or may not running. have chosen try track folders via id.

i have found way track files id answer this stack post. can grab file ids based on approach b in this answer.

while searching found this stack post stating found solution using fsctl_get_object_id. have spent quite bit of time trying figure out how use function, can not wrap head around it. have 0 experience calling native windows functions within c#.

can give me push in right direction this? feel must missing obvious.

is there reason c# can't access file/folder ids? tracking files/folders uncommon?

edit, adding code:

        static uint returnval;      //working example file id     public static string getfileid(string path)     {         winapi.by_handle_file_information objectfileinfo = new winapi.by_handle_file_information();          fileinfo fi = new fileinfo(path);         filestream fs = fi.open(filemode.open, fileaccess.read, fileshare.readwrite);          winapi.getfileinformationbyhandle(fs.handle, out objectfileinfo);          fs.close();          ulong fileindex = ((ulong)objectfileinfo.fileindexhigh << 32) + (ulong)objectfileinfo.fileindexlow;          return fileindex.tostring();     }      public static string getfolderid(string path)     {         //get handle on given folder         intptr cfile = winapi.createfile(             path,             winapi.generic_read,             fileshare.read,             intptr.zero,             (filemode)winapi.open_existing,             winapi.file_flag_backup_semantics,             intptr.zero);          console.writeline(path);         console.writeline(cfile);          if ((int)cfile != -1)         {             int cfilesize = marshal.sizeof(typeof(intptr));             console.writeline("cfile size = {0}", cfilesize);              intptr cfileblob = marshal.allochglobal(cfilesize);             uint numbytesread = 0;              winapi.deviceiocontrol(cfile, winapi.fsctl_get_object_id, intptr.zero, 0, cfileblob, (uint)cfilesize, ref numbytesread, intptr.zero);              if (returnval == 0)             {                 console.writeline(marshal.getlastwin32error()); // returning error 87 here             }         }          //should returning id folder.         return string.empty;     }      public static void main(string[] args)     {     console.writeline(getfileid(@"c:\users\matt\desktop\testdocument.txt"));     console.writeline(getfolderid(@"c:\users\matt\desktop"));     }  }  class winapi {     // win32 constants accessing files.     internal const int generic_read = unchecked((int)0x80000000);     internal const int file_flag_backup_semantics = unchecked((int)0x02000000);     internal const int open_existing = unchecked((int)3);     internal const int fsctl_get_object_id = 0x0009009c;     internal const int fsctl_create_or_get_object_id = 0x000900c0;      [dllimport("kernel32.dll", setlasterror = true)]     public static extern bool deviceiocontrol(intptr hdevice, uint dwiocontrolcode, intptr lpinbuffer, uint ninbuffersize, [out] intptr lpoutbuffer, uint noutbuffersize, ref uint lpbytesreturned, intptr lpoverlapped);      [dllimport("kernel32.dll", setlasterror = true)]     public static extern bool getfileinformationbyhandle(intptr hfile, out by_handle_file_information lpfileinformation);      [dllimport("kernel32.dll", setlasterror = true)]     public static extern intptr createfile(        string filename,        int dwdesiredaccess,        system.io.fileshare dwsharemode,        intptr securityattrs_mustbezero,        system.io.filemode dwcreationdisposition,        int dwflagsandattributes,        intptr htemplatefile_mustbezero);      public struct by_handle_file_information     {         public uint fileattributes;         public filetime creationtime;         public filetime lastaccesstime;         public filetime lastwritetime;         public uint volumeserialnumber;         public uint filesizehigh;         public uint filesizelow;         public uint numberoflinks;         public uint fileindexhigh;         public uint fileindexlow;     } } 

i getting error "87" deviceiocontrol, invalid parameter according post on msdn (i unable post more links due reputation restrictions.)

seems got no problem filesystemwatcher. so, how use deviceiocontrol in c#, have of answer:

physical disk size not correct (ioctldiskgetdrivegeometry)

to question, it's done following code:

class program {     const uint fsctl_get_object_id=0x0009009c;      public static string getfileid(string path) {         using(var fs=file.open(             path,              filemode.openorcreate, fileaccess.readwrite, fileshare.readwrite)             ) {             winapi.by_handle_file_information info;             winapi.getfileinformationbyhandle(fs.handle, out info);             return string.format(                     "{0:x}", ((info.fileindexhigh<<32)|info.fileindexlow));         }     }      public static winapi.file_objectid_buffer getfolderidbuffer(string path) {         using(var hfile=winapi.createfile(             path,             winapi.generic_read, fileshare.read,             intptr.zero,             (filemode)winapi.open_existing,             winapi.file_flag_backup_semantics,             intptr.zero             )) {             if(null==hfile||hfile.isinvalid)                 throw new win32exception(marshal.getlastwin32error());              var buffer=default(winapi.file_objectid_buffer);             var noutbuffersize=marshal.sizeof(buffer);             var lpoutbuffer=marshal.allochglobal(noutbuffersize);             var lpbytesreturned=default(uint);              var result=                 winapi.deviceiocontrol(                     hfile, fsctl_get_object_id,                     intptr.zero, 0,                     lpoutbuffer, noutbuffersize,                     ref lpbytesreturned, intptr.zero                     );              if(!result)                 throw new win32exception(marshal.getlastwin32error());              var type=typeof(winapi.file_objectid_buffer);              buffer=(winapi.file_objectid_buffer)                 marshal.ptrtostructure(lpoutbuffer, type);              marshal.freehglobal(lpoutbuffer);             return buffer;         }     }      public static void main(string[] args) {         console.writeline(             getfileid(@"c:\users\matt\desktop\testdocument.txt"));          var buffer=getfolderidbuffer(@"c:\users\matt\desktop");          var objectid=buffer.objectid                 .reverse()                 .select(x => x.tostring("x2"))                 .aggregate(string.concat);          console.writeline("{0}", objectid);     } }  class winapi {     internal const int         generic_read=unchecked((int)0x80000000),         file_flag_backup_semantics=unchecked((int)0x02000000),         open_existing=unchecked((int)3);      [structlayout(layoutkind.sequential)]     public struct file_objectid_buffer {         public struct union {             [marshalas(unmanagedtype.byvalarray, sizeconst=16)]             public byte[] birthvolumeid;              [marshalas(unmanagedtype.byvalarray, sizeconst=16)]             public byte[] birthobjectid;              [marshalas(unmanagedtype.byvalarray, sizeconst=16)]             public byte[] domainid;         }          [marshalas(unmanagedtype.byvalarray, sizeconst=16)]         public byte[] objectid;          public union birthinfo;          [marshalas(unmanagedtype.byvalarray, sizeconst=48)]         public byte[] extendedinfo;     }      [structlayout(layoutkind.sequential)]     public struct by_handle_file_information {         public uint fileattributes;         public filetime creationtime;         public filetime lastaccesstime;         public filetime lastwritetime;         public uint volumeserialnumber;         public uint filesizehigh;         public uint filesizelow;         public uint numberoflinks;         public uint fileindexhigh;         public uint fileindexlow;     }      [dllimport("kernel32.dll", setlasterror=true)]     public static extern bool deviceiocontrol(         safefilehandle hdevice,         uint dwiocontrolcode,         intptr lpinbuffer,         uint ninbuffersize,         [out] intptr lpoutbuffer,         int noutbuffersize,         ref uint lpbytesreturned,         intptr lpoverlapped         );      [dllimport("kernel32.dll", setlasterror=true)]     public static extern safefilehandle createfile(         string filename,         int dwdesiredaccess,         system.io.fileshare dwsharemode,         intptr securityattrs_mustbezero,         system.io.filemode dwcreationdisposition,         int dwflagsandattributes,         intptr htemplatefile_mustbezero         );      [dllimport("kernel32.dll", setlasterror=true)]     public static extern bool getfileinformationbyhandle(         intptr hfile, out by_handle_file_information lpfileinformation); } 

the name space required of using:

using microsoft.win32.safehandles; 

Comments