3 * (c) 2005-2009 Laurent Vivier <Laurent@vivier.eu>
5 * This file has been copied from EMILE, http://emile.sf.net
7 * some parts from mkisofs (c) J. Schilling
11 #include "libiso9660.h"
12 #include "libopenbios/bindings.h"
13 #include "libc/diskio.h"
15 void iso9660_name(iso9660_VOLUME *volume, struct iso_directory_record *idr, char *buffer)
21 if (idr->name_len[0] == 1 && idr->name[0] == 0)
23 else if (idr->name_len[0] == 1 && idr->name[0] == 1)
26 switch (volume->ucs_level) {
34 for (j = 0; j < (int)idr->name_len[0] / 2; j++) {
35 ul = idr->name[j*2+1];
39 * up = unls->unls_uni2cs[uh];
46 * we use only low byte
51 buffer[j] = uc ? uc : '_';
53 buffer[idr->name_len[0]/2] = '\0';
57 * Normal non-Unicode name.
59 strncpy(buffer, idr->name, idr->name_len[0]);
60 buffer[idr->name_len[0]] = 0;
64 * Don't know how to do these yet. Maybe they are the same
65 * as one of the above.
72 iso9660_VOLUME *iso9660_mount(int fd)
74 iso9660_VOLUME* volume;
75 struct iso_primary_descriptor *jpd;
76 struct iso_primary_descriptor ipd;
80 /* read filesystem descriptor */
82 seek_io(fd, 16 * ISOFS_BLOCK_SIZE);
83 read_io(fd, &ipd, sizeof (ipd));
88 * DESC TYPE == 1 (VD_SFS) offset 8 len 1
89 * STR ID == "CDROM" offset 9 len 5
90 * STD_VER == 1 offset 14 len 1
93 /* High Sierra format ? */
95 if ((((char *)&ipd)[8] == 1) &&
96 (strncmp(&((char *)&ipd)[9], "CDROM", 5) == 0) &&
97 (((char *)&ipd)[14] == 1)) {
98 printk("Incompatible format: High Sierra format\n");
105 * DESC TYPE == 1 (VD_PVD) offset 0 len 1
106 * STR ID == "CD001" offset 1 len 5
107 * STD_VER == 1 offset 6 len 1
110 /* NOT ISO 9660 format ? */
112 if ((ipd.type[0] != ISO_VD_PRIMARY) ||
113 (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) ||
114 (ipd.version[0] != 1)) {
122 jpd = (struct iso_primary_descriptor *)
123 malloc(sizeof(struct iso_primary_descriptor));
127 memcpy(jpd, &ipd, sizeof (ipd));
128 while ((uint8_t)jpd->type[0] != ISO_VD_END) {
131 * If Joliet UCS escape sequence found, we may be wrong
134 if (jpd->unused3[0] == '%' &&
135 jpd->unused3[1] == '/' &&
136 (jpd->unused3[3] == '\0' ||
137 jpd->unused3[3] == ' ') &&
138 (jpd->unused3[2] == '@' ||
139 jpd->unused3[2] == 'C' ||
140 jpd->unused3[2] == 'E')) {
142 if (jpd->version[0] != 1)
147 seek_io(fd, block * ISOFS_BLOCK_SIZE);
148 read_io(fd, jpd, sizeof (*jpd));
152 if (((unsigned char) jpd->type[0] == ISO_VD_END)) {
153 memcpy(jpd, &ipd, sizeof (ipd));
155 switch (jpd->unused3[2]) {
167 if (ucs_level && jpd->unused3[3] == ' ')
168 printk("Warning: Joliet escape sequence uses illegal space at offset 3\n");
171 volume = (iso9660_VOLUME*)malloc(sizeof(iso9660_VOLUME));
175 volume->descriptor = jpd;
176 volume->ucs_level = ucs_level;
182 int iso9660_umount(iso9660_VOLUME* volume)
186 free(volume->descriptor);
191 int iso9660_probe(int fd, long long offset)
193 struct iso_primary_descriptor ipd;
195 seek_io(fd, 16 * ISOFS_BLOCK_SIZE + offset);
196 read_io(fd, &ipd, sizeof (ipd));
198 if ((ipd.type[0] != ISO_VD_PRIMARY) ||
199 (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) ||
200 (ipd.version[0] != 1)) {
207 struct iso_directory_record *iso9660_get_root_node(iso9660_VOLUME* volume)
209 return (struct iso_directory_record *)volume->descriptor->root_directory_record;