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

📄 file.c

📁 linux下的DVD格式udf文件读取库
💻 C
📖 第 1 页 / 共 2 页
字号:
		fid->fileCharacteristics = fc;		fid->lengthFileIdent = length;		fid->lengthOfImpUse = cpu_to_le16(0);		memcpy(fid->fileIdent, name, length);		fid->descTag = udf_query_tag(disc, TAG_IDENT_FID, 1, le32_to_cpu(fid->descTag.tagLocation), data, ilength);		fe->informationLength = cpu_to_le64(le64_to_cpu(fe->informationLength) + ilength);	}	*(tag *)desc->data->buffer = query_tag(disc, pspace, desc, 1);	*(tag *)parent->data->buffer = query_tag(disc, pspace, parent, 1);}struct udf_desc *udf_create(struct udf_disc *disc, struct udf_extent *pspace, uint8_t *name, uint8_t length, uint32_t offset, struct udf_desc *parent, uint8_t filechar, uint8_t filetype, uint16_t flags){	struct udf_desc *desc;	if (disc->flags & FLAG_STRATEGY4096)		offset = udf_alloc_blocks(disc, pspace, offset, 2);	else		offset = udf_alloc_blocks(disc, pspace, offset, 1);	if (disc->flags & FLAG_EFE)	{		struct extendedFileEntry *efe;		desc = set_desc(disc, pspace, TAG_IDENT_EFE, offset, sizeof(struct extendedFileEntry), NULL);		efe = (struct extendedFileEntry *)desc->data->buffer;		memcpy(efe, &default_efe, sizeof(struct extendedFileEntry));		memcpy(&efe->accessTime, &disc->udf_pvd[0]->recordingDateAndTime, sizeof(timestamp));		memcpy(&efe->modificationTime, &efe->accessTime, sizeof(timestamp));		memcpy(&efe->attrTime, &efe->accessTime, sizeof(timestamp));		memcpy(&efe->createTime, &efe->accessTime, sizeof(timestamp));		if (filetype == ICBTAG_FILE_TYPE_STREAMDIR ||		    flags & ICBTAG_FLAG_STREAM)			efe->uniqueID = cpu_to_le64(0);		else		{			efe->uniqueID = cpu_to_le64(le64_to_cpu(((uint64_t *)disc->udf_lvid->logicalVolContentsUse)[0]));			if (!(le64_to_cpu(efe->uniqueID) & 0x00000000FFFFFFFFUL))				((uint64_t *)disc->udf_lvid->logicalVolContentsUse)[0] = cpu_to_le64(le64_to_cpu(efe->uniqueID) + 16);			else				((uint64_t *)disc->udf_lvid->logicalVolContentsUse)[0] = cpu_to_le64(le64_to_cpu(efe->uniqueID) + 1);		}		if (disc->flags & FLAG_STRATEGY4096)		{			efe->icbTag.strategyType = cpu_to_le16(4096);			efe->icbTag.strategyParameter = cpu_to_le16(1);			efe->icbTag.numEntries = cpu_to_le16(2);		}		if (parent)		{//			efe->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(parent->offset);			efe->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(0);			efe->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);			insert_fid(disc, pspace, desc, parent, name, length, filechar);		}		else		{			efe->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(0);			efe->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);		}		efe->icbTag.fileType = filetype;		efe->icbTag.flags = cpu_to_le16(le16_to_cpu(efe->icbTag.flags) | flags);		if (filetype == ICBTAG_FILE_TYPE_DIRECTORY)			query_lvidiu(disc)->numDirs = cpu_to_le32(le32_to_cpu(query_lvidiu(disc)->numDirs)+1);		else if (filetype != ICBTAG_FILE_TYPE_STREAMDIR && filetype != ICBTAG_FILE_TYPE_VAT20 && filetype != ICBTAG_FILE_TYPE_UNDEF && !(flags & ICBTAG_FLAG_STREAM))			query_lvidiu(disc)->numFiles = cpu_to_le32(le32_to_cpu(query_lvidiu(disc)->numFiles)+1);		efe->descTag = query_tag(disc, pspace, desc, 1);	}	else	{		struct fileEntry *fe;		desc = set_desc(disc, pspace, TAG_IDENT_FE, offset, sizeof(struct fileEntry), NULL);		fe = (struct fileEntry *)desc->data->buffer;		memcpy(fe, &default_fe, sizeof(struct fileEntry));		memcpy(&fe->accessTime, &disc->udf_pvd[0]->recordingDateAndTime, sizeof(timestamp));		memcpy(&fe->modificationTime, &fe->accessTime, sizeof(timestamp));		memcpy(&fe->attrTime, &fe->accessTime, sizeof(timestamp));		if (filetype == ICBTAG_FILE_TYPE_STREAMDIR ||		    flags & ICBTAG_FLAG_STREAM)			fe->uniqueID = cpu_to_le64(0);		else		{			fe->uniqueID = cpu_to_le64(le64_to_cpu(((uint64_t *)disc->udf_lvid->logicalVolContentsUse)[0]));			if (!(le64_to_cpu(fe->uniqueID) & 0x00000000FFFFFFFFUL))				((uint64_t *)disc->udf_lvid->logicalVolContentsUse)[0] = cpu_to_le64(le64_to_cpu(fe->uniqueID) + 16);			else				((uint64_t *)disc->udf_lvid->logicalVolContentsUse)[0] = cpu_to_le64(le64_to_cpu(fe->uniqueID) + 1);		}		if (disc->flags & FLAG_STRATEGY4096)		{			fe->icbTag.strategyType = cpu_to_le16(4096);			fe->icbTag.strategyParameter = cpu_to_le16(1);			fe->icbTag.numEntries = cpu_to_le16(2);		}		if (parent)		{//			fe->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(parent->offset);			fe->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(0);			fe->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);			insert_fid(disc, pspace, desc, parent, name, length, filechar);		}		else		{			fe->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(0);			fe->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);		}		fe->icbTag.fileType = filetype;		fe->icbTag.flags = cpu_to_le16(le16_to_cpu(fe->icbTag.flags) | flags);		if (filetype == ICBTAG_FILE_TYPE_DIRECTORY)			query_lvidiu(disc)->numDirs = cpu_to_le32(le32_to_cpu(query_lvidiu(disc)->numDirs)+1);		else if (filetype != ICBTAG_FILE_TYPE_STREAMDIR && filetype != ICBTAG_FILE_TYPE_VAT20 && filetype != ICBTAG_FILE_TYPE_UNDEF && !(flags & ICBTAG_FLAG_STREAM))			query_lvidiu(disc)->numFiles = cpu_to_le32(le32_to_cpu(query_lvidiu(disc)->numFiles)+1);		fe->descTag = query_tag(disc, pspace, desc, 1);	}	return desc;}struct udf_desc *udf_mkdir(struct udf_disc *disc, struct udf_extent *pspace, uint8_t *name, uint8_t length, uint32_t offset, struct udf_desc *parent){	struct udf_desc *desc;	desc = udf_create(disc, pspace, name, length, offset, parent, FID_FILE_CHAR_DIRECTORY, ICBTAG_FILE_TYPE_DIRECTORY, 0);	if (parent)		insert_fid(disc, pspace, parent, desc, NULL, 0, FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT);	else		insert_fid(disc, pspace, desc, desc, NULL, 0, FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT);		return desc;}#define BITS_PER_LONG 32#define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)#define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)#define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))#define uintBPL uint(BITS_PER_LONG)#define uint(x) xuint(x)#define xuint(x) uint ## x ## _tinline unsigned long ffz(unsigned long word){	unsigned long result;	result = 0;	while (word & 1)	{		result ++;		word >>= 1;	}	return result;}inline unsigned long udf_find_next_one_bit (void * addr, unsigned long size, unsigned long offset){	uintBPL * p = ((uintBPL *) addr) + (offset / BITS_PER_LONG);	uintBPL result = offset & ~(BITS_PER_LONG-1);	uintBPL tmp;	if (offset >= size)		return size;	size -= result;	offset &= (BITS_PER_LONG-1);	if (offset)	{		tmp = leBPL_to_cpup(p++);		tmp &= ~0UL << offset;		if (size < BITS_PER_LONG)			goto found_first;		if (tmp)			goto found_middle;		size -= BITS_PER_LONG;		result += BITS_PER_LONG;	}	while (size & ~(BITS_PER_LONG-1))	{		if ((tmp = leBPL_to_cpup(p++)))			goto found_middle;		result += BITS_PER_LONG;		size -= BITS_PER_LONG;	}	if (!size)		return result;	tmp = leBPL_to_cpup(p);found_first:	tmp &= ~0UL >> (BITS_PER_LONG-size);found_middle:	return result + ffz(~tmp);}inline unsigned long udf_find_next_zero_bit(void * addr, unsigned long size, unsigned long offset){	uintBPL * p = ((uintBPL *) addr) + (offset / BITS_PER_LONG);	uintBPL result = offset & ~(BITS_PER_LONG-1);	uintBPL tmp;	if (offset >= size)		return size;	size -= result;	offset &= (BITS_PER_LONG-1);	if (offset)	{		tmp = leBPL_to_cpup(p++);		tmp |= (~0UL >> (BITS_PER_LONG-offset));		if (size < BITS_PER_LONG)			goto found_first;		if (~tmp)			goto found_middle;		size -= BITS_PER_LONG;		result += BITS_PER_LONG;	}	while (size & ~(BITS_PER_LONG-1))	{		if (~(tmp = leBPL_to_cpup(p++)))			goto found_middle;		result += BITS_PER_LONG;		size -= BITS_PER_LONG;	}	if (!size)		return result;	tmp = leBPL_to_cpup(p);found_first:	tmp |= (~0UL << size);	if (tmp == ~0UL)	/* Are any bits zero? */		return result + size; /* Nope. */found_middle:	return result + ffz(tmp);}int udf_alloc_bitmap_blocks(struct udf_disc *disc, struct udf_extent *pspace, struct udf_desc *bitmap, uint32_t start, uint32_t blocks){	uint32_t alignment = disc->sizing[PSPACE_SIZE].align;	struct spaceBitmapDesc *sbd = (struct spaceBitmapDesc *)bitmap->data->buffer;	uint32_t end;	do	{		start = ((start + alignment - 1) / alignment) * alignment;		if (sbd->bitmap[start/8] & (1 << (start%8)))		{			end = udf_find_next_zero_bit(sbd->bitmap, sbd->numOfBits, start);		}		else			start = end = udf_find_next_one_bit(sbd->bitmap, sbd->numOfBits, start);	} while ((end - start) <= blocks);	clear_bits(sbd->bitmap, start, blocks);	return start;}int udf_alloc_table_blocks(struct udf_disc *disc, struct udf_extent *pspace, struct udf_desc *table, uint32_t start, uint32_t blocks){	uint32_t alignment = disc->sizing[PSPACE_SIZE].align;	struct unallocSpaceEntry *use = (struct unallocSpaceEntry *)table->data->buffer;	uint32_t end, offset = 0;	short_ad *sad;	do	{		sad = (short_ad *)&use->allocDescs[offset];		if (start < le32_to_cpu(sad->extPosition))			start = le32_to_cpu(sad->extPosition);		start = ((start + alignment - 1) / alignment) * alignment;		end = le32_to_cpu(sad->extPosition) + ((le32_to_cpu(sad->extLength) & 0x3FFFFFFF) >> disc->blocksize_bits);		if (start > end)			start = end;		offset += sizeof(short_ad);	} while ((end - start) < blocks);	if (start == le32_to_cpu(sad->extPosition) && start + blocks == end)	{		/* deleted extent */		memmove(&use->allocDescs[offset-sizeof(short_ad)],			&use->allocDescs[offset],			le32_to_cpu(use->lengthAllocDescs) - offset);		use->lengthAllocDescs = cpu_to_le32(le32_to_cpu(use->lengthAllocDescs) - sizeof(short_ad));		memset(&use->allocDescs[le32_to_cpu(use->lengthAllocDescs)], 0x00, sizeof(short_ad));	}	else if (start == le32_to_cpu(sad->extPosition))	{		sad->extPosition = cpu_to_le32(start + blocks);		sad->extLength = cpu_to_le32(le32_to_cpu(sad->extLength) - blocks * disc->blocksize);	}	else if (start + blocks == end)	{		sad->extLength = cpu_to_le32(le32_to_cpu(sad->extLength) - blocks * disc->blocksize);	}	else	{		memmove(&use->allocDescs[offset+sizeof(short_ad)],			&use->allocDescs[offset],			le32_to_cpu(use->lengthAllocDescs) - offset);		sad->extLength = cpu_to_le32(EXT_NOT_RECORDED_ALLOCATED | (start - le32_to_cpu(sad->extPosition)) * disc->blocksize);		sad = (short_ad *)&use->allocDescs[offset];		sad->extPosition = cpu_to_le32(start+blocks);		sad->extLength = cpu_to_le32(EXT_NOT_RECORDED_ALLOCATED | (end - start - blocks) * disc->blocksize);		use->lengthAllocDescs = cpu_to_le32(le32_to_cpu(use->lengthAllocDescs) + sizeof(short_ad));	}	use->descTag = udf_query_tag(disc, TAG_IDENT_USE, 1, table->offset, table->data, sizeof(struct unallocSpaceEntry) + le32_to_cpu(use->lengthAllocDescs));	return start;}int udf_alloc_blocks(struct udf_disc *disc, struct udf_extent *pspace, uint32_t start, uint32_t blocks){	struct udf_desc *desc;	struct partitionHeaderDesc *phd = (struct partitionHeaderDesc *)disc->udf_pd[0]->partitionContentsUse;	disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - blocks);	if (disc->flags & FLAG_FREED_BITMAP)	{		desc = find_desc(pspace, le32_to_cpu(phd->freedSpaceBitmap.extPosition));		return udf_alloc_bitmap_blocks(disc, pspace, desc, start, blocks);	}	else if (disc->flags & FLAG_FREED_TABLE)	{		desc = find_desc(pspace, le32_to_cpu(phd->freedSpaceTable.extPosition));		return udf_alloc_table_blocks(disc, pspace, desc, start, blocks);	}	else if (disc->flags & FLAG_UNALLOC_BITMAP)	{		desc = find_desc(pspace, le32_to_cpu(phd->unallocSpaceBitmap.extPosition));		return udf_alloc_bitmap_blocks(disc, pspace, desc, start, blocks);	}	else if (disc->flags & FLAG_UNALLOC_TABLE)	{		desc = find_desc(pspace, le32_to_cpu(phd->unallocSpaceTable.extPosition));		return udf_alloc_table_blocks(disc, pspace, desc, start, blocks);	}	else if (disc->flags & FLAG_VAT)	{		int offset = 0, length = 0;		if (pspace->tail)		{			offset = pspace->tail->offset;			length = (pspace->tail->length + disc->blocksize - 1) >>				disc->blocksize_bits;		}		if (offset + length > start)			start = offset + length;		disc->vat[disc->vat_entries++] = start;		return start;	}	else		return 0;}

⌨️ 快捷键说明

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