亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? dosfs.c

?? 好用的FAT文件系統,兼容FAT12/16/32
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*
	DOSFS Embedded FAT-Compatible Filesystem
	(C) 2005 Lewin A.R.W. Edwards (sysadm@zws.com)

	You are permitted to modify and/or use this code in your own projects without
	payment of royalty, regardless of the license(s) you choose for those projects.

	You cannot re-copyright or restrict use of the code as released by Lewin Edwards.
*/

#include <string.h>
#include <stdlib.h>

#include "dosfs.h"

/*
	Get starting sector# of specified partition on drive #unit
	NOTE: This code ASSUMES an MBR on the disk.
	scratchsector should point to a SECTOR_SIZE scratch area
	Returns 0xffffffff for any error.
	If pactive is non-NULL, this function also returns the partition active flag.
	If pptype is non-NULL, this function also returns the partition type.
	If psize is non-NULL, this function also returns the partition size.
*/
uint32_t DFS_GetPtnStart(uint8_t unit, uint8_t *scratchsector, uint8_t pnum, uint8_t *pactive, uint8_t *pptype, uint32_t *psize)
{
	uint32_t result;
	PMBR mbr = (PMBR) scratchsector;

	// DOS ptable supports maximum 4 partitions
	if (pnum > 3)
		return DFS_ERRMISC;

	// Read MBR from target media
	if (DFS_ReadSector(unit,scratchsector,0,1)) {
		return DFS_ERRMISC;
	}

	result = (uint32_t) mbr->ptable[pnum].start_0 |
	  (((uint32_t) mbr->ptable[pnum].start_1) << 8) |
	  (((uint32_t) mbr->ptable[pnum].start_2) << 16) |
	  (((uint32_t) mbr->ptable[pnum].start_3) << 24);

	if (pactive)
		*pactive = mbr->ptable[pnum].active;

	if (pptype)
		*pptype = mbr->ptable[pnum].type;

	if (psize)
		*psize = (uint32_t) mbr->ptable[pnum].size_0 |
		  (((uint32_t) mbr->ptable[pnum].size_1) << 8) |
		  (((uint32_t) mbr->ptable[pnum].size_2) << 16) |
		  (((uint32_t) mbr->ptable[pnum].size_3) << 24);

	return result;
}


