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

📄 fat_write.c

📁 索尼公司著名游戏机PS2使用的引导工具文件源代码,这是爱好者自编的工具,可以使用它来引导自己的程序,达到跳过原光驱启动执行自己制作的程序的目的,在windows上可以安装使用ps2的专用开发包,搭建c
💻 C
📖 第 1 页 / 共 5 页
字号:
/*

 * fat_driver.c - USB Mass storage driver for PS2

 *

 * (C) 2005, Marek Olejnik (ole00@post.cz)

 *

 * FAT filesystem layer -  write functions 

 *

 * See the file LICENSE included with this distribution for licensing terms.

 */



#ifdef _PS2_

#include <tamtypes.h>

#include <cdvdman.h>

#include <sysclib.h>

#else

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <time.h>

#endif /* _PS2_ */



#include <errno.h>



#include "fat.h"

#include "fat_driver.h"

#include "scache.h"



//#define DEBUG

#include "mass_debug.h"



#define DATE_CREATE 1

#define DATE_MODIFY 2



#define READ_SECTOR(a, b)	scache_readSector((a), (void **)&b)

#define ALLOC_SECTOR(a, b)	scache_allocSector((a), (void **)&b)

#define WRITE_SECTOR(a)		scache_writeSector((a))

#define FLUSH_SECTORS		scache_flushSectors



#define DIRENTRY_COUNT 1024

#define MAX_CLUSTER_STACK 128



#define MEMCPY(a,b,c) memcpy((a),(b),(c))



#define SECTOR_SIZE Size_Sector 

extern unsigned Size_Sector; // store size of sector from usb mass



extern unsigned char* sbuf; //sector buffer

extern unsigned int cbuf[MAX_DIR_CLUSTER]; //cluster index buffer

unsigned char tbuf[512]; //temporary buffer



/* enough for long filename of length 260 characters (20*13) and one short filename */

#define MAX_DE_STACK 21

unsigned int deSec[MAX_DE_STACK]; //direntry sector

int          deOfs[MAX_DE_STACK]; //direntry offset

int          deIdx = 0; //direntry index





unsigned int clStack[MAX_CLUSTER_STACK]; //cluster allocation stack

int clStackIndex = 0;

unsigned int clStackLast = 0; // last free cluster of the fat table



/*

 reorder (swap) the cluster stack records

*/

void swapClStack(int startIndex, int endIndex) {

	int i;

	int size;

	int offset1, offset2;

	unsigned int tmp;



	size = endIndex-startIndex;

	if (size < 2) {

		return;

	}	



#ifdef DEBUG

	printf("cluster stack: ");

	for (i = 0; i < endIndex; i++)  printf("%d, ", clStack[i]);

	printf("end \n");

#endif



	size/=2;

	for (i = 0; i < size; i++) {

		offset1 = startIndex + i;

		offset2 = endIndex - 1 - i;

		tmp = clStack[offset1];

		clStack[offset1] = clStack[offset2];

		clStack[offset2] = tmp;

	}

}



/*

 scan FAT12 for free clusters and store them to the cluster stack

*/



int fat_readEmptyClusters12(fat_bpb* bpb) {

	int ret;

	int i;

	int recordOffset;

	int sectorSpan;

	int fatSector;

	int cont;

	int lastFatSector;

	unsigned int cluster;

	unsigned int clusterValue;

	unsigned char xbuf[4];

	int oldClStackIndex;



	oldClStackIndex = clStackIndex;

		

	cont = 1;

	lastFatSector = -1;

	i = 0;

	cluster = clStackLast;



	while(clStackIndex < MAX_CLUSTER_STACK ) {

		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 -EIO;

				}

				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 -EIO;

					}

					xbuf[2] = sbuf[0]; 

					xbuf[3] = sbuf[1]; 

				}

		}

		if (sectorSpan) { // use xbuf as source buffer 

			clusterValue = fat_getClusterRecord12(xbuf + (recordOffset % bpb->sectorSize) - (bpb->sectorSize-2), cluster % 2);

		} else { // use sector buffer as source buffer

			clusterValue = fat_getClusterRecord12(sbuf + (recordOffset % bpb->sectorSize), cluster % 2);

		}

		if (clusterValue == 0) {

			clStackLast = cluster;

			clStack[clStackIndex] = cluster;

			clStackIndex++;



		}

		cluster++; //read next cluster record in the sequence

	}

	//the stack operates as LIFO but we put in the clusters as FIFO

	//we should reverse the cluster order - not necessary

	//but it will retain the natural (increasing) order of 

	//the cluster chain

	swapClStack(oldClStackIndex, clStackIndex);

	return clStackIndex;

	

}





