📄 mkudffs.c
字号:
/* * mkudffs.c * * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu> * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <malloc.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <time.h>#include <sys/time.h>#include <errno.h>#include "mkudffs.h"#include "defaults.h"#include "config.h"void udf_init_disc(struct udf_disc *disc){ timestamp ts; struct timeval tv; struct tm *tm; int altzone; memset(disc, 0x00, sizeof(disc)); disc->blocksize = 2048; disc->blocksize_bits = 11; disc->udf_rev = le16_to_cpu(default_lvidiu.minUDFReadRev); disc->flags = FLAG_UTF8 | FLAG_CLOSED; if (disc->udf_rev >= 0x0200) disc->flags |= FLAG_EFE; gettimeofday(&tv, NULL); tm = localtime(&tv.tv_sec); altzone = timezone - 3600; if (daylight) ts.typeAndTimezone = cpu_to_le16(((-altzone/60) & 0x0FFF) | 0x1000); else ts.typeAndTimezone = cpu_to_le16(((-timezone/60) & 0x0FFF) | 0x1000); ts.year = cpu_to_le16(1900 + tm->tm_year); ts.month = 1 + tm->tm_mon; ts.day = tm->tm_mday; ts.hour = tm->tm_hour; ts.minute = tm->tm_min; ts.second = tm->tm_sec; ts.centiseconds = tv.tv_usec / 10000; ts.hundredsOfMicroseconds = (tv.tv_usec - ts.centiseconds * 10000) / 100; ts.microseconds = tv.tv_usec - ts.centiseconds * 10000 - ts.hundredsOfMicroseconds * 100; /* Allocate/Initialize Descriptors */ disc->udf_pvd[0] = malloc(sizeof(struct primaryVolDesc)); memcpy(disc->udf_pvd[0], &default_pvd, sizeof(struct primaryVolDesc)); memcpy(&disc->udf_pvd[0]->recordingDateAndTime, &ts, sizeof(timestamp)); sprintf(&disc->udf_pvd[0]->volSetIdent[1], "%08lx%s", mktime(tm), &disc->udf_pvd[0]->volSetIdent[9]); disc->udf_pvd[0]->volIdent[31] = strlen(disc->udf_pvd[0]->volIdent); disc->udf_pvd[0]->volSetIdent[127] = strlen(disc->udf_pvd[0]->volSetIdent); disc->udf_lvd[0] = malloc(sizeof(struct logicalVolDesc)); memcpy(disc->udf_lvd[0], &default_lvd, sizeof(struct logicalVolDesc)); disc->udf_lvd[0]->logicalVolIdent[127] = strlen(disc->udf_lvd[0]->logicalVolIdent); disc->udf_pd[0] = malloc(sizeof(struct partitionDesc)); memcpy(disc->udf_pd[0], &default_pd, sizeof(struct partitionDesc)); disc->udf_usd[0] = malloc(sizeof(struct unallocSpaceDesc)); memcpy(disc->udf_usd[0], &default_usd, sizeof(struct unallocSpaceDesc)); disc->udf_iuvd[0] = malloc(sizeof(struct impUseVolDesc) + sizeof(struct impUseVolDescImpUse)); memcpy(disc->udf_iuvd[0], &default_iuvd, sizeof(struct impUseVolDesc)); memcpy(query_iuvdiu(disc), &default_iuvdiu, sizeof(struct impUseVolDescImpUse)); query_iuvdiu(disc)->logicalVolIdent[127] = strlen(query_iuvdiu(disc)->logicalVolIdent); query_iuvdiu(disc)->LVInfo1[35] = strlen(query_iuvdiu(disc)->LVInfo1); query_iuvdiu(disc)->LVInfo2[35] = strlen(query_iuvdiu(disc)->LVInfo2); query_iuvdiu(disc)->LVInfo3[35] = strlen(query_iuvdiu(disc)->LVInfo3); disc->udf_td[0] = malloc(sizeof(struct terminatingDesc)); memcpy(disc->udf_td[0], &default_td, sizeof(struct terminatingDesc)); disc->udf_lvid = malloc(sizeof(struct logicalVolIntegrityDesc) + sizeof(struct logicalVolIntegrityDescImpUse)); memcpy(disc->udf_lvid, &default_lvid, sizeof(struct logicalVolIntegrityDesc)); memcpy(&disc->udf_lvid->recordingDateAndTime, &ts, sizeof(timestamp)); memcpy(query_lvidiu(disc), &default_lvidiu, sizeof(struct logicalVolIntegrityDescImpUse)); disc->udf_stable[0] = malloc(sizeof(struct sparingTable)); memcpy(disc->udf_stable[0], &default_stable, sizeof(struct sparingTable)); disc->vat = calloc(1, disc->blocksize); disc->vat_entries = 0; disc->udf_fsd = malloc(sizeof(struct fileSetDesc)); memcpy(disc->udf_fsd, &default_fsd, sizeof(struct fileSetDesc)); memcpy(&disc->udf_fsd->recordingDateAndTime, &ts, sizeof(timestamp)); disc->udf_fsd->logicalVolIdent[127] = strlen(disc->udf_fsd->logicalVolIdent); disc->udf_fsd->fileSetIdent[31] = strlen(disc->udf_fsd->fileSetIdent); disc->udf_fsd->copyrightFileIdent[31] = strlen(disc->udf_fsd->copyrightFileIdent); disc->udf_fsd->abstractFileIdent[31] = strlen(disc->udf_fsd->abstractFileIdent); disc->head = malloc(sizeof(struct udf_extent)); disc->tail = disc->head; disc->head->space_type = USPACE; disc->head->start = 0; disc->head->next = NULL; disc->head->prev = NULL;}int udf_set_version(struct udf_disc *disc, int udf_rev){ struct logicalVolIntegrityDescImpUse *lvidiu; if (disc->udf_rev == udf_rev) return 0; else if (udf_rev != 0x0102 && udf_rev != 0x0150 && udf_rev != 0x0200 && udf_rev != 0x0201 && udf_rev != 0x0250) { return 1; } else disc->udf_rev = udf_rev; if (disc->udf_rev < 0x0200) { disc->flags &= ~FLAG_EFE; strcpy(disc->udf_pd[0]->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02); } else { disc->flags |= FLAG_EFE; strcpy(disc->udf_pd[0]->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03); } ((uint16_t *)disc->udf_fsd->domainIdent.identSuffix)[0] = cpu_to_le16(udf_rev); ((uint16_t *)disc->udf_lvd[0]->domainIdent.identSuffix)[0] = cpu_to_le16(udf_rev); ((uint16_t *)disc->udf_iuvd[0]->impIdent.identSuffix)[0] = le16_to_cpu(udf_rev); lvidiu = query_lvidiu(disc); lvidiu->minUDFReadRev = le16_to_cpu(udf_rev); lvidiu->minUDFWriteRev = le16_to_cpu(udf_rev); lvidiu->maxUDFWriteRev = le16_to_cpu(udf_rev); ((uint16_t *)disc->udf_stable[0]->sparingIdent.identSuffix)[0] = le16_to_cpu(udf_rev); return 0;}void split_space(struct udf_disc *disc){ uint32_t sizes[UDF_ALLOC_TYPE_SIZE]; uint32_t offsets[UDF_ALLOC_TYPE_SIZE]; uint32_t blocks = disc->head->blocks; uint32_t start, size; struct sparablePartitionMap *spm; struct udf_extent *ext; int i, j; if (disc->flags & FLAG_BRIDGE) { set_extent(disc, RESERVED, 0, 512); set_extent(disc, ANCHOR, 512, 1); } else { set_extent(disc, RESERVED, 0, 32768 / disc->blocksize); if (disc->blocksize >= 2048) set_extent(disc, VRS, (2048 * 16) / disc->blocksize, 3); else set_extent(disc, VRS, (2048 * 16) / disc->blocksize, ((2048 * 3) + disc->blocksize - 1) / disc->blocksize); set_extent(disc, ANCHOR, 256, 1); } if (disc->flags & FLAG_CLOSED) set_extent(disc, ANCHOR, blocks-257, 1); if (!(disc->flags & FLAG_VAT)) set_extent(disc, ANCHOR, blocks-1, 1); else set_extent(disc, PSPACE, blocks-1, 1); for (i=0; i<UDF_ALLOC_TYPE_SIZE; i++) { sizes[i] = disc->sizing[i].numSize * blocks / disc->sizing[i].denomSize; if (disc->sizing[i].minSize > sizes[i]) sizes[i] = disc->sizing[i].minSize; offsets[i] = disc->sizing[i].align; } start = next_extent_size(find_extent(disc, 256), USPACE, sizes[VDS_SIZE], offsets[VDS_SIZE]); set_extent(disc, PVDS, start, sizes[VDS_SIZE]); start = next_extent_size(find_extent(disc, 256), USPACE, sizes[LVID_SIZE], offsets[LVID_SIZE]); set_extent(disc, LVID, start, sizes[LVID_SIZE]); if (disc->flags & FLAG_VAT) { start = next_extent_size(find_extent(disc, 256), USPACE, sizes[VDS_SIZE], offsets[VDS_SIZE]); set_extent(disc, RVDS, start, sizes[VDS_SIZE]); } else { start = prev_extent_size(disc->tail, USPACE, sizes[VDS_SIZE], offsets[VDS_SIZE]); set_extent(disc, RVDS, start, sizes[VDS_SIZE]); } if ((spm = find_type2_sparable_partition(disc, 0))) { for (i=0; i<spm->numSparingTables; i++) { if (i & 0x1) start = prev_extent_size(disc->tail, USPACE, sizes[STABLE_SIZE], offsets[STABLE_SIZE]); else start = next_extent_size(find_extent(disc, 256), USPACE, sizes[STABLE_SIZE], offsets[STABLE_SIZE]); set_extent(disc, STABLE, start, sizes[STABLE_SIZE]); } start = next_extent_size(find_extent(disc, 256), USPACE, sizes[SSPACE_SIZE], offsets[SSPACE_SIZE]); set_extent(disc, SSPACE, start, sizes[SSPACE_SIZE]); } start = next_extent(disc->head, LVID)->start; ext = next_extent(find_extent(disc, start), USPACE); if (ext->start % offsets[PSPACE_SIZE]) { start = ext->start + offsets[PSPACE_SIZE] - (ext->start % offsets[PSPACE_SIZE]); size = ext->blocks - offsets[PSPACE_SIZE] + (ext->start % offsets[PSPACE_SIZE]); } else { start = ext->start; size = ext->blocks; } if (size % offsets[PSPACE_SIZE]) size -= (size % offsets[PSPACE_SIZE]); set_extent(disc, PSPACE, start, size); for (i=0; i<disc->udf_lvd[0]->numPartitionMaps; i++) { if (i == 1) disc->udf_lvid->freeSpaceTable[i] = cpu_to_le32(0xFFFFFFFF); else disc->udf_lvid->freeSpaceTable[i] = cpu_to_le32(size); } for (j=0; j<disc->udf_lvd[0]->numPartitionMaps; j++) { if (j == 1) disc->udf_lvid->sizeTable[i+j] = cpu_to_le32(0xFFFFFFFF); else disc->udf_lvid->sizeTable[i+j] = cpu_to_le32(size); }}void dump_space(struct udf_disc *disc){ struct udf_extent *start_ext; int i; start_ext = disc->head; while (start_ext != NULL) { printf("start=%d, blocks=%d, type=", start_ext->start, start_ext->blocks); for (i=0; i<UDF_SPACE_TYPE_SIZE; i++) { if (start_ext->space_type & (1<<i)) printf("%s ", udf_space_type_str[i]); } printf("\n"); start_ext = start_ext->next; }}int write_disc(struct udf_disc *disc){ struct udf_extent *start_ext; int ret; start_ext = disc->head; while (start_ext != NULL) { if ((ret = disc->write(disc, start_ext)) < 0) return ret; start_ext = start_ext->next; }}void setup_vrs(struct udf_disc *disc){ struct udf_extent *ext; struct udf_desc *desc; if (!(ext = next_extent(disc->head, VRS))) return; desc = set_desc(disc, ext, 0x00, 0, sizeof(struct volStructDesc), NULL); disc->udf_vrs[0] = (struct volStructDesc *)desc->data->buffer; disc->udf_vrs[0]->structType = 0x00; disc->udf_vrs[0]->structVersion = 0x01; memcpy(disc->udf_vrs[0]->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN); if (disc->blocksize >= 2048) desc = set_desc(disc, ext, 0x00, 1, sizeof(struct volStructDesc), NULL); else desc = set_desc(disc, ext, 0x00, 2048 / disc->blocksize, sizeof(struct volStructDesc), NULL); disc->udf_vrs[1] = (struct volStructDesc *)desc->data->buffer; disc->udf_vrs[1]->structType = 0x00; disc->udf_vrs[1]->structVersion = 0x01; if (disc->udf_rev >= 0x0200) memcpy(disc->udf_vrs[1]->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN); else memcpy(disc->udf_vrs[1]->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN); if (disc->blocksize >= 2048) desc = set_desc(disc, ext, 0x00, 2, sizeof(struct volStructDesc), NULL); else desc = set_desc(disc, ext, 0x00, 4096 / disc->blocksize, sizeof(struct volStructDesc), NULL); disc->udf_vrs[2] = (struct volStructDesc *)desc->data->buffer; disc->udf_vrs[2]->structType = 0x00; disc->udf_vrs[2]->structVersion = 0x01; memcpy(disc->udf_vrs[2]->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN);}void setup_anchor(struct udf_disc *disc){ struct udf_extent *ext; uint32_t mloc, rloc, mlen, rlen; int i = 0; ext = next_extent(disc->head, PVDS); mloc = ext->start; mlen = ext->blocks << disc->blocksize_bits; ext = next_extent(disc->head, RVDS); rloc = ext->start; rlen = ext->blocks << disc->blocksize_bits;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -