|
|
1.1 ! root 1: /* ! 2: * ! 3: * (c) 2005-2009 Laurent Vivier <[email protected]> ! 4: * ! 5: * This file has been copied from EMILE, http://emile.sf.net ! 6: * ! 7: * some parts from mkisofs (c) J. Schilling ! 8: * ! 9: */ ! 10: ! 11: #include "libiso9660.h" ! 12: #include "libopenbios/bindings.h" ! 13: #include "libc/diskio.h" ! 14: ! 15: void iso9660_name(iso9660_VOLUME *volume, struct iso_directory_record *idr, char *buffer) ! 16: { ! 17: int j; ! 18: unsigned char ul, uc; ! 19: ! 20: buffer[0] = 0; ! 21: if (idr->name_len[0] == 1 && idr->name[0] == 0) ! 22: strcpy(buffer, "."); ! 23: else if (idr->name_len[0] == 1 && idr->name[0] == 1) ! 24: strcpy(buffer, ".."); ! 25: else { ! 26: switch (volume->ucs_level) { ! 27: case 3: ! 28: case 2: ! 29: case 1: ! 30: /* ! 31: * Unicode name. ! 32: */ ! 33: ! 34: for (j = 0; j < (int)idr->name_len[0] / 2; j++) { ! 35: ul = idr->name[j*2+1]; ! 36: ! 37: /* ! 38: * unicode convertion ! 39: * up = unls->unls_uni2cs[uh]; ! 40: * ! 41: * if (up == NULL) ! 42: * uc = '\0'; ! 43: * else ! 44: * uc = up[ul]; ! 45: * ! 46: * we use only low byte ! 47: */ ! 48: ! 49: uc = ul; ! 50: ! 51: buffer[j] = uc ? uc : '_'; ! 52: } ! 53: buffer[idr->name_len[0]/2] = '\0'; ! 54: break; ! 55: case 0: ! 56: /* ! 57: * Normal non-Unicode name. ! 58: */ ! 59: strncpy(buffer, idr->name, idr->name_len[0]); ! 60: buffer[idr->name_len[0]] = 0; ! 61: break; ! 62: default: ! 63: /* ! 64: * Don't know how to do these yet. Maybe they are the same ! 65: * as one of the above. ! 66: */ ! 67: break; ! 68: } ! 69: } ! 70: } ! 71: ! 72: iso9660_VOLUME *iso9660_mount(int fd) ! 73: { ! 74: iso9660_VOLUME* volume; ! 75: struct iso_primary_descriptor *jpd; ! 76: struct iso_primary_descriptor ipd; ! 77: int block; ! 78: int ucs_level = 0; ! 79: ! 80: /* read filesystem descriptor */ ! 81: ! 82: seek_io(fd, 16 * ISOFS_BLOCK_SIZE); ! 83: read_io(fd, &ipd, sizeof (ipd)); ! 84: ! 85: /* ! 86: * High sierra: ! 87: * ! 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 ! 91: */ ! 92: ! 93: /* High Sierra format ? */ ! 94: ! 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"); ! 99: return NULL; ! 100: } ! 101: ! 102: /* ! 103: * ISO 9660: ! 104: * ! 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 ! 108: */ ! 109: ! 110: /* NOT ISO 9660 format ? */ ! 111: ! 112: if ((ipd.type[0] != ISO_VD_PRIMARY) || ! 113: (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) || ! 114: (ipd.version[0] != 1)) { ! 115: return NULL; ! 116: } ! 117: ! 118: /* UCS info */ ! 119: ! 120: block = 16; ! 121: ! 122: jpd = (struct iso_primary_descriptor *) ! 123: malloc(sizeof(struct iso_primary_descriptor)); ! 124: if (jpd == NULL) ! 125: return NULL; ! 126: ! 127: memcpy(jpd, &ipd, sizeof (ipd)); ! 128: while ((uint8_t)jpd->type[0] != ISO_VD_END) { ! 129: ! 130: /* ! 131: * If Joliet UCS escape sequence found, we may be wrong ! 132: */ ! 133: ! 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')) { ! 141: ! 142: if (jpd->version[0] != 1) ! 143: break; ! 144: } ! 145: ! 146: block++; ! 147: seek_io(fd, block * ISOFS_BLOCK_SIZE); ! 148: read_io(fd, jpd, sizeof (*jpd)); ! 149: } ! 150: ! 151: ucs_level = 0; ! 152: if (((unsigned char) jpd->type[0] == ISO_VD_END)) { ! 153: memcpy(jpd, &ipd, sizeof (ipd)); ! 154: } else { ! 155: switch (jpd->unused3[2]) { ! 156: case '@': ! 157: ucs_level = 1; ! 158: break; ! 159: case 'C': ! 160: ucs_level = 2; ! 161: break; ! 162: case 'E': ! 163: ucs_level = 3; ! 164: break; ! 165: } ! 166: ! 167: if (ucs_level && jpd->unused3[3] == ' ') ! 168: printk("Warning: Joliet escape sequence uses illegal space at offset 3\n"); ! 169: } ! 170: ! 171: volume = (iso9660_VOLUME*)malloc(sizeof(iso9660_VOLUME)); ! 172: if (volume == NULL) ! 173: return NULL; ! 174: ! 175: volume->descriptor = jpd; ! 176: volume->ucs_level = ucs_level; ! 177: volume->fd = fd; ! 178: ! 179: return volume; ! 180: } ! 181: ! 182: int iso9660_umount(iso9660_VOLUME* volume) ! 183: { ! 184: if (volume == NULL) ! 185: return -1; ! 186: free(volume->descriptor); ! 187: free(volume); ! 188: return 0; ! 189: } ! 190: ! 191: int iso9660_probe(int fd, long long offset) ! 192: { ! 193: struct iso_primary_descriptor ipd; ! 194: ! 195: seek_io(fd, 16 * ISOFS_BLOCK_SIZE + offset); ! 196: read_io(fd, &ipd, sizeof (ipd)); ! 197: ! 198: if ((ipd.type[0] != ISO_VD_PRIMARY) || ! 199: (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) || ! 200: (ipd.version[0] != 1)) { ! 201: return 0; ! 202: } ! 203: ! 204: return -1; ! 205: } ! 206: ! 207: struct iso_directory_record *iso9660_get_root_node(iso9660_VOLUME* volume) ! 208: { ! 209: return (struct iso_directory_record *)volume->descriptor->root_directory_record; ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.