private FileCacheElement getFileCacheElement(IoFlow InFlow, string InFileName, byte[] InData, UInt64 InFileOffset, uint copyOffset, uint InDataLength) { FileCacheElement elemReturn; bool reused = false; lock (this.freeFileCacheElements) { if (this.freeFileCacheElements.Count > 0){ LinkedListNode<FileCacheElement> llNode = this.freeFileCacheElements.First; this.freeFileCacheElements.Remove(llNode); elemReturn = llNode.Value; reused=true; } else { elemReturn = new FileCacheElement(InFlow, InFileName, InData, InFileOffset, copyOffset, InDataLength); } } if (reused) { Debug.Assert(elemReturn.DataLength == InDataLength); elemReturn.fileName = InFileName; elemReturn.Flow = InFlow; // keep data elemReturn.Data = null; elemReturn.FileOffset = InFileOffset; elemReturn.DataLength = InDataLength; elemReturn.Dirty = false; elemReturn.nodeInList = null; elemReturn.nodeInDirtyList = null; if (InData != null) { Buffer.BlockCopy(InData, (int)copyOffset, elemReturn.Data, 0, (int)InDataLength); } } return elemReturn; }
public LinkedListNode<FileCacheElement> nodeInList; // location in LRU linked list #endregion Fields #region Constructors // // Constructor. // Copies InData locally public FileCacheElement(IoFlow InFlow, string InFileName, byte[] InData, UInt64 InFileOffset, uint copyOffset, uint InDataLength) { LockObj = new object(); fileName = InFileName; Flow = InFlow; Data = null; FileOffset = InFileOffset; DataLength = InDataLength; Dirty = false; nodeInList = null; nodeInDirtyList = null; nodeInFreeFileCacheList = null; if (InData != null) { Data = new byte[InDataLength]; Buffer.BlockCopy(InData, (int)copyOffset, Data, 0, (int)InDataLength); //Array.Copy(InData, copyOffset, Data, 0, InDataLength); } }
/// <summary> /// Creates an IoFlow structure in runtime and corresponding structures (Flow and RAP) /// in the driver. /// </summary> /// <param name="accountName">A valid NT security account of form EUROPE\gregos.</param> /// <param name="fileName">A valid file name of form C:\tmp\gregos.txt or \Device\HarddiskVolumen\tmp\gregos.txt</param> /// <param name="callbackPreCreate">Callback func to invoke for IRPs on PreCreate path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostCreate">Callback func to invoke for IRPs on PostCreate path. /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="callbackPreRead">Callback func to invoke for IRPs on PreRead path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostRead">Callback func to invoke for IRPs on PostRead path /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="callbackPreWrite">Callback func to invoke for IRPs on PreWrite path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostWrite">Callback func to invoke for IRPs on PostWrite path. /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="callbackPreCleanup">Callback func to invoke for IRPs on PreCleanup path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostCreate">Callback func to invoke for IRPs on PostCleanup path. /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="context">Some object reference of your own for additional state associated with thie IoFlow</param> /// <returns></returns> public IoFlow CreateFlow( uint flowId, string accountName, string fileName, CallbackPreCreate callbackPreCreate, CallbackPostCreate callbackPostCreate, CallbackPreRead callbackPreRead, CallbackPostRead callbackPostRead, CallbackPreWrite callbackPreWrite, CallbackPostWrite callbackPostWrite, CallbackPreCleanup callbackPreCleanup, CallbackPostCleanup callbackPostCleanup, CallbackPreLockControl callbackPreLockControl, object context) { IoFlow ioFlow = null; // // Validate fileName, transforming drive letters to volume names. // fileName = fileName.ToLower(); string origFilename = fileName; if (string.IsNullOrEmpty(fileName) || string.IsNullOrWhiteSpace(fileName)) { throw new ArgumentNullException("fileName"); } else if (fileName.Length < 2) { throw new ArgumentOutOfRangeException("fileName", "too short"); } else if (fileName.Substring(1, 1).Equals(@":")) { string driveName = fileName.Substring(0, 2); // think "C:" string deviceName = ""; if (DriveNameToVolumeName.TryGetValue(driveName, out deviceName)) { fileName = deviceName + fileName.Substring(2); } } if (fileName.ToLower().StartsWith(DeviceMup.ToLower())) { Debug.Assert(0 == 1); //XXXIS: don't use \device\mup in the paths in the config file } else if (fileName.ToLower().StartsWith(RemoteDeviceSlash.ToLower())) { fileName = DeviceMup + fileName; } else if (fileName.ToLower().StartsWith(RemoteDeviceDoubleSlash.ToLower())) { fileName = DeviceMup + fileName.Substring(1); } else if (!fileName.ToLower().StartsWith(DeviceHarddiskVolume)) { throw new ArgumentException(@"must be format e.g. C: or \Device\HarddiskVolume", "fileName"); } #if gregos // "XXXET: not used, just for testing" crashes on launch due to FileToBlock.dll not found // for lock drives, test physical offset code // XXXET: not used, just for testing if (fileName.Substring(1, 1).Equals(@":") || origFilename.ToLower().StartsWith(DeviceHarddiskVolume)) { if (origFilename.ToLower().StartsWith(DeviceHarddiskVolume)) { origFilename = getDriveLetterFileName(origFilename); } Int64 poffset = FileToBlock.GetPhysicalOffset(origFilename); Console.WriteLine("File {0} starts in physical offset {1}", origFilename, poffset); } #endif // // Get SID for the given account name. // SecurityIdentifier sid = SidLookup(accountName); // // Create IoFlow object. // LockIoFlow.EnterWriteLock(); try { ioFlow = new IoFlow(flowId, context, accountName, sid, fileName, callbackPreCreate, callbackPostCreate, callbackPreRead, callbackPostRead, callbackPreWrite, callbackPostWrite, callbackPreCleanup, callbackPostCleanup, callbackPreLockControl); DictIoFlow.Add(flowId, ioFlow); Driver.CreateFlow.Request(hControlPort, TenantId, flowId, ioFlow.Flags); Driver.CreateRap.Request(hControlPort, TenantId, flowId, accountName, sid, fileName); } catch (ExceptionIoFlow) { DriverReset(); throw; } LockIoFlow.ExitWriteLock(); return(ioFlow); }
/// <summary> /// Creates an IoFlow structure in runtime and corresponding structures (Flow and RAP) /// in the driver. /// </summary> /// <param name="accountName">A valid NT security account of form EUROPE\gregos.</param> /// <param name="fileName">A valid file name of form C:\tmp\gregos.txt or \Device\HarddiskVolumen\tmp\gregos.txt</param> /// <param name="callbackPreCreate">Callback func to invoke for IRPs on PreCreate path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostCreate">Callback func to invoke for IRPs on PostCreate path. /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="callbackPreRead">Callback func to invoke for IRPs on PreRead path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostRead">Callback func to invoke for IRPs on PostRead path /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="callbackPreWrite">Callback func to invoke for IRPs on PreWrite path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostWrite">Callback func to invoke for IRPs on PostWrite path. /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="callbackPreCleanup">Callback func to invoke for IRPs on PreCleanup path. /// Corresponds to an IFS Minifilter PRE_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551109(v=vs.85).aspx</param> /// <param name="callbackPostCreate">Callback func to invoke for IRPs on PostCleanup path. /// Corresponds to an IFS Minifilter POST_OPERATION callback ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff551107(v=vs.85).aspx</param> /// <param name="context">Some object reference of your own for additional state associated with thie IoFlow</param> /// <returns></returns> public IoFlow CreateFlow( uint flowId, string accountName, string fileName, CallbackPreCreate callbackPreCreate, CallbackPostCreate callbackPostCreate, CallbackPreRead callbackPreRead, CallbackPostRead callbackPostRead, CallbackPreWrite callbackPreWrite, CallbackPostWrite callbackPostWrite, CallbackPreCleanup callbackPreCleanup, CallbackPostCleanup callbackPostCleanup, CallbackPreLockControl callbackPreLockControl, object context) { IoFlow ioFlow = null; // // Validate fileName, transforming drive letters to volume names. // fileName = fileName.ToLower(); string origFilename = fileName; if (string.IsNullOrEmpty(fileName) || string.IsNullOrWhiteSpace(fileName)) throw new ArgumentNullException("fileName"); else if (fileName.Length < 2) throw new ArgumentOutOfRangeException("fileName", "too short"); else if (fileName.Substring(1, 1).Equals(@":")) { string driveName = fileName.Substring(0, 2); // think "C:" string deviceName = ""; if (DriveNameToVolumeName.TryGetValue(driveName, out deviceName)) fileName = deviceName + fileName.Substring(2); } if (fileName.ToLower().StartsWith(DeviceMup.ToLower())) { Debug.Assert(0 == 1); //XXXIS: don't use \device\mup in the paths in the config file } else if (fileName.ToLower().StartsWith(RemoteDeviceSlash.ToLower())) { fileName = DeviceMup + fileName; } else if (fileName.ToLower().StartsWith(RemoteDeviceDoubleSlash.ToLower())) { fileName = DeviceMup + fileName.Substring(1); } else if (!fileName.ToLower().StartsWith(DeviceHarddiskVolume)) throw new ArgumentException(@"must be format e.g. C: or \Device\HarddiskVolume", "fileName"); #if gregos // "XXXET: not used, just for testing" crashes on launch due to FileToBlock.dll not found // for lock drives, test physical offset code // XXXET: not used, just for testing if (fileName.Substring(1, 1).Equals(@":") || origFilename.ToLower().StartsWith(DeviceHarddiskVolume)) { if (origFilename.ToLower().StartsWith(DeviceHarddiskVolume)) { origFilename = getDriveLetterFileName(origFilename); } Int64 poffset = FileToBlock.GetPhysicalOffset(origFilename); Console.WriteLine("File {0} starts in physical offset {1}", origFilename, poffset); } #endif // // Get SID for the given account name. // SecurityIdentifier sid = SidLookup(accountName); // // Create IoFlow object. // LockIoFlow.EnterWriteLock(); try { ioFlow = new IoFlow(flowId, context, accountName, sid, fileName, callbackPreCreate, callbackPostCreate, callbackPreRead, callbackPostRead, callbackPreWrite, callbackPostWrite, callbackPreCleanup, callbackPostCleanup, callbackPreLockControl); DictIoFlow.Add(flowId, ioFlow); Driver.CreateFlow.Request(hControlPort, TenantId, flowId, ioFlow.Flags); Driver.CreateRap.Request(hControlPort, TenantId, flowId, accountName, sid, fileName); } catch (ExceptionIoFlow) { DriverReset(); throw; } LockIoFlow.ExitWriteLock(); return ioFlow; }
private void parseControllerCommandString(IoFlow flow, string controllerCommand) { string[] commandStringSeparators = new string[] { " ", "\t" }; char[] tokenSeparator = new char[] { '=' }; string[] commandTokens = controllerCommand.Split(commandStringSeparators, StringSplitOptions.RemoveEmptyEntries); if (commandTokens.Length > 0) { Console.WriteLine("CallbackMessageIoFlowUpdate({0},{1})", flow.FlowId, controllerCommand); foreach (string token in commandTokens) { string param = token.Split(tokenSeparator)[0]; string value = token.Split(tokenSeparator)[1]; //Switch to the appropriate handler switch (param) { case "changeCacheSize": this.cache.CacheSetFlowSize(flow.FlowId, Convert.ToUInt64(value)); break; case "changeWritePolicy": switch (value) { case "write-through": this.cache.SetCacheWritePolicy(CacheWritePolicy.WriteThrough); break; default: Console.WriteLine("Command value invalid"); Debug.Assert(0 == 1); break; } break; case "changeOpPolicy": string op = value.Split(',')[0]; string policy = value.Split(',')[1]; switch (op) { case "W": switch (policy) { case "yes": this.cache.SetCacheWriteBuffering(CacheWriteBuffer.Cache); //Cache writes break; case "no": this.cache.SetCacheWriteBuffering(CacheWriteBuffer.noCache); //Don't cache writes break; default: Console.WriteLine("Command value invalid"); Debug.Assert(0 == 1); break; } break; case "R": //Nothing for now; add fine-grained control to cache/not cache reads here break; default: Console.WriteLine("Command value invalid"); Debug.Assert(0 == 1); break; } break; default: Console.WriteLine("Controller command invalid"); Debug.Assert(0 == 1); break; } } } }