/*
	Retrieve volume info from BPB and store it in a VOLINFO structure
	You must provide the unit and starting sector of the filesystem, and
	a pointer to a sector buffer for scratch
	Attempts to read BPB and glean information about the FS from that.
	Returns 0 OK, nonzero for any error.
*/
uint32_t DFS_GetVolInfo(uint8_t unit, uint8_t *scratchsector, uint32_t startsector, PVOLINFO volinfo)
{
	PLBR lbr = (PLBR) scratchsector;
	volinfo->unit = unit;
	volinfo->startsector = startsector;

	if(DFS_ReadSector(unit,scratchsector,startsector,1))
		return DFS_ERRMISC;

// tag: OEMID, refer dosfs.h
//	strncpy(volinfo->oemid, lbr->oemid, 8);
//	volinfo->oemid[8] = 0;

	volinfo->secperclus = lbr->bpb.secperclus;
	volinfo->reservedsecs = (uint16_t) lbr->bpb.reserved_l |
		  (((uint16_t) lbr->bpb.reserved_h) << 8);

	volinfo->numsecs =  (uint16_t) lbr->bpb.sectors_s_l |
		  (((uint16_t) lbr->bpb.sectors_s_h) << 8);

	if (!volinfo->numsecs)
		volinfo->numsecs = (uint32_t) lbr->bpb.sectors_l_0 |
		  (((uint32_t) lbr->bpb.sectors_l_1) << 8) |
		  (((uint32_t) lbr->bpb.sectors_l_2) << 16) |
		  (((uint32_t) lbr->bpb.sectors_l_3) << 24);

	// If secperfat is 0, we must be in a FAT32 volume; get secperfat
	// from the FAT32 EBPB. The volume label and system ID string are also
	// in different locations for FAT12/16 vs FAT32.
	volinfo->secperfat =  (uint16_t) lbr->bpb.secperfat_l |
		  (((uint16_t) lbr->bpb.secperfat_h) << 8);
	if (!volinfo->secperfat) {
		volinfo->secperfat = (uint32_t) lbr->ebpb.ebpb32.fatsize_0 |
		  (((uint32_t) lbr->ebpb.ebpb32.fatsize_1) << 8) |
		  (((uint32_t) lbr->ebpb.ebpb32.fatsize_2) << 16) |
		  (((uint32_t) lbr->ebpb.ebpb32.fatsize_3) << 24);

		memcpy(volinfo->label, lbr->ebpb.ebpb32.label, 11);
		volinfo->label[11] = 0;
	
// tag: OEMID, refer dosfs.h
//		memcpy(volinfo->system, lbr->ebpb.ebpb32.system, 8);
//		volinfo->system[8] = 0; 
	}
	else {
		memcpy(volinfo->label, lbr->ebpb.ebpb.label, 11);
		volinfo->label[11] = 0;
	
// tag: OEMID, refer dosfs.h
//		memcpy(volinfo->system, lbr->ebpb.ebpb.system, 8);
//		volinfo->system[8] = 0; 
	}

	// note: if rootentries is 0, we must be in a FAT32 volume.
	volinfo->rootentries =  (uint16_t) lbr->bpb.rootentries_l |
		  (((uint16_t) lbr->bpb.rootentries_h) << 8);

	// after extracting raw info we perform some useful precalculations
	volinfo->fat1 = startsector + volinfo->reservedsecs;

	// The calculation below is designed to round up the root directory size for FAT12/16
	// and to simply ignore the root directory for FAT32, since it's a normal, expandable
	// file in that situation.
	if (volinfo->rootentries) {
		volinfo->rootdir = volinfo->fat1 + (volinfo->secperfat * 2);
		volinfo->dataarea = volinfo->rootdir + (((volinfo->rootentries * 32) + (SECTOR_SIZE - 1)) / SECTOR_SIZE);
	}
	else {
		volinfo->dataarea = volinfo->fat1 + (volinfo->secperfat * 2);
		volinfo->rootdir = (uint32_t) lbr->ebpb.ebpb32.root_0 |
		  (((uint32_t) lbr->ebpb.ebpb32.root_1) << 8) |
		  (((uint32_t) lbr->ebpb.ebpb32.root_2) << 16) |
		  (((uint32_t) lbr->ebpb.ebpb32.root_3) << 24);
	}

	// Calculate number of clusters in data area and infer FAT type from this information.
	volinfo->numclusters = (volinfo->numsecs - volinfo->dataarea) / volinfo->secperclus;
	if (volinfo->numclusters < 4085)
		volinfo->filesystem = FAT12;
	else if (volinfo->numclusters < 65525)
		volinfo->filesystem = FAT16;
	else
		volinfo->filesystem = FAT32;

	return DFS_OK;
}

