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

📄 mkudffs.c

📁 linux下的DVD格式udf文件读取库
💻 C
📖 第 1 页 / 共 3 页
字号:
	ext = next_extent(disc->head, ANCHOR);	do	{		ext->head = ext->tail = malloc(sizeof(struct udf_desc) + sizeof(struct udf_data));		ext->head->data = (struct udf_data *)&(ext->head)[1];		ext->head->data->next = ext->head->data->prev = NULL;		ext->head->ident = TAG_IDENT_AVDP;		ext->head->offset = 0;		ext->head->length = ext->head->data->length = sizeof(struct anchorVolDescPtr);		disc->udf_anchor[i] = ext->head->data->buffer = malloc(sizeof(struct anchorVolDescPtr));		ext->head->next = ext->head->prev = NULL;		disc->udf_anchor[i]->mainVolDescSeqExt.extLocation = cpu_to_le32(mloc);		disc->udf_anchor[i]->mainVolDescSeqExt.extLength = cpu_to_le32(mlen);		disc->udf_anchor[i]->reserveVolDescSeqExt.extLocation = cpu_to_le32(rloc);		disc->udf_anchor[i]->reserveVolDescSeqExt.extLength = cpu_to_le32(rlen);		disc->udf_anchor[i]->descTag = query_tag(disc, ext, ext->head, 1);		ext = next_extent(ext->next, ANCHOR);	} while (i++, ext != NULL);}void setup_partition(struct udf_disc *disc){	struct udf_extent *vat, *pspace;	pspace = next_extent(disc->head, PSPACE);	setup_space(disc, pspace, 0);	setup_fileset(disc, pspace);	setup_root(disc, pspace);	if (disc->flags & FLAG_VAT)		setup_vat(disc, pspace);}int setup_space(struct udf_disc *disc, struct udf_extent *pspace, uint32_t offset){	struct udf_desc *desc;	struct partitionHeaderDesc *phd = (struct partitionHeaderDesc *)disc->udf_pd[0]->partitionContentsUse;	int length = (((sizeof(struct spaceBitmapDesc) + pspace->blocks) >> (disc->blocksize_bits + 3)) + 1) << disc->blocksize_bits;	if (disc->flags & FLAG_FREED_BITMAP)	{		phd->freedSpaceBitmap.extPosition = cpu_to_le32(offset);		phd->freedSpaceBitmap.extLength = cpu_to_le32(length);		disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - (length >> disc->blocksize_bits));	}	else if (disc->flags & FLAG_FREED_TABLE)	{		phd->freedSpaceTable.extPosition = cpu_to_le32(offset);		if (disc->flags & FLAG_STRATEGY4096)		{			phd->freedSpaceTable.extLength = cpu_to_le32(disc->blocksize * 2);			disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 2);		}		else		{			phd->freedSpaceTable.extLength = cpu_to_le32(disc->blocksize);			disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 1);		}	}	else if (disc->flags & FLAG_UNALLOC_BITMAP)	{		phd->unallocSpaceBitmap.extPosition = cpu_to_le32(offset);		phd->unallocSpaceBitmap.extLength = cpu_to_le32(length);		disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - (length >> disc->blocksize_bits));	}	else if (disc->flags & FLAG_UNALLOC_TABLE)	{		phd->unallocSpaceTable.extPosition = cpu_to_le32(offset);		if (disc->flags & FLAG_STRATEGY4096)		{			phd->unallocSpaceTable.extLength = cpu_to_le32(disc->blocksize * 2);			disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 2);		}		else		{			phd->unallocSpaceTable.extLength = cpu_to_le32(disc->blocksize);			disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 1);		}	}	if (disc->flags & FLAG_SPACE_BITMAP)	{		struct spaceBitmapDesc *sbd;		int nBytes = (pspace->blocks+7)/8;		length = sizeof(struct spaceBitmapDesc) + nBytes;		desc = set_desc(disc, pspace, TAG_IDENT_SBD, offset, length, NULL);		sbd = (struct spaceBitmapDesc *)desc->data->buffer;		sbd->numOfBits = cpu_to_le32(pspace->blocks);		sbd->numOfBytes = cpu_to_le32(nBytes);		memset(sbd->bitmap, 0xFF, sizeof(uint8_t) * nBytes);		if (pspace->blocks%8)			sbd->bitmap[nBytes-1] = 0xFF >> (8-(pspace->blocks%8));		clear_bits(sbd->bitmap, offset, (length + disc->blocksize - 1) >> disc->blocksize_bits);		sbd->descTag = udf_query_tag(disc, TAG_IDENT_SBD, 1, desc->offset, desc->data, sizeof(tag));	}	else if (disc->flags & FLAG_SPACE_TABLE)	{		struct unallocSpaceEntry *use;		short_ad *sad;		int max = (0x3FFFFFFF / disc->blocksize) * disc->blocksize;		int pos;		long long rem;		if (disc->flags & FLAG_STRATEGY4096)			length = disc->blocksize * 2;		else			length = disc->blocksize;		desc = set_desc(disc, pspace, TAG_IDENT_USE, offset, disc->blocksize, NULL);		use = (struct unallocSpaceEntry *)desc->data->buffer;		use->lengthAllocDescs = cpu_to_le32(sizeof(short_ad));		sad = (short_ad *)&use->allocDescs[0];		rem = (long long)pspace->blocks * disc->blocksize - length;		if (disc->blocksize - sizeof(struct unallocSpaceEntry) < (rem / max) * sizeof(short_ad))		pos = offset + (length/disc->blocksize);		printf("pos=%d, rem=%lld\n", pos, rem);		if (rem > 0x3FFFFFFF)		{			while (rem > max)			{				sad->extLength = cpu_to_le32(EXT_NOT_RECORDED_ALLOCATED | max);				sad->extPosition = cpu_to_le32(pos);				pos += max / disc->blocksize;				sad ++;				rem -= max;				use->lengthAllocDescs = cpu_to_le32(le32_to_cpu(use->lengthAllocDescs) + sizeof(short_ad));			}		}		sad->extLength = cpu_to_le32(EXT_NOT_RECORDED_ALLOCATED | rem);		sad->extPosition = cpu_to_le32(pos);		if (disc->flags & FLAG_STRATEGY4096)		{			use->icbTag.strategyType = cpu_to_le16(4096);			use->icbTag.strategyParameter = cpu_to_le16(1);			use->icbTag.numEntries = cpu_to_le16(2);		}		else		{			use->icbTag.strategyType = cpu_to_le16(4);			use->icbTag.numEntries = cpu_to_le16(1);		}		use->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(0);		use->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);		use->icbTag.fileType = ICBTAG_FILE_TYPE_USE;		use->icbTag.flags = cpu_to_le16(ICBTAG_FLAG_AD_SHORT);		use->descTag = udf_query_tag(disc, TAG_IDENT_USE, 1, desc->offset, desc->data, sizeof(struct unallocSpaceEntry) + le32_to_cpu(use->lengthAllocDescs));		if (disc->flags & FLAG_STRATEGY4096)		{			struct udf_desc *tdesc;			struct terminalEntry *te;			if (disc->flags & FLAG_BLANK_TERMINAL)			{//				tdesc = set_desc(disc, pspace, TAG_IDENT_IE, offset+1, sizeof(struct indirectEntry), NULL);			}			else			{				tdesc = set_desc(disc, pspace, TAG_IDENT_TE, offset+1, sizeof(struct terminalEntry), NULL);				te = (struct terminalEntry *)tdesc->data->buffer;				te->icbTag.priorRecordedNumDirectEntries = cpu_to_le32(1);				te->icbTag.strategyType = cpu_to_le16(4096);				te->icbTag.strategyParameter = cpu_to_le16(1);				te->icbTag.numEntries = cpu_to_le16(2);				te->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(desc->offset);				te->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);				te->icbTag.fileType = ICBTAG_FILE_TYPE_TE;				te->descTag = query_tag(disc, pspace, tdesc, 1);			}		}	}	return (length + disc->blocksize - 1) >> disc->blocksize_bits;}int setup_fileset(struct udf_disc *disc, struct udf_extent *pspace){	uint32_t offset = 0;	struct udf_desc *desc;	int length = sizeof(struct fileSetDesc);	offset = udf_alloc_blocks(disc, pspace, offset, 1);	((long_ad *)disc->udf_lvd[0]->logicalVolContentsUse)->extLength = cpu_to_le32(disc->blocksize);	((long_ad *)disc->udf_lvd[0]->logicalVolContentsUse)->extLocation.logicalBlockNum = cpu_to_le32(offset);	((long_ad *)disc->udf_lvd[0]->logicalVolContentsUse)->extLocation.partitionReferenceNum = cpu_to_le16(0);//	((uint16_t *)disc->udf_fsd->domainIdent.identSuffix)[0] = cpu_to_le16(disc->udf_rev);	desc = set_desc(disc, pspace, TAG_IDENT_FSD, offset, 0, NULL);	desc->length = desc->data->length = length;	desc->data->buffer = disc->udf_fsd;	if (!(disc->flags & FLAG_VAT) && disc->udf_rev >= 0x0200)	{		struct udf_desc *ss;		ss = udf_create(disc, pspace, NULL, 0, offset+1, NULL, FID_FILE_CHAR_DIRECTORY, ICBTAG_FILE_TYPE_STREAMDIR, 0);		insert_fid(disc, pspace, ss, ss, NULL, 0, FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT);		offset = ss->offset;		disc->udf_fsd->streamDirectoryICB.extLength = cpu_to_le32(disc->blocksize);		disc->udf_fsd->streamDirectoryICB.extLocation.logicalBlockNum = cpu_to_le32(offset);		disc->udf_fsd->streamDirectoryICB.extLocation.partitionReferenceNum = cpu_to_le16(0);			}	disc->udf_fsd->descTag = query_tag(disc, pspace, desc, 1);	return (length + disc->blocksize - 1) >> disc->blocksize_bits;}int setup_root(struct udf_disc *disc, struct udf_extent *pspace){	uint32_t offset = 0;	struct udf_desc *desc, *fsd_desc, *tdesc;	struct terminalEntry *te;	desc = udf_mkdir(disc, pspace, NULL, 0, offset, NULL);	offset = desc->offset;	if (disc->flags & FLAG_STRATEGY4096)		disc->udf_fsd->rootDirectoryICB.extLength = cpu_to_le32(disc->blocksize * 2);	else		disc->udf_fsd->rootDirectoryICB.extLength = cpu_to_le32(disc->blocksize);	disc->udf_fsd->rootDirectoryICB.extLocation.logicalBlockNum = cpu_to_le32(offset);	disc->udf_fsd->rootDirectoryICB.extLocation.partitionReferenceNum = cpu_to_le16(0);	fsd_desc = next_desc(pspace->head, TAG_IDENT_FSD);	disc->udf_fsd->descTag = query_tag(disc, pspace, fsd_desc, 1);	if (disc->flags & FLAG_STRATEGY4096)	{		if (disc->flags & FLAG_BLANK_TERMINAL)		{//			tdesc = set_desc(disc, pspace, TAG_IDENT_IE, offset+1, sizeof(struct indirectEntry), NULL);			offset ++;		}		else		{			tdesc = set_desc(disc, pspace, TAG_IDENT_TE, offset+1, sizeof(struct terminalEntry), NULL);			te = (struct terminalEntry *)tdesc->data->buffer;			te->icbTag.priorRecordedNumDirectEntries = cpu_to_le32(1);			te->icbTag.strategyType = cpu_to_le16(4096);			te->icbTag.strategyParameter = cpu_to_le16(1);			te->icbTag.numEntries = cpu_to_le16(2);			te->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(desc->offset);			te->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);			te->icbTag.fileType = ICBTAG_FILE_TYPE_TE;			te->descTag = query_tag(disc, pspace, tdesc, 1);			offset = tdesc->offset;		}	}	if (next_extent(disc->head, STABLE) && next_extent(disc->head, SSPACE))	{		struct udf_desc *nat;		if (disc->udf_rev == 0x0150)		{			struct fileEntry *fe;			nat = udf_create(disc, pspace, "\x08" "Non-Allocatable Space", 22, offset+1, desc, FID_FILE_CHAR_HIDDEN, ICBTAG_FILE_TYPE_REGULAR, ICBTAG_FLAG_SYSTEM);			fe = (struct fileEntry *)nat->data->buffer;			fe->icbTag.flags = cpu_to_le16((le16_to_cpu(fe->icbTag.flags) & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_SHORT);			fe->descTag = query_tag(disc, pspace, nat, 1);			offset = nat->offset;		}		else		{			struct extendedFileEntry *efe;			struct udf_desc *ss;			ss = find_desc(pspace, le32_to_cpu(disc->udf_fsd->streamDirectoryICB.extLocation.logicalBlockNum));#if 0			nat = udf_create(disc, pspace, NULL, 0, offset+1, NULL, FID_FILE_CHAR_DIRECTORY, ICBTAG_FILE_TYPE_STREAMDIR, 0);			insert_fid(disc, pspace, nat, nat, NULL, 0, FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT);			offset = nat->offset;			disc->udf_fsd->streamDirectoryICB.extLength = cpu_to_le32(disc->blocksize);			disc->udf_fsd->streamDirectoryICB.extLocation.logicalBlockNum = cpu_to_le32(offset);			disc->udf_fsd->streamDirectoryICB.extLocation.partitionReferenceNum = cpu_to_le16(0);#endif			nat = udf_create(disc, pspace, "\x08" "*UDF Non-Allocatable Space", 27, offset+1, ss, FID_FILE_CHAR_METADATA, ICBTAG_FILE_TYPE_REGULAR, ICBTAG_FLAG_STREAM | ICBTAG_FLAG_SYSTEM);			efe = (struct extendedFileEntry *)nat->data->buffer;			efe->icbTag.flags = cpu_to_le16((le16_to_cpu(efe->icbTag.flags) & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_SHORT);			efe->descTag = query_tag(disc, pspace, nat, 1);			offset = nat->offset;		}	}	desc = udf_mkdir(disc, pspace, "\x08" "lost+found", 11, offset+1, desc);	offset = desc->offset;	if (disc->flags & FLAG_STRATEGY4096)	{		if (disc->flags & FLAG_BLANK_TERMINAL)		{//			tdesc = set_desc(disc, pspace, TAG_IDENT_IE, offset+1, sizeof(struct indirectEntry), NULL);			offset ++;		}		else		{			tdesc = set_desc(disc, pspace, TAG_IDENT_TE, offset+1, sizeof(struct terminalEntry), NULL);			te = (struct terminalEntry *)tdesc->data->buffer;			te->icbTag.priorRecordedNumDirectEntries = cpu_to_le32(1);			te->icbTag.strategyType = cpu_to_le16(4096);			te->icbTag.strategyParameter = cpu_to_le16(1);			te->icbTag.numEntries = cpu_to_le16(2);			te->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(desc->offset);			te->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);			te->icbTag.fileType = ICBTAG_FILE_TYPE_TE;			te->descTag = query_tag(disc, pspace, tdesc, 1);			offset = tdesc->offset;		}	}	if (disc->flags & FLAG_STRATEGY4096)		return 4;	else		return 2;}void setup_vds(struct udf_disc *disc){	struct udf_extent *pvds, *rvds, *lvid, *stable[4], *sspace;	pvds = next_extent(disc->head, PVDS);	rvds = next_extent(disc->head, RVDS);	lvid = next_extent(disc->head, LVID);	stable[0] = next_extent(disc->head, STABLE);	sspace = next_extent(disc->head, SSPACE);	setup_pvd(disc, pvds, rvds, 0);	setup_lvid(disc, lvid);	if (stable[0] && sspace)	{		int i;		for (i=1; i<4 && stable[i-1]; i++)		{			stable[i] = next_extent(stable[i-1]->next, STABLE);		}		setup_stable(disc, stable, sspace);	}	setup_lvd(disc, pvds, rvds, lvid, 1);	setup_pd(disc, pvds, rvds, 2);	setup_usd(disc, pvds, rvds, 3);	setup_iuvd(disc, pvds, rvds, 4);	if (pvds->blocks > 5)		setup_td(disc, pvds, rvds, 5);}

⌨️ 快捷键说明

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