0

I would like to get the username of an accessed file (add, delete, rename,...). actually I use filesystemwatcher to monitor the file access and I have activated object access on an directory to get userinformation via eventlogs. This solution is not perfect, because there are a lot of file events and the eventlog messages are not so detailed. there is just one eventd id for write data. this it is used for add file, rename , move,... every write data. Additionally I had to crosscheck that the eventlog message matches the filesystemwatcher event. I would prefer handle this better. so i spend al lot of time googleing, reading, ... I know there is another post on stackoverflow

Get username of opened file

but i think there should be a possible solution because Windows Events can get the username.

with reading on a few pages i disovered that there should be a possible solution using netapi32.dll. the example code on http://vbcity.com/forums/t/133307.aspx?PageIndex=2 doesn't work for me. i was unable to get the fileid so i changed the code to

private ulong GetFileIdFromPath(string filePath)
{

  WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo = new WinAPI.BY_HANDLE_FILE_INFORMATION();

  Thread.Sleep(200);

  FileInfo fi = new FileInfo(filePath);

  FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read);

  WinAPI.GetFileInformationByHandle(fs.Handle, out objectFileInfo);


  fs.Close();


 ulong fileIndex = ((ulong)objectFileInfo.FileIndexHigh << 32) + (ulong)objectFileInfo.FileIndexLow;

  return fileIndex; 

}

with this code I'm able to get the fileid but with the fileid and the example code I'm unable to get the username.

Community
  • 1
  • 1
user1008764
  • 390
  • 1
  • 3
  • 7
  • What are you asking? You need to make that clear. All of the information about the event log, etc., seems unrelated to your actual question. – Adam Robinson Oct 22 '11 at 18:02
  • 1
    i think my question is clear. i want to get the username of the user accessing a file on a server. all the information about the eventlog mybe important because the other post was ansered with "this is impossible". – user1008764 Oct 22 '11 at 18:12
  • Please don't start your titles with "C#". We use tags for that on [so]. Also, see http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts – John Saunders Oct 22 '11 at 18:13
  • 1
    Your question is _not_ clear. "Username of the accessed file" is not the same as "username of the user who accessed the file". – John Saunders Oct 22 '11 at 18:15
  • @user1008764: If someone asks you to clarify your question, that should be a pretty clear indication that your question is *not* clear to people other than you. – Adam Robinson Oct 22 '11 at 18:36

1 Answers1

1

From My last program ( 2 week ago) - I was asked to audit change in files ( also the user name)

the Solution was by filesystemwatcher and after an event -> goto the Event Log of windows and bu Xpath search - To find which user made the action.

   public static EventUnit DisplayEventAndLogInformation(string fileToSearch, DateTime actionTime)
        {
            StringBuilder sb = new StringBuilder();
            const string queryString = @"<QueryList>
  <Query Id=""0"" Path=""Security"">
    <Select Path=""Security"">*</Select>
  </Query>
</QueryList>";
            EventLogQuery eventsQuery = new EventLogQuery("Security", PathType.LogName, queryString);
            eventsQuery.ReverseDirection = true;
            EventLogReader logReader = new EventLogReader(eventsQuery);
            EventUnit e = new EventUnit();
            bool isStop = false;
            for (EventRecord eventInstance = logReader.ReadEvent(); null != eventInstance; eventInstance = logReader.ReadEvent())
            {
                foreach (var VARIABLE in eventInstance.Properties)
                    if (VARIABLE.Value.ToString().ToLower().Contains(fileToSearch.ToLower()) && actionTime.ToString("d/M/yyyy HH:mm:ss") == eventInstance.TimeCreated.Value.ToString("d/M/yyyy HH:mm:ss"))
                    {
                        foreach (var VARIABLE2 in eventInstance.Properties) sb.AppendLine(VARIABLE2.Value.ToString());
                        e.Message = sb.ToString();
                        e.User = (eventInstance.Properties.Count > 1) ? eventInstance.Properties[1].Value.ToString() : "n/a";
                        e.File = fileToSearch;
                        isStop = true;
                        break;
                    }
                if (isStop) break;
                try
                {
                    //    Console.WriteLine("Description: {0}", eventInstance.FormatDescription());
                }
                catch (Exception e2)
                {
                }
            }
            return e;
        }
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • this is close to my solution. i have an eventlog handler. but i'm not sure this is the best sollution. – user1008764 Oct 22 '11 at 18:24
  • if you are using system File Watcher. you have no other choice. there is a code on the net which can catch via import dll - some events like delete and create but not rename or something more than that. believe me. its a waste of time. if you use XPATH search it is the fastest. – Royi Namir Oct 22 '11 at 18:37
  • and i have already wasted a lot of time. why is XPATH search better than an eventlog handler? – user1008764 Oct 22 '11 at 18:47
  • @because you donw want `any` event to come to your c# program and then to filter what is needed and what is not needed ( by event id etc...). the best approch is to let systemFileWatcher work. then after x sec of delay( in a new thread) goto EventLog and using `EventLogQuery eventsQuery = new EventLogQuery("Security", PathType.LogName, queryString); eventsQuery.ReverseDirection = true; EventLogReader logReader = new EventLogReader(eventsQuery);` you should read the top inserted records which contains the fileName. it s a matter of 2 second reading it all ( and my log is 200mb) using xpath – Royi Namir Oct 22 '11 at 19:35