public override NT_STATUS Close(FileContext FileObject, DateTime LastWriteTime) { // If you use a write cache, be sure to call flush or any similar method to write the data through. // The close should be done within 20 secounds and after all data is at the final media stored MyFileContext hinfo = (MyFileContext)FileObject; if (hinfo.FS != null) { hinfo.FS.Close(); } //FIXME: should we try to set the last write time on files and directories? /* * try * { * if (hinfo.IsDirectory) * Directory.SetLastWriteTime(root + hinfo.Name, LastWriteTime); * else * FileEx.SetLastWriteTime(root + hinfo.Name, LastWriteTime); * } * catch (Exception ex) * { * Trace.WriteLine("Warning->Beim Setzen der LastWriteTime für '" + hinfo.Name + "' ist in Close eine Exeption aufgetreten: " + ex.Message); * } */ return(NT_STATUS.OK); }
public override NT_STATUS Write(UserContext UserContext, FileContext FileObject, long Offset, ref int Count, ref byte[] Buffer, int Start) { // All locking issies are handled in the calling class, expect if other application access the files from outside // WinFUSE // It's possible to write all data to a cache and write it through to the final media after a flush or close. But this // write through should not last longer than 20 secounds NT_STATUS error = NT_STATUS.OK; MyFileContext HE = (MyFileContext)FileObject; if (HE.IsDirectory || HE.FS == null) { Debug.WriteLine("Warning->Cannot write to Directory."); Count = 0; return(NT_STATUS.INVALID_HANDLE); // ERROR_INVALID_HANDLE } if (!HE.FS.CanWrite && !HE.FS.CanSeek) { Debug.WriteLine("Warning->The file can not be written."); Count = 0; return(NT_STATUS.INVALID_PARAMETER); // ERROR_INVALID_PARAMETER; } if (Count > 0x0FFFFFFF) { Debug.WriteLine("Warning->Number of bytes to write is too large."); Count = 0; return(NT_STATUS.INVALID_PARAMETER); //ERROR_INVALID_PARAMETER } long NewOffset; try { NewOffset = HE.FS.Seek(Offset, System.IO.SeekOrigin.Begin); if (NewOffset != Offset) { Debug.WriteLine("Warning->The indicated position can not be written."); Count = 0; return(NT_STATUS.INVALID_PARAMETER); //132 ERROR_SEEK_ON_DEVICE } BinaryWriter Writer = new BinaryWriter(HE.FS); Writer.Write(Buffer, Start, Count); } catch (Exception ex) { Trace.WriteLine("Warning->Exception in Write: " + ex.Message); Count = 0; //error = 29; // ERROR_WRITE_FAULT error = (NT_STATUS)Marshal.GetHRForException(ex); } return(error); }
public override NT_STATUS Read(UserContext UserContext, FileContext FileObject, long Offset, ref int Count, ref byte[] Buffer, int Start) { // All locking issues are handled in the calling class, the only read collision that can occure are when other // application access the same file NT_STATUS error = NT_STATUS.OK; MyFileContext HE = (MyFileContext)FileObject; if (HE.IsDirectory || HE.FS == null) { Debug.WriteLine("Warning->Can not read from a Directory."); Count = 0; return(NT_STATUS.INVALID_HANDLE); // ERROR_INVALID_HANDLE } if (!HE.FS.CanRead && !HE.FS.CanSeek) { Debug.WriteLine("Warning->Can not Read or Seek the file."); Count = 0; return(NT_STATUS.INVALID_PARAMETER); // ERROR_INVALID_PARAMETER; } if (Count > 0x0FFFFFFF) { Debug.WriteLine("Warning->Number of bytes to read is too large."); Count = 0; return(NT_STATUS.INVALID_PARAMETER); //ERROR_INVALID_PARAMETER } long NewOffset; try { NewOffset = HE.FS.Seek(Offset, System.IO.SeekOrigin.Begin); if (NewOffset != Offset) { Debug.WriteLine("Warning->The indicated position can not be read"); Count = 0; return(NT_STATUS.INVALID_PARAMETER); // 132 = ERROR_SEEK_ON_DEVICE } BinaryReader Reader = new BinaryReader(HE.FS); Count = Reader.Read(Buffer, Start, Count); } catch (Exception ex) { Trace.WriteLine("Warning->Exception in Read: " + ex.Message); Count = 0; //error = 30; // ERROR_READ_FAULT error = (NT_STATUS)Marshal.GetHRForException(ex); } return(error); }
public override NT_STATUS Close(FileContext FileObject) { MyFileContext hinfo = (MyFileContext)FileObject; if (hinfo.FS != null) { hinfo.FS.Close(); } return(NT_STATUS.OK); }
//Implements the search for listings by means of identification FindFirst and FindNext public override NT_STATUS ReadDirectory(UserContext UserContext, FileContext FileObject) { NT_STATUS error = NT_STATUS.OK; MyFileContext HE = (MyFileContext)FileObject; if (!HE.IsDirectory) { Debug.WriteLine("Warning->Handle is not a directory, can not get a listing"); return(NT_STATUS.INVALID_HANDLE); } if (!phone.Exists(root + HE.Name) || !phone.IsDirectory(root + HE.Name)) { return(NT_STATUS.OBJECT_PATH_NOT_FOUND); // Directroy not found, should never happen } HE.Items.Add(new DirectoryContext(".", FileAttributes.Directory)); HE.Items.Add(new DirectoryContext("..", FileAttributes.Directory)); DirectoryContext Item = null; foreach (string DirName in phone.GetDirectories(root + HE.Name)) { error = GetAttributes(UserContext, root + HE.Name + DirName, out Item); if (error != 0) { Trace.WriteLine("Warning->Error: '" + error + "' during listing directories: " + HE.Name + DirName); } HE.Items.Add(Item); } foreach (string FileName in phone.GetFiles(root + HE.Name)) { error = GetAttributes(UserContext, root + HE.Name + FileName, out Item); if (error != 0) { Trace.WriteLine("Warning->Error: '" + error + "' during listing files: " + FileName); } else { HE.Items.Add(Item); } } return(NT_STATUS.OK); }
public override NT_STATUS Flush(UserContext UserContext, FileContext FileObject) { // Will not be called very often, but make sure that the call returns after the data is writen through the final media MyFileContext HE = (MyFileContext)FileObject; if (HE.IsDirectory || HE.FS == null) { return(NT_STATUS.OK); // or ERROR_INVALID_HANDLE } try { HE.FS.Flush(); } catch (Exception ex) { Trace.WriteLine("Warning->Exception in Flush: " + ex.Message); return((NT_STATUS)Marshal.GetHRForException(ex)); //return 29; // ERROR_WRITE_FAULT } return(NT_STATUS.OK); }
public override NT_STATUS Create(UserContext UserContext, string Name, SearchFlag Flags, FileMode Mode, FileAccess Access, FileShare Share, FileAttributes Attributes, out FileContext FileObject) { FileObject = null; string PathName = root + Name; try { switch (Mode) { case FileMode.Open: // Both work only if the file exists case FileMode.Truncate: switch (Flags) { case SearchFlag.FileAndDir: if (phone.Exists(PathName)) { if (!phone.IsDirectory(PathName)) { //FIXME: Implement FileMode and FileShare FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone, PathName, Access)); return(NT_STATUS.OK); } else { FileObject = new MyFileContext(Name, true, null); return(NT_STATUS.OK); } } return(NT_STATUS.NO_SUCH_FILE); case SearchFlag.File: if (phone.Exists(PathName) && !phone.IsDirectory(PathName)) { //FIXME: Implement FileMode and FileShare FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone, PathName, Access)); return(NT_STATUS.OK); } return(NT_STATUS.NO_SUCH_FILE);; case SearchFlag.Dir: if (phone.Exists(PathName) && phone.IsDirectory(PathName)) { FileObject = new MyFileContext(Name, true, null); return(NT_STATUS.OK); } return(NT_STATUS.OBJECT_PATH_NOT_FOUND); default: return(NT_STATUS.INVALID_PARAMETER); } case FileMode.CreateNew: // Works only if the file does not exists if (phone.Exists(PathName)) { return(NT_STATUS.OBJECT_NAME_COLLISION); // Access denied as it is already there } if (Access == FileAccess.Read) // Office 2003 makes the stupid call of: "CreateNew with Read access", C# refuse to execute it! { Access = FileAccess.ReadWrite; } //FIXME: Implement FileMode and FileShare FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone, PathName, Access)); return(NT_STATUS.OK); case FileMode.Create: case FileMode.OpenOrCreate: // Use existing file if possible otherwise create new FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone, PathName, Access)); return(NT_STATUS.OK); default: return(NT_STATUS.INVALID_PARAMETER); } } catch (Exception ex) { Trace.WriteLine("Warning->Exception when opening filestream: " + ex.Message); return(NT_STATUS.NO_SUCH_FILE); } }
public override NT_STATUS Create(UserContext UserContext, string Name, SearchFlag Flags, FileMode Mode, FileAccess Access, FileShare Share, FileAttributes Attributes, out FileContext FileObject) { FileObject = null; string PathName = root + Name; try { switch (Mode) { case FileMode.Open: // Both work only if the file exists case FileMode.Truncate: switch (Flags) { case SearchFlag.FileAndDir: if (phone.Exists(PathName)) { if (!phone.IsDirectory(PathName)) { //FIXME: Implement FileMode and FileShare FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone, PathName, Access)); return NT_STATUS.OK; } else { FileObject = new MyFileContext(Name, true, null); return NT_STATUS.OK; } } return NT_STATUS.NO_SUCH_FILE; case SearchFlag.File: if (phone.Exists(PathName) && !phone.IsDirectory(PathName)) { //FIXME: Implement FileMode and FileShare FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone, PathName, Access)); return NT_STATUS.OK; } return NT_STATUS.NO_SUCH_FILE; ; case SearchFlag.Dir: if (phone.Exists(PathName) && phone.IsDirectory(PathName)) { FileObject = new MyFileContext(Name, true, null); return NT_STATUS.OK; } return NT_STATUS.OBJECT_PATH_NOT_FOUND; default: return NT_STATUS.INVALID_PARAMETER; } case FileMode.CreateNew: // Works only if the file does not exists if (phone.Exists(PathName)) return NT_STATUS.OBJECT_NAME_COLLISION; // Access denied as it is already there if (Access == FileAccess.Read) // Office 2003 makes the stupid call of: "CreateNew with Read access", C# refuse to execute it! Access = FileAccess.ReadWrite; //FIXME: Implement FileMode and FileShare FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone,PathName, Access)); return NT_STATUS.OK; case FileMode.Create: case FileMode.OpenOrCreate: // Use existing file if possible otherwise create new FileObject = new MyFileContext(Name, false, iPhoneFile.Open(phone,PathName, Access)); return NT_STATUS.OK; default: return NT_STATUS.INVALID_PARAMETER; } } catch (Exception ex) { Trace.WriteLine("Warning->Exception when opening filestream: " + ex.Message); return NT_STATUS.NO_SUCH_FILE; } }