예제 #1
0
        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);
        }
예제 #2
0
        /*
         * 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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
 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);
         }
     }
 }
예제 #8
0
 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);
         }
     }
 }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
            }
            }
        }