udftools

- Main Page
- Classes
- Files

- File List
- File Members

All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
mkudffs.c
Go to the documentation of this file.
1 /*
2 * mkudffs.c
3 *
4 * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
5 * Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com>
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
29 #include "config.h"
30
31 #include <malloc.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <time.h>
39 #include <sys/time.h>
40 #include <errno.h>
41
42 #include "mkudffs.h"
43 #include "file.h"
44 #include "defaults.h"
45
46 void udf_init_disc(struct udf_disc *disc)
47 {
48 timestamp ts;
49 struct timeval tv;
50 struct tm *tm;
51 int altzone;
52 int fd;
53 unsigned long int rnd;
54
55 memset(disc, 0x00, sizeof(*disc));
56
57 disc->blocksize = 2048;
58 disc->blocksize_bits = 11;
59 disc->udf_rev = le16_to_cpu(default_lvidiu.minUDFReadRev);
60 disc->flags = FLAG_UTF8 | FLAG_CLOSED;
61
62 gettimeofday(&tv, NULL);
63 tm = localtime(&tv.tv_sec);
64 altzone = timezone - 3600;
65 if (daylight)
66 ts.typeAndTimezone = cpu_to_le16(((-altzone/60) & 0x0FFF) | 0x1000);
67 else
68 ts.typeAndTimezone = cpu_to_le16(((-timezone/60) & 0x0FFF) | 0x1000);
69 ts.year = cpu_to_le16(1900 + tm->tm_year);
70 ts.month = 1 + tm->tm_mon;
71 ts.day = tm->tm_mday;
72 ts.hour = tm->tm_hour;
73 ts.minute = tm->tm_min;
74 ts.second = tm->tm_sec;
75 ts.centiseconds = tv.tv_usec / 10000;
76 ts.hundredsOfMicroseconds = (tv.tv_usec - ts.centiseconds * 10000) / 100;
77 ts.microseconds = tv.tv_usec - ts.centiseconds * 10000 - ts.hundredsOfMicroseconds * 100;
78
79 fd = open("/dev/urandom", O_RDONLY);
80 if (fd >= 0) {
81 if (read(fd, &rnd, sizeof(rnd)) != sizeof(rnd)) {
82 srand(time(NULL));
83 rnd = rand();
84 }
85 close(fd);
86 } else {
87 srand(time(NULL));
88 rnd = rand();
89 }
90
91 /* Allocate/Initialize Descriptors */
92 disc->udf_pvd[0] = malloc(sizeof(struct primaryVolDesc));
93 memcpy(disc->udf_pvd[0], &default_pvd, sizeof(struct primaryVolDesc));
94 memcpy(&disc->udf_pvd[0]->recordingDateAndTime, &ts, sizeof(timestamp));
95 sprintf((char *)&disc->udf_pvd[0]->volSetIdent[1], "%08lx%08lx%s",
96 ((unsigned long int)mktime(tm))%0xFFFFFFFF, rnd%0xFFFFFFFF, &disc->udf_pvd[0]->volSetIdent[17]);
97 disc->udf_pvd[0]->volIdent[31] = strlen((char *)disc->udf_pvd[0]->volIdent);
98 disc->udf_pvd[0]->volSetIdent[127] = strlen((char *)disc->udf_pvd[0]->volSetIdent);
99
100 disc->udf_lvd[0] = malloc(sizeof(struct logicalVolDesc));
101 memcpy(disc->udf_lvd[0], &default_lvd, sizeof(struct logicalVolDesc));
102 disc->udf_lvd[0]->logicalVolIdent[127] = strlen((char *)disc->udf_lvd[0]->logicalVolIdent);
103
104 disc->udf_pd[0] = malloc(sizeof(struct partitionDesc));
105 memcpy(disc->udf_pd[0], &default_pd, sizeof(struct partitionDesc));
106
107 disc->udf_usd[0] = malloc(sizeof(struct unallocSpaceDesc));
108 memcpy(disc->udf_usd[0], &default_usd, sizeof(struct unallocSpaceDesc));
109
110 disc->udf_iuvd[0] = malloc(sizeof(struct impUseVolDesc) + sizeof(struct impUseVolDescImpUse));
111 memcpy(disc->udf_iuvd[0], &default_iuvd, sizeof(struct impUseVolDesc));
112 memcpy(query_iuvdiu(disc), &default_iuvdiu, sizeof(struct impUseVolDescImpUse));
113 query_iuvdiu(disc)->logicalVolIdent[127] = strlen((char *)query_iuvdiu(disc)->logicalVolIdent);
114 query_iuvdiu(disc)->LVInfo1[35] = strlen((char *)query_iuvdiu(disc)->LVInfo1);
115 query_iuvdiu(disc)->LVInfo2[35] = strlen((char *)query_iuvdiu(disc)->LVInfo2);
116 query_iuvdiu(disc)->LVInfo3[35] = strlen((char *)query_iuvdiu(disc)->LVInfo3);
117
118 disc->udf_td[0] = malloc(sizeof(struct terminatingDesc));
119 memcpy(disc->udf_td[0], &default_td, sizeof(struct terminatingDesc));
120
121 disc->udf_lvid = malloc(sizeof(struct logicalVolIntegrityDesc) + sizeof(struct logicalVolIntegrityDescImpUse));
122 memcpy(disc->udf_lvid, &default_lvid, sizeof(struct logicalVolIntegrityDesc));
123 memcpy(&disc->udf_lvid->recordingDateAndTime, &ts, sizeof(timestamp));
124 memcpy(query_lvidiu(disc), &default_lvidiu, sizeof(struct logicalVolIntegrityDescImpUse));
125
126 disc->udf_stable[0] = malloc(sizeof(struct sparingTable));
127 memcpy(disc->udf_stable[0], &default_stable, sizeof(struct sparingTable));
128
129 disc->vat = calloc(1, disc->blocksize);
130 disc->vat_entries = 0;
131
132 disc->udf_fsd = malloc(sizeof(struct fileSetDesc));
133 memcpy(disc->udf_fsd, &default_fsd, sizeof(struct fileSetDesc));
134 memcpy(&disc->udf_fsd->recordingDateAndTime, &ts, sizeof(timestamp));
135 disc->udf_fsd->logicalVolIdent[127] = strlen((char *)disc->udf_fsd->logicalVolIdent);
136 disc->udf_fsd->fileSetIdent[31] = strlen((char *)disc->udf_fsd->fileSetIdent);
137 disc->udf_fsd->copyrightFileIdent[31] = strlen((char *)disc->udf_fsd->copyrightFileIdent);
138 disc->udf_fsd->abstractFileIdent[31] = strlen((char *)disc->udf_fsd->abstractFileIdent);
139
140 disc->head = malloc(sizeof(struct udf_extent));
141 disc->tail = disc->head;
142
143 disc->head->space_type = USPACE;
144 disc->head->start = 0;
145 disc->head->blocks = 0;
146 disc->head->next = NULL;
147 disc->head->prev = NULL;
148 disc->head->head = NULL;
149 disc->head->tail = NULL;
150 }
151
152 int udf_set_version(struct udf_disc *disc, int udf_rev)
153 {
154 struct logicalVolIntegrityDescImpUse *lvidiu;
155
156 if (disc->udf_rev == udf_rev)
157 return 0;
158 else if (udf_rev != 0x0102 &&
159 udf_rev != 0x0150 &&
160 udf_rev != 0x0200 &&
161 udf_rev != 0x0201 &&
162 udf_rev != 0x0250)
163 {
164 return 1;
165 }
166 else
167 disc->udf_rev = udf_rev;
168
169 if (disc->udf_rev >= 0x0200)
170
171 {
172 disc->flags |= FLAG_EFE;
173 strcpy((char *)disc->udf_pd[0]->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03);
174 }
175 else if (disc->udf_rev == 0x0150)
176 {
177 disc->flags &= ~FLAG_EFE;
178 strcpy((char *)disc->udf_pd[0]->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02);
179 }
180 else // 0x0102
181 {
182 disc->flags &= ~FLAG_VAT;
183 disc->flags &= ~FLAG_EFE;
184 strcpy((char *)disc->udf_pd[0]->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02);
185 }
186
187 ((uint16_t *)disc->udf_fsd->domainIdent.identSuffix)[0] = cpu_to_le16(udf_rev);
188 ((uint16_t *)disc->udf_lvd[0]->domainIdent.identSuffix)[0] = cpu_to_le16(udf_rev);
189 ((uint16_t *)disc->udf_iuvd[0]->impIdent.identSuffix)[0] = le16_to_cpu(udf_rev);
190 lvidiu = query_lvidiu(disc);
191 lvidiu->minUDFReadRev = le16_to_cpu(udf_rev);
192 lvidiu->minUDFWriteRev = le16_to_cpu(udf_rev);
193 lvidiu->maxUDFWriteRev = le16_to_cpu(udf_rev);
194 ((uint16_t *)disc->udf_stable[0]->sparingIdent.identSuffix)[0] = le16_to_cpu(udf_rev);
195 return 0;
196 }
197
198 void split_space(struct udf_disc *disc)
199 {
200 uint32_t sizes[UDF_ALLOC_TYPE_SIZE];
201 uint32_t offsets[UDF_ALLOC_TYPE_SIZE];
202 uint32_t blocks = disc->head->blocks;
203 uint32_t start, size;
204 struct sparablePartitionMap *spm;
205 struct udf_extent *ext;
206 uint32_t i, j;
207
208 if (disc->flags & FLAG_BRIDGE) // UDF-Bridge had both UDF and ISO-9660 filesystems mapping the same files
209 {
210 set_extent(disc, RESERVED, 0, 512);
211 set_extent(disc, ANCHOR, 512, 1);
212 }
213 else
214 {
215 set_extent(disc, RESERVED, 0, 32768 / disc->blocksize); // OS boot area
216 if (disc->blocksize >= 2048) // Volume Recognition Sequence
217 set_extent(disc, VRS, (2048 * 16) / disc->blocksize, 3);
218 else
219 set_extent(disc, VRS, (2048 * 16) / disc->blocksize, ((2048 * 3) + disc->blocksize - 1) / disc->blocksize);
220 set_extent(disc, ANCHOR, 256, 1); // First Anchor Point at sector 256
221 }
222
223 if (disc->flags & FLAG_CLOSED) // Second anchor point at sector (End-Of-Volume - 256)
224 set_extent(disc, ANCHOR, blocks-257, 1);
225
226 if (!(disc->flags & FLAG_VAT)) // Final anchor point at sector End-Of-Volume/Session for sequentially writable media
227 set_extent(disc, ANCHOR, blocks-1, 1);
228 else
229 set_extent(disc, PSPACE, blocks-1, 1);
230
231 for (i=0; i<UDF_ALLOC_TYPE_SIZE; i++)
232 {
233 sizes[i] = disc->sizing[i].numSize * blocks / disc->sizing[i].denomSize;
234 if (disc->sizing[i].minSize > sizes[i])
235 sizes[i] = disc->sizing[i].minSize;
236 offsets[i] = disc->sizing[i].align;
237 }
238
239 start = next_extent_size(find_extent(disc, 256), USPACE, sizes[VDS_SIZE], offsets[VDS_SIZE]);
240 if (!start) {
241 fprintf(stderr, "mkudffs: Error: Cannot find free USPACE extent\n");
242 exit(1);
243 }
244 set_extent(disc, PVDS, start, sizes[VDS_SIZE]);
245 start = next_extent_size(find_extent(disc, 256), USPACE, sizes[LVID_SIZE], offsets[LVID_SIZE]);
246 if (!start) {
247 fprintf(stderr, "mkudffs: Error: Cannot find free USPACE extent\n");
248 exit(1);
249 }
250 set_extent(disc, LVID, start, sizes[LVID_SIZE]);
251 if (disc->flags & FLAG_VAT)
252 {
253 start = next_extent_size(find_extent(disc, 256), USPACE, sizes[VDS_SIZE], offsets[VDS_SIZE]);
254 if (!start) {
255 fprintf(stderr, "mkudffs: Error: Cannot find free USPACE extent\n");
256 exit(1);
257 }
258 set_extent(disc, RVDS, start, sizes[VDS_SIZE]);
259 }
260 else
261 {
262 start = prev_extent_size(disc->tail, USPACE, sizes[VDS_SIZE], offsets[VDS_SIZE]);
263 if (!start) {
264 fprintf(stderr, "mkudffs: Error: Cannot find free USPACE extent\n");
265 exit(1);
266 }
267 set_extent(disc, RVDS, start, sizes[VDS_SIZE]);
268 }
269
270 if ((spm = find_type2_sparable_partition(disc, 0)))
271 {
272 for (i=0; i<spm->numSparingTables; i++)
273 {
274 if (i & 0x1)
275 start = prev_extent_size(disc->tail, USPACE, sizes[STABLE_SIZE], offsets[STABLE_SIZE]);
276 else
277 start = next_extent_size(find_extent(disc, 256), USPACE, sizes[STABLE_SIZE], offsets[STABLE_SIZE]);
278 if (!start) {
279 fprintf(stderr, "mkudffs: Error: Cannot find free USPACE extent\n");
280 exit(1);
281 }
282 set_extent(disc, STABLE, start, sizes[STABLE_SIZE]);
283 }
284 start = next_extent_size(find_extent(disc, 256), USPACE, sizes[SSPACE_SIZE], offsets[SSPACE_SIZE]);
285 if (!start) {
286 fprintf(stderr, "mkudffs: Error: Cannot find free USPACE extent\n");
287 exit(1);
288 }
289 set_extent(disc, SSPACE, start, sizes[SSPACE_SIZE]);
290 }
291
292 start = next_extent(disc->head, LVID)->start;
293 if (!start) {
294 fprintf(stderr, "mkudffs: Error: Cannot find LVID extent\n");
295 exit(1);
296 }
297 ext = next_extent(find_extent(disc, start), USPACE);
298 if (!ext) {
299 fprintf(stderr, "mkudffs: Error: Cannot find USPACE extent\n");
300 exit(1);
301 }
302 if (ext->start % offsets[PSPACE_SIZE]) // round start up to a multiple of alignment/packet_size
303 {
304 start = ext->start + offsets[PSPACE_SIZE] - (ext->start % offsets[PSPACE_SIZE]);
305 size = ext->blocks - offsets[PSPACE_SIZE] + (ext->start % offsets[PSPACE_SIZE]);
306 }
307 else
308 {
309 start = ext->start;
310 size = ext->blocks;
311 }
312 if (size % offsets[PSPACE_SIZE]) // round size down to a multiple of alignment/packet_size
313 size -= (size % offsets[PSPACE_SIZE]);
314 set_extent(disc, PSPACE, start, size);
315 for (i=0; i<le32_to_cpu(disc->udf_lvd[0]->numPartitionMaps); i++)
316 {
317 if (i == 1)
318 disc->udf_lvid->freeSpaceTable[i] = cpu_to_le32(0xFFFFFFFF);
319 else
320 disc->udf_lvid->freeSpaceTable[i] = cpu_to_le32(size);
321 }
322 for (j=0; j<le32_to_cpu(disc->udf_lvd[0]->numPartitionMaps); j++)
323 {
324 if (j == 1)
325 disc->udf_lvid->sizeTable[i+j] = cpu_to_le32(0xFFFFFFFF);
326 else
327 disc->udf_lvid->sizeTable[i+j] = cpu_to_le32(size);
328 }
329 }
330
331 void dump_space(struct udf_disc *disc)
332 {
333 struct udf_extent *start_ext;
334 int i;
335
336 start_ext = disc->head;
337
338 while (start_ext != NULL)
339 {
340 printf("start=%lu, blocks=%lu, type=", (unsigned long int)start_ext->start, (unsigned long int)start_ext->blocks);
341 for (i=0; i<UDF_SPACE_TYPE_SIZE; i++)
342 {
343 if (start_ext->space_type & (1<<i))
344 printf("%s ", udf_space_type_str[i]);
345 }
346 printf("\n");
347 start_ext = start_ext->next;
348 }
349 }
350
351 int write_disc(struct udf_disc *disc)
352 {
353 struct udf_extent *start_ext;
354 int ret=0;
355
356 start_ext = disc->head;
357
358 while (start_ext != NULL)
359 {
360 if ((ret = disc->write(disc, start_ext)) < 0)
361 return ret;
362 start_ext = start_ext->next;
363 }
364 return ret;
365 }
366
367 void setup_vrs(struct udf_disc *disc)
368 {
369 struct udf_extent *ext;
370 struct udf_desc *desc;
371
372 if (!(ext = next_extent(disc->head, VRS)))
373 return;
374 desc = set_desc(disc, ext, 0x00, 0, sizeof(struct volStructDesc), NULL);
375 disc->udf_vrs[0] = (struct volStructDesc *)desc->data->buffer;
376 disc->udf_vrs[0]->structType = 0x00;
377 disc->udf_vrs[0]->structVersion = 0x01;
378 memcpy(disc->udf_vrs[0]->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN);
379
380 if (disc->blocksize >= 2048)
381 desc = set_desc(disc, ext, 0x00, 1, sizeof(struct volStructDesc), NULL);
382 else
383 desc = set_desc(disc, ext, 0x00, 2048 / disc->blocksize, sizeof(struct volStructDesc), NULL);
384 disc->udf_vrs[1] = (struct volStructDesc *)desc->data->buffer;
385 disc->udf_vrs[1]->structType = 0x00;
386 disc->udf_vrs[1]->structVersion = 0x01;
387 if (disc->udf_rev >= 0x0200)
388 memcpy(disc->udf_vrs[1]->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN);
389 else
390 memcpy(disc->udf_vrs[1]->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN);
391
392 if (disc->blocksize >= 2048)
393 desc = set_desc(disc, ext, 0x00, 2, sizeof(struct volStructDesc), NULL);
394 else
395 desc = set_desc(disc, ext, 0x00, 4096 / disc->blocksize, sizeof(struct volStructDesc), NULL);
396 disc->udf_vrs[2] = (struct volStructDesc *)desc->data->buffer;
397 disc->udf_vrs[2]->structType = 0x00;
398 disc->udf_vrs[2]->structVersion = 0x01;
399 memcpy(disc->udf_vrs[2]->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN);
400 }
401
402 void setup_anchor(struct udf_disc *disc)
403 {
404 struct udf_extent *ext;
405 uint32_t mloc, rloc, mlen, rlen;
406 int i = 0;
407
408 ext = next_extent(disc->head, PVDS);
409 if (!ext) {
410 fprintf(stderr, "mkudffs: Error: Cannot find PVDS extent\n");
411 exit(1);
412 }
413 mloc = ext->start;
414 mlen = ext->blocks << disc->blocksize_bits;
415
416 ext = next_extent(disc->head, RVDS);
417 if (!ext) {
418 fprintf(stderr, "mkudffs: Error: Cannot find RVDS extent\n");
419 exit(1);
420 }
421 rloc = ext->start;
422 rlen = ext->blocks << disc->blocksize_bits;
423
424 ext = next_extent(disc->head, ANCHOR);
425 if (!ext) {
426 fprintf(stderr, "mkudffs: Error: Cannot find ANCHOR extent\n");
427 exit(1);
428 }
429 do
430 {
431 ext->head = ext->tail = malloc(sizeof(struct udf_desc) + sizeof(struct udf_data));
432 ext->head->data = (struct udf_data *)&(ext->head)[1];
433 ext->head->data->next = ext->head->data->prev = NULL;
434 ext->head->ident = TAG_IDENT_AVDP;
435 ext->head->offset = 0;
436 ext->head->length = ext->head->data->length = sizeof(struct anchorVolDescPtr);
437 disc->udf_anchor[i] = ext->head->data->buffer = malloc(sizeof(struct anchorVolDescPtr));
438 ext->head->next = ext->head->prev = NULL;
439 disc->udf_anchor[i]->mainVolDescSeqExt.extLocation = cpu_to_le32(mloc);
440 disc->udf_anchor[i]->mainVolDescSeqExt.extLength = cpu_to_le32(mlen);
441 disc->udf_anchor[i]->reserveVolDescSeqExt.extLocation = cpu_to_le32(rloc);
442 disc->udf_anchor[i]->reserveVolDescSeqExt.extLength = cpu_to_le32(rlen);
443 memset(disc->udf_anchor[i]->reserved, 0, sizeof(disc->udf_anchor[i]->reserved));
444 disc->udf_anchor[i]->descTag = query_tag(disc, ext, ext->head, 1);
445 ext = next_extent(ext->next, ANCHOR);
446 } while (i++, ext != NULL);
447 }
448
449 void setup_partition(struct udf_disc *disc)
450 {
451 struct udf_extent *pspace;
452
453 pspace = next_extent(disc->head, PSPACE);
454 if (!pspace) {
455 fprintf(stderr, "mkudffs: Error: Cannot find PSPACE extent\n");
456 exit(1);
457 }
458 setup_space(disc, pspace, 0);
459 setup_fileset(disc, pspace);
460 setup_root(disc, pspace);
461 if (disc->flags & FLAG_VAT)
462 setup_vat(disc, pspace);
463 }
464
465 int setup_space(struct udf_disc *disc, struct udf_extent *pspace, uint32_t offset)
466 {
467 struct udf_desc *desc;
468 struct partitionHeaderDesc *phd = (struct partitionHeaderDesc *)disc->udf_pd[0]->partitionContentsUse;
469 int length = (((sizeof(struct spaceBitmapDesc) + pspace->blocks) >> (disc->blocksize_bits + 3)) + 1) << disc->blocksize_bits;
470
471 if (disc->flags & FLAG_FREED_BITMAP)
472 {
473 phd->freedSpaceBitmap.extPosition = cpu_to_le32(offset);
474 phd->freedSpaceBitmap.extLength = cpu_to_le32(length);
475 disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - (length >> disc->blocksize_bits));
476 }
477 else if (disc->flags & FLAG_FREED_TABLE)
478 {
479 phd->freedSpaceTable.extPosition = cpu_to_le32(offset);
480 if (disc->flags & FLAG_STRATEGY4096)
481 {
482 phd->freedSpaceTable.extLength = cpu_to_le32(disc->blocksize * 2);
483 disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 2);
484 }
485 else
486 {
487 phd->freedSpaceTable.extLength = cpu_to_le32(disc->blocksize);
488 disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 1);
489 }
490 }
491 else if (disc->flags & FLAG_UNALLOC_BITMAP)
492 {
493 phd->unallocSpaceBitmap.extPosition = cpu_to_le32(offset);
494 phd->unallocSpaceBitmap.extLength = cpu_to_le32(length);
495 disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - (length >> disc->blocksize_bits));
496 }
497 else if (disc->flags & FLAG_UNALLOC_TABLE)
498 {
499 phd->unallocSpaceTable.extPosition = cpu_to_le32(offset);
500 if (disc->flags & FLAG_STRATEGY4096)
501 {
502 phd->unallocSpaceTable.extLength = cpu_to_le32(disc->blocksize * 2);
503 disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 2);
504 }
505 else
506 {
507 phd->unallocSpaceTable.extLength = cpu_to_le32(disc->blocksize);
508 disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(le32_to_cpu(disc->udf_lvid->freeSpaceTable[0]) - 1);
509 }
510 }
511
512 if (disc->flags & FLAG_SPACE_BITMAP)
513 {
514 struct spaceBitmapDesc *sbd;
515 int nBytes = (pspace->blocks+7)/8;
516
517 length = sizeof(struct spaceBitmapDesc) + nBytes;
518 desc = set_desc(disc, pspace, TAG_IDENT_SBD, offset, length, NULL);
519 sbd = (struct spaceBitmapDesc *)desc->data->buffer;
520 sbd->numOfBits = cpu_to_le32(pspace->blocks);
521 sbd->numOfBytes = cpu_to_le32(nBytes);
522 memset(sbd->bitmap, 0xFF, sizeof(uint8_t) * nBytes);
523 if (pspace->blocks%8)
524 sbd->bitmap[nBytes-1] = 0xFF >> (8-(pspace->blocks%8));
525 clear_bits(sbd->bitmap, offset, (length + disc->blocksize - 1) >> disc->blocksize_bits);
526 sbd->descTag = udf_query_tag(disc, TAG_IDENT_SBD, 1, desc->offset, desc->data, sizeof(tag));
527 }
528 else if (disc->flags & FLAG_SPACE_TABLE)
529 {
530 struct unallocSpaceEntry *use;
531 short_ad *sad;
532 int max = (0x3FFFFFFF / disc->blocksize) * disc->blocksize;
533 int pos=0;
534 long long rem;
535
536 if (disc->flags & FLAG_STRATEGY4096)
537 length = disc->blocksize * 2;
538 else
539 length = disc->blocksize;
540 desc = set_desc(disc, pspace, TAG_IDENT_USE, offset, disc->blocksize, NULL);
541 use = (struct unallocSpaceEntry *)desc->data->buffer;
542 use->lengthAllocDescs = cpu_to_le32(sizeof(short_ad));
543 sad = (short_ad *)&use->allocDescs[0];
544 rem = (long long)pspace->blocks * disc->blocksize - length;
545 if (disc->blocksize - sizeof(struct unallocSpaceEntry) < (rem / max) * sizeof(short_ad)) {
546 fprintf(stderr, "Creation of so large filesystems with unalloc table not supported.\n");
547 exit(1);
548 }
549 pos = offset + (length/disc->blocksize);
550 printf("pos=%d, rem=%lld\n", pos, rem);
551 if (rem > 0x3FFFFFFF)
552 {
553 while (rem > max)
554 {
555 sad->extLength = cpu_to_le32(EXT_NOT_RECORDED_ALLOCATED | max);
556 sad->extPosition = cpu_to_le32(pos);
557 pos += max / disc->blocksize;
558 sad ++;
559 rem -= max;
560 use->lengthAllocDescs = cpu_to_le32(le32_to_cpu(use->lengthAllocDescs) + sizeof(short_ad));
561 }
562 }
563 sad->extLength = cpu_to_le32(EXT_NOT_RECORDED_ALLOCATED | rem);
564 sad->extPosition = cpu_to_le32(pos);
565
566 if (disc->flags & FLAG_STRATEGY4096)
567 {
568 use->icbTag.strategyType = cpu_to_le16(4096);
569 use->icbTag.strategyParameter = cpu_to_le16(1);
570 use->icbTag.numEntries = cpu_to_le16(2);
571 }
572 else
573 {
574 use->icbTag.strategyType = cpu_to_le16(4);
575 use->icbTag.numEntries = cpu_to_le16(1);
576 }
577 use->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(0);
578 use->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);
579 use->icbTag.fileType = ICBTAG_FILE_TYPE_USE;
580 use->icbTag.flags = cpu_to_le16(ICBTAG_FLAG_AD_SHORT);
581 use->descTag = udf_query_tag(disc, TAG_IDENT_USE, 1, desc->offset, desc->data, sizeof(struct unallocSpaceEntry) + le32_to_cpu(use->lengthAllocDescs));
582
583 if (disc->flags & FLAG_STRATEGY4096)
584 {
585 struct udf_desc *tdesc;
586 struct terminalEntry *te;
587
588 if (disc->flags & FLAG_BLANK_TERMINAL)
589 {
590 // tdesc = set_desc(disc, pspace, TAG_IDENT_IE, offset+1, sizeof(struct indirectEntry), NULL);
591 }
592 else
593 {
594 tdesc = set_desc(disc, pspace, TAG_IDENT_TE, offset+1, sizeof(struct terminalEntry), NULL);
595 te = (struct terminalEntry *)tdesc->data->buffer;
596 te->icbTag.priorRecordedNumDirectEntries = cpu_to_le32(1);
597 te->icbTag.strategyType = cpu_to_le16(4096);
598 te->icbTag.strategyParameter = cpu_to_le16(1);
599 te->icbTag.numEntries = cpu_to_le16(2);
600 te->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(desc->offset);
601 te->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);
602 te->icbTag.fileType = ICBTAG_FILE_TYPE_TE;
603 te->descTag = query_tag(disc, pspace, tdesc, 1);
604 }
605 }
606 }
607
608 return (length + disc->blocksize - 1) >> disc->blocksize_bits;
609 }
610
611 int setup_fileset(struct udf_disc *disc, struct udf_extent *pspace)
612 {
613 uint32_t offset = 0;
614 struct udf_desc *desc;
615 int length = sizeof(struct fileSetDesc);
616
617 offset = udf_alloc_blocks(disc, pspace, offset, 1);
618
619 ((long_ad *)disc->udf_lvd[0]->logicalVolContentsUse)->extLength = cpu_to_le32(disc->blocksize);
620 ((long_ad *)disc->udf_lvd[0]->logicalVolContentsUse)->extLocation.logicalBlockNum = cpu_to_le32(offset);
621 ((long_ad *)disc->udf_lvd[0]->logicalVolContentsUse)->extLocation.partitionReferenceNum = cpu_to_le16(0);
622 // ((uint16_t *)disc->udf_fsd->domainIdent.identSuffix)[0] = cpu_to_le16(disc->udf_rev);
623
624 desc = set_desc(disc, pspace, TAG_IDENT_FSD, offset, 0, NULL);
625 desc->length = desc->data->length = length;
626 desc->data->buffer = disc->udf_fsd;
627
628 if (!(disc->flags & FLAG_VAT) && disc->udf_rev >= 0x0200)
629 {
630 struct udf_desc *ss;
631
632 ss = udf_create(disc, pspace, NULL, 0, offset+1, NULL, FID_FILE_CHAR_DIRECTORY, ICBTAG_FILE_TYPE_STREAMDIR, 0);
633 insert_fid(disc, pspace, ss, ss, NULL, 0, FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT);
634 offset = ss->offset;
635
636 disc->udf_fsd->streamDirectoryICB.extLength = cpu_to_le32(disc->blocksize);
637 disc->udf_fsd->streamDirectoryICB.extLocation.logicalBlockNum = cpu_to_le32(offset);
638 disc->udf_fsd->streamDirectoryICB.extLocation.partitionReferenceNum = cpu_to_le16(0);
639
640 }
641
642 disc->udf_fsd->descTag = query_tag(disc, pspace, desc, 1);
643
644 return (length + disc->blocksize - 1) >> disc->blocksize_bits;
645 }
646
647 int setup_root(struct udf_disc *disc, struct udf_extent *pspace)
648 {
649 uint32_t offset = 0;
650 struct udf_desc *desc, *fsd_desc, *tdesc;
651 struct terminalEntry *te;
652
653 desc = udf_mkdir(disc, pspace, NULL, 0, offset, NULL); // the root directory does not have a name
654 offset = desc->offset;
655
656 if (disc->flags & FLAG_STRATEGY4096)
657 disc->udf_fsd->rootDirectoryICB.extLength = cpu_to_le32(disc->blocksize * 2);
658 else
659 disc->udf_fsd->rootDirectoryICB.extLength = cpu_to_le32(disc->blocksize);
660 disc->udf_fsd->rootDirectoryICB.extLocation.logicalBlockNum = cpu_to_le32(offset);
661 disc->udf_fsd->rootDirectoryICB.extLocation.partitionReferenceNum = cpu_to_le16(0);
662 fsd_desc = next_desc(pspace->head, TAG_IDENT_FSD);
663 disc->udf_fsd->descTag = query_tag(disc, pspace, fsd_desc, 1);
664
665 if (disc->flags & FLAG_STRATEGY4096)
666 {
667 if (disc->flags & FLAG_BLANK_TERMINAL)
668 {
669 // tdesc = set_desc(disc, pspace, TAG_IDENT_IE, offset+1, sizeof(struct indirectEntry), NULL);
670 offset ++;
671 }
672 else
673 {
674 tdesc = set_desc(disc, pspace, TAG_IDENT_TE, offset+1, sizeof(struct terminalEntry), NULL);
675 te = (struct terminalEntry *)tdesc->data->buffer;
676 te->icbTag.priorRecordedNumDirectEntries = cpu_to_le32(1);
677 te->icbTag.strategyType = cpu_to_le16(4096);
678 te->icbTag.strategyParameter = cpu_to_le16(1);
679 te->icbTag.numEntries = cpu_to_le16(2);
680 te->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(desc->offset);
681 te->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);
682 te->icbTag.fileType = ICBTAG_FILE_TYPE_TE;
683 te->descTag = query_tag(disc, pspace, tdesc, 1);
684 offset = tdesc->offset;
685 }
686 }
687
688 if (next_extent(disc->head, STABLE) && next_extent(disc->head, SSPACE))
689 {
690 struct udf_desc *nat;
691
692 if (disc->flags & FLAG_EFE)
693 {
694 struct extendedFileEntry *efe;
695 struct udf_desc *ss;
696
697 ss = find_desc(pspace, le32_to_cpu(disc->udf_fsd->streamDirectoryICB.extLocation.logicalBlockNum));
698 #if 0
699 nat = udf_create(disc, pspace, NULL, 0, offset+1, NULL, FID_FILE_CHAR_DIRECTORY, ICBTAG_FILE_TYPE_STREAMDIR, 0);
700 insert_fid(disc, pspace, nat, nat, NULL, 0, FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT);
701 offset = nat->offset;
702
703 disc->udf_fsd->streamDirectoryICB.extLength = cpu_to_le32(disc->blocksize);
704 disc->udf_fsd->streamDirectoryICB.extLocation.logicalBlockNum = cpu_to_le32(offset);
705 disc->udf_fsd->streamDirectoryICB.extLocation.partitionReferenceNum = cpu_to_le16(0);
706 #endif
707 nat = udf_create(disc, pspace, (uint8_t *)"\x08" "*UDF Non-Allocatable Space", 27, offset+1, ss, FID_FILE_CHAR_METADATA, ICBTAG_FILE_TYPE_REGULAR, ICBTAG_FLAG_STREAM | ICBTAG_FLAG_SYSTEM);
708
709 efe = (struct extendedFileEntry *)nat->data->buffer;
710 efe->icbTag.flags = cpu_to_le16((le16_to_cpu(efe->icbTag.flags) & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_SHORT);
711 efe->descTag = query_tag(disc, pspace, nat, 1);
712 offset = nat->offset;
713 }
714 else
715 {
716 struct fileEntry *fe;
717 nat = udf_create(disc, pspace, (uint8_t *)"\x08" "Non-Allocatable Space", 22, offset+1, desc, FID_FILE_CHAR_HIDDEN, ICBTAG_FILE_TYPE_REGULAR, ICBTAG_FLAG_SYSTEM);
718 fe = (struct fileEntry *)nat->data->buffer;
719 fe->icbTag.flags = cpu_to_le16((le16_to_cpu(fe->icbTag.flags) & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_SHORT);
720 fe->descTag = query_tag(disc, pspace, nat, 1);
721 offset = nat->offset;
722 }
723 }
724
725 #if 0 // this works fine if you really want a lost+find directory on disc
726 desc = udf_mkdir(disc, pspace, "\x08" "lost+found", 11, offset+1, desc); // x08 is the compression id for 8-bit OSTA compressed unicode
727 offset = desc->offset;
728
729 if (disc->flags & FLAG_STRATEGY4096)
730 {
731 if (disc->flags & FLAG_BLANK_TERMINAL)
732 {
733 // tdesc = set_desc(disc, pspace, TAG_IDENT_IE, offset+1, sizeof(struct indirectEntry), NULL);
734 offset ++;
735 }
736 else
737 {
738 tdesc = set_desc(disc, pspace, TAG_IDENT_TE, offset+1, sizeof(struct terminalEntry), NULL);
739 te = (struct terminalEntry *)tdesc->data->buffer;
740 te->icbTag.priorRecordedNumDirectEntries = cpu_to_le32(1);
741 te->icbTag.strategyType = cpu_to_le16(4096);
742 te->icbTag.strategyParameter = cpu_to_le16(1);
743 te->icbTag.numEntries = cpu_to_le16(2);
744 te->icbTag.parentICBLocation.logicalBlockNum = cpu_to_le32(desc->offset);
745 te->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);
746 te->icbTag.fileType = ICBTAG_FILE_TYPE_TE;
747 te->descTag = query_tag(disc, pspace, tdesc, 1);
748 offset = tdesc->offset;
749 }
750 }
751 #endif
752 if (disc->flags & FLAG_STRATEGY4096)
753 return 4;
754 else
755 return 2;
756 }
757
758 void setup_vds(struct udf_disc *disc)
759 {
760 struct udf_extent *pvds, *rvds, *lvid, *stable[4], *sspace;
761
762 pvds = next_extent(disc->head, PVDS);
763 if (!pvds) {
764 fprintf(stderr, "mkudffs: Error: Cannot find PVDS extent\n");
765 exit(1);
766 }
767 rvds = next_extent(disc->head, RVDS);
768 if (!rvds) {
769 fprintf(stderr, "mkudffs: Error: Cannot find RVDS extent\n");
770 exit(1);
771 }
772 lvid = next_extent(disc->head, LVID);
773 if (!lvid) {
774 fprintf(stderr, "mkudffs: Error: Cannot find LVID extent\n");
775 exit(1);
776 }
777 stable[0] = next_extent(disc->head, STABLE);
778 sspace = next_extent(disc->head, SSPACE);
779
780 setup_pvd(disc, pvds, rvds, 0);
781 setup_lvid(disc, lvid);
782 if (stable[0] && sspace)
783 {
784 int i;
785
786 for (i=1; i<4 && stable[i-1]; i++)
787 {
788 stable[i] = next_extent(stable[i-1]->next, STABLE);
789 }
790 setup_stable(disc, stable, sspace);
791 }
792 setup_lvd(disc, pvds, rvds, lvid, 1);
793 setup_pd(disc, pvds, rvds, 2);
794 setup_usd(disc, pvds, rvds, 3);
795 setup_iuvd(disc, pvds, rvds, 4);
796 if (pvds->blocks > 5)
797 setup_td(disc, pvds, rvds, 5);
798 }
799
800 void setup_pvd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
801 {
802 struct udf_desc *desc;
803 int length = sizeof(struct primaryVolDesc);
804
805 desc = set_desc(disc, pvds, TAG_IDENT_PVD, offset, 0, NULL);
806 desc->length = desc->data->length = length;
807 desc->data->buffer = disc->udf_pvd[0];
808 disc->udf_pvd[0]->descTag = query_tag(disc, pvds, desc, 1);
809
810 desc = set_desc(disc, rvds, TAG_IDENT_PVD, offset, length, NULL);
811 memcpy(disc->udf_pvd[1] = desc->data->buffer, disc->udf_pvd[0], length);
812 disc->udf_pvd[1]->descTag = query_tag(disc, rvds, desc, 1);
813 }
814
815 void setup_lvd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, struct udf_extent *lvid, uint32_t offset)
816 {
817 struct udf_desc *desc;
818 int length = sizeof(struct logicalVolDesc) + le32_to_cpu(disc->udf_lvd[0]->mapTableLength);
819
820 disc->udf_lvd[0]->integritySeqExt.extLength = cpu_to_le32(lvid->blocks * disc->blocksize);
821 disc->udf_lvd[0]->integritySeqExt.extLocation = cpu_to_le32(lvid->start);
822 // ((uint16_t *)disc->udf_lvd[0]->domainIdent.identSuffix)[0] = cpu_to_le16(disc->udf_rev);
823
824 desc = set_desc(disc, pvds, TAG_IDENT_LVD, offset, 0, NULL);
825 desc->length = desc->data->length = length;
826 desc->data->buffer = disc->udf_lvd[0];
827 disc->udf_lvd[0]->descTag = query_tag(disc, pvds, desc, 1);
828
829 desc = set_desc(disc, rvds, TAG_IDENT_LVD, offset, length, NULL);
830 memcpy(disc->udf_lvd[1] = desc->data->buffer, disc->udf_lvd[0], length);
831 disc->udf_lvd[1]->descTag = query_tag(disc, rvds, desc, 1);
832 }
833
834 void setup_pd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
835 {
836 struct udf_desc *desc;
837 struct udf_extent *ext;
838 int length = sizeof(struct partitionDesc);
839
840 ext = next_extent(disc->head, PSPACE);
841 if (!ext) {
842 fprintf(stderr, "mkudffs: Error: Cannot find PSPACE extent\n");
843 exit(1);
844 }
845 disc->udf_pd[0]->partitionStartingLocation = cpu_to_le32(ext->start);
846 disc->udf_pd[0]->partitionLength = cpu_to_le32(ext->blocks);
847 #if 0
848 if (disc->udf_rev >= 0x0200)
849 strcpy(disc->udf_pd[0]->partitionContents.ident, PARTITION_CONTENTS_NSR03);
850 else
851 strcpy(disc->udf_pd[0]->partitionContents.ident, PARTITION_CONTENTS_NSR02);
852 #endif
853
854 desc = set_desc(disc, pvds, TAG_IDENT_PD, offset, 0, NULL);
855 desc->length = desc->data->length = length;
856 desc->data->buffer = disc->udf_pd[0];
857 disc->udf_pd[0]->descTag = query_tag(disc, pvds, desc, 1);
858
859 desc = set_desc(disc, rvds, TAG_IDENT_PD, offset, length, NULL);
860 memcpy(disc->udf_pd[1] = desc->data->buffer, disc->udf_pd[0], length);
861 disc->udf_pd[1]->descTag = query_tag(disc, rvds, desc, 1);
862 }
863
864 void setup_usd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
865 {
866 struct udf_desc *desc;
867 struct udf_extent *ext;
868 int count = 0;
869 int length = sizeof(struct unallocSpaceDesc);
870
871 ext = next_extent(disc->head, USPACE);
872 while (ext)
873 {
874 length += sizeof(extent_ad);
875 disc->udf_usd[0] = realloc(disc->udf_usd[0], length);
876 disc->udf_usd[0]->numAllocDescs = cpu_to_le32(le32_to_cpu(disc->udf_usd[0]->numAllocDescs)+1);
877 disc->udf_usd[0]->allocDescs[count].extLength = cpu_to_le32(ext->blocks * disc->blocksize);
878 disc->udf_usd[0]->allocDescs[count].extLocation = cpu_to_le32(ext->start);
879 count ++;
880 ext = next_extent(ext->next, USPACE);
881 }
882
883 desc = set_desc(disc, pvds, TAG_IDENT_USD, offset, 0, NULL);
884 desc->length = desc->data->length = length;
885 desc->data->buffer = disc->udf_usd[0];
886 disc->udf_usd[0]->descTag = query_tag(disc, pvds, desc, 1);
887
888 desc = set_desc(disc, rvds, TAG_IDENT_USD, offset, length, NULL);
889 memcpy(disc->udf_usd[1] = desc->data->buffer, disc->udf_usd[0], length);
890 disc->udf_usd[1]->descTag = query_tag(disc, rvds, desc, 1);
891 }
892
893 void setup_iuvd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
894 {
895 struct udf_desc *desc;
896 int length = sizeof(struct impUseVolDesc);
897
898 // ((uint16_t *)disc->udf_iuvd[0]->impIdent.identSuffix)[0] = cpu_to_le16(disc->udf_rev);
899
900 desc = set_desc(disc, pvds, TAG_IDENT_IUVD, offset, 0, NULL);
901 desc->length = desc->data->length = length;
902 desc->data->buffer = disc->udf_iuvd[0];
903 disc->udf_iuvd[0]->descTag = query_tag(disc, pvds, desc, 1);
904
905 desc = set_desc(disc, rvds, TAG_IDENT_IUVD, offset, length, NULL);
906 memcpy(disc->udf_iuvd[1] = desc->data->buffer, disc->udf_iuvd[0], length);
907 disc->udf_iuvd[1]->descTag = query_tag(disc, rvds, desc, 1);
908 }
909
910 void setup_td(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
911 {
912 struct udf_desc *desc;
913 int length = sizeof(struct terminatingDesc);
914
915 desc = set_desc(disc, pvds, TAG_IDENT_TD, offset, 0, NULL);
916 desc->length = desc->data->length = length;
917 desc->data->buffer = disc->udf_td[0];
918 disc->udf_td[0]->descTag = query_tag(disc, pvds, desc, 1);
919
920 desc = set_desc(disc, rvds, TAG_IDENT_TD, offset, length, NULL);
921 memcpy(disc->udf_td[1] = desc->data->buffer, disc->udf_td[0], length);
922 disc->udf_td[1]->descTag = query_tag(disc, rvds, desc, 1);
923 }
924
925 void setup_lvid(struct udf_disc *disc, struct udf_extent *lvid)
926 {
927 struct udf_desc *desc;
928 // struct udf_extent *ext;
929 int length = sizeof(struct logicalVolIntegrityDesc) + le32_to_cpu(disc->udf_lvid->numOfPartitions) * sizeof(uint32_t) * 2 + le32_to_cpu(disc->udf_lvid->lengthOfImpUse);
930
931 // ext = next_extent(disc->head, PSPACE);
932 // disc->udf_lvid->freeSpaceTable[0] = cpu_to_le32(ext->blocks);
933 // disc->udf_lvid->sizeTable[1] = cpu_to_le32(ext->blocks);
934 if (disc->flags & FLAG_VAT)
935 disc->udf_lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
936 desc = set_desc(disc, lvid, TAG_IDENT_LVID, 0, 0, NULL);
937 desc->length = desc->data->length = length;
938 desc->data->buffer = disc->udf_lvid;
939 disc->udf_lvid->descTag = query_tag(disc, lvid, desc, 1);
940
941 if (!(disc->flags & FLAG_BLANK_TERMINAL) && lvid->blocks > 1)
942 {
943 desc = set_desc(disc, lvid, TAG_IDENT_TD, 1, sizeof(struct terminatingDesc), NULL);
944 ((struct terminatingDesc *)desc->data->buffer)->descTag = query_tag(disc, lvid, desc, 1);
945 }
946 }
947
948 void setup_stable(struct udf_disc *disc, struct udf_extent *stable[4], struct udf_extent *sspace)
949 {
950 struct udf_desc *desc;
951 int i, length = 0, num, packetlen;
952 struct sparablePartitionMap *spm;
953
954 spm = find_type2_sparable_partition(disc, 0);
955 packetlen = le16_to_cpu(spm->packetLength);
956 num = sspace->blocks / packetlen;
957 length = sizeof(struct sparingTable) + num * sizeof(struct sparingEntry);
958 spm->sizeSparingTable = cpu_to_le32(length);
959 for (i=0; i<spm->numSparingTables; i++)
960 spm->locSparingTable[i] = cpu_to_le32(stable[i]->start);
961
962 disc->udf_stable[0] = realloc(disc->udf_stable[0], length);
963 disc->udf_stable[0]->reallocationTableLen = cpu_to_le16(num);
964 for (i=0; i<num; i++)
965 {
966 disc->udf_stable[0]->mapEntry[i].origLocation = cpu_to_le32(0xFFFFFFFF);
967 disc->udf_stable[0]->mapEntry[i].mappedLocation = cpu_to_le32(sspace->start + (i * packetlen));
968 }
969 desc = set_desc(disc, stable[0], 0, 0, 0, NULL);
970 desc->length = desc->data->length = length;
971 desc->data->buffer = disc->udf_stable[0];
972 disc->udf_stable[0]->descTag = query_tag(disc, stable[0], desc, 1);
973
974 for (i=1; i<4 && stable[i]; i++)
975 {
976 desc = set_desc(disc, stable[i], 0, 0, length, NULL);
977 memcpy(disc->udf_stable[i] = desc->data->buffer, disc->udf_stable[0], length);
978 disc->udf_stable[i]->descTag = query_tag(disc, stable[i], desc, 1);
979 }
980 }
981
982 void setup_vat(struct udf_disc *disc, struct udf_extent *ext)
983 {
984 uint32_t offset = 0;
985 struct udf_desc *vtable;
986 struct udf_data *data;
987 uint32_t len;
988 struct virtualAllocationTable15 *vat15;
989 struct virtualAllocationTable20 *vat20;
990
991 ext = disc->tail;
992
993 if (disc->udf_rev >= 0x0200)
994 {
995 vtable = udf_create(disc, ext, (uint8_t *)"\x08" UDF_ID_ALLOC, strlen(UDF_ID_ALLOC)+1, offset, NULL, FID_FILE_CHAR_HIDDEN, ICBTAG_FILE_TYPE_VAT20, 0);
996 len = sizeof(struct virtualAllocationTable20);
997 data = alloc_data(&default_vat20, len);
998 vat20 = data->buffer;
999 vat20->numFiles = query_lvidiu(disc)->numFiles;
1000 vat20->numDirs = query_lvidiu(disc)->numDirs;
1001 vat20->logicalVolIdent[127] = strlen((char *)vat20->logicalVolIdent);
1002 insert_data(disc, ext, vtable, data);
1003 data = alloc_data(disc->vat, disc->vat_entries * sizeof(uint32_t));
1004 insert_data(disc, ext, vtable, data);
1005 }
1006 else
1007 {
1008 vtable = udf_create(disc, ext, (uint8_t *)"\x08" UDF_ID_ALLOC, strlen(UDF_ID_ALLOC)+1, offset, NULL, FID_FILE_CHAR_HIDDEN, ICBTAG_FILE_TYPE_UNDEF, 0);
1009 len = sizeof(struct virtualAllocationTable15);
1010 data = alloc_data(disc->vat, disc->vat_entries * sizeof(uint32_t));
1011 insert_data(disc, ext, vtable, data);
1012 data = alloc_data(&default_vat15, len);
1013 vat15 = data->buffer;
1014 ((uint16_t *)vat15->vatIdent.identSuffix)[0] = cpu_to_le16(disc->udf_rev);
1015 insert_data(disc, ext, vtable, data);
1016 }
1017 }
1018
1019 void add_type1_partition(struct udf_disc *disc, uint16_t partitionNum)
1020 {
1021 struct genericPartitionMap1 *pm;
1022 int mtl = le32_to_cpu(disc->udf_lvd[0]->mapTableLength);
1023 int npm = le32_to_cpu(disc->udf_lvd[0]->numPartitionMaps);
1024
1025 disc->udf_lvd[0] = realloc(disc->udf_lvd[0],
1026 sizeof(struct logicalVolDesc) + mtl +
1027 sizeof(struct genericPartitionMap1));
1028
1029 pm = (struct genericPartitionMap1 *)&disc->udf_lvd[0]->partitionMaps[mtl];
1030 mtl += sizeof(struct genericPartitionMap1);
1031
1032 disc->udf_lvd[0]->mapTableLength = cpu_to_le32(mtl);
1033 disc->udf_lvd[0]->numPartitionMaps = cpu_to_le32(npm + 1);
1034 pm->partitionMapType = 1;
1035 pm->partitionMapLength = sizeof(struct genericPartitionMap1);
1036 pm->volSeqNum = cpu_to_le16(1);
1037 pm->partitionNum = cpu_to_le16(partitionNum);
1038
1039 disc->udf_lvid->numOfPartitions = cpu_to_le32(npm + 1);
1040 disc->udf_lvid = realloc(disc->udf_lvid,
1041 sizeof(struct logicalVolIntegrityDesc) +
1042 sizeof(uint32_t) * 2 * (npm + 1) +
1043 sizeof(struct logicalVolIntegrityDescImpUse));
1044 memmove(&disc->udf_lvid->impUse[sizeof(uint32_t) * 2 * (npm + 1)],
1045 &disc->udf_lvid->impUse[sizeof(uint32_t) * 2 * npm],
1046 sizeof(struct logicalVolIntegrityDescImpUse));
1047 memmove(&disc->udf_lvid->impUse[sizeof(uint32_t) * (npm + 1)],
1048 &disc->udf_lvid->impUse[sizeof(uint32_t) * npm],
1049 sizeof(uint32_t));
1050 }
1051
1052 void add_type2_sparable_partition(struct udf_disc *disc, uint16_t partitionNum, uint8_t spartable, uint16_t packetlen)
1053 {
1054 struct sparablePartitionMap *pm;
1055 int mtl = le32_to_cpu(disc->udf_lvd[0]->mapTableLength);
1056 int npm = le32_to_cpu(disc->udf_lvd[0]->numPartitionMaps);
1057
1058 disc->udf_lvd[0] = realloc(disc->udf_lvd[0],
1059 sizeof(struct logicalVolDesc) + mtl +
1060 sizeof(struct sparablePartitionMap));
1061
1062 pm = (struct sparablePartitionMap *)&disc->udf_lvd[0]->partitionMaps[mtl];
1063 mtl += sizeof(struct sparablePartitionMap);
1064
1065 disc->udf_lvd[0]->mapTableLength = cpu_to_le32(mtl);
1066 disc->udf_lvd[0]->numPartitionMaps = cpu_to_le32(npm + 1);
1067 memcpy(pm, &default_sparmap, sizeof(struct sparablePartitionMap));
1068 pm->partitionNum = cpu_to_le16(partitionNum);
1069 ((uint16_t *)pm->partIdent.identSuffix)[0] = cpu_to_le16(disc->udf_rev);
1070 if (packetlen)
1071 pm->packetLength = cpu_to_le16(packetlen);
1072 pm->numSparingTables = spartable;
1073 pm->sizeSparingTable = cpu_to_le32(sizeof(struct sparingTable));
1074
1075 disc->udf_lvid->numOfPartitions = cpu_to_le32(npm + 1);
1076 disc->udf_lvid = realloc(disc->udf_lvid,
1077 sizeof(struct logicalVolIntegrityDesc) +
1078 sizeof(uint32_t) * 2 * (npm + 1) +
1079 sizeof(struct logicalVolIntegrityDescImpUse));
1080 memmove(&disc->udf_lvid->impUse[sizeof(uint32_t) * 2 * (npm + 1)],
1081 &disc->udf_lvid->impUse[sizeof(uint32_t) * 2 * npm],
1082 sizeof(struct logicalVolIntegrityDescImpUse));
1083 memmove(&disc->udf_lvid->impUse[sizeof(uint32_t) * (npm + 1)],
1084 &disc->udf_lvid->impUse[sizeof(uint32_t) * npm],
1085 sizeof(uint32_t));
1086 }
1087
1088 struct sparablePartitionMap *find_type2_sparable_partition(struct udf_disc *disc, uint16_t partitionNum)
1089 {
1090 int i, npm, mtl = 0;
1091 struct genericPartitionMap *pm;
1092 struct udfPartitionMap2 *pm2;
1093 struct sparablePartitionMap *spm;
1094
1095 npm = le32_to_cpu(disc->udf_lvd[0]->numPartitionMaps);
1096
1097 for (i=0; i<npm; i++)
1098 {
1099 pm = (struct genericPartitionMap *)&disc->udf_lvd[0]->partitionMaps[mtl];
1100 if (pm->partitionMapType == 2)
1101 {
1102 pm2 = (struct udfPartitionMap2 *)&disc->udf_lvd[0]->partitionMaps[mtl];
1103 if (!strncmp((char *)pm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
1104 {
1105 spm = (struct sparablePartitionMap *)&disc->udf_lvd[0]->partitionMaps[mtl];
1106 if (le16_to_cpu(spm->partitionNum) == partitionNum)
1107 return spm;
1108 }
1109 }
1110 mtl += pm->partitionMapLength;
1111 }
1112 return NULL;
1113 }
1114
1115 void add_type2_virtual_partition(struct udf_disc *disc, uint16_t partitionNum)
1116 {
1117 struct virtualPartitionMap *pm;
1118 int mtl = le32_to_cpu(disc->udf_lvd[0]->mapTableLength);
1119 int npm = le32_to_cpu(disc->udf_lvd[0]->numPartitionMaps);
1120
1121 disc->udf_lvd[0] = realloc(disc->udf_lvd[0],
1122 sizeof(struct logicalVolDesc) + mtl +
1123 sizeof(struct virtualPartitionMap));
1124
1125 pm = (struct virtualPartitionMap *)&disc->udf_lvd[0]->partitionMaps[mtl];
1126 mtl += sizeof(struct virtualPartitionMap);
1127
1128 disc->udf_lvd[0]->mapTableLength = cpu_to_le32(mtl);
1129 disc->udf_lvd[0]->numPartitionMaps = cpu_to_le32(npm + 1);
1130 memcpy(pm, &default_virtmap, sizeof(struct virtualPartitionMap));
1131 pm->partitionNum = cpu_to_le16(partitionNum);
1132 ((uint16_t *)pm->partIdent.identSuffix)[0] = cpu_to_le16(disc->udf_rev);
1133
1134 disc->udf_lvid->numOfPartitions = cpu_to_le32(npm + 1);
1135 disc->udf_lvid = realloc(disc->udf_lvid,
1136 sizeof(struct logicalVolIntegrityDesc) +
1137 sizeof(uint32_t) * 2 * (npm + 1) +
1138 sizeof(struct logicalVolIntegrityDescImpUse));
1139 memmove(&disc->udf_lvid->impUse[sizeof(uint32_t) * 2 * (npm + 1)],
1140 &disc->udf_lvid->impUse[sizeof(uint32_t) * 2 * npm],
1141 sizeof(struct logicalVolIntegrityDescImpUse));
1142 memmove(&disc->udf_lvid->impUse[sizeof(uint32_t) * (npm + 1)],
1143 &disc->udf_lvid->impUse[sizeof(uint32_t) * npm],
1144 sizeof(uint32_t));
1145 }
1146
1147
1148 char *udf_space_type_str[UDF_SPACE_TYPE_SIZE] = { "RESERVED", "VRS", "ANCHOR", "PVDS", "RVDS", "LVID", "STABLE", "SSPACE", "PSPACE", "USPACE", "BAD" };
FID_FILE_CHAR_METADATA
#define FID_FILE_CHAR_METADATA
Definition: ecma_167.h:478
setup_usd
void setup_usd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
Definition: mkudffs.c:864
virtualAllocationTable20::logicalVolIdent
dstring logicalVolIdent[128]
Definition: osta_udf.h:171
udf_extent::blocks
uint32_t blocks
Definition: libudffs.h:135
udf_query_tag
tag udf_query_tag(struct udf_disc *disc, uint16_t Ident, uint16_t SerialNum, uint32_t Location, struct udf_data *data, uint16_t length)
create an on-disc format tag from udf_descriptor components
Definition: file.c:129
ICBTAG_FLAG_STREAM
#define ICBTAG_FLAG_STREAM
Definition: ecma_167.h:540
TAG_IDENT_PVD
#define TAG_IDENT_PVD
Definition: ecma_167.h:182
PD_PARTITION_CONTENTS_NSR03
#define PD_PARTITION_CONTENTS_NSR03
Definition: ecma_167.h:286
fileSetDesc::rootDirectoryICB
long_ad rootDirectoryICB
Definition: ecma_167.h:441
extendedFileEntry::icbTag
icbtag icbTag
Definition: ecma_167.h:801
UDF_ID_ALLOC
#define UDF_ID_ALLOC
Definition: osta_udf.h:65
PD_PARTITION_CONTENTS_NSR02
#define PD_PARTITION_CONTENTS_NSR02
Definition: ecma_167.h:280
FLAG_BRIDGE
#define FLAG_BRIDGE
Definition: libudffs.h:53
udf_disc::vat_entries
uint64_t vat_entries
Definition: libudffs.h:123
FLAG_CLOSED
#define FLAG_CLOSED
Definition: libudffs.h:54
partitionDesc::partitionContentsUse
uint8_t partitionContentsUse[128]
Definition: ecma_167.h:267
add_type2_virtual_partition
void add_type2_virtual_partition(struct udf_disc *disc, uint16_t partitionNum)
Definition: mkudffs.c:1115
logicalVolIdent
dstring logicalVolIdent[128]
Definition: ecma_167.h:67
default_pd
struct partitionDesc default_pd
Definition: defaults.c:218
setup_lvd
void setup_lvd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, struct udf_extent *lvid, uint32_t offset)
Definition: mkudffs.c:815
logicalVolDesc::integritySeqExt
extent_ad integritySeqExt
Definition: ecma_167.h:309
primaryVolDesc::recordingDateAndTime
timestamp recordingDateAndTime
Definition: ecma_167.h:221
setup_td
void setup_td(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
Definition: mkudffs.c:910
cpu_to_le32
#define cpu_to_le32(x)
Definition: bswap.h:247
default_fsd
struct fileSetDesc default_fsd
Definition: defaults.c:390
extendedFileEntry
Definition: ecma_167.h:798
sparingEntry
Definition: osta_udf.h:186
VSD_STD_ID_NSR03
#define VSD_STD_ID_NSR03
Definition: ecma_167.h:118
virtualPartitionMap::partitionNum
uint16_t partitionNum
Definition: osta_udf.h:136
udf_disc::tail
struct udf_extent * tail
Definition: libudffs.h:128
FLAG_BLANK_TERMINAL
#define FLAG_BLANK_TERMINAL
Definition: libudffs.h:51
udf_disc::blocksize
uint16_t blocksize
Definition: libudffs.h:98
udf_disc::udf_lvid
struct logicalVolIntegrityDesc * udf_lvid
Definition: libudffs.h:118
PVDS
Definition: libudffs.h:66
fileEntry::icbTag
icbtag icbTag
Definition: ecma_167.h:561
next_desc
struct udf_desc * next_desc(struct udf_desc *, uint16_t)
find the next udf_descriptor of a given tag ident on a udf_descriptor list
Definition: extent.c:351
sparingTable::mapEntry
struct sparingEntry mapEntry[0]
Definition: osta_udf.h:199
default_usd
struct unallocSpaceDesc default_usd
Definition: defaults.c:245
logicalVolIntegrityDescImpUse::numDirs
uint32_t numDirs
Definition: osta_udf.h:98
sparingTable
Definition: osta_udf.h:192
find_extent
struct udf_extent * find_extent(struct udf_disc *, uint32_t)
find the udf_extent on a udf_disc's udf_extent list which contains a particular block ...
Definition: extent.c:207
anchorVolDescPtr::descTag
tag descTag
Definition: ecma_167.h:235
udfPartitionMap2
Definition: osta_udf.h:118
LVID_INTEGRITY_TYPE_OPEN
#define LVID_INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:375
udf_disc::udf_pd
struct partitionDesc * udf_pd[2]
Definition: libudffs.h:114
sparablePartitionMap::sizeSparingTable
uint32_t sizeSparingTable
Definition: osta_udf.h:152
setup_pd
void setup_pd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
Definition: mkudffs.c:834
sparablePartitionMap::locSparingTable
uint32_t locSparingTable[4]
Definition: osta_udf.h:153
USPACE
Definition: libudffs.h:72
udf_extent::next
struct udf_extent * next
Definition: libudffs.h:140
FLAG_EFE
#define FLAG_EFE
Definition: libudffs.h:43
FID_FILE_CHAR_PARENT
#define FID_FILE_CHAR_PARENT
Definition: ecma_167.h:477
ICBTAG_FILE_TYPE_USE
#define ICBTAG_FILE_TYPE_USE
Definition: ecma_167.h:510
unallocSpaceDesc::descTag
tag descTag
Definition: ecma_167.h:346
fileSetDesc::fileSetIdent
dstring fileSetIdent[32]
Definition: ecma_167.h:438
genericPartitionMap1::partitionMapType
uint8_t partitionMapType
Definition: ecma_167.h:329
udf_create
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)
create a file tag:FE/EFE udf_descriptor and add the file to a directory
Definition: file.c:466
VSD_STD_ID_LEN
#define VSD_STD_ID_LEN
Definition: ecma_167.h:100
terminalEntry::descTag
tag descTag
Definition: ecma_167.h:553
anchorVolDescPtr
Definition: ecma_167.h:233
udf_disc::vat
uint32_t * vat
Definition: libudffs.h:122
partitionDesc::partitionStartingLocation
uint32_t partitionStartingLocation
Definition: ecma_167.h:269
unallocSpaceDesc::numAllocDescs
uint32_t numAllocDescs
Definition: ecma_167.h:348
logicalVolIntegrityDescImpUse::numFiles
uint32_t numFiles
Definition: osta_udf.h:97
setup_vrs
void setup_vrs(struct udf_disc *disc)
Definition: mkudffs.c:367
ICBTAG_FLAG_AD_MASK
#define ICBTAG_FLAG_AD_MASK
Definition: ecma_167.h:525
sparablePartitionMap
Definition: osta_udf.h:141
mkudffs.h
FLAG_UNALLOC_TABLE
#define FLAG_UNALLOC_TABLE
Definition: libudffs.h:38
sparingTable::descTag
tag descTag
Definition: osta_udf.h:194
udf_extent::tail
struct udf_desc * tail
Definition: libudffs.h:138
LVInfo2
dstring LVInfo2[36]
Definition: osta_udf.h:164
logicalVolDesc::mapTableLength
uint32_t mapTableLength
Definition: ecma_167.h:305
TAG_IDENT_TD
#define TAG_IDENT_TD
Definition: ecma_167.h:189
clear_bits
static void clear_bits(uint8_t *bitmap, uint32_t offset, uint64_t length)
Definition: file.h:37
udf_disc::udf_pvd
struct primaryVolDesc * udf_pvd[2]
Definition: libudffs.h:112
virtualPartitionMap::partIdent
regid partIdent
Definition: osta_udf.h:134
partitionNum
uint16_t partitionNum
Definition: ecma_167.h:67
setup_iuvd
void setup_iuvd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
Definition: mkudffs.c:893
LVID
Definition: libudffs.h:68
virtualAllocationTable15
Definition: osta_udf.h:157
udf_data::prev
struct udf_data * prev
Definition: libudffs.h:160
FLAG_UNALLOC_BITMAP
#define FLAG_UNALLOC_BITMAP
Definition: libudffs.h:37
set_extent
struct udf_extent * set_extent(struct udf_disc *, enum udf_space_type, uint32_t, uint32_t)
set the space_type, location and size of a udf_extent on a udf_disc's udf_extent list, splitting the udf_extent if required to have the returned udf_extent only contain the requested blocks
Definition: extent.c:230
impUseVolDescImpUse::logicalVolIdent
dstring logicalVolIdent[128]
Definition: osta_udf.h:110
udf_disc::head
struct udf_extent * head
Definition: libudffs.h:127
impUseVolDescImpUse::LVInfo1
dstring LVInfo1[36]
Definition: osta_udf.h:111
udf_desc::length
uint64_t length
Definition: libudffs.h:148
impUseVolDescImpUse
Definition: osta_udf.h:107
udf_disc::udf_anchor
struct anchorVolDescPtr * udf_anchor[3]
Definition: libudffs.h:111
default_vat15
struct virtualAllocationTable15 default_vat15
Definition: defaults.c:343
RESERVED
Definition: libudffs.h:63
setup_partition
void setup_partition(struct udf_disc *disc)
Definition: mkudffs.c:449
cpu_to_le16
#define cpu_to_le16(x)
Definition: bswap.h:246
file.h
find_desc
struct udf_desc * find_desc(struct udf_extent *, uint32_t)
search the udf_descriptor list of a udf_extent to find the udf_descriptor that describes a particular...
Definition: extent.c:366
spaceBitmapDesc::descTag
tag descTag
Definition: ecma_167.h:751
sparingTable::reallocationTableLen
uint16_t reallocationTableLen
Definition: osta_udf.h:196
logicalVolDesc::descTag
tag descTag
Definition: ecma_167.h:298
unallocSpaceEntry
Definition: ecma_167.h:740
FLAG_FREED_TABLE
#define FLAG_FREED_TABLE
Definition: libudffs.h:36
udf_set_version
int udf_set_version(struct udf_disc *disc, int udf_rev)
Definition: mkudffs.c:152
udf_desc::next
struct udf_desc * next
Definition: libudffs.h:151
udf_desc::data
struct udf_data * data
Definition: libudffs.h:149
setup_root
int setup_root(struct udf_disc *disc, struct udf_extent *pspace)
Definition: mkudffs.c:647
partitionDesc::descTag
tag descTag
Definition: ecma_167.h:262
logicalVolIntegrityDesc::freeSpaceTable
uint32_t freeSpaceTable[0]
Definition: ecma_167.h:369
insert_fid
void insert_fid(struct udf_disc *disc, struct udf_extent *pspace, struct udf_desc *desc, struct udf_desc *parent, uint8_t *name, uint8_t length, uint8_t filechar)
create a FID and add it to a directory then increment the file link count
Definition: file.c:385
udf_data::length
uint64_t length
Definition: libudffs.h:157
VRS
Definition: libudffs.h:64
ANCHOR
Definition: libudffs.h:65
dump_space
void dump_space(struct udf_disc *disc)
Definition: mkudffs.c:331
next_extent_size
uint32_t next_extent_size(struct udf_extent *, enum udf_space_type, uint32_t, uint32_t)
find the next udf_extent of a given space_type on a udf_extent list that satisfies the necessary size...
Definition: extent.c:129
logicalVolIntegrityDescImpUse::maxUDFWriteRev
uint16_t maxUDFWriteRev
Definition: osta_udf.h:101
fileSetDesc::logicalVolIdent
dstring logicalVolIdent[128]
Definition: ecma_167.h:436
udf_init_disc
void udf_init_disc(struct udf_disc *disc)
Definition: mkudffs.c:46
TAG_IDENT_SBD
#define TAG_IDENT_SBD
Definition: ecma_167.h:420
UDF_SPACE_TYPE_SIZE
Definition: libudffs.h:74
sparablePartitionMap::packetLength
uint16_t packetLength
Definition: osta_udf.h:149
primaryVolDesc::descTag
tag descTag
Definition: ecma_167.h:205
virtualAllocationTable20::numFiles
uint32_t numFiles
Definition: osta_udf.h:173
TAG_IDENT_IUVD
#define TAG_IDENT_IUVD
Definition: ecma_167.h:185
ICBTAG_FLAG_SYSTEM
#define ICBTAG_FLAG_SYSTEM
Definition: ecma_167.h:537
query_tag
tag query_tag(struct udf_disc *disc, struct udf_extent *ext, struct udf_desc *desc, uint16_t SerialNum)
create an on-disc format tag for a udf_descriptor of a udf_extent with any space_type. For type:PSPACE the block number will be relative to to the first block of the partition, otherwise it will be relative to the first block of the media
Definition: file.c:83
FID_FILE_CHAR_DIRECTORY
#define FID_FILE_CHAR_DIRECTORY
Definition: ecma_167.h:475
terminalEntry
Definition: ecma_167.h:551
VDS_SIZE
Definition: libudffs.h:87
TAG_IDENT_PD
#define TAG_IDENT_PD
Definition: ecma_167.h:186
logicalVolDesc
Definition: ecma_167.h:296
partitionHeaderDesc
Definition: ecma_167.h:449
impUseVolDescImpUse::LVInfo2
dstring LVInfo2[36]
Definition: osta_udf.h:112
SSPACE_SIZE
Definition: libudffs.h:90
udf_data::next
struct udf_data * next
Definition: libudffs.h:159
ICBTAG_FLAG_AD_SHORT
#define ICBTAG_FLAG_AD_SHORT
Definition: ecma_167.h:526
udf_desc::ident
uint16_t ident
Definition: libudffs.h:146
fileSetDesc::descTag
tag descTag
Definition: ecma_167.h:427
setup_vat
void setup_vat(struct udf_disc *disc, struct udf_extent *ext)
Definition: mkudffs.c:982
default_lvidiu
struct logicalVolIntegrityDescImpUse default_lvidiu
Definition: defaults.c:282
primaryVolDesc
Definition: ecma_167.h:203
lvid
struct logicalVolIntegrityDesc * lvid
Definition: wrudf.c:71
primaryVolDesc::volSetIdent
dstring volSetIdent[128]
Definition: ecma_167.h:215
unallocSpaceDesc::allocDescs
extent_ad allocDescs[0]
Definition: ecma_167.h:349
udf_disc::udf_usd
struct unallocSpaceDesc * udf_usd[2]
Definition: libudffs.h:115
partitionHeaderDesc::freedSpaceBitmap
short_ad freedSpaceBitmap
Definition: ecma_167.h:455
primaryVolDesc::volIdent
dstring volIdent[32]
Definition: ecma_167.h:208
write_disc
int write_disc(struct udf_disc *disc)
Definition: mkudffs.c:351
volStructDesc::stdIdent
uint8_t stdIdent[VSD_STD_ID_LEN]
Definition: ecma_167.h:104
setup_space
int setup_space(struct udf_disc *disc, struct udf_extent *pspace, uint32_t offset)
Definition: mkudffs.c:465
setup_fileset
int setup_fileset(struct udf_disc *disc, struct udf_extent *pspace)
Definition: mkudffs.c:611
default_vat20
struct virtualAllocationTable20 default_vat20
Definition: defaults.c:360
udf_data
Definition: libudffs.h:155
FLAG_FREED_BITMAP
#define FLAG_FREED_BITMAP
Definition: libudffs.h:35
TAG_IDENT_FSD
#define TAG_IDENT_FSD
Definition: ecma_167.h:412
logicalVolIntegrityDesc::impUse
uint8_t impUse[0]
Definition: ecma_167.h:371
udf_sizing::denomSize
uint32_t denomSize
Definition: libudffs.h:81
TAG_IDENT_LVD
#define TAG_IDENT_LVD
Definition: ecma_167.h:187
FLAG_SPACE_BITMAP
#define FLAG_SPACE_BITMAP
Definition: libudffs.h:39
FLAG_UTF8
#define FLAG_UTF8
Definition: libudffs.h:47
alloc_data
struct udf_data * alloc_data(void *, int)
allocate a new udf_data item and initialize it with either allocated zeros or the supplied payload ...
Definition: extent.c:462
udf_disc::sizing
struct udf_sizing sizing[UDF_ALLOC_TYPE_SIZE]
Definition: libudffs.h:105
default_iuvdiu
struct impUseVolDescImpUse default_iuvdiu
Definition: defaults.c:172
EXT_NOT_RECORDED_ALLOCATED
#define EXT_NOT_RECORDED_ALLOCATED
Definition: ecma_167.h:773
LVInfo1
dstring LVInfo1[36]
Definition: osta_udf.h:163
split_space
void split_space(struct udf_disc *disc)
Definition: mkudffs.c:198
ICBTAG_FILE_TYPE_REGULAR
#define ICBTAG_FILE_TYPE_REGULAR
Definition: ecma_167.h:514
impUseVolDesc::impIdent
regid impIdent
Definition: ecma_167.h:255
fileEntry
Definition: ecma_167.h:558
SSPACE
Definition: libudffs.h:70
ICBTAG_FILE_TYPE_STREAMDIR
#define ICBTAG_FILE_TYPE_STREAMDIR
Definition: ecma_167.h:522
PSPACE_SIZE
Definition: libudffs.h:91
setup_anchor
void setup_anchor(struct udf_disc *disc)
Definition: mkudffs.c:402
fileSetDesc
Definition: ecma_167.h:425
VSD_STD_ID_BEA01
#define VSD_STD_ID_BEA01
Definition: ecma_167.h:114
udf_extent
Definition: libudffs.h:131
udf_disc::udf_vrs
struct volStructDesc * udf_vrs[3]
Definition: libudffs.h:110
TAG_IDENT_LVID
#define TAG_IDENT_LVID
Definition: ecma_167.h:190
logicalVolDesc::domainIdent
regid domainIdent
Definition: ecma_167.h:303
unallocSpaceEntry::allocDescs
uint8_t allocDescs[0]
Definition: ecma_167.h:745
PSPACE
Definition: libudffs.h:71
sparablePartitionMap::partitionNum
uint16_t partitionNum
Definition: osta_udf.h:148
logicalVolIntegrityDesc::descTag
tag descTag
Definition: ecma_167.h:362
partitionHeaderDesc::unallocSpaceBitmap
short_ad unallocSpaceBitmap
Definition: ecma_167.h:452
fileSetDesc::domainIdent
regid domainIdent
Definition: ecma_167.h:442
udf_desc::prev
struct udf_desc * prev
Definition: libudffs.h:152
LVID_SIZE
Definition: libudffs.h:88
default_td
struct terminatingDesc default_td
Definition: defaults.c:257
genericPartitionMap1::partitionNum
uint16_t partitionNum
Definition: ecma_167.h:332
genericPartitionMap1::partitionMapLength
uint8_t partitionMapLength
Definition: ecma_167.h:330
UDF_ID_SPARABLE
#define UDF_ID_SPARABLE
Definition: osta_udf.h:64
udf_extent::start
uint32_t start
Definition: libudffs.h:134
set_desc
struct udf_desc * set_desc(struct udf_disc *, struct udf_extent *, uint16_t, uint32_t, uint32_t, struct udf_data *)
allocate a new udf_descriptor having a udf_data item and insert it into the udf_descriptor list of a ...
Definition: extent.c:393
query_lvidiu
static struct logicalVolIntegrityDescImpUse * query_lvidiu(struct udf_disc *disc)
Definition: file.h:50
partitionDesc::partitionLength
uint32_t partitionLength
Definition: ecma_167.h:270
virtualAllocationTable20
Definition: osta_udf.h:167
STABLE
Definition: libudffs.h:69
partitionDesc::partitionContents
regid partitionContents
Definition: ecma_167.h:266
logicalVolDesc::logicalVolIdent
dstring logicalVolIdent[128]
Definition: ecma_167.h:301
fileEntry::descTag
tag descTag
Definition: ecma_167.h:560
sparingEntry::mappedLocation
uint32_t mappedLocation
Definition: osta_udf.h:189
default_virtmap
struct virtualPartitionMap default_virtmap
Definition: defaults.c:371
VSD_STD_ID_TEA01
#define VSD_STD_ID_TEA01
Definition: ecma_167.h:119
udf_disc::udf_td
struct terminatingDesc * udf_td[2]
Definition: libudffs.h:117
TAG_IDENT_TE
#define TAG_IDENT_TE
Definition: ecma_167.h:416
virtualAllocationTable15::vatIdent
regid vatIdent
Definition: osta_udf.h:160
logicalVolDesc::numPartitionMaps
uint32_t numPartitionMaps
Definition: ecma_167.h:306
udf_sizing::minSize
uint32_t minSize
Definition: libudffs.h:82
default_lvid
struct logicalVolIntegrityDesc default_lvid
Definition: defaults.c:268
udf_disc::flags
uint32_t flags
Definition: libudffs.h:100
udfPartitionMap2::partIdent
regid partIdent
Definition: osta_udf.h:123
add_type1_partition
void add_type1_partition(struct udf_disc *disc, uint16_t partitionNum)
Definition: mkudffs.c:1019
fileSetDesc::streamDirectoryICB
long_ad streamDirectoryICB
Definition: ecma_167.h:444
VSD_STD_ID_NSR02
#define VSD_STD_ID_NSR02
Definition: ecma_167.h:110
udf_desc
Definition: libudffs.h:144
fileSetDesc::abstractFileIdent
dstring abstractFileIdent[32]
Definition: ecma_167.h:440
logicalVolIntegrityDesc
Definition: ecma_167.h:360
udf_desc::offset
uint32_t offset
Definition: libudffs.h:147
terminatingDesc
Definition: ecma_167.h:353
LVInfo3
dstring LVInfo3[36]
Definition: osta_udf.h:165
udf_disc
Definition: libudffs.h:95
udf_mkdir
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)
create a directory tag:FE/EFE udf_descriptor and add the directory to a parent directory ...
Definition: file.c:587
udf_alloc_blocks
int udf_alloc_blocks(struct udf_disc *disc, struct udf_extent *pspace, uint32_t start, uint32_t blocks)
allocate blocks on-disc
Definition: file.c:814
virtualAllocationTable20::numDirs
uint32_t numDirs
Definition: osta_udf.h:174
RVDS
Definition: libudffs.h:67
volStructDesc
Definition: ecma_167.h:101
genericPartitionMap1::volSeqNum
uint16_t volSeqNum
Definition: ecma_167.h:331
udf_extent::head
struct udf_desc * head
Definition: libudffs.h:137
impUseVolDesc::descTag
tag descTag
Definition: ecma_167.h:253
unallocSpaceEntry::descTag
tag descTag
Definition: ecma_167.h:742
partitionHeaderDesc::freedSpaceTable
short_ad freedSpaceTable
Definition: ecma_167.h:454
volStructDesc::structVersion
uint8_t structVersion
Definition: ecma_167.h:105
TAG_IDENT_USE
#define TAG_IDENT_USE
Definition: ecma_167.h:419
find_type2_sparable_partition
struct sparablePartitionMap * find_type2_sparable_partition(struct udf_disc *disc, uint16_t partitionNum)
Definition: mkudffs.c:1088
default_stable
struct sparingTable default_stable
Definition: defaults.c:298
logicalVolIntegrityDesc::recordingDateAndTime
timestamp recordingDateAndTime
Definition: ecma_167.h:363
logicalVolIntegrityDescImpUse::minUDFWriteRev
uint16_t minUDFWriteRev
Definition: osta_udf.h:100
insert_data
void insert_data(struct udf_disc *disc, struct udf_extent *pspace, struct udf_desc *desc, struct udf_data *data)
append a udf_data list to a (hidden) VAT file ???
Definition: file.c:333
logicalVolIntegrityDesc::numOfPartitions
uint32_t numOfPartitions
Definition: ecma_167.h:367
anchorVolDescPtr::mainVolDescSeqExt
extent_ad mainVolDescSeqExt
Definition: ecma_167.h:236
logicalVolDesc::partitionMaps
uint8_t partitionMaps[0]
Definition: ecma_167.h:310
extendedFileEntry::descTag
tag descTag
Definition: ecma_167.h:800
logicalVolIntegrityDesc::sizeTable
uint32_t sizeTable[0]
Definition: ecma_167.h:370
logicalVolIntegrityDescImpUse::minUDFReadRev
uint16_t minUDFReadRev
Definition: osta_udf.h:99
fileSetDesc::recordingDateAndTime
timestamp recordingDateAndTime
Definition: ecma_167.h:428
spaceBitmapDesc::numOfBytes
uint32_t numOfBytes
Definition: ecma_167.h:753
STABLE_SIZE
Definition: libudffs.h:89
default_sparmap
struct sparablePartitionMap default_sparmap
Definition: defaults.c:323
unallocSpaceEntry::icbTag
icbtag icbTag
Definition: ecma_167.h:743
query_iuvdiu
static struct impUseVolDescImpUse * query_iuvdiu(struct udf_disc *disc)
Definition: file.h:45
fileSetDesc::copyrightFileIdent
dstring copyrightFileIdent[32]
Definition: ecma_167.h:439
genericPartitionMap
Definition: ecma_167.h:314
default_pvd
struct primaryVolDesc default_pvd
Definition: defaults.c:72
volStructDesc::structType
uint8_t structType
Definition: ecma_167.h:103
ICBTAG_FILE_TYPE_TE
#define ICBTAG_FILE_TYPE_TE
Definition: ecma_167.h:520
prev_extent_size
uint32_t prev_extent_size(struct udf_extent *, enum udf_space_type, uint32_t, uint32_t)
find the previous udf_extent of a given space_type on a udf_extent list that satisfies the necessary ...
Definition: extent.c:176
setup_lvid
void setup_lvid(struct udf_disc *disc, struct udf_extent *lvid)
Definition: mkudffs.c:925
udf_extent::prev
struct udf_extent * prev
Definition: libudffs.h:141
FID_FILE_CHAR_HIDDEN
#define FID_FILE_CHAR_HIDDEN
Definition: ecma_167.h:474
add_type2_sparable_partition
void add_type2_sparable_partition(struct udf_disc *disc, uint16_t partitionNum, uint8_t spartable, uint16_t packetlen)
Definition: mkudffs.c:1052
logicalVolIntegrityDesc::integrityType
uint32_t integrityType
Definition: ecma_167.h:364
udf_disc::blocksize_bits
uint8_t blocksize_bits
Definition: libudffs.h:99
spaceBitmapDesc::numOfBits
uint32_t numOfBits
Definition: ecma_167.h:752
ICBTAG_FILE_TYPE_VAT20
#define ICBTAG_FILE_TYPE_VAT20
Definition: osta_udf.h:183
udf_disc::udf_rev
uint16_t udf_rev
Definition: libudffs.h:97
udf_data::buffer
void * buffer
Definition: libudffs.h:158
setup_vds
void setup_vds(struct udf_disc *disc)
Definition: mkudffs.c:758
UDF_ALLOC_TYPE_SIZE
Definition: libudffs.h:92
next_extent
struct udf_extent * next_extent(struct udf_extent *, enum udf_space_type)
find the next udf_extent of a given space_type on a udf_extent list
Definition: extent.c:112
sparablePartitionMap::partIdent
regid partIdent
Definition: osta_udf.h:146
unallocSpaceEntry::lengthAllocDescs
uint32_t lengthAllocDescs
Definition: ecma_167.h:744
logicalVolIntegrityDesc::lengthOfImpUse
uint32_t lengthOfImpUse
Definition: ecma_167.h:368
logicalVolIntegrityDescImpUse
Definition: osta_udf.h:94
spaceBitmapDesc::bitmap
uint8_t bitmap[0]
Definition: ecma_167.h:754
sparablePartitionMap::numSparingTables
uint8_t numSparingTables
Definition: osta_udf.h:150
udf_disc::udf_fsd
struct fileSetDesc * udf_fsd
Definition: libudffs.h:125
udf_sizing::align
uint32_t align
Definition: libudffs.h:79
unallocSpaceDesc
Definition: ecma_167.h:344
udf_disc::write
int(* write)(struct udf_disc *, struct udf_extent *)
Definition: libudffs.h:107
setup_stable
void setup_stable(struct udf_disc *disc, struct udf_extent *stable[4], struct udf_extent *sspace)
Definition: mkudffs.c:948
FLAG_VAT
#define FLAG_VAT
Definition: libudffs.h:55
genericPartitionMap1
Definition: ecma_167.h:327
anchorVolDescPtr::reserveVolDescSeqExt
extent_ad reserveVolDescSeqExt
Definition: ecma_167.h:237
sparingTable::sparingIdent
regid sparingIdent
Definition: osta_udf.h:195
genericPartitionMap::partitionMapLength
uint8_t partitionMapLength
Definition: ecma_167.h:317
ICBTAG_FILE_TYPE_UNDEF
#define ICBTAG_FILE_TYPE_UNDEF
Definition: ecma_167.h:509
logicalVolDesc::logicalVolContentsUse
uint8_t logicalVolContentsUse[16]
Definition: ecma_167.h:304
anchorVolDescPtr::reserved
uint8_t reserved[480]
Definition: ecma_167.h:238
sparingEntry::origLocation
uint32_t origLocation
Definition: osta_udf.h:188
partitionDesc
Definition: ecma_167.h:260
genericPartitionMap::partitionMapType
uint8_t partitionMapType
Definition: ecma_167.h:316
udf_extent::space_type
enum udf_space_type space_type
Definition: libudffs.h:133
udf_disc::udf_lvd
struct logicalVolDesc * udf_lvd[2]
Definition: libudffs.h:113
partitionHeaderDesc::unallocSpaceTable
short_ad unallocSpaceTable
Definition: ecma_167.h:451
udf_disc::udf_stable
struct sparingTable * udf_stable[4]
Definition: libudffs.h:120
FLAG_STRATEGY4096
#define FLAG_STRATEGY4096
Definition: libudffs.h:50
virtualPartitionMap
Definition: osta_udf.h:129
spaceBitmapDesc
Definition: ecma_167.h:749
udf_sizing::numSize
uint32_t numSize
Definition: libudffs.h:80
udf_space_type_str
char * udf_space_type_str[UDF_SPACE_TYPE_SIZE]
Definition: mkudffs.c:1148
impUseVolDesc
Definition: ecma_167.h:251
default_lvd
struct logicalVolDesc default_lvd
Definition: defaults.c:122
TAG_IDENT_USD
#define TAG_IDENT_USD
Definition: ecma_167.h:188
default_iuvd
struct impUseVolDesc default_iuvd
Definition: defaults.c:195
udf_disc::udf_iuvd
struct impUseVolDesc * udf_iuvd[2]
Definition: libudffs.h:116
FLAG_SPACE_TABLE
#define FLAG_SPACE_TABLE
Definition: libudffs.h:40
TAG_IDENT_AVDP
#define TAG_IDENT_AVDP
Definition: ecma_167.h:183
defaults.h
terminatingDesc::descTag
tag descTag
Definition: ecma_167.h:355
setup_pvd
void setup_pvd(struct udf_disc *disc, struct udf_extent *pvds, struct udf_extent *rvds, uint32_t offset)
Definition: mkudffs.c:800
terminalEntry::icbTag
icbtag icbTag
Definition: ecma_167.h:554
impUseVolDescImpUse::LVInfo3
dstring LVInfo3[36]
Definition: osta_udf.h:113