EaseFilter.cs

Download EaseFilter Filter Driver SDK Setup File
Download EaseFilter Filter Driver SDK Zip File

///////////////////////////////////////////////////////////////////////////////

//

//    (C) Copyright 2011 EaseFilter Technologies Inc.

//    All Rights Reserved

//

//    This software is part of a licensed software product and may

//    only be used or copied in accordance with the terms of that license.

//

///////////////////////////////////////////////////////////////////////////////

 

using System;

using System.Text;

using System.IO;

using System.Windows.Forms;

using System.Runtime.InteropServices;

 

namespace CSharpDemo

{

 

    static public class EaseFilter

    {

        public delegate Boolean FilterDelegate(IntPtr sendData, IntPtr replyData);

        public delegate void DisconnectDelegate();

        static GCHandle gchFilter;

        static GCHandle gchDisconnect;

        static bool isFilterStarted = false;

        public const int MAX_FILE_NAME_LENGTH = 512;

        public const int MAX_SID_LENGTH = 256;

        public const int MAX_MESSAGE_LENGTH = 65536;

        public const int MAX_PATH = 260;

        public const int MAX_ERROR_MESSAGE_SIZE = 1024;

 

        public const uint MESSAGE_SEND_VERIFICATION_NUMBER = 0xFF000001;

 

        public enum MessageType : uint

        {

            PRE_CREATE = 0x00000001,

            POST_CREATE = 0x00000002,

            PRE_FASTIO_READ = 0x00000004,

            POST_FASTIO_READ = 0x00000008,

            PRE_CACHE_READ = 0x00000010,

            POST_CACHE_READ = 0x00000020,

            PRE_NOCACHE_READ = 0x00000040,

            POST_NOCACHE_READ = 0x00000080,

            PRE_PAGING_IO_READ = 0x00000100,

            POST_PAGING_IO_READ = 0x00000200,

            PRE_FASTIO_WRITE = 0x00000400,

            POST_FASTIO_WRITE = 0x00000800,

            PRE_CACHE_WRITE = 0x00001000,

            POST_CACHE_WRITE = 0x00002000,

            PRE_NOCACHE_WRITE = 0x00004000,

            POST_NOCACHE_WRITE = 0x00008000,

            PRE_PAGING_IO_WRITE = 0x00010000,

            POST_PAGING_IO_WRITE = 0x00020000,

            PRE_QUERY_INFORMATION = 0x00040000,

            POST_QUERY_INFORMATION = 0x00080000,

            PRE_SET_INFORMATION = 0x00100000,

            POST_SET_INFORMATION = 0x00200000,

            PRE_DIRECTORY = 0x00400000,

            POST_DIRECTORY = 0x00800000,

            PRE_QUERY_SECURITY = 0x01000000,

            POST_QUERY_SECURITY = 0x02000000,

            PRE_SET_SECURITY = 0x04000000,

            POST_SET_SECURITY = 0x08000000,

            PRE_CLEANUP = 0x10000000,

            POST_CLEANUP = 0x20000000,

            PRE_CLOSE = 0x40000000,

            POST_CLOSE = 0x80000000,

 

        }

 

        public const uint ALLOW_MAX_RIGHT_ACCESS = 0xfffffff0;

 

        public enum AccessFlag : uint

        {

            EXCLUDE_FILTER_RULE = 0X00000000,

            INCLUDE_FILTER_RULE = 0x00000001,

            REPARSE_FILE_OPEN = 0x00000002,

            HIDE_FILES_IN_DIRECTORY_BROWSING = 0x00000004,

            ALLOW_OPEN_WTIH_ACCESS_SYSTEM_SECURITY = 0x00000010,

            ALLOW_OPEN_WITH_READ_ACCESS = 0x00000020,

            ALLOW_OPEN_WITH_WRITE_ACCESS = 0x00000040,

            ALLOW_OPEN_WITH_CREATE_OR_OVERWRITE_ACCESS = 0x00000080,

            ALLOW_OPEN_WITH_DELETE_ACCESS = 0x00000100,

            ALLOW_READ_ACCESS = 0x00000200,

            ALLOW_WRITE_ACCESS = 0x00000400,

            ALLOW_QUERY_INFORMATION_ACCESS = 0x00000800,

            //allow to change file time and file attributes

            ALLOW_SET_INFORMATION = 0x00001000,

            ALLOW_FILE_RENAME = 0x00002000,

            ALLOW_FILE_DELETE = 0x00004000,

            ALLOW_FILE_SIZE_CHANGE = 0x00008000,

            ALLOW_QUERY_SECURITY_ACCESS = 0x00010000,

            ALLOW_SET_SECURITY_ACCESS = 0x00020000,

            ALLOW_DIRECTORY_LIST_ACCESS = 0x00040000,

        }

 

        public enum FilterType : uint

        {

            FILE_SYSTEM_MONITOR = 0,

            FILE_SYSTEM_CONTROL = 1,

        }

 

 

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

        public struct MessageSendData

        {

            public uint MessageId;          //this is the request sequential number.

            public IntPtr FileObject;       //the address of FileObject,it is equivalent to file handle,it is unique per file stream open.

            public IntPtr FsContext;        //the address of FsContext,it is unique per file.

            public uint MessageType;        //the I/O request type.

            public uint ProcessId;          //the process ID for the process associated with the thread that originally requested the I/O operation.

            public uint ThreadId;           //the thread ID which requested the I/O operation.

