15 using System.Collections.Generic;
16 using Microsoft.Win32.SafeHandles;
17 using System.Runtime.InteropServices;
18 using System.Security.Principal;
19 using System.Security.Cryptography;
25 static public class FilterAPI
27 public delegate Boolean FilterDelegate(IntPtr sendData, IntPtr replyData);
28 public delegate
void DisconnectDelegate();
29 static GCHandle gchFilter;
30 static GCHandle gchDisconnect;
31 static bool isFilterStarted =
false;
34 public const int MAX_MESSAGE_LENGTH = 65536;
38 public const uint GENERIC_WRITE = 0x40000000;
41 static Dictionary<byte[], string> userNameTable =
new Dictionary<byte[], string>(
new ByteArrayComparer());
42 static Dictionary<uint, string> processNameTable =
new Dictionary<uint, string>();
45 public static byte[] DEFAULT_IV_TAG = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
117 public enum EVENTTYPE : uint
120 CREATED = 0x00000020,
121 WRITTEN = 0x00000040,
122 RENAMED = 0x00000080,
123 DELETED = 0x00000100,
124 SECURITY_CHANGED = 0x00000200,
125 INFO_CHANGED = 0x00000400,
132 STATUS_UNSUCCESSFUL = 0xc0000001,
176 public enum SecureFileAccessRights : uint
178 ENABLE_REVOKE_ACCESS_CONTROL = 1,
183 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
208 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)]
211 [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_SID_LENGTH)]
214 [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_MESSAGE_LENGTH)]
224 BLOCK_DATA_WAS_RETURNED = 0x00000008,
225 WHOLE_FILE_WAS_RESTORED = 0x00000010,
228 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
231 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
234 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
238 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
246 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)]
255 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
256 public static extern bool SetBooleanConfig(uint booleanConfig);
258 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
259 public static extern bool InstallDriver();
261 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
262 public static extern bool UnInstallDriver();
264 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
265 public static extern bool IsDriverServiceRunning();
267 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
268 public static extern bool SetRegistrationKey([MarshalAs(UnmanagedType.LPStr)]
string key);
270 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
271 public static extern bool Disconnect();
273 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
274 public static extern bool GetLastErrorMessage(
275 [MarshalAs(UnmanagedType.LPWStr)]
277 ref
int messageLength);
279 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
280 public static extern bool RegisterMessageCallback(
282 IntPtr filterCallback,
283 IntPtr disconnectCallback);
285 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
286 public static extern bool ResetConfigData();
288 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
289 public static extern bool SetFilterType(uint filterType);
291 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
292 public static extern bool SetConnectionTimeout(uint timeOutInSeconds);
294 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
295 public static extern bool AddNewFilterRule(
297 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask);
299 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
300 public static extern bool AddEncryptionKeyToFilterRule(
301 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
305 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
306 public static extern bool AddExcludeFileMaskToFilterRule(
307 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
310 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
311 public static extern bool AddHiddenFileMaskToFilterRule(
312 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
315 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
316 public static extern bool AddReparseFileMaskToFilterRule(
317 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
318 [MarshalAs(UnmanagedType.LPWStr)]
string reparseFileFilterMask);
320 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
321 public static extern bool AddIncludeProcessNameToFilterRule(
322 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
323 [MarshalAs(UnmanagedType.LPWStr)]
string processName);
326 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
327 public static extern bool AddExcludeProcessNameToFilterRule(
328 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
329 [MarshalAs(UnmanagedType.LPWStr)]
string processName);
331 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
332 public static extern bool AddIncludeProcessIdToFilterRule(
333 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
334 uint includeProcessId);
336 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
337 public static extern bool AddExcludeProcessIdToFilterRule(
338 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
339 uint excludeProcessId);
341 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
342 public static extern bool AddIncludeUserNameToFilterRule(
343 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
344 [MarshalAs(UnmanagedType.LPWStr)]
string userName);
347 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
348 public static extern bool AddExcludeUserNameToFilterRule(
349 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
350 [MarshalAs(UnmanagedType.LPWStr)]
string userName);
352 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
353 public static extern bool RegisterEventTypeToFilterRule(
354 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
357 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
358 public static extern bool RegisterMoinitorIOToFilterRule(
359 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
362 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
363 public static extern bool RegisterControlIOToFilterRule(
364 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask,
367 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
368 public static extern bool RemoveFilterRule(
369 [MarshalAs(UnmanagedType.LPWStr)]
string filterMask);
371 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
372 public static extern bool AddIncludedProcessId(uint processId);
374 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
375 public static extern bool RemoveIncludeProcessId(uint processId);
377 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
378 public static extern bool AddExcludedProcessId(uint processId);
380 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
381 public static extern bool RemoveExcludeProcessId(uint processId);
388 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
389 public static extern bool AddProtectedProcessId(uint processId);
391 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
392 public static extern bool RemoveProtectedProcessId(uint processId);
399 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
400 public static extern bool AddBlockSaveAsProcessId(uint processId);
402 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
403 public static extern bool RemoveBlockSaveAsProcessId(uint processId);
405 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
406 public static extern bool RegisterIoRequest(uint requestRegistration);
408 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
409 public static extern bool GetFileHandleInFilter(
410 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
414 [DllImport(
"advapi32.dll", CharSet = CharSet.Unicode, SetLastError =
true)]
415 public static extern bool ConvertSidToStringSid(
417 [Out] out IntPtr sidString);
419 [DllImport(
"kernel32.dll", SetLastError =
true)]
420 public static extern IntPtr LocalFree(IntPtr hMem);
422 [DllImport(
"kernel32", SetLastError =
true)]
423 public static extern uint GetCurrentProcessId();
425 [DllImport(
"Kernel32.dll", CharSet = CharSet.Unicode, SetLastError =
true)]
426 public static extern int QueryDosDeviceW(
427 [MarshalAs(UnmanagedType.LPWStr)]
string dosName,
428 [MarshalAs(UnmanagedType.LPWStr)]ref
string volumeName,
429 int volumeNameLength);
431 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
432 private static extern bool CreateFileAPI(
433 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
440 [DllImport(
"kernel32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
441 private static extern bool SetFileTime(SafeFileHandle hFile,
442 [In] ref
long lpCreationTime,
443 [In] ref
long lpLastAccessTime,
444 [In] ref
long lpLastWriteTime);
446 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
447 private static extern bool CreateStubFile(
448 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
456 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
457 public static extern bool OpenStubFile(
458 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
463 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
464 private static extern bool QueryAllocatedRanges(
468 IntPtr allocatedRangesBuffer,
469 int allocatedRangesBufferSize,
470 ref uint returnedLength);
472 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
473 private static extern bool AESEncryptDecryptBuffer(
484 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
485 public static extern bool AESEncryptFile(
486 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
493 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
494 public static extern bool AESDecryptFile(
495 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
502 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
503 public static extern bool AESEncryptFileToFile(
504 [MarshalAs(UnmanagedType.LPWStr)]
string sourceFileName,
512 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
513 public static extern bool AESDecryptFileToFile(
514 [MarshalAs(UnmanagedType.LPWStr)]
string sourceFileName,
521 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
522 public static extern bool ProcessEncryptedFile(
523 [MarshalAs(UnmanagedType.LPWStr)]
string sourceFileName,
526 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
527 public static extern bool AddIVAndExpireTimeTag(
528 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
533 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
534 public static extern bool AddReparseTagData(
535 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
539 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
540 public static extern bool RemoveTagData(
543 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
544 public static extern bool AddTagData(
549 public static bool EmbedDRPolicyDataToFile(
552 out
string lastError )
556 lastError =
string.Empty;
560 GCHandle pinnedArray = GCHandle.Alloc(drPolicyData, GCHandleType.Pinned);
561 IntPtr pointer = pinnedArray.AddrOfPinnedObject();
563 ret = AddReparseTagData(fileName, drPolicyData.Length, pointer);
569 lastError = GetLastErrorMessage();
575 lastError = ex.Message;
582 [DllImport(
"kernel32.dll", SetLastError =
true)]
583 public static extern bool CloseHandle(IntPtr handle);
592 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
593 private static extern bool GetIVTag(
594 [MarshalAs(UnmanagedType.LPWStr)]
string fileName,
604 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
605 public static extern bool GetUniqueComputerId(
607 ref uint outputBufferLength);
609 [DllImport(
"FilterAPI.dll", SetLastError =
true)]
610 public static extern bool ActivateLicense(
612 uint outputBufferLength);
614 public enum EncryptType
620 public static bool GetUniqueComputerId(ref
string myComputerId,ref
string lastError)
626 byte[] computerId =
new byte[52];
627 uint computerIdLength = (uint)computerId.Length;
628 IntPtr computerIdPtr = Marshal.UnsafeAddrOfPinnedArrayElement(computerId, 0);
629 retVal = FilterAPI.GetUniqueComputerId(computerIdPtr, ref computerIdLength);
631 if (!retVal || computerIdLength <= 0)
633 lastError = GetLastErrorMessage();
637 Array.Resize(ref computerId, (
int)computerIdLength);
638 myComputerId = UnicodeEncoding.Unicode.GetString(computerId);
644 lastError =
"Get computerId got exception,system return error:" + ex.Message;
651 public static bool GetIVTag(
string fileName, ref byte[]
iv, out
string lastError)
654 IntPtr tagPtr = IntPtr.Zero;
657 lastError =
string.Empty;
659 tagPtr = Marshal.AllocHGlobal((
int)ivLength);
660 ret = GetIVTag(fileName, ref ivLength, tagPtr);
664 lastError = GetLastErrorMessage();
666 else if (ivLength > 0)
669 Marshal.Copy(tagPtr, iv, 0, (
int)ivLength);
676 if (tagPtr != IntPtr.Zero)
678 Marshal.FreeHGlobal(tagPtr);
686 public static string AESEncryptDecryptStr(
string inStr, EncryptType encryptType)
689 if (
string.IsNullOrEmpty(inStr))
694 byte[] inbuffer = null;
696 if (encryptType == EncryptType.Encryption)
698 inbuffer = ASCIIEncoding.UTF8.GetBytes(inStr);
700 else if (encryptType == EncryptType.Decryption)
702 inbuffer = Convert.FromBase64String(inStr);
706 throw new Exception(
"Failed to encrypt decrypt string, the encryptType " + encryptType.ToString() +
" doesn't know.");
709 byte[] outBuffer =
new byte[inbuffer.Length];
710 IntPtr inBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(inbuffer, 0);
711 IntPtr outBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(outBuffer, 0);
713 bool retVal = AESEncryptDecryptBuffer(inBufferPtr, outBufferPtr, (uint)inbuffer.Length, 0, null, 0, null, 0);
716 if (encryptType == EncryptType.Encryption)
718 return Convert.ToBase64String(outBuffer);
722 return ASCIIEncoding.UTF8.GetString(outBuffer);
728 public static void AESEncryptDecryptBuffer(byte[] inbuffer,
long offset, byte[]
key, byte[] IV)
730 if (null == inbuffer || inbuffer.Length == 0)
732 throw new Exception(
"Failed to encrypt decrypt buffer, the input buffer can't be null");
735 IntPtr inBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(inbuffer, 0);
742 keyLength =(uint) key.Length;
747 IVLength = (uint)IV.Length;
751 bool retVal = AESEncryptDecryptBuffer(inBufferPtr, inBufferPtr, (uint)inbuffer.Length, offset, key, keyLength, IV, IVLength);
755 throw new Exception(
"Failed to encrypt buffer, return error:" + GetLastErrorMessage());
761 public static bool DecodeUserName(byte[]sid, out
string userName)
765 IntPtr sidStringPtr = IntPtr.Zero;
766 string sidString =
string.Empty;
768 userName =
string.Empty;
775 if (userNameTable.ContainsKey(sid))
777 userName = userNameTable[sid];
782 IntPtr sidBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(sid, 0);
784 if (FilterAPI.ConvertSidToStringSid(sidBuffer, out sidStringPtr))
786 sidString = Marshal.PtrToStringAuto(sidStringPtr);
787 SecurityIdentifier secIdentifier =
new SecurityIdentifier(sidString);
788 IdentityReference reference = secIdentifier.Translate(typeof(NTAccount));
789 userName = reference.Value;
793 string errorMessage =
"Convert sid to sid string failed with error " + Marshal.GetLastWin32Error();
794 Console.WriteLine(errorMessage);
799 Console.WriteLine(
string.Format(
"Convert sid to user name got exception:{0}", ex.Message));
805 if (sidStringPtr != null && sidStringPtr != IntPtr.Zero)
807 FilterAPI.LocalFree(sidStringPtr);
814 public static bool DecodeProcessName(uint processId, out
string processName)
818 processName =
string.Empty;
822 System.Diagnostics.Process requestProcess =
System.Diagnostics.Process.GetProcessById((
int)processId);
823 processName = requestProcess.ProcessName;
827 Console.WriteLine(
string.Format(
"Convert pid to process name got exception:{0}", ex.Message));
836 public static string GetLastErrorMessage()
839 string lastError =
new string((
char)0, len);
841 if (!GetLastErrorMessage(lastError, ref len))
843 lastError =
new string((
char)0, len);
844 if (!GetLastErrorMessage(lastError, ref len))
846 return "failed to get last error message.";
850 if (lastError.IndexOf((
char)0) >= 0)
852 lastError = lastError.Substring(0, lastError.IndexOf((
char)0));
858 static bool IsDriverChanged()
864 System.Reflection.Assembly assembly =
System.Reflection.Assembly.GetEntryAssembly();
865 string localPath = Path.GetDirectoryName(assembly.Location);
866 string driverName = Path.Combine(localPath,
"EaseFlt.sys");
868 if (
File.Exists(driverName))
870 string driverInstalledPath = Path.Combine(Environment.SystemDirectory,
"drivers\\easeflt.sys");
872 if (
File.Exists(driverInstalledPath))
874 FileInfo fsInstalled =
new FileInfo(driverInstalledPath);
875 FileInfo fsToInstall =
new FileInfo(driverName);
877 if (fsInstalled.LastWriteTime < fsToInstall.LastWriteTime)
894 EventManager.WriteMessage(630,
"IsDriverChanged",
EventLevel.Error,
"Check IsDriverChanged failed with error:" + ex.Message);
900 static public bool StartFilter(
int threadCount,
string registerKey,FilterDelegate filterCallback, DisconnectDelegate disconnectCallback,ref
string lastError)
907 if (IsDriverChanged() || !FilterAPI.IsDriverServiceRunning() )
909 FilterAPI.UnInstallDriver();
912 System.Threading.Thread.Sleep(3000);
914 ret = FilterAPI.InstallDriver();
917 lastError =
"Installed driver failed with error:" + FilterAPI.GetLastErrorMessage();
922 isFilterStarted =
false;
923 EventManager.WriteMessage(59,
"InstallDriver",
EventLevel.Information,
"Install filter driver succeeded.");
928 if (!isFilterStarted)
932 if (!SetRegistrationKey(registerKey))
934 lastError =
"Set registration key failed with error:" + GetLastErrorMessage();
939 gchFilter = GCHandle.Alloc(filterCallback);
940 IntPtr filterCallbackPtr = Marshal.GetFunctionPointerForDelegate(filterCallback);
942 gchDisconnect = GCHandle.Alloc(disconnectCallback);
943 IntPtr disconnectCallbackPtr = Marshal.GetFunctionPointerForDelegate(disconnectCallback);
945 isFilterStarted = RegisterMessageCallback(threadCount, filterCallbackPtr, disconnectCallbackPtr);
946 if (!isFilterStarted)
948 lastError =
"SRegisterMessageCallback failed with error:" + GetLastErrorMessage();
959 lastError =
"Start filter failed with error " + ex.Message;
965 lastError = lastError +
" Make sure you run this application as administrator.";
972 static public void StopFilter()
978 gchDisconnect.Free();
979 isFilterStarted =
false;
985 static public bool IsFilterStarted
987 get {
return isFilterStarted; }
ULONG encryptionKeyLength
enum _BooleanConfig BooleanConfig
ULONG PUCHAR encryptionKey
ULONG BYTE ULONG BYTE BOOLEAN addIVTag
DWORD DWORD DWORD dwCreationDisposition
WCHAR WCHAR ULONG keyLength
LONGLONG ULONG ULONG BYTE * tagData
BYTE ULONG LONGLONG offset
enum _FilterType FilterType
#define MAX_FILE_NAME_LENGTH
LONGLONG ULONG fileAttributes
WCHAR * excludeFileFilterMask
enum _FilterStatus FilterStatus
LONGLONG ULONG ULONG BYTE BOOL overwriteIfExist
#define STATUS_ACCESS_DENIED
enum _AccessFlag AccessFlag
ULONG BYTE ULONG ivLength
LONGLONG ULONG ULONG tagDataLength
#define MESSAGE_SEND_VERIFICATION_NUMBER
enum _FilterCommand FilterCommand
IN LONGLONG IN LONGLONG queryLength
WCHAR * hiddenFileFilterMask
ULONG BYTE LONGLONG HANDLE fileHandle
enum _MessageType MessageType
#define MAX_ERROR_MESSAGE_SIZE
ULONG BYTE LONGLONG expireTime
DWORD DWORD DWORD DWORD dwFlagsAndAttributes