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

📄 fat_driver.c

📁 索尼公司著名游戏机PS2使用的引导工具文件源代码,这是爱好者自编的工具,可以使用它来引导自己的程序,达到跳过原光驱启动执行自己制作的程序的目的,在windows上可以安装使用ps2的专用开发包,搭建c
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef DEBUG	//debug	printf("SEEK CLUSTER CHAIN CACHE fileSize=%i blockSize=%i \n", fatDir->size, blockSize);	for (i = 0; i < DIR_CHAIN_SIZE; i++) {		printf("index=%i cluster=%i offset= %i - %i start=%i \n", 			fatDir->chain[i].index, fatDir->chain[i].cluster,			fatDir->chain[i].index * bpb->clusterSize * bpb->sectorSize,			(fatDir->chain[i].index+1) * bpb->clusterSize * bpb->sectorSize,			i * blockSize);	}#endif /* debug */	XPRINTF("FAT driver: read cluster chain  done!\n");}/* Set base attributes of direntry */void fat_setFatDir(fat_bpb* bpb, fat_dir* fatDir, fat_direntry_sfn* dsfn, fat_direntry* dir, int getClusterInfo ) {	int i;	unsigned char* srcName;	XPRINTF("setting fat dir...\n");	srcName = dir->sname; 	if (dir->name[0] != 0) { //long filename not empty		srcName = dir->name;	}	//copy name	for (i = 0; srcName[i] != 0; i++) fatDir->name[i] = srcName[i];	fatDir->name[i] = 0; //terminate	fatDir->attr = dsfn->attr;	fatDir->size = dir->size;	//Date: Day, Month, Year-low, Year-high	fatDir->date[0] = (dsfn->dateWrite[0] & 0x1F);	fatDir->date[1] = (dsfn->dateWrite[0] >> 5) + ((dsfn->dateWrite[1] & 0x01) << 3 );	i = 1980 + (dsfn->dateWrite[1] >> 1);	fatDir->date[2] = (i & 0xFF);	fatDir->date[3] = ((i & 0xFF00)>> 8);	//Time: Hours, Minutes, Seconds	fatDir->time[0] = ((dsfn->timeWrite[1] & 0xF8) >> 3);	fatDir->time[1] = ((dsfn->timeWrite[1] & 0x07) << 3) + ((dsfn->timeWrite[0] & 0xE0) >> 5);	fatDir->time[2] = ((dsfn->timeWrite[0] & 0x1F) << 1);	fatDir->chain[0].cluster = dir->cluster;	fatDir->chain[0].index  = 0;	if (getClusterInfo) {		fat_setFatDirChain(bpb, fatDir);	}}int fat_getDirentrySectorData(fat_bpb* bpb, unsigned int* startCluster, unsigned int* startSector, int* dirSector) {	int chainSize;	if (*startCluster == 0 && bpb->fatType < FAT32) { //Root directory		*startSector = bpb->rootDirStart;		*dirSector =  bpb->rootSize / (bpb->sectorSize / 32);		return 0;	} 	 //other directory or fat 32	if (*startCluster == 0 && bpb->fatType == FAT32) {		*startCluster = bpb->rootDirCluster;	} 	*startSector = fat_cluster2sector(bpb, *startCluster);	chainSize = fat_getClusterChain(bpb, *startCluster, cbuf, MAX_DIR_CLUSTER, 1);	if (chainSize > 0) {		*dirSector = chainSize * bpb->clusterSize;	} else {		printf("FAT driver: Error getting cluster chain! startCluster=%i \n", *startCluster);		return -1;	}#ifdef DEBUG	fat_dumpClusterChain(cbuf, chainSize, 0);#endif 	return chainSize;}int fat_getDirentryStartCluster(fat_bpb* bpb, unsigned char* dirName, unsigned int* startCluster, fat_dir* fatDir) {	fat_direntry_sfn* dsfn;	fat_direntry_lfn* dlfn;	fat_direntry dir;	int i, j;	int dirSector;	unsigned int startSector;	int cont;	int ret;	int dirPos;	int clusterMod;	cont = 1;	XPRINTF("\n");	XPRINTF("getting cluster for dir entry: %s \n", dirName);	clusterMod = bpb->clusterSize - 1;	//clear name strings	dir.sname[0] = 0;	dir.name[0] = 0;	fat_getDirentrySectorData(bpb, startCluster, &startSector, &dirSector);	XPRINTF("dirCluster=%i startSector=%i (%i) dirSector=%i \n", *startCluster, startSector, startSector * Size_Sector, dirSector);	//go through first directory sector till the max number of directory sectors	//or stop when no more direntries detected	for (i = 0; i < dirSector && cont; i++) {		ret = READ_SECTOR(startSector + i, sbuf); 		if (ret < 0) {			printf("FAT driver: read directory sector failed ! sector=%i\n", startSector + i);			return FAT_ERROR;		}		XPRINTF("read sector ok, scanning sector for direntries...\n");				//get correct sector from cluster chain buffer		if ((*startCluster != 0) && (i % bpb->clusterSize == clusterMod)) {			startSector = fat_cluster2sector(bpb, cbuf[(i / bpb->clusterSize) +  1]);			startSector -= (i+1);		}		dirPos = 0;		// go through start of the sector till the end of sector		while (cont &&  dirPos < bpb->sectorSize) {			dsfn = (fat_direntry_sfn*) (sbuf + dirPos);			dlfn = (fat_direntry_lfn*) (sbuf + dirPos);			cont = fat_getDirentry(dsfn, dlfn, &dir); //get single directory entry from sector buffer			if (cont == 1) { //when short file name entry detected				if (!(dir.attr & 0x08)) { //not volume label					if ((strEqual(dir.sname, dirName) == 0) || 						(strEqual(dir.name, dirName) == 0) ) {							XPRINTF("found! %s\n", dir.name);							if (fatDir != NULL) { //fill the directory properties								fat_setFatDir(bpb, fatDir, dsfn, &dir, 1);							}							*startCluster = dir.cluster; 							XPRINTF("direntry %s found at cluster: %i \n", dirName, dir.cluster);							return dir.attr; //returns file or directory attr						}				}				//clear name strings				dir.sname[0] = 0;				dir.name[0] = 0;			}			dirPos += 32; //directory entry of size 32 bytes		}			}	XPRINTF("direntry %s not found! \n", dirName);	return -EFAULT;}// start cluster should be 0 - if we want to search from root directory// otherwise the start cluster should be correct cluster of directory// to search directory - set fatDir as NULLint fat_getFileStartCluster(fat_bpb* bpb, const char* fname, unsigned int* startCluster, fat_dir* fatDir) {	unsigned char tmpName[257];	int i;	int offset;	int cont;	int ret;	cont = 1;	offset = 0;	i=0;	if (fname[i] == '/' || fname[i] == '\\' ) {		i++;	}	for ( ; fname[i] !=0; i++) {		if (fname[i] == '/' || fname[i] == '\\') { //directory separator			tmpName[offset] = 0; //terminate string			ret = fat_getDirentryStartCluster(bpb, tmpName, startCluster, fatDir);			if (ret < 0) {				return -ENOENT;			}			offset = 0;		} else{			tmpName[offset] = fname[i];			offset++;		}	}	//and the final file	if (fatDir != NULL) {		//if the last char of the name was slash - the name was already found -exit		if (offset == 0 && i > 1) { 			return 1;		}		tmpName[offset] = 0; //terminate string		ret = fat_getDirentryStartCluster(bpb, tmpName, startCluster, fatDir);		if (ret < 0) {			return ret;		}		XPRINTF("file's startCluster found. Name=%s, cluster=%i \n", fname, *startCluster);	}	return 1;}void fat_getClusterAtFilePos(fat_bpb* bpb, fat_dir* fatDir, unsigned int filePos, unsigned int* cluster, unsigned int* clusterPos) {	int i;	int blockSize;	int j = (DIR_CHAIN_SIZE-1);	blockSize = bpb->clusterSize * bpb->sectorSize;	for (i = 0; i < (DIR_CHAIN_SIZE-1); i++) {		if (fatDir->chain[i].index   * blockSize <= filePos &&			fatDir->chain[i+1].index * blockSize >  filePos) {				j = i;				break;			}	}	*cluster    = fatDir->chain[j].cluster;	*clusterPos = (fatDir->chain[j].index * blockSize);}int fat_readFile(fat_bpb* bpb, fat_dir* fatDir, unsigned int filePos, unsigned char* buffer, int size) {	int ret;	int i,j;	int chainSize;	int nextChain; 	int startSector;	int bufSize;	int sectorSkip;	int clusterSkip;	int dataSkip;	unsigned int bufferPos;	unsigned int fileCluster;	unsigned int clusterPos;	int clusterChainStart;	fat_getClusterAtFilePos(bpb, fatDir, filePos, &fileCluster, &clusterPos);	sectorSkip = (filePos - clusterPos) / bpb->sectorSize;	clusterSkip = sectorSkip / bpb->clusterSize;	sectorSkip %= bpb->clusterSize;	dataSkip  = filePos  % bpb->sectorSize;	bufferPos = 0;	XPRINTF("fileCluster = %i,  clusterPos= %i clusterSkip=%i, sectorSkip=%i dataSkip=%i \n",		fileCluster, clusterPos, clusterSkip, sectorSkip, dataSkip);	if (fileCluster < 2) {		return 0;	}	bufSize = SECTOR_SIZE;	nextChain = 1;	clusterChainStart = 1;	while (nextChain && size > 0 ) {		chainSize = fat_getClusterChain(bpb, fileCluster, cbuf, MAX_DIR_CLUSTER, clusterChainStart);		clusterChainStart = 0;		if (chainSize == 0) { //the chain is full, but more chain parts exist			chainSize = MAX_DIR_CLUSTER;			fileCluster = cbuf[MAX_DIR_CLUSTER - 1];		}else { //chain fits in the chain buffer completely - no next chain needed			nextChain = 0;		}		while (clusterSkip >= MAX_DIR_CLUSTER) {			chainSize = fat_getClusterChain(bpb, fileCluster, cbuf, MAX_DIR_CLUSTER, clusterChainStart);			clusterChainStart = 0;			if (chainSize == 0) { //the chain is full, but more chain parts exist				chainSize = MAX_DIR_CLUSTER;				fileCluster = cbuf[MAX_DIR_CLUSTER - 1];			}else { //chain fits in the chain buffer completely - no next chain needed				nextChain = 0;			}			clusterSkip -= MAX_DIR_CLUSTER;		}#ifdef DEBUG		fat_dumpClusterChain(cbuf, chainSize, clusterSkip);		printf("fileCluster = %i,  clusterPos= %i clusterSkip=%i, sectorSkip=%i dataSkip=%i filePos=%i \n",		fileCluster, clusterPos, clusterSkip, sectorSkip, dataSkip, filePos);#endif		//process the cluster chain (cbuf) and skip leading clusters if needed		for (i = 0 + clusterSkip; i < chainSize && size > 0; i++) {			//read cluster and save cluster content			startSector = fat_cluster2sector(bpb, cbuf[i]);			//process all sectors of the cluster (and skip leading sectors if needed)			for (j = 0 + sectorSkip; j < bpb->clusterSize && size > 0; j++) {				ret = READ_SECTOR(startSector + j, sbuf); 				if (ret < 0) {					printf("Read sector failed ! sector=%i\n", startSector + j);					return bufferPos;				}				//compute exact size of transfered bytes				if (size < bufSize) {					bufSize = size + dataSkip;				}				if (bufSize > SECTOR_SIZE) {					bufSize = SECTOR_SIZE;				}				XPRINTF("memcopy dst=%i, src=%i, size=%i  bufSize=%i \n", bufferPos, dataSkip, bufSize-dataSkip, bufSize);				MEMCPY(buffer+bufferPos, sbuf + dataSkip, bufSize - dataSkip);				size-= (bufSize - dataSkip);				bufferPos +=  (bufSize - dataSkip);				dataSkip = 0;				bufSize = SECTOR_SIZE;			}			sectorSkip = 0;		}		clusterSkip = 0;	}	return bufferPos;}int fat_mountCheck() {	int mediaStatus;	int ret;#ifdef _PS2_	mediaStatus = mass_stor_getStatus(); 	if (mediaStatus < 0) {		mounted = 0;		return mediaStatus;	}	if ((mediaStatus & 0x03) == 3) { /* media is ready for operation */		/* in the meantime the media was reconnected and maybe changed - force unmount*/		if ((mediaStatus & 0x04) == 4) { 			mounted = 0;		}		if (mounted) { /* and is mounted */        		return 1;        	}	        ret = fat_initDriver();		return ret;	}	if (mounted) { /* fs mounted but media is not ready - force unmount */		mounted = 0;	}	return -10;#else	return 1;#endif}int fat_getNextDirentry(fat_dir* fatDir) {	fat_bpb* bpb;	fat_direntry_sfn* dsfn;	fat_direntry_lfn* dlfn;	fat_direntry dir;	int i, j;	int dirSector;	unsigned int startSector;	int cont = 1;	int ret;	int dirPos;	int clusterMod;	int index;	unsigned int dirCluster;	//the getFirst function was not called	if (direntryCluster == 0xFFFFFFFF || fatDir == NULL) {		return -2;	}	bpb = &partBpb;	dirCluster = direntryCluster;	index  = 0;	clusterMod = bpb->clusterSize - 1;	//clear name strings	dir.sname[0] = 0;	dir.name[0] = 0;	fat_getDirentrySectorData(bpb, &dirCluster, &startSector, &dirSector);		XPRINTF("dirCluster=%i startSector=%i (%i) dirSector=%i \n", dirCluster, startSector, startSector * Size_Sector, dirSector);	//go through first directory sector till the max number of directory sectors	//or stop when no more direntries detected	for (i = 0; i < dirSector && cont; i++) {		ret = READ_SECTOR(startSector + i, sbuf); 		if (ret < 0) {			printf("Read directory  sector failed ! sector=%i\n", startSector + i);			return -3;		}		//get correct sector from cluster chain buffer		if ((dirCluster != 0) && (i % bpb->clusterSize == clusterMod)) {			startSector = fat_cluster2sector(bpb, cbuf[(i / bpb->clusterSize) +  1]);			startSector -= (i+1);		}		dirPos = 0;		// go through start of the sector till the end of sector		while (cont &&  dirPos < bpb->sectorSize) {			dsfn = (fat_direntry_sfn*) (sbuf + dirPos);			dlfn = (fat_direntry_lfn*) (sbuf + dirPos);			cont = fat_getDirentry(dsfn, dlfn, &dir); //get single directory entry from sector buffer			if (cont == 1) { //when short file name entry detected				index++;				if ((index-1) == direntryIndex) {						direntryIndex++;						fat_setFatDir(bpb, fatDir, dsfn, &dir, 0);						return 1;				}				//clear name strings				dir.sname[0] = 0;				dir.name[0] = 0;			}			dirPos += 32; //directory entry of size 32 bytes		}			}	// when we get this far - reset the direntry cluster	direntryCluster = 0xFFFFFFFF; //no more files	return -1; //indicate that no direntry is avalable}int fat_getFirstDirentry(char * dirName, fat_dir* fatDir) {	int ret; 	unsigned int startCluster = 0;	ret = fat_mountCheck();	if (ret < 0) {		return ret;	}	if ( ((dirName[0] == '/' || dirName[0]=='\\') && dirName[1] == 0) || // the root directory		dirName[0] == 0 || dirName == NULL) {			direntryCluster = 0;	} else {		ret = fat_getFileStartCluster(&partBpb, dirName, &startCluster, fatDir);		if (ret < 0) { //dir name not found			return -4;		}		//check that direntry is directory 		if ((fatDir->attr & 0x10) == 0) {			return -3; //it's a file - exit		}		direntryCluster = startCluster;	}	direntryIndex = 0;	return fat_getNextDirentry(fatDir);}int fat_initDriver() {	int ret;	lastChainCluster = 0xFFFFFFFF;	lastChainResult = -1;	direntryCluster = 0xFFFFFFFF;	direntryIndex = 0;	ret = DISK_INIT("disk1.bin", Size_Sector); // modified by Hermes	if (ret < 0) {		printf ("fat_driver: disk init failed \n" );		return ret;	}	fat_getPartitionTable(&partTable);		fat_getPartitionBootSector(&partTable.record[workPartition],  &partBpb);#ifdef DEBUG	fat_dumpPartitionTable();	fat_dumpPartitionBootSector();#endif	fs_init(NULL);	mounted = 1;}void fat_closeDriver() {	DISK_CLOSE();}fat_bpb*  fat_getBpb() { 	return &partBpb;}/*************************************************************************************//*    File IO functions                                                              *//*************************************************************************************/#ifdef _PS2_int	nameSignature;int	removalTime;int     removalResult;#endif /* __PS2_ */typedef struct {   int status;   fat_dir fatdir;} D_PRIVATE;int fs_findFreeFileSlot(int fd) {	int i;	int result = -1;	for (i = 0; i < MAX_FILES; i++) {		if (fsRec[i].fd == fd) {			result = i;			break;		}	}	return result;}int fs_findFileSlot(iop_file_t* file) {	int i;	int result = -1;	fs_rec* rec = (fs_rec*)file->privdata;	int fd = rec->fd;	for (i = 0; i < MAX_FILES; i++) {		if (fsRec[i].fd == fd) {			result = i;			break;		}	}	return result;}int fs_findFileSlotByName(const char* name) {	int i;	int result = -1;	for (i = 0; i < MAX_FILES; i++) {		if (fsRec[i].fd >= 0 && strEqual(fsDir[i].name, (unsigned char*) name) == 0) {			result = i;			break;		}	}	return result;}int fs_init(iop_device_t *driver) {	int i;	mounted = 0;	for (i = 0; i < MAX_FILES; i++) {		fsRec[i].fd = -1;	}	return 1;}int fs_open(iop_file_t* fd, const char *name, int mode, ...) {	int index, index2;	int mode2;	int ret;	unsigned int cluster;	char escapeNotExist;	XPRINTF("fs_open called: %s mode=%X \n", name, mode) ;        //check if media mounted        ret = fat_mountCheck();        if (ret < 0) {        	return ret;        }#ifndef WRITE_SUPPORT			//read only support	if (mode != 0 && mode != O_RDONLY) { //correct O_RDONLY  number?		XPRINTF("mode  (%d) != O_RDONLY	(%d) \n", mode, O_RDONLY);		return -EROFS;	} #endif	//check if the slot is free	index = fs_findFreeFileSlot(-1);	if (index  < 0) return -EMFILE;#ifdef WRITE_SUPPORT	//check if the file is already open	index2 = fs_findFileSlotByName(name);	//file already open	if (index2 >= 0) {		mode2 = fsRec[index2].mode;		if (	(mode  & O_RDWR || mode  & O_WRONLY) || //current file is opened for write			(mode2 & O_RDWR || mode2 & O_WRONLY) ) {//other file is opened for write			return 	-EACCES;		}

⌨️ 快捷键说明

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