            public long Offset;             //the read/write offset.

            public uint Length;             //the read/write length.

            public long FileSize;           //the size of the file for the I/O operation.

            public long TransactionTime;    //the transaction time in UTC of this request.

            public long CreationTime;       //the creation time in UTC of the file.

            public long LastAccessTime;     //the last access time in UTC of the file.

            public long LastWriteTime;      //the last write time in UTC of the file.

            public uint FileAttributes;     //the file attributes.

            public uint DesiredAccess;      //the DesiredAccess for file open, please reference CreateFile windows API.

            public uint Disposition;        //the Disposition for file open, please reference CreateFile windows API.

            public uint SharedAccess;       //the SharedAccess for file open, please reference CreateFile windows API.

            public uint CreateOptions;      //the CreateOptions for file open, please reference CreateFile windows API.

            public uint CreateStatus;       //the CreateStatus after file was openned, please reference CreateFile windows API.

            public uint InfoClass;          //the information class or security information

            public uint Status;             //the I/O status which returned from file system.

            public uint FileNameLength;     //the file name length in byte.

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_FILE_NAME_LENGTH)]

            public string FileName;         //the file name of the I/O operation.

            public uint SidLength;          //the length of the security identifier.

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_SID_LENGTH)]

            public byte[] Sid;              //the security identifier data.

            public uint DataBufferLength;   //the data buffer length.

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_MESSAGE_LENGTH)]

            public byte[] DataBuffer;       //the data buffer which contains read/write/query information/set information data.

            public uint VerificationNumber; //the verification number which verifiys the data structure integerity.

        }

 

        public enum FilterStatus : uint

        {

            FILTER_MESSAGE_IS_DIRTY = 0x00000001,

            FILTER_COMPLETE_PRE_OPERATION = 0x00000002, //ONLY FOR PRE CALL OPERATION,the IO won't pass down to the lower drivers and file system.

            FILTER_DATA_BUFFER_IS_UPDATED = 0x00000004, //only for pre create,to reparse the file open to the new file name.    

        }

 

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

        public struct MessageReplyData

        {

            public uint MessageId;

            public uint MessageType;

            public uint ReturnStatus;

            public uint FilterStatus;

            public uint DataBufferLength;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)]

            public byte[] DataBuffer;

        }

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool InstallDriver();

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool UnInstallDriver();

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool SetRegistrationKey([MarshalAs(UnmanagedType.LPStr)]string key);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool Disconnect();

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool GetLastErrorMessage(

            [MarshalAs(UnmanagedType.LPWStr)]

            string errorMessage,

            ref int messageLength);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool RegisterMessageCallback(

            int threadCount,

            IntPtr filterCallback,

            IntPtr disconnectCallback);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool ResetConfigData();

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool SetFilterType(uint filterType);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool SetConnectionTimeout(uint timeOutInSeconds);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool AddFilterRule(

         uint accessFlag,

        [MarshalAs(UnmanagedType.LPWStr)]string filterMask,       

        [MarshalAs(UnmanagedType.LPWStr)] string reparseMask);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool RemoveFilterRule(

        [MarshalAs(UnmanagedType.LPWStr)] string filterMask);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool AddExcludedProcessId(uint processId);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool RemoveExcludeProcessId(uint processId);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool RegisterIoRequest(uint requestRegistration);

 

        [DllImport("FilterAPI.dll", SetLastError = true)]

        public static extern bool GetFileHandleInFilter(

             [MarshalAs(UnmanagedType.LPWStr)]string fileName,

             IntPtr fileHandle);

 

         [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        public static extern bool ConvertSidToStringSid(

            [In] IntPtr sid,

            [Out] out IntPtr sidString);

 

        [DllImport("kernel32.dll", SetLastError = true)]

        public static extern IntPtr LocalFree(IntPtr hMem);

 

        public static string GetLastErrorMessage()

        {

            int len = MAX_ERROR_MESSAGE_SIZE;

            string errorMessage = new string((char)0, len);

 

            if (!GetLastErrorMessage(errorMessage, ref len))

            {

                errorMessage = new string((char)0, len);

                if (!GetLastErrorMessage(errorMessage, ref len))

                {

                    return "failed to get last error message.";

                }

            }

 

            return errorMessage;

        }

 

        static public bool StartFilter(string registerKey,int threadCount, FilterDelegate filterCallback, DisconnectDelegate disconnectCallback)

        {

            if (!isFilterStarted)

            {

                if (!SetRegistrationKey(registerKey))

                {

                    return false;

                }

 

                gchFilter = GCHandle.Alloc(filterCallback);

                IntPtr filterCallbackPtr = Marshal.GetFunctionPointerForDelegate(filterCallback);

 

                gchDisconnect = GCHandle.Alloc(disconnectCallback);

                IntPtr disconnectCallbackPtr = Marshal.GetFunctionPointerForDelegate(disconnectCallback);

 

                isFilterStarted = RegisterMessageCallback(threadCount, filterCallbackPtr, disconnectCallbackPtr);

 

            }

 

            return isFilterStarted;

        }

 

        static public void StopFilter()

        {

            if (isFilterStarted)

            {

                Disconnect();

                gchFilter.Free();

                gchDisconnect.Free();

                isFilterStarted = false;

            }

 

            return;

        }

 

        static public bool IsFilterStarted

        {

            get { return isFilterStarted; }

        }

 

    }

}