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

📄 fat_write.c

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

	unsigned int fatSector;



	ret = -1;

	//indexCount is numer of cluster indices per sector

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

	

	//save both fat tables

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

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

		fatSector += currentCluster / indexCount;



		ret = READ_SECTOR(fatSector,  sbuf); 

		if (ret < 0) {

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

			return -EIO;

		}

		i = currentCluster % indexCount;

		i*=2; //fat16

		sbuf[i++] = value & 0xFF;

		sbuf[i]   = ((value & 0xFF00) >> 8);

		ret = WRITE_SECTOR(fatSector); 

		if (ret < 0) {

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

			return -EIO;

		}

	}

	return ret;

}



/*

   save value at the cluster record in FAT 16

*/

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

        int i;

	int ret;

	int indexCount;

	int fatNumber;

	unsigned int fatSector;



	ret = -1;

	//indexCount is numer of cluster indices per sector

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

	

	//save both fat tables

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

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

		fatSector += currentCluster / indexCount;



		ret = READ_SECTOR(fatSector,  sbuf); 

		if (ret < 0) {

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

			return -EIO;

		}

		i = currentCluster % indexCount;

		i*=4; //fat32

		sbuf[i++] = value & 0xFF;

		sbuf[i++] = ((value & 0xFF00) >> 8);

		sbuf[i++] = ((value & 0xFF0000) >> 16);

		sbuf[i]   = (sbuf[i] &0xF0) + ((value >> 24) & 0x0F); //preserve the highest nibble intact



		ret = WRITE_SECTOR(fatSector); 

		if (ret < 0) {

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

			return -EIO;

		}

	}

	return ret;

}





/*

  Append (and write) cluster chain to the FAT table.



  currentCluster - current end cluster record.

  endCluster     - new end cluster record.



  Note: there is no checking wether the currentCluster holds the EOF marker!



  Example

  current FAT:



  index   09    10    11    12

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

  value + 10  | EOF | 0   | 0   |

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





  currentcluster = 10, endcluster = 12

  updated FAT (after the function ends):



  index   09    10    11    12

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

  value + 10  | 12  | 0   | EOF |

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



*/



int fat_appendClusterChain(fat_bpb* bpb, unsigned int currentCluster, unsigned int endCluster) {

	int ret;

	ret = -1;

	switch (bpb->fatType) {

		case FAT12: 

			ret = fat_saveClusterRecord12(bpb, currentCluster, endCluster);

			if (ret < 0) return ret;

			ret = fat_saveClusterRecord12(bpb, endCluster, 0xFFF);

			break;

	

		case FAT16: 

			XPRINTF("I: appending cluster chain : current=%d end=%d \n", currentCluster, endCluster);

			ret = fat_saveClusterRecord16(bpb, currentCluster, endCluster);

			if (ret < 0) return ret;

			ret = fat_saveClusterRecord16(bpb, endCluster, 0xFFFF);

			break;



		case FAT32: 

			ret = fat_saveClusterRecord32(bpb, currentCluster, endCluster);

			if (ret < 0) return ret;

			ret = fat_saveClusterRecord32(bpb, endCluster, 0xFFFFFFF);

			break;

	}

	return ret;

}



/*

 create new cluster chain (of size 1 cluster) at the cluster index

*/

int fat_createClusterChain(fat_bpb* bpb, unsigned int cluster) {

	switch (bpb->fatType) {

		case FAT12: return fat_saveClusterRecord12(bpb, cluster, 0xFFF);

		case FAT16: return fat_saveClusterRecord16(bpb, cluster, 0xFFFF);

		case FAT32: return fat_saveClusterRecord32(bpb, cluster, 0xFFFFFFF);

	}

	return -EFAULT;

}





/*

 modify the cluster (in FAT table) at the cluster index

*/

