📄 mkudffs.c
字号:
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 + -