/*

 scan FAT32 for free clusters and store them to the cluster stack

*/

int fat_readEmptyClusters32(fat_bpb* bpb) {

        int i,j;

	int ret;

	int indexCount;

	unsigned int fatStartSector;

	unsigned int cluster;

	unsigned int clusterValue;

	int oldClStackIndex;

	int sectorSkip;

	int recordSkip;



	oldClStackIndex = clStackIndex;



	//indexCount = numer of cluster indices per sector

	indexCount = bpb->sectorSize / 4; //FAT16->2, FAT32->4

	//skip areas we have already searched through 

	sectorSkip = clStackLast / indexCount;

	recordSkip = clStackLast % indexCount;



	fatStartSector = bpb->partStart + bpb->resSectors;



	for (i = sectorSkip; i < bpb->fatSize && clStackIndex < MAX_CLUSTER_STACK ; i++) {

		ret = READ_SECTOR(fatStartSector + i,  sbuf); 

		if (ret < 0) {

			printf("FAT driver:Read fat32 sector failed! sector=%i! \n", fatStartSector + i);

			return -EIO;

		}

		for (j = recordSkip; j < indexCount && clStackIndex < MAX_CLUSTER_STACK ; j++) {

			cluster = getI32(sbuf + (j * 4));

			if (cluster == 0) { //the cluster is free

				clusterValue = (i * indexCount) + j;

				if (clusterValue < 0xFFFFFF7) {

					clStackLast = clusterValue;

					clStack[clStackIndex] = clusterValue;

					clStackIndex++;

				}

			}

		}

		recordSkip = 0;

	}

	//the stack operates as LIFO but we put in the clusters as FIFO

	//we should reverse the cluster order - not necessary

	//but it will retain the natural (increasing) order of 

	//the cluster chain

	swapClStack(oldClStackIndex, clStackIndex);

	return clStackIndex;

}



/*

 scan FAT16 for free clusters and store them to the cluster stack

*/

int fat_readEmptyClusters16(fat_bpb* bpb) {

        int i,j;

	int ret;

	int indexCount;

	unsigned int fatStartSector;

	unsigned int cluster;

	int oldClStackIndex;

	int sectorSkip;

	int recordSkip;



	oldClStackIndex = clStackIndex;

	//XPRINTF("#### Read empty clusters16: clStackIndex=%d MAX=%d\n",  clStackIndex, MAX_CLUSTER_STACK);



	//indexCount = numer of cluster indices per sector

	indexCount = bpb->sectorSize / 2; //FAT16->2, FAT32->4



	//skip areas we have already searched through 

	sectorSkip = clStackLast / indexCount;

	recordSkip = clStackLast % indexCount;



	fatStartSector = bpb->partStart + bpb->resSectors;



	for (i = sectorSkip; i < bpb->fatSize && clStackIndex < MAX_CLUSTER_STACK ; i++) {

		ret = READ_SECTOR(fatStartSector + i,  sbuf); 

		if (ret < 0) {

			printf("FAT driver:Read fat16 sector failed! sector=%i! \n", fatStartSector + i);

			return -EIO;

		}

		for (j = recordSkip; j < indexCount && clStackIndex < MAX_CLUSTER_STACK ; j++) {

			cluster = getI16(sbuf + (j * 2));

			if (cluster == 0) { //the cluster is free

				clStackLast = (i * indexCount) + j;

				clStack[clStackIndex] = clStackLast;

				XPRINTF("%d ", clStack[clStackIndex]);

				clStackIndex++;

			}

		}

		recordSkip = 0;

	}

	XPRINTF("\n");

	//the stack operates as LIFO but we put in the clusters as FIFO

	//we should reverse the cluster order - not necessary

	//but it will retain the natural (increasing) order of 

	//the cluster chain

	swapClStack(oldClStackIndex, clStackIndex);

	return clStackIndex;

}





/*

 scan FAT for free clusters and store them to the cluster stack

*/

int fat_readEmptyClusters(fat_bpb* bpb) {

	switch (bpb->fatType) {

		case FAT12: return fat_readEmptyClusters12(bpb);

		case FAT16: return fat_readEmptyClusters16(bpb);

		case FAT32: return fat_readEmptyClusters32(bpb); 

	}

}