/*
	Fetch FAT entry for specified cluster number
	You must provide a scratch buffer for one sector (SECTOR_SIZE) and a populated VOLINFO
	Returns a FAT32 BAD_CLUSTER value for any error, otherwise the contents of the desired
	FAT entry.
	scratchcache should point to a UINT32. This variable caches the physical sector number
	last read into the scratch buffer for performance enhancement reasons.
*/
uint32_t DFS_GetFAT(PVOLINFO volinfo, uint8_t *scratch, uint32_t *scratchcache, uint32_t cluster)
{
	uint32_t offset, sector, result;

	if (volinfo->filesystem == FAT12) {
		offset = cluster + (cluster / 2);
	}
	else if (volinfo->filesystem == FAT16) {
		offset = cluster * 2;
	}
	else if (volinfo->filesystem == FAT32) {
		offset = cluster * 4;
	}
	else
		return 0x0ffffff7;	// FAT32 bad cluster	

	// at this point, offset is the BYTE offset of the desired sector from the start
	// of the FAT. Calculate the physical sector containing this FAT entry.
	sector = ldiv(offset, SECTOR_SIZE).quot + volinfo->fat1;

	// If this is not the same sector we last read, then read it into RAM
	if (sector != *scratchcache) {
		if(DFS_ReadSector(volinfo->unit, scratch, sector, 1)) {
			// avoid anyone assuming that this cache value is still valid, which
			// might cause disk corruption
			*scratchcache = 0;
			return 0x0ffffff7;	// FAT32 bad cluster	
		}
		*scratchcache = sector;
	}

	// At this point, we "merely" need to extract the relevant entry.
	// This is easy for FAT16 and FAT32, but a royal PITA for FAT12 as a single entry
	// may span a sector boundary. The normal way around this is always to read two
	// FAT sectors, but that luxury is (by design intent) unavailable to DOSFS.
	offset = ldiv(offset, SECTOR_SIZE).rem;

	if (volinfo->filesystem == FAT12) {
		// Special case for sector boundary - Store last byte of current sector.
		// Then read in the next sector and put the first byte of that sector into
		// the high byte of result.
		if (offset == SECTOR_SIZE - 1) {
			result = (uint32_t) scratch[offset];
			sector++;
			if(DFS_ReadSector(volinfo->unit, scratch, sector, 1)) {
				// avoid anyone assuming that this cache value is still valid, which
				// might cause disk corruption
				*scratchcache = 0;
				return 0x0ffffff7;	// FAT32 bad cluster	
			}
			*scratchcache = sector;
			// Thanks to Claudio Leonel for pointing out this missing line.
			result |= ((uint32_t) scratch[0]) << 8;
		}
		else {
			result = (uint32_t) scratch[offset] |
			  ((uint32_t) scratch[offset+1]) << 8;
		}
		if (cluster & 1)
			result = result >> 4;
		else
			result = result & 0xfff;
	}
	else if (volinfo->filesystem == FAT16) {
		result = (uint32_t) scratch[offset] |
		  ((uint32_t) scratch[offset+1]) << 8;
	}
	else if (volinfo->filesystem == FAT32) {
		result = ((uint32_t) scratch[offset] |
		  ((uint32_t) scratch[offset+1]) << 8 |
		  ((uint32_t) scratch[offset+2]) << 16 |
		  ((uint32_t) scratch[offset+3]) << 24) & 0x0fffffff;
	}
	else
		result = 0x0ffffff7;	// FAT32 bad cluster	
	return result;
}