int fat_modifyClusterChain(fat_bpb* bpb, unsigned int cluster, unsigned int value) {

	switch (bpb->fatType) {

		case FAT12: return fat_saveClusterRecord12(bpb, cluster, value);

		case FAT16: return fat_saveClusterRecord16(bpb, cluster, value);

		case FAT32: return fat_saveClusterRecord32(bpb, cluster, value);

	}

	return -EFAULT;

}







/*

  delete cluster chain starting at cluster

*/

int fat_deleteClusterChain(fat_bpb* bpb, unsigned int cluster) {

	int ret;

	int size;

	int cont;

	int end;	

	int i;



	if (cluster < 2) {

		return -EFAULT;

	}

	XPRINTF("I: delete cluster chain starting at cluster=%d\n", cluster);



	cont = 1;



	while (cont) {

		size = fat_getClusterChain(bpb, cluster, cbuf, MAX_DIR_CLUSTER, 1);

		if (size == 0) {

			size = MAX_DIR_CLUSTER;

		}



		end = size-1; //do not delete last cluster in the chain buffer

#ifdef DEBUG

		fat_dumpClusterChain(cbuf, size, 0);

#endif

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

			ret = fat_modifyClusterChain(bpb, cbuf[i], 0);

			if (ret < 0) {

				return ret;

			}

		}

		//the cluster chain continues

		if (size == MAX_DIR_CLUSTER) {

			cluster = cbuf[end];

		} else {

		//no more cluster entries - delete the last cluster entry

			ret = fat_modifyClusterChain(bpb, cbuf[end], 0);

			if (ret < 0) {

				return ret;

			}

			cont = 0;

		}

		fat_invalidateLastChainResult(); //prevent to misuse current (now deleted) cbuf

	}

	return 1;

}



/*

  Get single empty cluster from the clusterStack (cS is small cache of free clusters)

  Passed currentCluster is updated in the FAT and the new returned cluster index is

  appended at the end of fat chain!

*/

unsigned int fat_getFreeCluster(fat_bpb* bpb, unsigned int currentCluster) {



	int ret;

	unsigned int result;



	//cluster stack is empty - find and fill the cS

	if (clStackIndex <= 0) {

		clStackIndex = 0;

		ret = fat_readEmptyClusters(bpb);

		if (ret <= 0) return 0;

		clStackIndex = ret;



	}

	//pop from cluster stack

	clStackIndex--;

	result = clStack[clStackIndex];

        //append the cluster chain

	if (currentCluster) {

		ret = fat_appendClusterChain(bpb, currentCluster, result);

	} else { //create new cluster chain

		ret = fat_createClusterChain(bpb, result);

	}

	if (ret < 0) return 0;

	return result;

}





/*

 simple conversion of the char from lower case to upper case

*/

inline unsigned char toUpperChar(unsigned char c) {

	if (c >96  && c < 123) { 

		return (c - 32);

	} 

	return c;

}



/*

returns number of direntry positions that the name takes

*/

int getDirentrySize(unsigned char* lname) {

	int len;

	int result;

	len = strlen((const char*)lname);

	result = len / 13;

	if (len % 13 > 0) result++;

	return result;

}



/*

compute checksum of the short filename

*/

unsigned char computeNameChecksum(unsigned char* sname) {

	unsigned char result;

	int i;

	

	result = 0;

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

		result = (0x80 * (0x01 & result)) + (result >> 1);  //ROR 1

		result += sname[i];

	}

	return result;

}





/*

  fill the LFN (long filename) direntry

*/

