EaseFilter Demo Project
FileMonitorService/FilterMessage.cs
Go to the documentation of this file.
1 //
3 // (C) Copyright 2011 EaseFilter Technologies Inc.
4 // All Rights Reserved
5 //
6 // This software is part of a licensed software product and may
7 // only be used or copied in accordance with the terms of that license.
8 //
10 
11 using System;
12 using System.Collections.Generic;
13 using System.ComponentModel;
14 using System.Data;
15 using System.Text;
16 using System.Runtime.InteropServices;
17 using System.Security.Principal;
18 using System.IO;
19 using System.Threading;
20 using System.Reflection;
21 
23 
24 namespace FileMonitorService
25 {
26  public class ByteArrayComparer : IEqualityComparer<byte[]>
27  {
28  public bool Equals(byte[] left, byte[] right)
29  {
30  if (left == null || right == null)
31  {
32  return left == right;
33  }
34  if (left.Length != right.Length)
35  {
36  return false;
37  }
38  for (int i = 0; i < left.Length; i++)
39  {
40  if (left[i] != right[i])
41  {
42  return false;
43  }
44  }
45  return true;
46  }
47 
48  public int GetHashCode(byte[] key)
49  {
50  if (key == null)
51  throw new ArgumentNullException("key");
52  int sum = 0;
53  foreach (byte cur in key)
54  {
55  sum += cur;
56  }
57  return sum;
58  }
59  }
60 
61  public class FilterMessage : IDisposable
62  {
63  Thread messageThread = null;
64  Queue<FilterAPI.MessageSendData> messageQueue = new Queue<FilterAPI.MessageSendData>();
65 
66  static Dictionary<string, DateTime> readFileCacheTable = new Dictionary<string, DateTime>();
67  static Dictionary<string, DateTime> writeFileCacheTable = new Dictionary<string, DateTime>();
68  static int cacheTimeOutInSeconds = 30;
69  static System.Timers.Timer deleteCachedItemTimer = new System.Timers.Timer();
70 
71  delegate void LogFileEventDlg(FileEvent fileEvent);
72  static event LogFileEventDlg OnFileEvent = new LogFileEventDlg(FileEventHandler.LogFileEvent);
73 
74  AutoResetEvent autoEvent = new AutoResetEvent(false);
75  bool disposed = false;
76 
77 
78  public FilterMessage()
79  {
80  deleteCachedItemTimer.Interval = cacheTimeOutInSeconds * 1000 / 4; //millisecond
81  deleteCachedItemTimer.Start();
82  deleteCachedItemTimer.Enabled = true;
83  deleteCachedItemTimer.Elapsed += new System.Timers.ElapsedEventHandler(deleteCachedItemTimer_Elapsed);
84 
85  messageThread = new Thread(new ThreadStart(ProcessMessage));
86  messageThread.Start();
87  }
88 
89  public void Dispose()
90  {
91  Dispose(true);
92  GC.SuppressFinalize(this);
93  }
94 
95  private void Dispose(bool disposing)
96  {
97  if (!this.disposed)
98  {
99  }
100 
101  autoEvent.Set();
102  messageThread.Abort();
103  disposed = true;
104  }
105 
106  ~FilterMessage()
107  {
108  Dispose(false);
109  }
110 
111 
112  private static void deleteCachedItemTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
113  {
114 
115  try
116  {
117  List<string> keysToRemove = new List<string>();
118 
119  foreach (KeyValuePair<string, DateTime> userItem in readFileCacheTable)
120  {
121 
122  TimeSpan tsSinceLastAccess = DateTime.Now - userItem.Value;
123 
124  if (tsSinceLastAccess.TotalSeconds >= cacheTimeOutInSeconds)
125  {
126  EventManager.WriteMessage(124, "deleteCachedItemTimer_Elapsed", EventLevel.Verbose, "Remove read key " + userItem.Key);
127  keysToRemove.Add(userItem.Key);
128  }
129  }
130 
131  foreach (string key in keysToRemove)
132  {
133  lock (readFileCacheTable)
134  {
135  readFileCacheTable.Remove(key);
136  }
137  }
138 
139  keysToRemove.Clear();
140 
141  foreach (KeyValuePair<string, DateTime> userItem in writeFileCacheTable)
142  {
143 
144  TimeSpan tsSinceLastAccess = DateTime.Now - userItem.Value;
145 
146  if (tsSinceLastAccess.TotalSeconds >= cacheTimeOutInSeconds)
147  {
148  EventManager.WriteMessage(145, "deleteCachedItemTimer_Elapsed", EventLevel.Verbose, "Remove write key " + userItem.Key );
149 
150  keysToRemove.Add(userItem.Key);
151  }
152  }
153 
154  foreach (string key in keysToRemove)
155  {
156  lock (writeFileCacheTable)
157  {
158  writeFileCacheTable.Remove(key);
159  }
160  }
161  }
162  catch (System.Exception ex)
163  {
164  EventManager.WriteMessage(46, "deleteCachedItemTimer_Elapsed", EventLevel.Error, "Delete cached item failed with error:" + ex.Message);
165  }
166 
167  }
168 
169  public void AddMessage(FilterAPI.MessageSendData messageSend)
170  {
171  lock (messageQueue)
172  {
173  if (messageQueue.Count > GlobalConfig.MaximumFilterMessages)
174  {
175  messageQueue.Clear();
176  }
177 
178  messageQueue.Enqueue(messageSend);
179  }
180 
181  autoEvent.Set();
182 
183 
184  }
185 
186 
187  void ProcessMessage()
188  {
189 
190  WaitHandle[] waitHandles = new WaitHandle[] { autoEvent, GlobalConfig.stopEvent };
191 
192  while (GlobalConfig.isRunning)
193  {
194  if (messageQueue.Count == 0)
195  {
196  int result = WaitHandle.WaitAny(waitHandles);
197  if (!GlobalConfig.isRunning)
198  {
199  return;
200  }
201  }
202 
203  while (messageQueue.Count > 0)
204  {
205  FilterAPI.MessageSendData messageSend;
206 
207  lock (messageQueue)
208  {
209  messageSend = (FilterAPI.MessageSendData)messageQueue.Dequeue();
210  }
211 
212  var fileEvent = DecodeFilterMessage(messageSend);
213 
214  if (null != fileEvent && null != OnFileEvent)
215  {
216  OnFileEvent(fileEvent);
217  }
218  }
219 
220  }
221 
222 
223  }
224 
225 
226 
227  FileEvent DecodeFilterMessage(FilterAPI.MessageSendData messageSend)
228  {
229 
230 
231  try
232  {
233 
234  string userName = string.Empty;
235  string processName = string.Empty;
236  string fileName = messageSend.FileName;
237  string description = string.Empty;
238  FileAttributes fileAttributes = (FileAttributes)messageSend.FileAttributes;
239  DateTime timestamp = DateTime.FromFileTime(messageSend.TransactionTime);
240  FileEventResult result = (messageSend.Status == (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS) ? FileEventResult.SUCCESS : FileEventResult.FAILURE;
241 
242  FilterAPI.DecodeUserName(messageSend.Sid, out userName);
243  FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName);
244 
245  FilterAPI.EVENTTYPE eventType = (FilterAPI.EVENTTYPE)messageSend.InfoClass;
246 
247  if ((eventType & FilterAPI.EVENTTYPE.RENAMED) == FilterAPI.EVENTTYPE.RENAMED)
248  {
249  description = "file was renamed to " + Encoding.Unicode.GetString(messageSend.DataBuffer);
250  description = description.Substring(0, description.IndexOf('\0'));
251  }
252 
253 
254  if (eventType != FilterAPI.EVENTTYPE.NONE)
255  {
256  FileEvent fileEvent = new FileEvent();
257 
258  fileEvent.User = userName;
259  fileEvent.Process = processName;
260  fileEvent.Resource = fileName;
261  fileEvent.Result = result;
262  fileEvent.Timestamp = timestamp;
263  fileEvent.Type = eventType;
264  fileEvent.Description = description;
265  fileEvent.Attributes = fileAttributes;
266 
267  return fileEvent;
268 
269  }
270 
271  }
272  catch (Exception ex)
273  {
274  EventManager.WriteMessage(296, "DecodeFilterMessage", EventLevel.Error, "Decode filter message failed because of error:" + ex.Message);
275  }
276 
277  return null;
278  }
279 
280 
281 
282 
283  }
284 }
WCHAR * userName
Definition: FilterAPI.h:604
unsigned char key[]
string Process
The process name
string Resource
Full path of the file name
FilterAPI.EVENTTYPE Type
type of the event -can be an enum
LONGLONG ULONG fileAttributes
Definition: FilterAPI.h:684
FileAttributes Attributes
the file attributes
WCHAR * processName
Definition: FilterAPI.h:596
DateTime Timestamp
// timestamp of event
void AddMessage(FilterAPI.MessageSendData messageSend)
FileEventResult Result
The status of the result
string Description
The description of the IO
ULONG eventType
Definition: FilterAPI.h:584
static ManualResetEvent stopEvent
Definition: GlobalConfig.cs:77

Social Network


Services Overview

Architect, implement and test file system filter drivers for a wide range of functionality. We can offer several levels of assistance to meet your specific.

Contact Us

You are welcome to contact us for salse or partnership.

Sales: sales@easefilter.com
Support: support@easefilter.com
Info: info@easefilter.com