int DokanOperations.WriteFile(
            string filename,
            byte[] buffer,
            ref uint writtenBytes,
            long offset,
            DokanFileInfo info)
        {
            mLog.DebugFormat(
                "WriteFile - offset: {0, 5} - bytes: {1, 5} - {2}",
                offset, buffer.Length, filename);

            Node node = WalkTree.Find(GetRoot(), filename);

            if (node == null)
            {
                return(-DokanNet.ERROR_PATH_NOT_FOUND);
            }

            if (node.IsControlledAndReadOnly())
            {
                return(-DokanNet.ERROR_ACCESS_DENIED);
            }

            return(mLocalFiles.WriteFile(
                       node.GetNodeId(),
                       filename,
                       buffer,
                       ref writtenBytes,
                       offset,
                       FileContext.Get(info)));
        }
        int DokanOperations.Cleanup(string filename, DokanFileInfo info)
        {
            if (info == null)
            {
                mLog.DebugFormat("Cleanup - {0} - INFO IS NULL", filename);
                return(0);
            }

            long size = 0;

            if (!info.IsDirectory)
            {
                Stream st = mHandles.GetStream(FileContext.Get(info));
                if (st != null)
                {
                    size = st.Length;
                }
            }

            Node node = WalkTree.Find(GetRoot(), filename);

            if (node != null)
            {
                mLog.DebugFormat("Cleanup - [{0}] - new size {1}", filename, size);

                node.UpdateSize(size);
            }
            else
            {
                mLog.DebugFormat("Cleanup - {0}", filename);
            }

            return(0);
        }
        int DokanOperations.FlushFileBuffers(string filename, DokanFileInfo info)
        {
            mLog.DebugFormat("FlushFileBuffers {0}", filename);

            if (info.IsDirectory)
            {
                return(0);
            }

            FileStream fs = mHandles.GetStream(FileContext.Get(info));

            if (fs != null)
            {
                fs.Flush();
            }

            return(0);
        }
        int DokanOperations.CloseFile(string filename, DokanFileInfo info)
        {
            mLog.DebugFormat("CloseFile - {0}", filename);

            Node node = WalkTree.Find(GetRoot(), filename);

            if (node == null)
            {
                return(-DokanNet.ERROR_FILE_NOT_FOUND);
            }

            if (mHistoryDirectories.Close(node))
            {
                return(0);
            }

            IVirtualFile virtualFile;

            if ((virtualFile = mVirtualFiles.Get(node.GetNodeId())) != null)
            {
                int handle = FileContext.Get(info);

                if (handle == -1)
                {
                    return(0);
                }

                virtualFile.CloseFile(handle);

                return(0);
            }

            if (info.IsDirectory)
            {
                return(0);
            }

            mHandles.Close(FileContext.Get(info));

            return(0);
        }
        int DokanOperations.ReadFile(
            string filename,
            byte[] buffer,
            ref uint readBytes,
            long offset,
            DokanFileInfo info)
        {
            // this thing sometimes trows exceptions because
            // System.Diagnostics.Process.GetProcessById((int)info.ProcessId).MainModule.FileName,
            // System.ComponentModel.Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process.
            // so we need to find a different way to do it

            mLog.DebugFormat(
                "ReadFile - offset: {0, 5} - bytes: {1, 5} - {2}",
                offset, buffer.Length, filename);

            if (info.IsDirectory)
            {
                return(-1);
            }

            try
            {
                FileStream fs = mHandles.GetStream(FileContext.Get(info));

                if (fs == null)
                {
                    // some apps (Notepad) don't open the file first!!
                    if ((this as DokanOperations).CreateFile(
                            filename,
                            FileAccess.Read,
                            FileShare.Read,
                            FileMode.Open,
                            FileOptions.None,
                            info) != 0)
                    {
                        mLog.ErrorFormat("Can't find open file {0}", filename);

                        return(-DokanNet.ERROR_PATH_NOT_FOUND);
                    }

                    fs = mHandles.GetStream(FileContext.Get(info));
                }

                if (!fs.CanRead)
                {
                    mLog.ErrorFormat("Can't read from open file [{0}]",
                                     filename);
                    return(-DokanNet.ERROR_ACCESS_DENIED);
                }

                fs.Seek(offset, SeekOrigin.Begin);
                readBytes = (uint)fs.Read(buffer, 0, buffer.Length);
                return(0);
            }
            catch (Exception e)
            {
                mLog.ErrorFormat("Error reading from {0}. {1}",
                                 filename, e.Message);
                return(-1);
            }
        }