/*

   set sinlge cluster record (FAT12)into buffer



   0x321, 0xABC

    

    byte0|byte1|byte2|

   +--+--+--+--+--+--+

   |2 |1 |C |3 |A |B |

   +--+--+--+--+--+--+



*/

void fat_setClusterRecord12(unsigned char* buf, unsigned int cluster, int type) {



	if (type) { //type 1

		buf[0] = (buf[0] & 0x0F) + ((cluster & 0x0F)<<4) ;

		buf[1] = (cluster & 0xFF0) >> 4;		

	} else { // type 0

		buf[0] = (cluster & 0xFF);

		buf[1] = (buf[1] & 0xF0) + ((cluster & 0xF00) >> 8);

	}



}



void fat_setClusterRecord12part1(unsigned char* buf, unsigned int cluster, int type) {

	if (type) { //type 1

		buf[0] = (buf[0] & 0x0F) + ((cluster & 0x0F)<<4);

	} else { // type 0

		buf[0] = (cluster & 0xFF);

	}

}



void fat_setClusterRecord12part2(unsigned char* buf, unsigned int cluster, int type) {

	if (type) { //type 1

		buf[0] = (cluster & 0xFF0) >> 4;		

	} else { // type 0

		buf[0] = (buf[0] & 0xF0) + ((cluster & 0xF00) >> 8);

	}

}



/*

   save value at the cluster record in FAT 12

*/

int fat_saveClusterRecord12(fat_bpb* bpb, unsigned int currentCluster, unsigned int value) {

        int i;

	int ret;

	int sectorSpan;

	int recordOffset;

	int recordType;

	int fatNumber;

	unsigned int fatSector;



	ret = -1;

	//recordOffset is byte offset of the record from the start of the fat table

	recordOffset =  (currentCluster * 3) / 2; 



	//save both fat tables

	for (fatNumber = 0; fatNumber < bpb->fatCount; fatNumber++) {

	

		fatSector  = bpb->partStart + bpb->resSectors + (fatNumber * bpb->fatSize);

		fatSector += recordOffset / bpb->sectorSize;

		sectorSpan = bpb->sectorSize - (recordOffset % bpb->sectorSize);

		if (sectorSpan > 1) {

			sectorSpan = 0;

		}

		recordType = currentCluster % 2;



		ret = READ_SECTOR(fatSector,  sbuf); 

		if (ret < 0) {

			printf("FAT driver:Read fat16 sector failed! sector=%i! \n", fatSector);

			return -EIO;

		}

		if (!sectorSpan) { // not sector span - the record is copmact and fits in single sector

	 		fat_setClusterRecord12(sbuf + (recordOffset % bpb->sectorSize), value, recordType);

			ret = WRITE_SECTOR(fatSector); 

			if (ret < 0) {

				printf("FAT driver:Write fat12 sector failed! sector=%i! \n", fatSector);

				return -EIO;

			}

		} else { // sector span - the record is broken in 2 pieces - each one on different sector

			//modify one last byte of the sector buffer

			fat_setClusterRecord12part1(sbuf + (recordOffset % bpb->sectorSize), value, recordType);

			//save current sector

			ret = WRITE_SECTOR(fatSector); 

			if (ret < 0) {

				printf("FAT driver:Write fat12 sector failed! sector=%i! \n", fatSector);

				return -EIO;

			}

			//read next sector from the fat

			fatSector++;

			ret = READ_SECTOR(fatSector,  sbuf); 

			if (ret < 0) {

				printf("FAT driver:Read fat16 sector failed! sector=%i! \n", fatSector);

				return -EIO;

			}

			//modify first byte of the sector buffer

			fat_setClusterRecord12part2(sbuf, value, recordType);

			//save current sector

			ret = WRITE_SECTOR(fatSector); 

			if (ret < 0) {

				printf("FAT driver:Write fat12 sector failed! sector=%i! \n", fatSector);

				return -EIO;

			}

		}

	} //end for

	return ret;

}



/*

   save value at the cluster record in FAT 16

*/

int fat_saveClusterRecord16(fat_bpb* bpb, unsigned int currentCluster, unsigned int value) {

        int i;

	int ret;

	int indexCount;

	int fatNumber;

⌨️ 快捷键说明

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