⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatdriver.cpp

📁 Jazmyn is a 32-bit, protected mode, multitasking OS which runs on i386 & above CPU`s. Its complete
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if(!_fv->chdir(parent))
		{
			void *buf;
			uint size;
			char **names;
			uint n;
			if(buf = _fv->read_file(child,size))
                        {
                                if(names = fetch_long_names(buf,size,n))
                                {
                                        __ret = curr_proc->_f.opendir(names,n);
                                        for(int i=0;i<n;i++) delete names[i];
                                        delete names;
                                }
                                delete buf;
                        }
		}
		RESTORE_ROOT(r);
		pwd = cwd;
	}
        bsem.up();
        return (DIR*)__ret;
}	

dirent* FATdriver::readdir(DIR* d_fd)
{
        return curr_proc->_f.readdir(d_fd);
}

int FATdriver::closedir(DIR* d_fd)
{
        return curr_proc->_f.closedir(d_fd);
}

void FATdriver::rewinddir(DIR* d_fd)
{
        curr_proc->_f.rewinddir(d_fd);
}

int FATdriver::open(char* path,int access,mode_t perm)
{

        bsem.down();
	int __ret = -1;
	FATvolume *_fv;
        void *buf;
        uint size;
	if(_fv = get_FATvolume(path))
	{
                fdir cwd = pwd;
		fdir r,dir;
		int opened = 0;
                int newly_created = 0;
                char nchild[255],rchild[255];
		char parent[1024],child[255];
		split_path(path,parent,child);

                strcpy(nchild,child);
                strcpy(rchild,child);

		SAVE_ROOT(r);
		if(!_fv->chdir(parent))
		if(!_fv->get_short_dir_entry(child,dir))
		{
                        if((access & O_CREAT) && (access & O_EXCL))
                        {
				
				pwd = cwd;
				RESTORE_ROOT(r);
                                bsem.up();
				return __ret;
			}
		}
		else
		{
			if(access & O_CREAT)
                        {
                                newly_created = 1;
                                _fv->put_dir_entry(child,ATTR_ARCHIVE,0);
                        }
			else
			{
				pwd = cwd;
				RESTORE_ROOT(r);
                                bsem.up();
				return __ret;
			}
		}
                if(is_open(_fv->get_drive(),dir)) opened = 1;
                if(newly_created)
                _fv->get_short_dir_entry(nchild,dir);
		if(!opened) 
                if(!(buf = _fv->read_file(rchild,size)))
		{
			pwd = cwd;
			RESTORE_ROOT(r);
                        bsem.up();
			return -1;
		}

		int fi,fti;

                if((fi = curr_proc->_f.get_fi()) >= 0)
		if((fti = get_fti()) >= 0)
		{

                        FILE_tab[fti].p_finode = get_finode(_fv->get_drive(),dir);
                        FILE_tab[fti].rw_ptr = 0;
			if(access & O_APPEND) 
                        FILE_tab[fti].rw_ptr = (opened) ? FILE_tab[fti].p_finode->size:size;
                        if(access & O_TRUNC) FILE_tab[fti].rw_ptr = 0;
                        FILE_tab[fti].mode = access;
                        FILE_tab[fti].fd = fi;
                        FILE_tab[fti].rc++; 
                        FILE_tab[fti].p_finode->rc++;
			if(!opened)
			{
                                FILE_tab[fti].p_finode->buf = buf;
                                FILE_tab[fti].p_finode->size = size;
                                FILE_tab[fti].p_finode->dir = dir;
			}
                        curr_proc->_f.fd[fi] = &FILE_tab[fti];
                        curr_proc->_f.fcount++;
		}
		pwd = cwd;
		RESTORE_ROOT(r);
		__ret = fi;
	}
        bsem.up();
	return __ret;
}

void* FATdriver::open_init(char *path)
{
        bsem.down();
	void *__ret = NULL;
        FATvolume *_fv;
        if(_fv = get_FATvolume(path))
	{
                fdir cwd = pwd,r;
                uint size;
		SAVE_ROOT(r);
		char parent[1024],child[255];
		split_path(path,parent,child);

                if(!_fv->chdir(parent))
                __ret = _fv->read_file(child,size);
		RESTORE_ROOT(r);
		pwd = cwd;
	}
        bsem.up();
	return __ret;
}

int FATdriver::creat(char* path,int mode)
{
	return open(path,O_WRONLY|O_CREAT|O_TRUNC,mode);
}

ssize_t FATdriver::read(int fdesc,void *buf,size_t size)
{
        int rw_ptr = curr_proc->_f.fd[fdesc]->rw_ptr;
        if(rw_ptr + size > curr_proc->_f.fd[fdesc]->p_finode->size)
        size = curr_proc->_f.fd[fdesc]->p_finode->size - rw_ptr;
	if(!size) return 0;
        if((curr_proc->_f.fd[fdesc]->mode & O_RDONLY)||(curr_proc->_f.fd[fdesc]->mode & O_RDWR))
	{
                void *src = (byte*)curr_proc->_f.fd[fdesc]->p_finode->buf+rw_ptr;
		memcpy(buf,src,size);
                curr_proc->_f.fd[fdesc]->rw_ptr += size;
		return size;
        }
	return -1;
}

ssize_t FATdriver::write(int fdesc,void* buf,size_t size)
{
        bsem.down();
        int rw_ptr = curr_proc->_f.fd[fdesc]->rw_ptr;
        if(rw_ptr + size > curr_proc->_f.fd[fdesc]->p_finode->size)
        size = curr_proc->_f.fd[fdesc]->p_finode->size - rw_ptr;
        if(!size)
        {
                bsem.up();
                return 0;
        }
        if((curr_proc->_f.fd[fdesc]->mode & O_WRONLY)||(curr_proc->_f.fd[fdesc]->mode & O_RDWR))
	{
                void *dst = (byte*)curr_proc->_f.fd[fdesc]->p_finode->buf+rw_ptr;
		memcpy(dst,buf,size);
                curr_proc->_f.fd[fdesc]->rw_ptr += size;  
                bsem.up();
		return size;
	}
        bsem.up();
	return -1;
}

int FATdriver::close(int fdesc)
{
      
        FILE *fp = curr_proc->_f.fd[fdesc];
	if(!fp) return -1;
	fp->fd = 0;
	fp->rc--;
	fp->rw_ptr = 0;
        fp->p_finode->rc--;

        /*if rc = 0 we have to write the file back to disk if it is opened in write mode*/
        if(fp->p_finode->rc == 0)
	{
                if(fp->mode == O_WRONLY)
                {
                        cout<<"file will be written\n";
                        getch();
                        bsem.down();
                        FATvolume *_fv;
                        if(_fv = get_FATvolume(fp->p_finode->drive))
                        {
                                uint start = _fv->get_start_clus(&fp->p_finode->dir);
                                if(_fv->write_clus_chain(start,fp->p_finode->buf,fp->p_finode->size)<0)
                                {
                                        bsem.up();
                                        return -1;
                                }
                                bsem.up();
                        }
                }
                fp->p_finode->size = 0;
                delete fp->p_finode->buf;
	}
        curr_proc->_f.fd[fdesc] = NULL;
        curr_proc->_f.fcount--;
	return 0;
}

off_t FATdriver::lseek(int fdesc,int pos,int whence)
{
        /* if pos exceeds EOF, the file should be expanded */
        uint end = curr_proc->_f.fd[fdesc]->p_finode->size;
	switch(whence)
	{
                case SEEK_CUR:curr_proc->_f.fd[fdesc]->rw_ptr += pos;break;
                case SEEK_SET:curr_proc->_f.fd[fdesc]->rw_ptr = 0 + pos;break;
                case SEEK_END:curr_proc->_f.fd[fdesc]->rw_ptr = end+pos;break;
	}
        return curr_proc->_f.fd[fdesc]->rw_ptr;
}

finode* FATdriver::get_finode(char drive,fdir &dir)
{
	for(int i=0;i<SYS_FILE_OPENMAX;i++)
        if(FAT_inode[i].drive == drive && is_equal(FAT_inode[i].dir,dir))
			return &FAT_inode[i];
	for(int i=0;i<SYS_FILE_OPENMAX;i++)
	{
		if(FAT_inode[i].rc == 0) return &FAT_inode[i];
	}
	return NULL;
}

int FATdriver::is_open(char drive,fdir &dir)
{
	for(int i=0;i<SYS_FILE_OPENMAX;i++)
          if(FAT_inode[i].drive == drive && is_equal(FAT_inode[i].dir,dir))
			return 1;
	return 0;
}

char** FATdriver::fetch_long_names(void *buf,uint size,uint &n)
{
        /*
         *This function should fetch long names. currently i have implemented to fetch short
         *names only
         */

	fdir *dir = (fdir*)buf;
        int i = 0;
        n = 0;
	char **ret;
	uint processed = 0;

	while(dir[i].dir_name[0] != 0x00 && processed < size)
	{
                if(dir[i].dir_name[0] != 0xE5 && dir[i].dir_attr != ATTR_LONG_NAME)
		{
			n++;
		}
		i++;
		processed += 32;
	}

	ret = new char*[n];
	for(i=0;i<n;i++)
	ret[i] = new char[13];
	
	i=0;n=0;processed = 0;
	while(dir[i].dir_name[0] != 0x00 && processed < size)
	{
                if(dir[i].dir_name[0] != 0xE5 && dir[i].dir_attr != ATTR_LONG_NAME)
		{
                        strncpy(ret[n],(char*)dir[i].dir_name,11);
                        ret[n][11] = '\0';
			n++;
		}
		i++;
		processed += 32;
	}
	return ret;
}

void FATdriver::split_path(char *path,char *parent,char *child)
{
	if(path[1] == ':') path = path + 2;
	int len = strlen(path);
	int j,flag = 0;
	for(int i=0;i<len;i++)
	{
		if(path[i] == '\\')
		{
			j = i;	
			flag = 1;
		}
	}
	if(!flag)
	{
		strcpy(parent,"");
		strcpy(child,path);
	}
	else
	{

                if(!j)
                {
                        strncpy(parent,path,j+1);
                        parent[j+1]='\0';
                }
                else
                {
                        strncpy(parent,path,j);
                        parent[j]='\0';
                }
		strcpy(child,path+j+1);
	}
}
  
int FATdriver::get_fti()
{
	for(int i=0;i<SYS_FILE_OPENMAX;i++)
	if(FILE_tab[i].rc == 0)
	return i;
	return -1;
}
FATdriver       _FAT_driver;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -