public NtStatus ReadFile(string fileName, byte[] buffer, out int bytesRead, long offset, IDokanFileInfo info) { bytesRead = 0; VFile vfile = (VFile)info.Context; if (vfile == null) { return(NtStatus.NoSuchFile); } // trying to fill all of the buffer bytesRead = buffer.Length; // if reading past the EOF then read 0 bytes if (offset > vfile.Length) { bytesRead = 0; return(NtStatus.Success); } // if reading to the EOF then set the number of bytes left to read if (offset + bytesRead > vfile.Length) { bytesRead = (int)(vfile.Length - offset); } foreach (VFile.VZipFile gf in vfile.Files) { copyData(gf.LocalHeader, buffer, gf.LocalHeaderOffset, offset, gf.LocalHeaderLength, bytesRead); copyStream(gf, buffer, gf.CompressedDataOffset, offset, gf.CompressedDataLength, bytesRead); } return(NtStatus.Success); }
/* * private static string path = @"D:\tmp"; * private static string GetPath(string searchFilename) * { * return path + searchFilename; * } */ /* * Dokan Filename format: * \DatRoot * \DatRoot\Rom * \DatRoot\Rom\file.zip * * DB DIR -> fullname * DatRoot\ * DatRoot\Rom\ * */ // using the supplied filename, try and find and return the information (vFile) about this testFilename // this may be a file or a directory, so we need to also figure that out. public static VFile FindFilename(string filename) { Debug.WriteLine("Trying to find information about " + filename); // 1) test for the root direction VFile retVal = FindRoot(filename); if (retVal != null) { return(retVal); } // 2) test for a regular DB Directory retVal = FindInDBDir(filename); if (retVal != null) { return(retVal); } // 3) test for a Dat Entry retVal = FindInDBDat(filename); if (retVal != null) { return(retVal); } // Failed to file this filename return(null); }
private static VFile FindInDBDat(string filename) { int filenameLength = filename.Length; // we only search in the DB for .zip files so test for that extension bool isFile = (filenameLength > 4) && (filename.Substring(filenameLength - 4).ToLower() == ".zip"); string testFilename = filename; if (isFile) { // if is File remove the .zip file extension testFilename = testFilename.Substring(0, filenameLength - 4); } string dirName = testFilename; while (true) { int slashPos = dirName.LastIndexOf(@"\", StringComparison.Ordinal); if (slashPos <= 0) { return(null); } dirName = testFilename.Substring(0, slashPos); int?dirId = DirFind(dirName); if (dirId == null) { continue; // loop to next slash } string filePart = testFilename.Substring(slashPos + 1); if (isFile) { VFile vFile = DBGameFindFile((int)dirId, filePart, filename); if (vFile != null) { vFile._fileSplitIndex = slashPos; return(vFile); } } else { VFile vFile = DBGameFindDir((int)dirId, filePart, filename); if (vFile != null) { vFile._fileSplitIndex = slashPos; return(vFile); } } return(null); } }
public void CloseFile(string fileName, IDokanFileInfo info) { Debug.WriteLine(""); Debug.WriteLine("-----------CloseFile---------------------------------"); Debug.WriteLine("Filename : " + fileName); VFile vfile = (VFile)info.Context; if (vfile?.Files == null) { return; } foreach (VFile.VZipFile gf in vfile.Files) { gf.GZip?.ZipFileClose(); } }
private static VFile FindRoot(string filename) { if (filename != @"\") { return(null); } VFile vfile = new VFile { FileName = filename, IsDirectory = true, _fileId = 0, _creationTime = DateTime.Today, _lastWriteTime = DateTime.Today, _lastAccessTime = DateTime.Today }; return(vfile); }
public NtStatus GetFileInformation(string fileName, out FileInformation fileInfo, IDokanFileInfo info) { Debug.WriteLine(""); Debug.WriteLine("-----------GetFileInformation---------------------------------"); Debug.WriteLine("Filename : " + fileName); VFile vfile = (VFile)info.Context; if (vfile == null) { fileInfo = new FileInformation(); Debug.WriteLine("No such File"); return(NtStatus.NoSuchFile); } fileInfo = (FileInformation)vfile; Debug.WriteLine("Returning File Info " + fileInfo.FileName); return(NtStatus.Success); }
private static VFile DBGameFindDir(int dirId, string searchDirectoryName, string realFilename) { using (DbCommand getFileInDirectory = DBSqlite.db.Command(@" SELECT GameId, ZipFileLength, LastWriteTime, CreationTime, LastAccessTime FROM Game WHERE Dirid = @dirId AND ZipFileLength > 0 AND name Like @name LIMIT 1")) { DbParameter pDirId = DBSqlite.db.Parameter("DirId", dirId); getFileInDirectory.Parameters.Add(pDirId); DbParameter pName = DBSqlite.db.Parameter("Name", searchDirectoryName.Replace(@"\", @"/") + @"/%"); getFileInDirectory.Parameters.Add(pName); using (DbDataReader dr = getFileInDirectory.ExecuteReader()) { if (!dr.Read()) { return(null); } VFile vFile = new VFile { IsDirectory = true, _fileId = dirId, // we are storing the id of the DIR not the GameId (So we can use the dirId later) FileName = realFilename, Length = Convert.ToInt64(dr["ZipFileLength"]), _lastWriteTime = new DateTime(Convert.ToInt64(dr["LastWriteTime"])), _creationTime = new DateTime(Convert.ToInt64(dr["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(dr["LastAccessTime"])) }; return(vFile); } } }
private static VFile DBGameFindFile(int dirId, string searchFilename, string realFilename) { using (DbCommand getFileInDirectory = DBSqlite.db.Command(@" SELECT GameId, ZipFileLength, LastWriteTime, CreationTime, LastAccessTime FROM Game WHERE Dirid = @dirId AND ZipFileLength > 0 AND name = @name ")) { DbParameter pDirId = DBSqlite.db.Parameter("DirId", dirId); getFileInDirectory.Parameters.Add(pDirId); DbParameter pName = DBSqlite.db.Parameter("Name", searchFilename.Replace(@"\", @"/")); getFileInDirectory.Parameters.Add(pName); using (DbDataReader dr = getFileInDirectory.ExecuteReader()) { if (!dr.Read()) { return(null); } VFile vFile = new VFile { IsDirectory = false, _fileId = Convert.ToInt32(dr["GameId"]), FileName = realFilename, Length = Convert.ToInt64(dr["ZipFileLength"]), _lastWriteTime = new DateTime(Convert.ToInt64(dr["LastWriteTime"])), _creationTime = new DateTime(Convert.ToInt64(dr["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(dr["LastAccessTime"])) }; return(vFile); } } }
private static VFile FindInDBDir(string filename) { // try and find this directory in the DIR table string testName = filename.Substring(1) + @"\"; // takes the slash of the front of the string and add one on the end Debug.WriteLine("Looking in DIR from " + testName); using (DbCommand getDirectoryId = DBSqlite.db.Command(@" SELECT DirId, CreationTime, LastAccessTime, LastWriteTime FROM Dir WHERE fullname=@FName")) { DbParameter pFName = DBSqlite.db.Parameter("FName", testName); getDirectoryId.Parameters.Add(pFName); using (DbDataReader reader = getDirectoryId.ExecuteReader()) { if (!reader.Read()) { return(null); } VFile vDir = new VFile { FileName = filename, IsDirectory = true, _fileId = Convert.ToInt32(reader["DirId"]), _creationTime = new DateTime(Convert.ToInt64(reader["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(reader["LastAccessTime"])), _lastWriteTime = new DateTime(Convert.ToInt64(reader["LastWriteTime"])) }; return(vDir); } } }
public NtStatus FindFilesWithPattern(string fileName, string searchPattern, out IList <FileInformation> files, IDokanFileInfo info) { Debug.WriteLine(""); Debug.WriteLine("-----------FindFilesWithPattern---------------------------------"); Debug.WriteLine("Filename : " + fileName); Debug.WriteLine("searchPattern : " + searchPattern); // if (searchPattern != "*" && searchPattern !="DatRoot") // Debug.WriteLine("Unknown search pattern"); files = new List <FileInformation>(); VFile vfile = (VFile)info.Context; if (vfile == null) { return(NtStatus.NoSuchFile); } // we should only be searching directories here if (!vfile.IsDirectory) { return(NtStatus.NoSuchFile); } List <VFile> dirs = VFile.DirGetSubItems(vfile); foreach (VFile dir in dirs) { if ((searchPattern != "*") && (searchPattern != dir.FileName)) { continue; } FileInformation fi = (FileInformation)dir; files.Add(fi); } return(NtStatus.Success); }
public static List <VFile> DirGetSubItems(VFile vDir) { int dirId = vDir._fileId; List <VFile> dirs = new List <VFile>(); if (!vDir.IsDirectory) { return(dirs); } if (vDir._fileSplitIndex == -1) { // we are not inside a DAT directory structure // find any child DIR's from this DIR level using (DbCommand getDirectory = DBSqlite.db.Command(@" SELECT DirId, Name, CreationTime, LastAccessTime, LastWriteTime FROM Dir WHERE ParentDirId=@DirId")) { DbParameter pParentDirId = DBSqlite.db.Parameter("DirId", dirId); getDirectory.Parameters.Add(pParentDirId); using (DbDataReader dr = getDirectory.ExecuteReader()) { while (dr.Read()) { string filename = (string)dr["name"]; bool found = dirs.Any(t => t.FileName == filename); if (!found) { dirs.Add( new VFile { IsDirectory = true, _fileId = Convert.ToInt32(dr["DirId"]), FileName = filename, _creationTime = new DateTime(Convert.ToInt64(dr["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(dr["LastAccessTime"])), _lastWriteTime = new DateTime(Convert.ToInt64(dr["LastWriteTime"])) } ); } } } } // find any DB items from top filename level using (DbCommand getFilesInDirectory = DBSqlite.db.Command(@" SELECT GameId, Name, ZipFileLength, LastWriteTime, CreationTime, LastAccessTime FROM Game WHERE DirId=@dirId AND ZipFileLength>0 ")) { DbParameter pDirId = DBSqlite.db.Parameter("DirId", vDir._fileId); getFilesInDirectory.Parameters.Add(pDirId); using (DbDataReader dr = getFilesInDirectory.ExecuteReader()) { while (dr.Read()) { string filename = (string)dr["name"]; // test if filename is a directory int filenameSplit = filename.IndexOf(@"/", StringComparison.Ordinal); if (filenameSplit >= 0) { string dirFilename = filename.Substring(0, filenameSplit); bool found = dirs.Any(t => t.FileName == dirFilename); if (!found) { dirs.Add(new VFile { IsDirectory = true, _fileId = Convert.ToInt32(dr["GameId"]), FileName = dirFilename, _fileSplitIndex = filenameSplit, Length = Convert.ToInt64(dr["ZipFileLength"]), _creationTime = new DateTime(Convert.ToInt64(dr["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(dr["LastAccessTime"])), _lastWriteTime = new DateTime(Convert.ToInt64(dr["LastWriteTime"])) }); } } else { string zipFilename = filename + ".zip"; bool found = dirs.Any(t => t.FileName == zipFilename); if (!found) { dirs.Add(new VFile { IsDirectory = false, _fileId = Convert.ToInt32(dr["GameId"]), FileName = zipFilename, Length = Convert.ToInt64(dr["ZipFileLength"]), _creationTime = new DateTime(Convert.ToInt64(dr["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(dr["LastAccessTime"])), _lastWriteTime = new DateTime(Convert.ToInt64(dr["LastWriteTime"])) }); } } } } } } else { // we are in a DAT with sub directories string datfilePart = vDir.FileName.Substring(1 + vDir._fileSplitIndex).Replace(@"\", @"/") + @"/"; int datfilePartLength = datfilePart.Length; // find any DB items from top filename level using (DbCommand getFilesInDirectory = DBSqlite.db.Command(@" SELECT GameId, Name, ZipFileLength, LastWriteTime, CreationTime, LastAccessTime FROM Game WHERE DirId=@dirId AND ZipFileLength>0 AND Name LIKE @dirName ")) { DbParameter pDirName = DBSqlite.db.Parameter("DirName", datfilePart + "%"); getFilesInDirectory.Parameters.Add(pDirName); DbParameter pDirId = DBSqlite.db.Parameter("DirId", vDir._fileId); getFilesInDirectory.Parameters.Add(pDirId); using (DbDataReader dr = getFilesInDirectory.ExecuteReader()) { while (dr.Read()) { string filename = (string)dr["name"]; filename = filename.Substring(datfilePartLength); int filenameSplit = filename.IndexOf(@"/", StringComparison.Ordinal); if (filenameSplit >= 0) { string dirFilename = filename.Substring(0, filenameSplit); bool found = dirs.Any(t => t.FileName == dirFilename); if (!found) { dirs.Add(new VFile { IsDirectory = true, _fileId = Convert.ToInt32(dr["GameId"]), FileName = dirFilename, _fileSplitIndex = vDir._fileSplitIndex + filenameSplit, // check this is correct Length = Convert.ToInt64(dr["ZipFileLength"]), _creationTime = new DateTime(Convert.ToInt64(dr["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(dr["LastAccessTime"])), _lastWriteTime = new DateTime(Convert.ToInt64(dr["LastWriteTime"])) }); } } else { string zipFilename = filename + ".zip"; bool found = dirs.Any(t => t.FileName == zipFilename); if (!found) { dirs.Add(new VFile { IsDirectory = false, _fileId = Convert.ToInt32(dr["GameId"]), FileName = zipFilename, Length = Convert.ToInt64(dr["ZipFileLength"]), _creationTime = new DateTime(Convert.ToInt64(dr["CreationTime"])), _lastAccessTime = new DateTime(Convert.ToInt64(dr["LastAccessTime"])), _lastWriteTime = new DateTime(Convert.ToInt64(dr["LastWriteTime"])) }); } } } } } } return(dirs); }
public NtStatus CreateFile(string fileName, FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, IDokanFileInfo info) { Debug.WriteLine(""); Debug.WriteLine("-----------CreateFile---------------------------------"); Debug.WriteLine("Filename : " + fileName + " IsDirectory : " + info.IsDirectory); VFile vDir = VFile.FindFilename(fileName); //First check a DIR. (If we know it is a directory.) if (info.IsDirectory) { switch (mode) { case FileMode.Open: { info.Context = vDir; return(vDir != null ? DokanResult.Success : DokanResult.PathNotFound); } case FileMode.CreateNew: { if (vDir != null) { return(DokanResult.FileExists); } return(DokanResult.PathNotFound); } default: { throw new NotImplementedException("Missing Directory Mode " + mode); } } } //Check again for a DIR. (As we may not have know we have a directory.) if ((vDir != null) && vDir.IsDirectory) { switch (mode) { case FileMode.Open: { info.IsDirectory = true; info.Context = vDir; return(DokanResult.Success); } default: { throw new NotImplementedException("Missing Directory Mode " + mode); } } } bool readWriteAttributes = (access & DataAccess) == 0; bool readAccess = (access & DataWriteAccess) == 0; switch (mode) { case FileMode.Open: { if (vDir == null) { return(DokanResult.FileNotFound); } if (readWriteAttributes) { info.Context = vDir; return(DokanResult.Success); } if (readAccess) { if (!vDir.LoadVFileZipData()) { return(DokanResult.Error); } info.Context = vDir; return(DokanResult.Success); } // looks like we are trying to write to the file. return(DokanResult.AccessDenied); } default: { throw new NotImplementedException("Missing Directory Mode " + mode); } } }