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

📄 fat_driver.c

📁 索尼公司著名游戏机PS2使用的引导工具文件源代码,这是爱好者自编的工具,可以使用它来引导自己的程序,达到跳过原光驱启动执行自己制作的程序的目的,在windows上可以安装使用ps2的专用开发包,搭建c
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * fat_driver.c - USB Mass storage driver for PS2 * * (C) 2004, Marek Olejnik (ole00@post.cz) * (C) 2004  Hermes (support for sector sizes from 512 to 4096 bytes) * (C) 2004  raipsu (fs_dopen, fs_dclose, fs_dread, fs_getstat implementation) * * FAT filesystem layer * * See the file LICENSE included with this distribution for licensing terms. *//*  This layer should be "independent". Just supply a function that reads sectors  from media (READ_SECTOR) and use fs_xxxx functions for file access. */#include <stdio.h>//#include <malloc.h>#include <sys/stat.h>#ifndef _PS2_#include <stdlib.h>#include <memory.h>#else#include <thbase.h>#define malloc(a)       AllocSysMemory(0,(a), NULL)#define free(a)         FreeSysMemory((a))#endif#include <errno.h>#include "scache.h"#include "fat_driver.h"#ifdef WRITE_SUPPORT#include "fat_write.h"#endif//#define DEBUG 1#include "mass_debug.h"// Added by Hermes extern unsigned Size_Sector; // store size of sector from usb mass#define MEMCPY(a,b,c) memcpy((a),(b),(c))#define SECTOR_SIZE Size_Sector //512 modified by Hermes#define DISK_INIT(a,b)		scache_init((a), (b))#define DISK_CLOSE		scache_close//#define READ_SECTOR(a, b)	scache_readSector((a), (b))#define READ_SECTOR(a, b)	scache_readSector((a), (void **)&b)#define FLUSH_SECTORS		scache_flushSectors#define MAX_FILES 16fs_rec  fsRec[MAX_FILES]; //file info recordfat_dir fsDir[MAX_FILES]; //directory entrystatic int fsCounter = 0;int	mounted;	//disk mounted=1 not monuted=0 fat_part partTable;	//partition master recordfat_bpb  partBpb;	//partition bios parameter block// modified by Hermesunsigned char* sbuf; //sector bufferunsigned int cbuf[MAX_DIR_CLUSTER]; //cluster index buffer // 2048 by Hermesstatic int workPartition;unsigned int  direntryCluster; //the directory cluster requested by getFirstDirentryint direntryIndex; //index of the directory childrenunsigned int  lastChainCluster;int lastChainResult;int getI32(unsigned char* buf) {	return (buf[0]  + (buf[1] <<8) + (buf[2] << 16) + (buf[3] << 24));}int getI32_2(unsigned char* buf1, unsigned char* buf2) {	return (buf1[0]  + (buf1[1] <<8) + (buf2[0] << 16) + (buf2[1] << 24));}int getI16(unsigned char* buf) {	return (buf[0] + (buf[1] <<8) );}int strEqual(unsigned char *s1, unsigned char* s2) {    unsigned char u1, u2;    for (;;) {		u1 = *s1++;		u2 = *s2++;		if (u1 >64 && u1 < 91)  u1+=32;		if (u2 >64 && u2 < 91)  u2+=32;        		if (u1 != u2) {			return -1;		}		if (u1 == '\0') {		    return 0;		}    }}unsigned int fat_cluster2sector1216(fat_bpb* bpb, unsigned int cluster) {	//return /* bpb->rootDirStart + (bpb->rootSize / 16)  + (bpb->clusterSize * (cluster-2));	return  bpb->rootDirStart + (bpb->rootSize / (bpb->sectorSize>>5))+ (bpb->clusterSize * (cluster-2));                           //modified by Hermes    ^ this work :)}unsigned int fat_cluster2sector32(fat_bpb* bpb, unsigned int cluster) {	return  bpb->rootDirStart + (bpb->clusterSize * (cluster-2));}unsigned int fat_cluster2sector(fat_bpb* bpb, unsigned int cluster) {	switch(bpb->fatType) {		case FAT32: return fat_cluster2sector32(bpb, cluster);		default:    return fat_cluster2sector1216(bpb, cluster);	}}void fat_getPartitionRecord(part_raw_record* raw, part_record* rec) {	rec->sid = raw->sid;	rec->start = getI32(raw->startLBA);	rec->count = getI32(raw->size);}/*   0x321, 0xABC     byte| byte| byte|   +--+--+--+--+--+--+   |2 |1 |C |3 |A |B |   +--+--+--+--+--+--+*/unsigned int fat_getClusterRecord12(unsigned char* buf, int type) {	if (type) { //1		return ((buf[1]<< 4) + (buf[0] >>4));	} else { // 0		return (((buf[1] & 0x0F) << 8) + buf[0]);	}}// Get Cluster chain into <buf> buffer// returns:// 0    :if buf is full (bufSize entries) and more chain entries exist// 1-n  :number of filled entries of the buf// -1   :error//for fat12 /* fat12 cluster records can overlap the edge of the sector so we need to detect and maintain   these cases*/int fat_getClusterChain12(fat_bpb* bpb, unsigned int cluster, unsigned int* buf, int bufSize, int start) {	int ret;	int i;	int recordOffset;	int sectorSpan;	int fatSector;	int cont;	int lastFatSector;	unsigned char xbuf[4];			cont = 1;	lastFatSector = -1;	i = 0;	if (start) {		buf[i] = cluster; //strore first cluster		i++;	}	while(i < bufSize && cont) {		recordOffset = (cluster * 3) / 2; //offset of the cluster record (in bytes) from the FAT start		fatSector = recordOffset / bpb->sectorSize;		sectorSpan = 0;		if ((recordOffset % bpb->sectorSize) == (bpb->sectorSize - 1)) {			sectorSpan = 1;		}		if (lastFatSector !=  fatSector || sectorSpan) {				ret = READ_SECTOR(bpb->partStart + bpb->resSectors + fatSector, sbuf); 				if (ret < 0) {					printf("FAT driver:Read fat12 sector failed! sector=%i! \n", bpb->partStart + bpb->resSectors + fatSector );					return -1;				}				lastFatSector = fatSector;				if (sectorSpan) {					xbuf[0] = sbuf[bpb->sectorSize - 2]; 					xbuf[1] = sbuf[bpb->sectorSize - 1]; 					ret = READ_SECTOR(bpb->partStart + bpb->resSectors + fatSector + 1, sbuf); 					if (ret < 0) {						printf("FAT driver:Read fat12 sector failed sector=%i! \n", bpb->partStart + bpb->resSectors + fatSector + 1);						return -1;					}					xbuf[2] = sbuf[0]; 					xbuf[3] = sbuf[1]; 				}		}		if (sectorSpan) { // use xbuf as source buffer 			cluster = fat_getClusterRecord12(xbuf + (recordOffset % bpb->sectorSize) - (bpb->sectorSize-2), cluster % 2);		} else { // use sector buffer as source buffer			cluster = fat_getClusterRecord12(sbuf + (recordOffset % bpb->sectorSize), cluster % 2);		}		if (cluster >= 0xFF8) {			cont = 0; //continue = false		} else {			buf[i] = cluster;			i++;		}	}	if (cont) {		return 0;	} else {		return i;	}}//for fat16 int fat_getClusterChain16(fat_bpb* bpb, unsigned int cluster, unsigned int* buf, int bufSize, int start) {	int ret;	int i;	int indexCount;	int fatSector;	int cont;	int lastFatSector;			cont = 1;	indexCount = bpb->sectorSize / 2; //FAT16->2, FAT32->4	lastFatSector = -1;	i = 0;	if (start) {		buf[i] = cluster; //strore first cluster		i++;	}	while(i < bufSize && cont) {		fatSector = cluster / indexCount;		if (lastFatSector !=  fatSector) {				ret = READ_SECTOR(bpb->partStart + bpb->resSectors + fatSector,  sbuf); 				if (ret < 0) {					printf("FAT driver:Read fat16 sector failed! sector=%i! \n", bpb->partStart + bpb->resSectors + fatSector );					return -1;				}				lastFatSector = fatSector;		}		cluster = getI16(sbuf + ((cluster % indexCount) * 2));		if (cluster >= 0xFFF8) {			cont = 0; //continue = false		} else {			buf[i] = cluster;			i++;		}	}	if (cont) {		return 0;	} else {		return i;	}}//for fat32int fat_getClusterChain32(fat_bpb* bpb, unsigned int cluster, unsigned int* buf, int bufSize, int start) {	int ret;	int i;	int indexCount;	int fatSector;	int cont;	int lastFatSector;			cont = 1;	indexCount = bpb->sectorSize / 4; //FAT16->2, FAT32->4	lastFatSector = -1;	i = 0;	if (start) {		buf[i] = cluster; //strore first cluster		i++;	}	while(i < bufSize && cont) {		fatSector = cluster / indexCount;		if (lastFatSector !=  fatSector) {				ret = READ_SECTOR(bpb->partStart + bpb->resSectors + fatSector,  sbuf); 				if (ret < 0) {					printf("FAT driver: Read fat32 sector failed sector=%i! \n", bpb->partStart + bpb->resSectors + fatSector );					return -1;				}				lastFatSector = fatSector;		}		cluster = getI32(sbuf + ((cluster % indexCount) * 4));		if ((cluster & 0xFFFFFFF) >= 0xFFFFFF8) {			cont = 0; //continue = false		} else {			buf[i] = cluster & 0xFFFFFFF;			i++;		}	}	if (cont) {		return 0;	} else {		return i;	}}int fat_getClusterChain(fat_bpb* bpb, unsigned int cluster, unsigned int* buf, int bufSize, int start) {	if (cluster == lastChainCluster) {		return lastChainResult;	}	switch (bpb->fatType) {		case FAT12: lastChainResult = fat_getClusterChain12(bpb, cluster, buf, bufSize, start); break;		case FAT16: lastChainResult = fat_getClusterChain16(bpb, cluster, buf, bufSize, start); break;		case FAT32: lastChainResult = fat_getClusterChain32(bpb, cluster, buf, bufSize, start); break;	}	lastChainCluster = cluster;	return lastChainResult;}void fat_invalidateLastChainResult() {	lastChainCluster  = 0;}void fat_getPartitionTable(fat_part* part) {	part_raw_record* part_raw;	int i;	int ret;	workPartition = 0;	ret = READ_SECTOR(0 , sbuf); //read sector 0 - Disk MBR	if (ret < 0) {		printf("FAT driver: Read sector 0 failed ! \n");		return;	}	/* read 4 partition records */	for (i= 0; i < 4; i++) {		part_raw = (part_raw_record*) (sbuf + 0x01BE + (i* 16));		fat_getPartitionRecord(part_raw, &part->record[i]);		if (part->record[i].sid == 6 || part->record[i].sid == 4 || part->record[i].sid == 1 ||// fat 16, fat 12			part->record[i].sid == 0x0B || part->record[i].sid == 0x0C) { // fat 32 			workPartition = i;		}	}}void fat_determineFatType(fat_bpb* bpb) {	int sector;	int clusterCount;	//get sector of cluster 0	sector = fat_cluster2sector(bpb, 0);	//remove partition start sector to get BR+FAT+ROOT_DIR sector count	sector -= bpb->partStart;	sector = bpb->sectorCount - sector;	clusterCount = sector / bpb->clusterSize;	//printf("Data cluster count = %i \n", clusterCount);	if (clusterCount < 4085) {		bpb->fatType = FAT12;	} else	if (clusterCount < 65525) {		bpb->fatType = FAT16;	} else {		bpb->fatType = FAT32;	}}void fat_getPartitionBootSector(part_record* part_rec, fat_bpb* bpb) {	fat_raw_bpb* bpb_raw; //fat16, fat12	fat32_raw_bpb* bpb32_raw; //fat32	int ret;	ret = READ_SECTOR(part_rec->start, sbuf); //read partition boot sector (first sector on partition)	if (ret < 0) {		printf("FAT driver: Read partition boot sector failed sector=%i! \n", part_rec->start);		return;	}	bpb_raw = (fat_raw_bpb*) sbuf;	bpb32_raw = (fat32_raw_bpb*) sbuf;	//set fat common properties	bpb->sectorSize	= getI16(bpb_raw->sectorSize);	bpb->clusterSize = bpb_raw->clusterSize;	bpb->resSectors = getI16(bpb_raw->resSectors);	bpb->fatCount = bpb_raw->fatCount;	bpb->rootSize = getI16(bpb_raw->rootSize);	bpb->fatSize = getI16(bpb_raw->fatSize);	bpb->trackSize = getI16(bpb_raw->trackSize);	bpb->headCount = getI16(bpb_raw->headCount);	bpb->hiddenCount = getI32(bpb_raw->hiddenCountL);	bpb->sectorCount = getI16(bpb_raw->sectorCountO);	if (bpb->sectorCount == 0) {		bpb->sectorCount = getI32(bpb_raw->sectorCount); // large partition	}	bpb->partStart = part_rec->start;	bpb->rootDirStart = part_rec->start + (bpb->fatCount * bpb->fatSize) + bpb->resSectors;	for (ret = 0; ret < 8; ret++) {		bpb->fatId[ret] = bpb_raw->fatId[ret];	}	bpb->fatId[ret] = 0;	bpb->rootDirCluster = 0;	fat_determineFatType(bpb);	//fat32 specific info	if (bpb->fatType == FAT32 && bpb->fatSize == 0) {		bpb->fatSize = getI32(bpb32_raw->fatSize32);		bpb->activeFat = getI16(bpb32_raw->fatStatus);		if (bpb->activeFat & 0x80) { //fat not synced			bpb->activeFat = (bpb->activeFat & 0xF);		} else {			bpb->activeFat = 0;		}		bpb->rootDirStart = part_rec->start + (bpb->fatCount * bpb->fatSize) + bpb->resSectors;		bpb->rootDirCluster = getI32(bpb32_raw->rootDirCluster);		for (ret = 0; ret < 8; ret++) {			bpb->fatId[ret] = bpb32_raw->fatId[ret];		}		bpb->fatId[ret] = 0;	}}/* returns: 0 - no more dir entries 1 - short name dir entry found 2 - long name dir entry found 3 - deleted dir entry found*/int fat_getDirentry(fat_direntry_sfn* dsfn, fat_direntry_lfn* dlfn, fat_direntry* dir ) {	int i, j;	int offset;	int cont;	//detect last entry - all zeros	if (dsfn->name[0] == 0 && dsfn->name[1] == 0) {		return 0;	}	//detect deleted entry - it will be ignored	if (dsfn->name[0] == 0xE5) {		return 3;	}	//detect long filename	if (dlfn->rshv == 0x0F && dlfn->reserved1 == 0x00 && dlfn->reserved2[0] == 0x00) {		//long filename - almost whole direntry is unicode string - extract it		offset = dlfn->entrySeq & 0x3f;		offset--;		offset = offset * 13;		//name - 1st part		cont = 1;		for (i = 0; i < 10 && cont; i+=2) {			if (dlfn->name1[i]==0 && dlfn->name1[i+1] == 0) {				dir->name[offset] = 0; //terminate				cont = 0; //stop 			} else {				dir->name[offset] = dlfn->name1[i];				offset++;			}		}		//name - 2nd part		for (i = 0; i < 12 && cont; i+=2) {			if (dlfn->name2[i]==0 && dlfn->name2[i+1] == 0) {				dir->name[offset] = 0; //terminate				cont = 0; //stop 			} else {				dir->name[offset] = dlfn->name2[i];				offset++;			}		}		//name - 3rd part		for (i = 0; i < 4 && cont; i+=2) {			if (dlfn->name3[i]==0 && dlfn->name3[i+1] == 0) {				dir->name[offset] = 0; //terminate				cont = 0; //stop 			} else {				dir->name[offset] = dlfn->name3[i];				offset++;			}		}		if ((dlfn->entrySeq & 0x40)) { //terminate string flag			dir->name[offset] = 0;		}		return 2;	} else {		//short filename		//copy name		for (i = 0; i < 8 && dsfn->name[i]!= 32; i++) {			dir->sname[i] = dsfn->name[i];			// NT梊栺椞堟撉傒庢傝			if (dsfn->reservedNT & 0x08 &&			  dir->sname[i] >= 'A' && dir->sname[i] <= 'Z') {				dir->sname[i] += 0x20;			}		}		for (j=0; j < 3 && dsfn->ext[j] != 32; j++) {			if (j == 0) {				dir->sname[i] = '.';				i++;			}			dir->sname[i+j] = dsfn->ext[j];			// NT梊栺椞堟撉傒庢傝			if (dsfn->reservedNT & 0x10 &&			  dir->sname[i+j] >= 'A' && dir->sname[i+j] <= 'Z') {				dir->sname[i+j] += 0x20;			}		}		dir->sname[i+j] = 0; //terminate		if (dir->name[0] == 0) { //long name desn't exit 			for (i =0 ; dir->sname[i] !=0; i++) dir->name[i] = dir->sname[i];			dir->name[i] = 0;		}		dir->attr = dsfn->attr;		dir->size = getI32(dsfn->size);		dir->cluster = getI32_2(dsfn->clusterL, dsfn->clusterH);		return 1;	}}//Set chain info (cluster/offset) cachevoid fat_setFatDirChain(fat_bpb* bpb, fat_dir* fatDir) {	int i,j;	int index;	int chainSize;	int nextChain; 	int clusterChainStart ;	unsigned int fileCluster;	int fileSize;	int blockSize;	XPRINTF("FAT driver: reading cluster chain  \n");	fileCluster = fatDir->chain[0].cluster;	if (fileCluster < 2) {		XPRINTF("   early exit... \n");		return;	}	fileSize = fatDir->size;	blockSize = fileSize / DIR_CHAIN_SIZE;	nextChain = 1;	clusterChainStart = 0;	j = 1;	fileSize = 0;	index = 0;	while (nextChain) {		chainSize = fat_getClusterChain(bpb, fileCluster, cbuf, MAX_DIR_CLUSTER, 1);		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 exist			nextChain = 0;		}#ifdef DEBUG		fat_dumpClusterChain(cbuf, chainSize, 0);#endif		//process the cluster chain (cbuf)		for (i = clusterChainStart; i < chainSize; i++) {			fileSize += (bpb->clusterSize * bpb->sectorSize);			while (fileSize >= (j * blockSize) && j < DIR_CHAIN_SIZE) {				fatDir->chain[j].cluster = cbuf[i];				fatDir->chain[j].index = index;				j++;			}			index++;		}		clusterChainStart = 1;	}	fatDir->lastCluster = cbuf[i-1];

⌨️ 快捷键说明

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