/*
	Set FAT entry for specified cluster number
	You must provide a scratch buffer for one sector (SECTOR_SIZE) and a populated VOLINFO
	Returns DFS_ERRMISC for any error, otherwise DFS_OK
	scratchcache should point to a UINT32. This variable caches the physical sector number
	last read into the scratch buffer for performance enhancement reasons.

	NOTE: This code is HIGHLY WRITE-INEFFICIENT, particularly for flash media. Considerable
	performance gains can be realized by caching the sector. However this is difficult to
	achieve on FAT12 without requiring 2 sector buffers of scratch space, and it is a design
	requirement of this code to operate on a single 512-byte scratch.

	If you are operating DOSFS over flash, you are strongly advised to implement a writeback
	cache in your physical I/O driver. This will speed up your code significantly and will
	also conserve power and flash write life.
*/
uint32_t DFS_SetFAT(PVOLINFO volinfo, uint8_t *scratch, uint32_t *scratchcache, uint32_t cluster, uint32_t new_contents)
{
	uint32_t offset, sector, result;
	if (volinfo->filesystem == FAT12) {
		offset = cluster + (cluster / 2);
		new_contents &=0xfff;
	}
	else if (volinfo->filesystem == FAT16) {
		offset = cluster * 2;
		new_contents &=0xffff;
	}
	else if (volinfo->filesystem == FAT32) {
		offset = cluster * 4;
		new_contents &=0x0fffffff;	// FAT32 is really "FAT28"
	}
	else
		return DFS_ERRMISC;	

	// at this point, offset is the BYTE offset of the desired sector from the start
	// of the FAT. Calculate the physical sector containing this FAT entry.
	sector = ldiv(offset, SECTOR_SIZE).quot + volinfo->fat1;

	// If this is not the same sector we last read, then read it into RAM
	if (sector != *scratchcache) {
		if(DFS_ReadSector(volinfo->unit, scratch, sector, 1)) {
			// avoid anyone assuming that this cache value is still valid, which
			// might cause disk corruption
			*scratchcache = 0;
			return DFS_ERRMISC;
		}
		*scratchcache = sector;
	}

	// At this point, we "merely" need to extract the relevant entry.
	// This is easy for FAT16 and FAT32, but a royal PITA for FAT12 as a single entry
	// may span a sector boundary. The normal way around this is always to read two
	// FAT sectors, but that luxury is (by design intent) unavailable to DOSFS.
	offset = ldiv(offset, SECTOR_SIZE).rem;

	if (volinfo->filesystem == FAT12) {

		// If this is an odd cluster, pre-shift the desired new contents 4 bits to
		// make the calculations below simpler
		if (cluster & 1)
			new_contents = new_contents << 4;

		// Special case for sector boundary
		if (offset == SECTOR_SIZE - 1) {

			// Odd cluster: High 12 bits being set
			if (cluster & 1) {
				scratch[offset] = (scratch[offset] & 0x0f) | new_contents & 0xf0;
			}
			// Even cluster: Low 12 bits being set
			else {
				scratch[offset] = new_contents & 0xff;
			}
			result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1);
			// mirror the FAT into copy 2
			if (DFS_OK == result)
				result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1);

			// If we wrote that sector OK, then read in the subsequent sector
			// and poke the first byte with the remainder of this FAT entry.
			if (DFS_OK == result) {
				*scratchcache++;
				result = DFS_ReadSector(volinfo->unit, scratch, *scratchcache, 1);
				if (DFS_OK == result) {
					// Odd cluster: High 12 bits being set
					if (cluster & 1) {
						scratch[0] = new_contents & 0xff00;
					}
					// Even cluster: Low 12 bits being set
					else {
						scratch[0] = (scratch[0] & 0xf0) | new_contents & 0x0f;
					}
					result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1);
					// mirror the FAT into copy 2
					if (DFS_OK == result)
						result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1);
				}
				else {
					// avoid anyone assuming that this cache value is still valid, which
					// might cause disk corruption
					*scratchcache = 0;
				}
			}
		} // if (offset == SECTOR_SIZE - 1)

		// Not a sector boundary. But we still have to worry about if it's an odd
		// or even cluster number.
		else {
			// Odd cluster: High 12 bits being set
			if (cluster & 1) {
				scratch[offset] = (scratch[offset] & 0x0f) | new_contents & 0xf0;
				scratch[offset+1] = new_contents & 0xff00;
			}
			// Even cluster: Low 12 bits being set
			else {
				scratch[offset] = new_contents & 0xff;
				scratch[offset+1] = (scratch[offset+1] & 0xf0) | new_contents & 0x0f;
			}
			result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1);
			// mirror the FAT into copy 2
			if (DFS_OK == result)
				result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1);
		}
	}
	else if (volinfo->filesystem == FAT16) {
		scratch[offset] = (new_contents & 0xff);
		scratch[offset+1] = (new_contents & 0xff00) >> 8;
		result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1);
		// mirror the FAT into copy 2
		if (DFS_OK == result)
			result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1);
	}
	else if (volinfo->filesystem == FAT32) {
		scratch[offset] = (new_contents & 0xff);
		scratch[offset+1] = (new_contents & 0xff00) >> 8;
		scratch[offset+2] = (new_contents & 0xff0000) >> 16;
		scratch[offset+3] = (scratch[offset+3] & 0xf0) | ((new_contents & 0x0f000000) >> 24);
		// Note well from the above: Per Microsoft's guidelines we preserve the upper
		// 4 bits of the FAT32 cluster value. It's unclear what these bits will be used
		// for; in every example I've encountered they are always zero.
		result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1);
		// mirror the FAT into copy 2
		if (DFS_OK == result)
			result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1);
	}
	else
		result = DFS_ERRMISC;

	return result;
}

