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

📄 hfs_fs.c

📁 open source bios with linux platform, very good and can be reused.
💻 C
字号:
/*  *   Creation Date: <2001/05/06 22:47:23 samuel> *   Time-stamp: <2004/01/12 10:24:35 samuel> *    *	<hfs_fs.c> *	 *	HFS world interface *    *   Copyright (C) 2001-2004 Samuel Rydh (samuel@ibrium.se) *    *   This program is free software; you can redistribute it and/or *   modify it under the terms of the GNU General Public License *   as published by the Free Software Foundation *    */#include "openbios/config.h"#include "openbios/fs.h"#include "libhfs.h"#define MAC_OS_ROM_CREATOR	0x63687270	/* 'chrp' */#define MAC_OS_ROM_TYPE		0x74627869	/* 'tbxi' */#define MAC_OS_ROM_NAME		"Mac OS ROM"#define FINDER_TYPE		0x464E4452	/* 'FNDR' */#define FINDER_CREATOR		0x4D414353	/* 'MACS' */#define SYSTEM_TYPE		0x7A737973	/* 'zsys' */#define SYSTEM_CREATOR		0x4D414353	/* 'MACS' *//************************************************************************//*	Search Functions						*//************************************************************************/static int_find_file( hfsvol *vol, const char *path, ulong type, ulong creator ){	hfsdirent ent;	hfsdir *dir;	int ret=1;		if( !(dir=hfs_opendir(vol, path)) )		return 1;	while( ret && !hfs_readdir(dir, &ent) ) {		if( ent.flags & HFS_ISDIR )			continue;		ret = !(*(ulong*)ent.u.file.type == type && *(ulong*)ent.u.file.creator == creator );	}	hfs_closedir( dir );	return ret;}/* ret: 0=success, 1=not_found, 2=not_a_dir */static int_search( hfsvol *vol, const char *path, const char *sname, file_desc_t **ret_fd ){	hfsdir *dir;	hfsdirent ent;	int topdir=0, status = 1;	char *p, buf[256];	strncpy( buf, path, sizeof(buf) );	if( buf[strlen(buf)-1] != ':' )		strncat( buf, ":", sizeof(buf) );	buf[sizeof(buf)-1] = 0;	p = buf + strlen( buf );	if( !(dir=hfs_opendir(vol, path)) )		return 2;	/* printk("DIRECTORY: %s\n", path ); */	while( status && !hfs_readdir(dir, &ent) ) {		ulong type, creator;				*p = 0;		topdir = 0;				strncat( buf, ent.name, sizeof(buf) );		if( (status=_search(vol, buf, sname, ret_fd)) != 2 )			continue;		topdir = 1;				/* name search? */		if( sname ) {			status = strcasecmp( ent.name, sname );			continue;		}				type = *(ulong*)ent.u.file.type;		creator = *(ulong*)ent.u.file.creator;				/* look for Mac OS ROM, System and Finder in the same directory */		if( type == MAC_OS_ROM_TYPE && creator == MAC_OS_ROM_CREATOR ) {			if( strcasecmp(ent.name, MAC_OS_ROM_NAME) )				continue;			status = _find_file( vol, path, FINDER_TYPE, FINDER_CREATOR )				|| _find_file( vol, path, SYSTEM_TYPE, SYSTEM_CREATOR );		}	}	if( !status && topdir && ret_fd && !(*ret_fd=(file_desc_t*)hfs_open(vol, buf)) ) {		printk("Unexpected error: failed to open matched ROM\n");		status = 1;	}	hfs_closedir( dir );	return status;}static file_desc_t *_do_search( fs_ops_t *fs, const char *sname ) {	hfsvol *vol = hfs_getvol( NULL );	file_desc_t *ret_fd = NULL;		(void)_search( vol, ":", sname, &ret_fd );	return ret_fd;}static file_desc_t *search_rom( fs_ops_t *fs ){	return _do_search( fs, NULL );}static file_desc_t *search_file( fs_ops_t *fs, const char *sname ){	return _do_search( fs, sname );}/************************************************************************//*	file/fs ops							*//************************************************************************/static voidfile_close( file_desc_t *fd ){	hfsfile *file = (hfsfile*)fd;	hfs_close( file );}static intfile_lseek( file_desc_t *fd, off_t offs, int whence ){	hfsfile *file = (hfsfile*)fd;	switch( whence ) {	case SEEK_CUR:		whence = HFS_SEEK_CUR;		break;	case SEEK_END:		whence = HFS_SEEK_END;		break;	default:	case SEEK_SET:		whence = HFS_SEEK_SET;		break;	}	return hfs_seek( file, offs, whence );}static intfile_read( file_desc_t *fd, void *buf, size_t count ){	hfsfile *file = (hfsfile*)fd;	return hfs_read( file, buf, count );}static char *get_path( file_desc_t *fd, char *retbuf, int len ){	char buf[256], buf2[256];	hfsvol *vol = hfs_getvol( NULL );	hfsfile *file = (hfsfile*)fd;	hfsdirent ent;	int start, ns;	ulong id;		hfs_fstat( file, &ent );	start = sizeof(buf) - strlen(ent.name) - 1;	if( start <= 0 )		return NULL;	strcpy( buf+start, ent.name );	buf[--start] = '\\';	ns = start;	for( id=ent.parid ; !hfs_dirinfo(vol, &id, buf2) ; ) {		start = ns;		ns -= strlen(buf2);		if( ns <= 0 )			return NULL;		strcpy( buf+ns, buf2 );		buf[--ns] = buf[start] = '\\';	}	if( strlen(buf + start) >= len )		return NULL;		strcpy( retbuf, buf+start );	return retbuf;}static char *vol_name( fs_ops_t *fs, char *buf, int size ){	return get_hfs_vol_name( fs->fd, buf, size );}static file_desc_t *open_path( fs_ops_t *fs, const char *path ){	hfsvol *vol = (hfsvol*)fs->fs_data;	const char *s;	char buf[256];		if( !strncmp(path, "\\\\", 2) ) {		hfsvolent ent;		/* \\ is an alias for the (blessed) system folder */		if( hfs_vstat(vol, &ent) < 0 || hfs_setcwd(vol, ent.blessed) )			return NULL;		path += 2;	} else {		hfs_chdir( vol, ":" );	}		for( path-- ;; ) {		int n;		s = ++path;		if( !(path=strchr(s, '\\')) )			break;		n = MIN( sizeof(buf)-1, (path-s) );		if( !n )			continue;				strncpy( buf, s, n );		buf[n] = 0;		if( hfs_chdir(vol, buf) )			return NULL;	}	/* support the ':filetype' syntax */	if( *s == ':' ) {		unsigned long id, oldid = hfs_getcwd(vol);		file_desc_t *ret = NULL;		hfsdirent ent;		hfsdir *dir;				s++;		id = oldid;		hfs_dirinfo( vol, &id, buf );		hfs_setcwd( vol, id );				if( !(dir=hfs_opendir(vol, buf)) )			return NULL;		hfs_setcwd( vol, oldid );				while( !hfs_readdir(dir, &ent) ) {			if( ent.flags & HFS_ISDIR )				continue;			if( !strncmp(s, ent.u.file.type, 4) ) {				ret = (file_desc_t*)hfs_open( vol, ent.name );				break;			}		}		hfs_closedir( dir );		return ret;	}	return (file_desc_t*)hfs_open( vol, s );}static voidclose_fs( fs_ops_t *fs ){	hfsvol *vol = (hfsvol*)fs->fs_data;	hfs_umount( vol );	/* callers responsibility to call free(fs) */}static char *get_fstype( fs_ops_t *fs ) {	return ("HFS");}		static const fs_ops_t hfs_ops = {	.close_fs	= close_fs,	.open_path	= open_path,	.search_rom	= search_rom,	.search_file	= search_file,	.vol_name	= vol_name,	.get_path	= get_path,	.close		= file_close,	.read		= file_read,	.lseek		= file_lseek,	.get_fstype	= get_fstype,};intfs_hfs_open( int os_fd, fs_ops_t *fs ){	hfsvol *vol = hfs_mount( os_fd, 0 );	if( !vol )		return -1;	*fs = hfs_ops;	fs->fs_data = vol;		return 0;}

⌨️ 快捷键说明

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