static string FormatInfoClass(FilterAPI.MessageType messageType, uint infoClass) { string ret = string.Empty; if (FilterAPI.MessageType.PRE_QUERY_SECURITY == messageType || FilterAPI.MessageType.PRE_SET_SECURITY == messageType || FilterAPI.MessageType.POST_QUERY_SECURITY == messageType || FilterAPI.MessageType.POST_SET_SECURITY == messageType) { ret = ((WinData.SecurityInformation)(infoClass)).ToString(); } else if (infoClass > 0) { ret = ((WinData.FileInfomationClass)infoClass).ToString(); } else { ret = string.Empty; } return(ret); }
public static bool UnitTestCallbackHandler(FilterAPI.MessageSendData messageSend) { try { string fileName = messageSend.FileName.ToLower(); if (fileName.ToLower().StartsWith(unitTestMonitorTestFolder.ToLower())) { return(FileIOEventHandler(messageSend)); } if (!fileName.StartsWith(unitTestCallbackFile.ToLower())) { return(true); } FilterAPI.MessageType messageType = (FilterAPI.MessageType)messageSend.MessageType; WinData.FileInfomationClass infoClass = (WinData.FileInfomationClass)messageSend.InfoClass; if (messageType == FilterAPI.MessageType.POST_CREATE) { isPostCreateNotificationTriggered = true; } else if (messageType == FilterAPI.MessageType.POST_SET_INFORMATION) { isPostSetInformationNotificationTriggered = true; } } catch (Exception ex) { EventManager.WriteMessage(156, "UnitTestCallbackHandler", EventLevel.Error, "UnitTestCallbackHandler failed." + ex.Message); } return(true); }
public static bool IOAccessControl(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) { bool ret = true; try { messageReply.MessageId = messageSend.MessageId; messageReply.MessageType = messageSend.MessageType; // //here you can control all the registered IO requests,block the access or modify the I/O data base on the file IO information from MessageSend struture // // //if you don't want to change anything to this IO request, just let it pass through as below setting: //messageReply.FilterStatus = 0; //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; //if you want to block the access this IO request before it goes down to the file system, you can return the status as below, //it is only for pre IO requests, it means the user IO reuqests will be completed here instead of going down to the file system. //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; //if you want to modify the IO data and complete the pre IO with your own data, you can return status as below: // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.DataBufferLength = the return data buffer length. // messageReply.DataBuffer = the data you want to return. // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; FilterAPI.MessageType messageType = (FilterAPI.MessageType)messageSend.MessageType; WinData.FileInfomationClass infoClass = (WinData.FileInfomationClass)messageSend.InfoClass; uint dataLength = messageSend.DataBufferLength; byte[] data = messageSend.DataBuffer; //here is some IO information for your reference: if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) { //this is file access request comes from remote network server } //you can check the file create option with this data: //"DesiredAccess: messageSend.DesiredAccess //"Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); //"ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); //"CreateOptions:"messageSend.CreateOptions //Here is the demo to copy file content before it was deleted.----------------------------------------------- bool isFileDeleted = false; if (messageSend.Status == (uint)NtStatus.Status.Success) { if (messageType == FilterAPI.MessageType.POST_CREATE) { if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) { isFileDeleted = true; } } else if (messageType == FilterAPI.MessageType.POST_SET_INFORMATION) { if (infoClass == WinData.FileInfomationClass.FileDispositionInformation) { isFileDeleted = true; } } if (isFileDeleted) { IntPtr fileHandle = IntPtr.Zero; bool retVal = FilterAPI.GetFileHandleInFilter(messageSend.FileName, (uint)FileAccess.Read, ref fileHandle); if (retVal) { SafeFileHandle sHandle = new SafeFileHandle(fileHandle, true); FileStream fileStream = new FileStream(sHandle, FileAccess.Read); //copy your data here... fileStream.Close(); } } } //End ----------------------------------------------- switch (messageType) { case FilterAPI.MessageType.PRE_CREATE: { //here you reparse the file open to another new file name //string newReparseFileName = "\\??\\c:\\myNewFile.txt"; //byte[] returnData = Encoding.Unicode.GetBytes(newReparseFileName); //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); //messageReply.DataBufferLength = (uint)returnData.Length; //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.Reparse; break; } case FilterAPI.MessageType.PRE_CACHE_READ: case FilterAPI.MessageType.POST_CACHE_READ: case FilterAPI.MessageType.PRE_NOCACHE_READ: case FilterAPI.MessageType.POST_NOCACHE_READ: case FilterAPI.MessageType.PRE_PAGING_IO_READ: case FilterAPI.MessageType.POST_PAGING_IO_READ: case FilterAPI.MessageType.PRE_CACHE_WRITE: case FilterAPI.MessageType.POST_CACHE_WRITE: case FilterAPI.MessageType.PRE_NOCACHE_WRITE: case FilterAPI.MessageType.POST_NOCACHE_WRITE: case FilterAPI.MessageType.PRE_PAGING_IO_WRITE: case FilterAPI.MessageType.POST_PAGING_IO_WRITE: { //byte[] returnData = //new data you want to modify the read/write data; //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); //messageReply.DataBufferLength = (uint)returnData.Length; ////for pre IO,use this one //// messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; break; } case FilterAPI.MessageType.PRE_SET_INFORMATION: case FilterAPI.MessageType.POST_SET_INFORMATION: case FilterAPI.MessageType.PRE_QUERY_INFORMATION: case FilterAPI.MessageType.POST_QUERY_INFORMATION: { ret = true; switch (infoClass) { case WinData.FileInfomationClass.FileRenameInformation: { //you can block file rename as below //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; break; } case WinData.FileInfomationClass.FileDispositionInformation: { //you can block file delete as below //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; break; } case WinData.FileInfomationClass.FileEndOfFileInformation: { //change file size break; } case WinData.FileInfomationClass.FileBasicInformation: { //file basic information break; } case WinData.FileInfomationClass.FileStandardInformation: { //file standard information break; } case WinData.FileInfomationClass.FileNetworkOpenInformation: { //file network information break; } case WinData.FileInfomationClass.FileInternalInformation: { //file internal inofrmation break; } default: { ret = false; break; } } break; } } } catch (Exception ex) { EventManager.WriteMessage(174, "IOAccessControl", EventLevel.Error, "IOAccessControl failed." + ex.Message); } return(ret); }
static string FormatDataBuffer(FilterAPI.MessageType messageType, WinData.FileInfomationClass infoClass, uint dataLength, byte[] data) { string ret = string.Empty; try { switch (messageType) { case FilterAPI.MessageType.PRE_SET_INFORMATION: case FilterAPI.MessageType.POST_SET_INFORMATION: case FilterAPI.MessageType.PRE_QUERY_INFORMATION: case FilterAPI.MessageType.POST_QUERY_INFORMATION: switch (infoClass) { case WinData.FileInfomationClass.FileRenameInformation: { //destination name ret = "Destination name:" + Encoding.Unicode.GetString(data); break; } case WinData.FileInfomationClass.FileDispositionInformation: { ret = "Delete file."; break; } case WinData.FileInfomationClass.FileEndOfFileInformation: { long newFileSize = BitConverter.ToInt64(data, 0); ret = "Change file size to:" + newFileSize.ToString(); break; } case WinData.FileInfomationClass.FileBasicInformation: { WinData.FileBasicInformation basiInfo = new WinData.FileBasicInformation(); GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); basiInfo = (WinData.FileBasicInformation)Marshal.PtrToStructure( pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileBasicInformation)); pinnedPacket.Free(); ret = "creation time:" + FormatDateTime(basiInfo.CreationTime) + " "; ret += "last access time:" + FormatDateTime(basiInfo.LastAccessTime) + " "; ret += "last write time:" + FormatDateTime(basiInfo.LastWriteTime) + " "; ret += "file attributes:" + ((FileAttributes)basiInfo.FileAttributes).ToString(); break; } case WinData.FileInfomationClass.FileStandardInformation: { WinData.FileStandardInformation standardInfo = new WinData.FileStandardInformation(); GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); standardInfo = (WinData.FileStandardInformation)Marshal.PtrToStructure( pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileStandardInformation)); pinnedPacket.Free(); ret = "File size:" + standardInfo.EndOfFile.ToString() + " "; ret += "Allocation size:" + standardInfo.AllocationSize.ToString() + " "; ret += "IsDirectory:" + standardInfo.Directory.ToString(); break; } case WinData.FileInfomationClass.FileNetworkOpenInformation: { WinData.FileNetworkInformation networkInfo = new WinData.FileNetworkInformation(); GCHandle pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned); networkInfo = (WinData.FileNetworkInformation)Marshal.PtrToStructure( pinnedPacket.AddrOfPinnedObject(), typeof(WinData.FileNetworkInformation)); pinnedPacket.Free(); ret = "creation time:" + FormatDateTime(networkInfo.CreationTime) + " "; ret += "last access time:" + FormatDateTime(networkInfo.LastAccessTime) + " "; ret += "last write time:" + FormatDateTime(networkInfo.LastWriteTime) + " "; ret += "file size:" + networkInfo.FileSize.ToString() + " "; ret += "file attributes:" + ((FileAttributes)networkInfo.FileAttributes).ToString(); break; } case WinData.FileInfomationClass.FileInternalInformation: { long fileId = BitConverter.ToInt64(data, 0); ret = "FileId: (0x)" + fileId.ToString("X"); break; } } break; } } catch (Exception ex) { Console.WriteLine("Format data failed." + ex.Message); ret = ex.Message; } return(ret); }