wok-next annotate syslinux/stuff/iso2exe/iso9660.c @ rev 18775

syslinux/isohybrid.exe: add -a & -i support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Jan 01 10:53:50 2016 +0100 (2016-01-01)
parents 6aed6fc5819d
children
rev   line source
pascal@13691 1 #include <sys/types.h>
pascal@13691 2 #include <fcntl.h>
pascal@13691 3 #include <stdio.h>
pascal@17489 4 #include <string.h>
pascal@13691 5 #include "iso9660.h"
pascal@13691 6 #define __ROCKRIDGE
pascal@17489 7 #ifdef __AS386_16__
pascal@17473 8 #asm
pascal@17473 9 use16 86
pascal@17473 10 #endasm
pascal@17489 11 #endif
pascal@13691 12
pascal@13691 13 char *isofilename;
pascal@13691 14 unsigned long isofileofs, isofilesize;
pascal@13691 15 unsigned short isofilemod;
pascal@13691 16 int isofd;
pascal@13691 17
pascal@13691 18 #define SECTORSZ 2048
pascal@13691 19 #define SECTORBITS 11
pascal@13691 20 static char buffer[SECTORSZ];
pascal@13691 21
pascal@13691 22 static int readsector(unsigned long offset)
pascal@13691 23 {
pascal@13691 24 return (lseek(isofd, offset, SEEK_SET) != -1
pascal@13691 25 && read(isofd, buffer, SECTORSZ) == SECTORSZ);
pascal@13691 26 }
pascal@13691 27
pascal@13691 28 int isoread(char *data, unsigned size)
pascal@13691 29 {
pascal@13691 30 int get, n;
pascal@13691 31
pascal@13691 32 if (size > isofilesize)
pascal@13691 33 size = isofilesize;
pascal@13691 34 if (lseek(isofd, isofileofs, SEEK_SET) == -1)
pascal@13691 35 return -1;
pascal@13691 36 for (get = size; get; get -= n, data += n) {
pascal@13691 37 n = read(isofd,data,get);
pascal@13691 38 if (n < 0)
pascal@13691 39 return n;
pascal@13691 40 if (n == 0)
pascal@13691 41 break;
pascal@13691 42 isofileofs += n;
pascal@13691 43 isofilesize -= n;
pascal@13691 44 }
pascal@13691 45 return size - get;
pascal@13691 46 }
pascal@13691 47
pascal@13691 48 static unsigned long isodirofs, isodirsize;
pascal@13691 49 int isoreset(char *name)
pascal@13691 50 {
pascal@13691 51 if (name)
pascal@13691 52 isofd = open(name, O_RDONLY);
pascal@13691 53 if (!readsector(16UL * 2048) || strncmp(buffer+1,"CD001",5))
pascal@13691 54 return -1;
pascal@13691 55 isodirofs = * (unsigned long *) (buffer + 0x9E);
pascal@13691 56 isodirofs <<= SECTORBITS;
pascal@13691 57 isodirsize = * (unsigned long *) (buffer + 0xA6);
pascal@13691 58 return 0;
pascal@13691 59 }
pascal@13691 60
pascal@13691 61 int isoreaddir(int restart)
pascal@13691 62 {
pascal@13691 63 static unsigned long pos, dirofs, dirsize;
pascal@13691 64 static char dots[] = "..";
pascal@13691 65 int size, n;
pascal@13691 66 #ifdef __ROCKRIDGE
pascal@13691 67 char *endname;
pascal@13691 68 #endif
pascal@13691 69
pascal@13691 70 if (restart) {
pascal@13691 71 dirofs = isodirofs;
pascal@13691 72 dirsize = isodirsize;
pascal@13691 73 pos = SECTORSZ;
pascal@13691 74 }
pascal@17489 75 if (pos >= SECTORSZ || * (short *) (buffer + pos) == 0) {
pascal@13691 76 if (dirsize < SECTORSZ) return -1;
pascal@13691 77 readsector(dirofs);
pascal@13691 78 dirofs += SECTORSZ;
pascal@13691 79 dirsize -= SECTORSZ;
pascal@13691 80 pos = 0;
pascal@13691 81 }
pascal@13691 82 size = * (short *) (buffer + pos);
pascal@13691 83 if (size == 0)
pascal@13691 84 return -1;
pascal@13691 85 isofileofs = (* (unsigned long *) (buffer + pos + 2)) << SECTORBITS;
pascal@13691 86 isofilesize = * (unsigned long *) (buffer + pos + 10);
pascal@13691 87 isofilemod = (buffer[pos + 25] & 2) ? 0040755 : 0100755;
pascal@13691 88 #ifdef __ROCKRIDGE
pascal@13691 89 endname = NULL;
pascal@13691 90 n = (buffer[pos + 32] + pos + 34) & -2;
pascal@13691 91 do {
pascal@13691 92 int len = buffer[n + 2];
pascal@13691 93 switch (* (short *) (buffer + n)) {
pascal@13691 94 case 0x4D4E: // NM
pascal@13691 95 isofilename = buffer + n + 5;
pascal@13691 96 endname = buffer + n + len;
pascal@13691 97 break;
pascal@13691 98 case 0x5850: // PX
pascal@13691 99 isofilemod = * (short *) (buffer + n + 4);
pascal@13691 100 break;
pascal@13691 101 }
pascal@13691 102 n += len;
pascal@13691 103 }
pascal@13691 104 while (n + 2 < pos + size);
pascal@13691 105 if (endname)
pascal@13691 106 *endname = 0;
pascal@13691 107 else
pascal@13691 108 #endif
pascal@13691 109 {
pascal@13691 110 isofilename = buffer + pos + 33;
pascal@13691 111 switch (* (short *) (isofilename - 1)) {
pascal@13691 112 case 0x0101:
pascal@13691 113 isofilename = dots;
pascal@13691 114 break;
pascal@13691 115 case 0x0001:
pascal@13691 116 isofilename = dots + 1;
pascal@13691 117 break;
pascal@13691 118 default:
pascal@13691 119 n = isofilename[-1];
pascal@13691 120 if (* (short *) (isofilename + n - 2) == 0x313B)
pascal@13691 121 n -= 2; // remove ;1
pascal@13691 122 if (isofilename[n - 1] == '.') n--;
pascal@13691 123 isofilename[n] = 0;
pascal@13691 124 }
pascal@13691 125 }
pascal@13691 126 pos += size;
pascal@13691 127 return 0;
pascal@13691 128 }
pascal@13691 129
pascal@17489 130 #ifndef __AS386_16__
pascal@17489 131 #define cpuhaslm() (0)
pascal@17489 132 #else
pascal@17473 133 static int cpuhaslm(void)
pascal@17473 134 {
pascal@17473 135 #asm
pascal@17473 136 pushf // save flags
pascal@17473 137 // bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
pascal@17473 138 // flags 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF
pascal@17473 139 mov ax, #0x1000
pascal@17473 140 push ax
pascal@17473 141 popf // < 286 : flags[12..15] are forced 1
pascal@17473 142 pushf // = 286 : flags[12..15] are forced 0
pascal@17473 143 pop bx // > 286 : only flags[15] is forced 0
pascal@17473 144 popf // restore flags (IOPL)
pascal@17473 145 add bh, ah // test F0 and 00 cases
pascal@17473 146 cmp bh, ah
pascal@17473 147 cbw
pascal@17473 148 jbe not386 // C=8086/80186, Z=80286
pascal@17473 149 use16 386
pascal@17473 150 pushfd
pascal@17473 151 pushfd
pascal@17473 152 pop ebx
pascal@17473 153 mov ecx, ebx
pascal@17473 154 btc ebx, #21 // toggle CPUID feature bit
pascal@17473 155 push ebx
pascal@17473 156 popfd
pascal@17473 157 pushfd
pascal@17473 158 pop ebx
pascal@17473 159 popfd
pascal@17473 160 xor ebx, ecx
pascal@17473 161 bt ebx, #21 // CPUID feature bit ?
pascal@17473 162 jnc nocpuid
pascal@17473 163 mov eax, #0x80000001 // Extended Processor Info and Feature Bits
pascal@17473 164 .byte 0x0F, 0xA2 // cpuid
pascal@17473 165 xor ax, ax
pascal@17473 166 bt edx, #29 // LM feature bit ?
pascal@17473 167 adc ax, ax
pascal@17473 168 use16 86
pascal@17473 169 nocpuid:
pascal@17473 170 not386:
pascal@17473 171 #endasm
pascal@17473 172 }
pascal@17489 173 #endif
pascal@17473 174
pascal@13691 175 #define IS_DIR(x)( ((x) & ~0777) == 040000)
pascal@17473 176 int isoopen(char *filename)
pascal@13691 177 {
pascal@13691 178 int restart;
pascal@17473 179 char *name, *s, c;
pascal@17473 180 int _64bits = cpuhaslm();
pascal@13691 181
pascal@17473 182 retry32:
pascal@17473 183 name = filename;
pascal@13691 184 while (*name == '/') {
pascal@13691 185 name++;
pascal@13691 186 isoreset(NULL);
pascal@13691 187 }
pascal@13691 188 s = name;
pascal@13691 189 while (1) {
pascal@13691 190 while (*s && *s != '/') s++;
pascal@13691 191 c = *s;
pascal@13691 192 *s = 0;
pascal@13691 193 for (restart = 1; isoreaddir(restart) == 0; restart = 0) {
pascal@17473 194 char *n = name, *i = isofilename;
pascal@17473 195 if (_64bits) {
pascal@17473 196 int len = strlen(name);
pascal@17489 197 if (strncmp(name, isofilename, len)) continue;
pascal@17473 198 n = "64";
pascal@17473 199 i += len;
pascal@17473 200 }
pascal@17473 201 if (strcmp(n, i)) continue;
pascal@13691 202 if (IS_DIR(isofilemod)) {
pascal@13691 203 isodirofs = isofileofs;
pascal@13691 204 isodirsize = isofilesize;
pascal@13691 205 if (c) {
pascal@13691 206 *s++ = c;
pascal@13691 207 name = s;
pascal@13691 208 goto next;
pascal@13691 209 }
pascal@13691 210 }
pascal@13691 211 return 0;
pascal@13691 212 }
pascal@17473 213 if (_64bits) {
pascal@17473 214 _64bits = 0;
pascal@17473 215 *s = c;
pascal@17473 216 goto retry32;
pascal@17473 217 }
pascal@13691 218 return -1;
pascal@13691 219 next: ;
pascal@13691 220 }
pascal@13691 221 }