/*
	Convert a filename element from canonical (8.3) to directory entry (11) form
	src must point to the first non-separator character.
	dest must point to a 12-byte buffer.
*/
uint8_t *DFS_CanonicalToDir(uint8_t *dest, uint8_t *src)
{
	uint8_t *destptr = dest;

	memset(dest, ' ', 11);
	dest[11] = 0;

	while (*src && (*src != DIR_SEPARATOR) && (destptr - dest < 11)) {
		if (*src >= 'a' && *src <='z') {
			*destptr++ = (*src - 'a') + 'A';
			src++;
		}
		else if (*src == '.') {
			src++;
			destptr = dest + 8;
		}
		else {
			*destptr++ = *src++;
		}
	}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美性色黄大片手机版| 亚洲女人的天堂| 欧美国产精品一区| 一区二区三区在线免费观看| 看片的网站亚洲| 91丝袜高跟美女视频| 91精品免费在线观看| 日本一区二区视频在线观看| 美女网站在线免费欧美精品| 色综合久久久网| 久久精品欧美日韩精品 | 日韩制服丝袜av| 成人黄色在线看| 欧美不卡在线视频| 亚洲电影一级片| 在线观看视频一区二区| 国产女人水真多18毛片18精品视频| 午夜精品爽啪视频| 欧洲视频一区二区| 亚洲伦理在线精品| 91原创在线视频| 亚洲精品一区二区三区99| 天使萌一区二区三区免费观看| 激情深爱一区二区| 奇米色777欧美一区二区| 一本久久综合亚洲鲁鲁五月天| 国产色91在线| 国产福利一区二区三区视频| 欧美成人福利视频| 老司机免费视频一区二区三区| 欧美日韩亚洲高清一区二区| 夜夜亚洲天天久久| 在线观看网站黄不卡| 亚洲国产日日夜夜| 欧美剧情片在线观看| 午夜精品成人在线| 日韩一区二区三区四区五区六区| 日韩国产精品久久久| 91精品国产一区二区三区香蕉| 视频一区二区中文字幕| 欧美一卡二卡三卡| 免费看黄色91| 26uuu另类欧美亚洲曰本| 国产精品白丝jk黑袜喷水| 国产午夜精品久久久久久久| 成人18视频在线播放| 一区二区三区中文在线| 欧美日本一道本| 免费欧美日韩国产三级电影| 欧美精品一区二区三区久久久| 国产一区激情在线| 中文字幕在线观看不卡视频| 欧美最猛性xxxxx直播| 日韩高清国产一区在线| 精品成人a区在线观看| 成人a级免费电影| 亚洲国产sm捆绑调教视频 | 精品国产91亚洲一区二区三区婷婷| 精品一区二区综合| 国产精品色哟哟| 欧美色涩在线第一页| 久久国内精品自在自线400部| 久久久亚洲国产美女国产盗摄 | 久久综合色鬼综合色| 国产精品一区二区果冻传媒| 国产精品久久久久久久久久免费看| 色综合久久综合网97色综合 | 日韩免费一区二区| av午夜精品一区二区三区| 亚洲成av人片在线观看| 国产老肥熟一区二区三区| 亚洲视频一区在线| 日韩亚洲欧美中文三级| 91丨九色丨尤物| 精品亚洲国产成人av制服丝袜| 亚洲欧美综合另类在线卡通| 91精品国产福利在线观看| 国产91精品在线观看| 午夜欧美在线一二页| 日本一区二区三区久久久久久久久不| 一本大道av一区二区在线播放 | 99re热视频精品| 美女视频一区在线观看| 亚洲三级电影网站| 久久精品日韩一区二区三区| 欧美精品久久天天躁| 99国产一区二区三精品乱码| 精品一区二区三区在线播放视频| 亚洲激情欧美激情| 一本色道久久综合狠狠躁的推荐 | 婷婷丁香激情综合| 亚洲欧洲国产日韩| 久久久99免费| 日韩一区二区在线观看视频| 在线观看成人小视频| 不卡一区二区中文字幕| 麻豆精品在线播放| 亚洲成人一二三| 亚洲精品国产无天堂网2021| 色妹子一区二区| 国产高清亚洲一区| 久久99久国产精品黄毛片色诱| 日韩一二三四区| 欧美色国产精品| 99re热视频精品| a在线播放不卡| 成年人午夜久久久| 不卡高清视频专区| 国产不卡视频在线播放| 毛片一区二区三区| 久久精品免费观看| 蜜桃视频在线观看一区| 日日摸夜夜添夜夜添精品视频| 日韩一区二区电影在线| 欧美一区欧美二区| 91精品国产色综合久久ai换脸| 欧美精三区欧美精三区| 精品视频1区2区| 91精品婷婷国产综合久久竹菊| 欧美日韩的一区二区| 91麻豆精品国产自产在线观看一区| 欧美色国产精品| 日韩欧美一区二区三区在线| 精品少妇一区二区三区| 精品国产电影一区二区| 国产亚洲一区二区在线观看| 中文字幕不卡的av| 亚洲女同一区二区| 91麻豆精品国产自产在线观看一区 | 亚洲桃色在线一区| 一区二区三区精品久久久| 亚洲午夜久久久久久久久久久| 亚洲一二三四久久| 日本怡春院一区二区| 久久精品国产第一区二区三区| 极品少妇一区二区| av一区二区三区在线| 欧美中文字幕一区二区三区 | 久久综合99re88久久爱| 欧美国产一区视频在线观看| 亚洲天堂精品视频| 午夜激情一区二区| 国产精品一区二区在线观看不卡| 成人免费视频caoporn| 欧美午夜理伦三级在线观看| 国产欧美日本一区二区三区| 日本乱人伦aⅴ精品| 在线播放一区二区三区| 国产欧美一区二区精品性| 亚洲视频免费观看| 蜜桃av噜噜一区| bt欧美亚洲午夜电影天堂| 欧美巨大另类极品videosbest | 日韩成人dvd| 成人精品视频一区二区三区尤物| 在线观看成人小视频| 精品粉嫩超白一线天av| 欧美少妇一区二区| www日韩大片| 亚洲国产精品麻豆| 国产乱码字幕精品高清av| 91黄视频在线| 国产亚洲美州欧州综合国| 伊人夜夜躁av伊人久久| 狠狠久久亚洲欧美| 91福利国产成人精品照片| 久久久亚洲欧洲日产国码αv| 亚洲精品少妇30p| 国产精品一区二区视频| 欧美一级片在线看| 亚洲欧美国产毛片在线| 国产精品一区二区久久不卡| 欧美肥妇毛茸茸| 亚洲乱码国产乱码精品精小说| 国产一区在线观看麻豆| 在线不卡中文字幕播放| 一区二区三区日韩欧美精品| 成人性生交大合| 精品剧情在线观看| 日韩av在线免费观看不卡| 色悠悠久久综合| 国产精品久久久久aaaa| 国产美女精品在线| 日韩欧美的一区| 免费成人美女在线观看.| 欧美视频中文字幕| 一区二区三区日本| 成人黄色小视频在线观看| 久久亚洲一区二区三区四区| 日韩黄色片在线观看| 日韩精品资源二区在线| 欧美伦理电影网| 亚洲电影第三页| 色猫猫国产区一区二在线视频| 亚洲精选视频在线| av网站一区二区三区| 亚洲色图清纯唯美| 99久久99久久精品免费看蜜桃 | 一区二区三区日韩欧美精品| 91极品美女在线|