//Check if incore, otherwise do full reverse lookup. ino could be either dir/file.
        //XXX order of locking is important,
        //first lock rootdir to modify incore ifsd, the lock FSIDList[] so that inofile is safe
        //Never do the other way round.
        private string Load_Dirtree_Internal(int fsid, int[] list, int length, ref FileAttributes fa)
        {
            string retval = "";

            for (int i = length - 1; i >= 0; i--)
            {
                CInode ci = REDDY.FSIDList[fsid].rootdir.check_if_inode_incore(list[i], true);

                //DEFS.ASSERT(ci != null, "check_if_inode_incore cannot return null here, ino = " + list[i]);
                //DEFS.ASSERT(ci.gettype() == FileAttributes.Directory || (i == 0), "we should have reached the end and this must be a file, i=" + i);
                //Console.WriteLine("---->" + ci.get_full_path());
                if (ci != null && ci.gettype() == FileAttributes.Directory)
                {
                    //DEFS.DEBUGYELLOW("X", "Calling opendirectory for " + ci.get_full_path());
                    //((CDirectory)ci).open_directory();
                }
                if (i != (length - 1)) //ignore first folder
                {
                    retval += "\\" + ci.get_iname();
                }
                if (i == 0)
                {
                    fa = ci.gettype();
                }
            }
            return(retval);
        }
        public int SetInternalFlag(int fsid, string filename, int key, int value)
        {
            CInode ix = get_cfile_internal(fsid, filename);

            if (ix != null)
            {
                REDDY.FSIDList[fsid].set_dirty(true);
                if (ix.gettype() == FileAttributes.Normal)
                {
                    ((CFile)ix).set_ibflag(value);
                    return(0);
                }
            }
            return(-1);
        }
        /*
         * Returns the path of the inode, from here on always use the path
         * to access the inode.
         */
        public string Load_Inode(int fsid, int ino, ref FileAttributes fa)
        {
            int[] orderlist = new int[1024];
            int   length    = 0;

            lock (REDDY.FSIDList[fsid].rootdir)
            {
                //Prepare the path, one by one.
                int parent   = -1;
                int curr_ino = ino;
                do
                {
                    //till you find a incore directory or you reach the root node.
                    CInode cix = REDDY.FSIDList[fsid].rootdir.check_if_inode_incore(curr_ino, false);
                    if (cix != null || curr_ino == 0)
                    {
                        orderlist[length++] = curr_ino;
                        string computedpath = Load_Dirtree_Internal(fsid, orderlist, length, ref fa);
                        return((curr_ino == 0)? computedpath : cix.get_full_path() + computedpath);
                    }
                    else
                    {
                        WIP_TYPE type = WIP_TYPE.UNDEFINED;
                        parent = LoadWip_FindPINO(fsid, curr_ino, ref type);
                        //DEFS.DEBUGYELLOW("@", "(ino,pino,type) = (" + curr_ino + "," + parent + "," + type + ")");
                        DEFS.ASSERT(curr_ino == ino || type == WIP_TYPE.DIRECTORY_FILE, "Mismatch in load ino " + curr_ino + "," + ino);
                        if (parent == -1)
                        {
                            return(null);              //inode does not exist.
                        }
                        else
                        {
                            orderlist[length++] = curr_ino;
                        }

                        //move to parent now.
                        curr_ino = parent;
                    }
                } while (length < 1024);
            }
            return(null);
        }
        public int SetFileTime(int midx, String filename, DateTime ctime,
                               DateTime atime, DateTime mtime, DokanFileInfo info)
        {
            CInode ix = get_cfile_internal(midx, filename);

            if (ix != null)
            {
                REDDY.FSIDList[midx].set_dirty(true);
                ix.set_acm_times(atime, ctime, mtime);
                if (ix.gettype() == FileAttributes.Normal)
                {
                    ((CFile)ix).set_dokanio_flag2(false);
                }
                else
                {
                    info.IsDirectory = true;
                }
                return(0);
            }
            return(-1);
        }