void setLfnEntry(unsigned char* lname, int nameSize, unsigned char chsum, unsigned char* buffer, int part, int maxPart){

        int i,j;

	unsigned char* offset;

	unsigned char name[26]; //unicode name buffer = 13 characters per 2 bytes

	int nameStart;

	fat_direntry_lfn* dlfn;



        offset = buffer + (maxPart-part) * 32;

	dlfn = (fat_direntry_lfn*) offset;



	nameStart = 13 * part;

        j = nameSize - nameStart;

        if (j > 13) {

        	j = 13;

        } 

		

        //fake unicode conversion

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

        	name[i*2]   = lname[nameStart + i];

        	name[i*2+1] = 0; 

        }



        //rest of the name is zero terminated and padded with 0xFF

        for (i = j; i < 13; i++) {

		if (i == j) {

	        	name[i*2]   = 0;

       			name[i*2+1] = 0;

		} else {

			name[i*2] = 0xFF;

			name[i*2+1] = 0xFF;

		}

        }



	if (maxPart == 0) {

		i = 1;

	} else {

		i = part/maxPart;

	}

	dlfn->entrySeq = (part+1) + (i * 64);

	dlfn->checksum = chsum;

	//1st part of the name

	for (i = 0; i < 10; i++) dlfn->name1[i] = name[i];

	//2nd part of the name

	for (i = 0; i < 12; i++) dlfn->name2[i] = name[i+10];

	//3rd part of the name

	for (i = 0; i < 4; i++) dlfn->name3[i] = name[i+22];

	dlfn->rshv = 0x0f;

	dlfn->reserved1 = 0;

	dlfn->reserved2[0] = 0;

	dlfn->reserved2[1] = 0;	

}



/*

  update the SFN (long filename) direntry - DATE and TIME

*/

void setSfnDate(fat_direntry_sfn* dsfn, int mode) {

	int year, month, day, hour, minute, sec;

	unsigned char tmpClk[4];



#ifdef _PS2_

	//ps2 specific routine to get time and date

	cd_clock_t	cdtime;

	s32		tmp;



	if(CdReadClock(&cdtime)!=0 && cdtime.stat==0)

	{

		

		tmp=cdtime.second>>4;

		sec=(u32)(((tmp<<2)+tmp)<<1)+(cdtime.second&0x0F);



		tmp=cdtime.minute>>4;

		minute=(((tmp<<2)+tmp)<<1)+(cdtime.minute&0x0F);



		tmp=cdtime.hour>>4;

		hour=(((tmp<<2)+tmp)<<1)+(cdtime.hour&0x0F);

		hour= (hour + 4 + 12) % 24; // TEMP FIX (need to deal with timezones?)

		

		tmp=cdtime.day>>4;

		day=(((tmp<<2)+tmp)<<1)+(cdtime.day&0x0F);



		tmp=cdtime.month>>4;

		//value=(((tmp<<2)+tmp)<<1)+(cdtime.month&0x0F);

		month= cdtime.month & 0x0F;



		tmp=cdtime.year>>4;

		year=(((tmp<<2)+tmp)<<1)+(cdtime.year&0xF)+2000;

	} else  {

		year = 2005; month = 1;	day = 6;

		hour = 14; minute = 12; sec = 10;

	}

#else

	time_t nowTime;

	struct tm* nowTm;



	time(&nowTime);

	nowTm = localtime(&nowTime);



	year  = nowTm->tm_year + 1900;

	month = nowTm->tm_mon+1;

	day   = nowTm->tm_mday;

	hour  = nowTm->tm_hour;

	minute= nowTm->tm_min;

	sec   = nowTm->tm_sec;

#endif /* _PS2_ */



	if (dsfn == NULL || mode == 0)  {

		return;

	}



	tmpClk[0]  = (sec / 2) & 0x1F; //seconds

	tmpClk[0] += (minute & 0x07) << 5; // minute

	tmpClk[1]  = (minute & 0x38) >> 3; // minute

	tmpClk[1] += (hour & 0x1F) << 3; // hour



	tmpClk[2]  = (day & 0x1F); //day

	tmpClk[2] += (month & 0x07) << 5; // month

	tmpClk[3]  = (month & 0x08) >> 3; // month

	tmpClk[3] += ((year-1980) & 0x7F) << 1; //year



	XPRINTF("year=%d, month=%d, day=%d   h=%d m=%d s=%d \n", year, month, day, hour, minute, sec);

	//set date & time of creation

	if (mode & DATE_CREATE) {

		dsfn->timeCreate[0] = tmpClk[0];

⌨️ 快捷键说明

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