Root/
Source at commit 393 created 13 years 10 months ago. By blackosx, Updated default theme. | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * The contents of this file constitute Original Code as defined in and␊ |
7 | * are subject to the Apple Public Source License Version 2.0 (the␊ |
8 | * "License"). You may not use this file except in compliance with the␊ |
9 | * License. Please obtain a copy of the License at␊ |
10 | * http://www.apple.com/publicsource and read it before using this file.␊ |
11 | * ␊ |
12 | * This Original Code and all software distributed under the License are␊ |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
17 | * License for the specific language governing rights and limitations␊ |
18 | * under the License.␊ |
19 | * ␊ |
20 | * @APPLE_LICENSE_HEADER_END@␊ |
21 | */␊ |
22 | /*␊ |
23 | * Copyright (c) 1998 Robert Nordier␊ |
24 | * All rights reserved.␊ |
25 | *␊ |
26 | * Redistribution and use in source and binary forms, with or without␊ |
27 | * modification, are permitted provided that the following conditions␊ |
28 | * are met:␊ |
29 | * 1. Redistributions of source code must retain the above copyright␊ |
30 | * notice, this list of conditions and the following disclaimer.␊ |
31 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
32 | * notice, this list of conditions and the following disclaimer in␊ |
33 | * the documentation and/or other materials provided with the␊ |
34 | * distribution.␊ |
35 | *␊ |
36 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS␊ |
37 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED␊ |
38 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
39 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY␊ |
40 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
41 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE␊ |
42 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS␊ |
43 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER␊ |
44 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR␊ |
45 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN␊ |
46 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.␊ |
47 | */␊ |
48 | ␊ |
49 | #define tolower(c) (((c)>='A' && c<='Z')?((c) | 0x20):(c))␊ |
50 | #include "libsaio.h"␊ |
51 | #include "sl.h"␊ |
52 | ␊ |
53 | #include "msdos_private.h"␊ |
54 | #include "msdos.h"␊ |
55 | ␊ |
56 | #define LABEL_LENGTH␉␉11␊ |
57 | #define MAX_DOS_BLOCKSIZE␉2048␊ |
58 | ␊ |
59 | #define␉CLUST_FIRST␉␉2/* reserved cluster range */␊ |
60 | #define␉CLUST_RSRVD32␉0x0ffffff8␉/* reserved cluster range */␊ |
61 | #define␉CLUST_RSRVD16␉0xfff8␉/* reserved cluster range */␊ |
62 | #define␉CLUST_RSRVD12␉0xff8␉/* reserved cluster range */␊ |
63 | ␊ |
64 | ␊ |
65 | #define false 0␊ |
66 | #define true 1␊ |
67 | ␊ |
68 | static int msdosressector=0;␊ |
69 | static int msdosnfats = 0;␊ |
70 | static int msdosfatsecs = 0;␊ |
71 | static int msdosbps = 0;␊ |
72 | static int msdosclustersize = 0;␊ |
73 | static int msdosrootDirSectors = 0;␊ |
74 | static CICell msdoscurrent = 0;␊ |
75 | static int msdosrootcluster = 0;␊ |
76 | static int msdosfatbits = 0;␊ |
77 | ␊ |
78 | #if UNUSED␊ |
79 | /*␊ |
80 | * Check a volume label.␊ |
81 | */␊ |
82 | static int␊ |
83 | oklabel(const char *src)␊ |
84 | {␊ |
85 | int c, i;␊ |
86 | ␊ |
87 | for (i = 0, c = 0; i <= 11; i++) {␊ |
88 | c = (u_char)*src++;␊ |
89 | if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))␊ |
90 | break;␊ |
91 | }␊ |
92 | return i && !c;␊ |
93 | }␊ |
94 | #endif /* UNUSED */␊ |
95 | ␊ |
96 | void MSDOSFree(CICell ih)␊ |
97 | {␊ |
98 | ␉if(msdoscurrent == ih)␊ |
99 | msdoscurrent = 0;␊ |
100 | free(ih);␊ |
101 | }␊ |
102 | ␊ |
103 | int MSDOSProbe(const void * buffer)␊ |
104 | {␊ |
105 | union bootsector *bsp;␊ |
106 | struct bpb33 *b33;␊ |
107 | struct bpb50 *b50;␊ |
108 | struct bpb710 *b710;␊ |
109 | u_int16_t␉ bps;␊ |
110 | u_int8_t␉␉spc;␊ |
111 | ␉␊ |
112 | bsp = (union bootsector *)buffer;␊ |
113 | b33 = (struct bpb33 *)bsp->bs33.bsBPB;␊ |
114 | b50 = (struct bpb50 *)bsp->bs50.bsBPB;␊ |
115 | b710 = (struct bpb710 *)bsp->bs710.bsBPB;␊ |
116 | ␊ |
117 | /* We only work with 512, 1024, and 2048 byte sectors */␊ |
118 | bps = OSSwapLittleToHostInt16(b33->bpbBytesPerSec);␊ |
119 | if ((bps < 0x200) || (bps & (bps - 1)) || (bps > 0x800)) ␊ |
120 | return 0;␊ |
121 | ␊ |
122 | ␉/* Check to make sure valid sectors per cluster */␊ |
123 | spc = b33->bpbSecPerClust;␊ |
124 | if ((spc == 0 ) || (spc & (spc - 1))) ␊ |
125 | return 0;␉␊ |
126 | ␉␊ |
127 | ␉if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0) { /* It's FAT32 */␊ |
128 | ␉␉if (!memcmp(((struct extboot *)bsp->bs710.bsExt)->exFileSysType, "FAT32 ", 8))␊ |
129 | ␉␉␉return 32;␊ |
130 | ␉}␊ |
131 | ␉else if (((struct extboot *)bsp->bs50.bsExt)->exBootSignature == EXBOOTSIG) {␊ |
132 | ␉␉if (!memcmp((char *)((struct extboot *)bsp->bs50.bsExt)->exFileSysType, "FAT16 ", 8))␊ |
133 | ␉␉␉return 16;␊ |
134 | ␉␉if (!memcmp((char *)((struct extboot *)bsp->bs50.bsExt)->exFileSysType, "FAT12 ", 8))␊ |
135 | ␉␉␉return 12;␊ |
136 | ␉}␉␊ |
137 | ␉␉␊ |
138 | ␉return 0;␊ |
139 | }␊ |
140 | ␊ |
141 | ␊ |
142 | long␊ |
143 | MSDOSInitPartition (CICell ih)␊ |
144 | {␊ |
145 | union bootsector *bsp;␊ |
146 | struct bpb33 *b33;␊ |
147 | struct bpb50 *b50;␊ |
148 | struct bpb710 *b710;␊ |
149 | u_int8_t␉␉spc;␊ |
150 | char *buf;␊ |
151 | ␉␊ |
152 | ␉if (msdoscurrent == ih)␊ |
153 | ␉{␊ |
154 | ␉␉CacheInit(ih, msdosclustersize);␊ |
155 | ␉␉return 0;␊ |
156 | ␉}␊ |
157 | ␉␊ |
158 | ␉buf=malloc (512);␊ |
159 | ␉/*␊ |
160 | * Read the boot sector of the filesystem, and then check the␊ |
161 | * boot signature. If not a dos boot sector then error out.␊ |
162 | *␊ |
163 | * NOTE: 2048 is a maximum sector size in current...␊ |
164 | */␊ |
165 | Seek(ih, 0);␊ |
166 | Read(ih, (long)buf, 512);␊ |
167 | ␉␊ |
168 | bsp = (union bootsector *)buf;␊ |
169 | b33 = (struct bpb33 *)bsp->bs33.bsBPB;␊ |
170 | b50 = (struct bpb50 *)bsp->bs50.bsBPB;␊ |
171 | b710 = (struct bpb710 *)bsp->bs710.bsBPB;␊ |
172 | ␊ |
173 | ␉␊ |
174 | /* We only work with 512, 1024, and 2048 byte sectors */␊ |
175 | msdosbps = OSSwapLittleToHostInt16(b33->bpbBytesPerSec);␊ |
176 | if ((msdosbps < 0x200) || (msdosbps & (msdosbps - 1)) || (msdosbps > 0x800)) ␊ |
177 | ␉{␊ |
178 | ␉␉free (buf);␊ |
179 | ␉␉return -1;␊ |
180 | ␉}␊ |
181 | ␉␊ |
182 | /* Check to make sure valid sectors per cluster */␊ |
183 | spc = b33->bpbSecPerClust;␊ |
184 | if ((spc == 0 ) || (spc & (spc - 1))) ␊ |
185 | ␉␉return -1;␊ |
186 | ␉␊ |
187 | ␉if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0) { /* It's FAT32 */␊ |
188 | ␉␉if (memcmp(((struct extboot *)bsp->bs710.bsExt)->exFileSysType, "FAT32 ", 8))␊ |
189 | ␉␉{␊ |
190 | ␉␉␉free (buf);␊ |
191 | ␉␉␉return -1;␊ |
192 | ␉␉}␊ |
193 | ␉␉msdosressector = OSSwapLittleToHostInt16(b710->bpbResSectors);␊ |
194 | ␉␉msdosnfats = b710->bpbFATs;␊ |
195 | ␉␉msdosfatsecs = OSSwapLittleToHostInt16(b710->bpbBigFATsecs);␊ |
196 | ␉␉msdosrootcluster = OSSwapLittleToHostInt32(b710->bpbRootClust);␊ |
197 | ␉␉msdosrootDirSectors = 0;␊ |
198 | ␉␉msdosfatbits = 32;␊ |
199 | ␉}␊ |
200 | ␉else if (((struct extboot *)bsp->bs50.bsExt)->exBootSignature == EXBOOTSIG) {␊ |
201 | ␉␉if (!memcmp((char *)((struct extboot *)bsp->bs50.bsExt)->exFileSysType, "FAT16 ", 8))␊ |
202 | ␉␉␉msdosfatbits = 16;␊ |
203 | ␉␉else if (!memcmp((char *)((struct extboot *)bsp->bs50.bsExt)->exFileSysType, "FAT12 ", 8))␊ |
204 | ␉␉␉msdosfatbits = 12;␊ |
205 | ␉␉else␊ |
206 | ␉␉{␊ |
207 | ␉␉␉free (buf);␊ |
208 | ␉␉␉return -1;␊ |
209 | ␉␉}␉␉␊ |
210 | ␉␉␊ |
211 | ␉␉msdosressector = OSSwapLittleToHostInt16(b33->bpbResSectors);␊ |
212 | ␉␉msdosnfats = b33->bpbFATs;␊ |
213 | ␉␉msdosfatsecs = OSSwapLittleToHostInt16(b33->bpbFATsecs);␊ |
214 | ␉␉msdosrootcluster = 0;␉␉␊ |
215 | ␉␉msdosrootDirSectors = ((OSSwapLittleToHostInt16(b50->bpbRootDirEnts) * sizeof(struct direntry)) +␊ |
216 | ␉␉␉␉␉␉␉ (msdosbps-1)) / msdosbps;␊ |
217 | ␉} else {␊ |
218 | ␉␉free (buf);␊ |
219 | ␉␉return -1;␊ |
220 | ␉}␊ |
221 | ␉␊ |
222 | ␉msdosclustersize = msdosbps * spc;␊ |
223 | ␊ |
224 | ␉msdoscurrent = ih;␊ |
225 | ␉CacheInit(ih, msdosclustersize);␊ |
226 | ␉free (buf);␊ |
227 | ␉return 0;␊ |
228 | }␊ |
229 | ␊ |
230 | static int␊ |
231 | msdosreadcluster (CICell ih, uint8_t *buf, int size, off_t *cluster)␊ |
232 | {␊ |
233 | off_t readOffset;␊ |
234 | ␉char tmpbuf[8];␊ |
235 | ␉off_t clusn;␊ |
236 | ␉␊ |
237 | ␉switch (msdosfatbits) {␊ |
238 | ␉␉case 32:␊ |
239 | ␉␉␉if (*cluster < CLUST_FIRST ||*cluster >= CLUST_RSRVD32)␊ |
240 | ␉␉␉␉return 0;␊ |
241 | ␉␉␉clusn = *cluster - CLUST_FIRST;␊ |
242 | ␉␉␉break;␊ |
243 | ␉␉case 16:␊ |
244 | ␉␉␉if (*cluster < CLUST_FIRST ||*cluster >= CLUST_RSRVD16)␊ |
245 | ␉␉␉␉return 0;␊ |
246 | ␉␉␉clusn = *cluster - CLUST_FIRST;␊ |
247 | ␉␉␉break;␉␉␉␊ |
248 | ␉␉case 12:␊ |
249 | ␉␉␉if (*cluster < CLUST_FIRST ||*cluster >= CLUST_RSRVD12)␊ |
250 | ␉␉␉␉return 0;␊ |
251 | ␉␉␉clusn = *cluster - CLUST_FIRST;␊ |
252 | ␉␉␉break;␊ |
253 | ␉␉default:␊ |
254 | ␉␉␉return 0;␊ |
255 | ␉}␊ |
256 | ␉␊ |
257 | ␉/* Find sector where clusters start */␊ |
258 | ␉readOffset = (msdosressector +␊ |
259 | ␉␉␉␉ (msdosnfats * msdosfatsecs)+msdosrootDirSectors)*msdosbps;␊ |
260 | ␉/* Find sector where "cluster" starts */␊ |
261 | ␉readOffset += clusn * msdosclustersize;␊ |
262 | ␉␊ |
263 | ␉/* Read in "cluster" */␊ |
264 | ␉if (buf)␊ |
265 | ␉{␊ |
266 | ␉␉Seek(ih, readOffset);␊ |
267 | ␉␉Read(ih, (long)buf, size);␊ |
268 | ␉}␊ |
269 | ␉␊ |
270 | ␉/* Find first sector of FAT */␊ |
271 | ␉readOffset = msdosressector*msdosbps;␊ |
272 | ␉/* Find sector containing "cluster" entry in FAT */␊ |
273 | ␉readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits)/8;␊ |
274 | ␉␊ |
275 | ␉/* Read one sector of the FAT */␊ |
276 | ␉Seek(ih, readOffset);␊ |
277 | ␉Read(ih, (long)tmpbuf, 4);␊ |
278 | ␉␊ |
279 | ␉switch (msdosfatbits) {␊ |
280 | ␉␉case 32:␊ |
281 | ␉␉␉*cluster = OSReadLittleInt32(tmpbuf, 0);␊ |
282 | ␉␉␉*cluster &= 0x0FFFFFFF;␉// ignore reserved upper bits␊ |
283 | ␉␉␉return 1;␊ |
284 | ␉␉case 16:␊ |
285 | ␉␉␉*cluster = OSReadLittleInt16(tmpbuf, 0);␊ |
286 | ␉␉␉return 1;␉␉␉␊ |
287 | ␉␉case 12:␊ |
288 | ␉␉␉*cluster = OSReadLittleInt16(tmpbuf, 0)>>(((uint64_t)*cluster * (uint64_t)msdosfatbits)%8);␊ |
289 | ␉␉␉*cluster &= 0xfff;␊ |
290 | ␉␉␉return 1;␊ |
291 | ␉␉default:␊ |
292 | ␉␉␉return 0;␊ |
293 | ␉}␊ |
294 | }␊ |
295 | ␊ |
296 | struct msdosdirstate␊ |
297 | {␊ |
298 | ␉struct direntry *buf;␊ |
299 | ␉uint8_t vfatchecksum;␊ |
300 | ␉int root16;␊ |
301 | ␉off_t cluster;␊ |
302 | ␉int nument;␊ |
303 | ␉int vfatnumber;␊ |
304 | };␊ |
305 | ␊ |
306 | static struct direntry *␊ |
307 | getnextdirent (CICell ih, uint16_t *longname, struct msdosdirstate *st)␊ |
308 | {␊ |
309 | ␉struct direntry *dirp;␊ |
310 | ␉while (1)␊ |
311 | ␉{␊ |
312 | ␉␉if (st->root16)␊ |
313 | ␉␉{␊ |
314 | ␉␉␉if (st->cluster >= msdosrootDirSectors && st->nument == 0)␊ |
315 | ␉␉␉␉return 0;␊ |
316 | ␉␉␉if (st->nument == 0)␊ |
317 | ␉␉␉{␊ |
318 | ␉␉␉␉Seek(ih, (msdosressector +␊ |
319 | ␉␉␉␉␉␉ (msdosnfats * msdosfatsecs)+st->cluster)*msdosbps);␊ |
320 | ␉␉␉␉Read(ih, (long)st->buf, msdosbps);␊ |
321 | ␉␉␉␉st->cluster++;␊ |
322 | ␉␉␉}␊ |
323 | ␉␉} else if (st->nument == 0 && !msdosreadcluster (ih, (uint8_t *)st->buf, msdosclustersize, &(st->cluster)))␊ |
324 | ␉␉␉return 0;␊ |
325 | ␉␉␊ |
326 | ␉␉dirp=st->buf+st->nument;␊ |
327 | ␉␉␊ |
328 | ␉␉if (dirp->deName[0] == SLOT_EMPTY)␊ |
329 | ␉␉␉return 0;␊ |
330 | ␉␉else if (dirp->deName[0] == SLOT_DELETED)␊ |
331 | ␉␉␉st->vfatnumber = 0;␊ |
332 | ␉␉else if (dirp->deAttributes == ATTR_WIN95)␊ |
333 | ␉␉{␊ |
334 | ␉␉␉struct winentry *wdirp = (struct winentry *)dirp;␊ |
335 | ␉␉␉int num;␊ |
336 | ␉␉␉if (wdirp->weCnt & 0x80)␊ |
337 | ␉␉␉␉continue;␊ |
338 | ␉␉␉num=(wdirp->weCnt&0x3f);␊ |
339 | ␉␉␉if (WIN_CHARS * num > WIN_MAXLEN)␊ |
340 | ␉␉␉␉continue;␊ |
341 | ␉␉␉if (st->vfatchecksum!=wdirp->weChksum)␊ |
342 | ␉␉␉{␊ |
343 | ␉␉␉␉st->vfatnumber = 0;␊ |
344 | ␉␉␉␉st->vfatchecksum = wdirp->weChksum;␊ |
345 | ␉␉␉}␊ |
346 | ␉␉␉if (st->vfatnumber < num)␊ |
347 | ␉␉␉␉st->vfatnumber = num;␊ |
348 | ␉␉␉bcopy (&(wdirp->wePart1),longname+WIN_CHARS*(num-1),sizeof (wdirp->wePart1));␊ |
349 | ␉␉␉bcopy (&(wdirp->wePart2),longname+WIN_CHARS*(num-1)+5,sizeof (wdirp->wePart2));␊ |
350 | ␉␉␉bcopy (&(wdirp->wePart3),longname+WIN_CHARS*(num-1)+11,sizeof (wdirp->wePart3));␊ |
351 | ␉␉} else {␊ |
352 | ␉␉␉uint8_t labelchecksum;␊ |
353 | ␉␉␉int i;␊ |
354 | ␉␉␉longname[st->vfatnumber*WIN_CHARS]=0;␊ |
355 | ␉␉␉␊ |
356 | ␉␉␉labelchecksum=0;␊ |
357 | ␉␉␉for(i=0;i<LABEL_LENGTH;i++)␊ |
358 | ␉␉␉␉labelchecksum=(labelchecksum>>1)+(labelchecksum<<7)+dirp->deName[i];␊ |
359 | ␉␉␉if (!(labelchecksum==st->vfatchecksum && st->vfatnumber))␊ |
360 | ␉␉␉␉longname[0]=0;␊ |
361 | ␉␉␉st->vfatnumber = 0;␊ |
362 | ␉␉␉st->vfatchecksum = 0;␊ |
363 | ␉␉␉st->vfatnumber = 0;␊ |
364 | ␉␉␉st->nument++;␊ |
365 | ␉␉␉if ((!st->root16 &&st->nument * sizeof (struct direntry)>=msdosclustersize)␊ |
366 | ␉␉␉␉|| (st->root16 &&st->nument * sizeof (struct direntry)>=msdosbps))␊ |
367 | ␉␉␉␉st->nument = 0;␊ |
368 | ␉␉␉return dirp;␊ |
369 | ␉␉}␊ |
370 | ␉␉st->nument++;␊ |
371 | ␉␉if ((!st->root16 &&st->nument * sizeof (struct direntry)>=msdosclustersize)␊ |
372 | ␉␉␉|| (st->root16 &&st->nument * sizeof (struct direntry)>=msdosbps))␊ |
373 | ␉␉␉st->nument = 0;␉␉␊ |
374 | ␉}␊ |
375 | }␊ |
376 | ␊ |
377 | static void␊ |
378 | initRoot (struct msdosdirstate *st)␊ |
379 | {␊ |
380 | ␉if (msdosrootDirSectors) {␉␉␉/* FAT12 or FAT16 */␊ |
381 | ␉␉st->root16 = 1;␊ |
382 | ␉␉st->vfatchecksum = 0;␊ |
383 | ␉␉st->nument = 0;␊ |
384 | ␉␉st->cluster = 0;␊ |
385 | ␉␉st->vfatnumber = 0;␊ |
386 | ␉} else {␉/* FAT32 */␊ |
387 | ␉␉st->root16 = 0;␊ |
388 | ␉␉st->vfatchecksum = 0;␊ |
389 | ␉␉st->nument = 0;␊ |
390 | ␉␉st->cluster = msdosrootcluster;␊ |
391 | ␉␉st->vfatnumber = 0;␊ |
392 | ␉}␊ |
393 | }␊ |
394 | ␊ |
395 | /* First comes lowercase, then uppercase*/␊ |
396 | static uint16_t cp850[128][2]=␊ |
397 | {␊ |
398 | {0x00E7,0x00C7},␊ |
399 | {0x00FC,0x00DC},␊ |
400 | {0x00E9,0x00C9},␊ |
401 | {0x00E2,0x00C2},␊ |
402 | {0x00E4,0x00C4},␊ |
403 | {0x00E0,0x00C0},␊ |
404 | {0x00E5,0x00C5},␊ |
405 | {0x00E7,0x00C7},␊ |
406 | {0x00EA,0x00CA},␊ |
407 | {0x00EB,0x00CB},␊ |
408 | {0x00E8,0x00C8},␊ |
409 | {0x00EF,0x00CF},␊ |
410 | {0x00EE,0x00CE},␊ |
411 | {0x00EC,0x00CC},␊ |
412 | {0x00E4,0x00C4},␊ |
413 | {0x00E5,0x00C5},␊ |
414 | {0x00E9,0x00C9},␊ |
415 | {0x00E6,0x00C6},␊ |
416 | {0x00E6,0x00C6},␊ |
417 | {0x00F4,0x00D4},␊ |
418 | {0x00F6,0x00D6},␊ |
419 | {0x00F2,0x00D2},␊ |
420 | {0x00FB,0x00DB},␊ |
421 | {0x00F9,0x00D9},␊ |
422 | {0x00FF,0x0178},␊ |
423 | {0x00F6,0x00D6},␊ |
424 | {0x00FC,0x00DC},␊ |
425 | {0x00F8,0x00D8},␊ |
426 | {0x00A3,0x00A3},␊ |
427 | {0x00F8,0x00D8},␊ |
428 | {0x00D7,0x00D7},␊ |
429 | {0x0192,0x0191},␊ |
430 | {0x00E1,0x00C1},␊ |
431 | {0x00ED,0x00CD},␊ |
432 | {0x00F3,0x00D3},␊ |
433 | {0x00FA,0x00DA},␊ |
434 | {0x00F1,0x00D1},␊ |
435 | {0x00F1,0x00D1},␊ |
436 | {0x00AA,0x00AA},␊ |
437 | {0x00BA,0x00BA},␊ |
438 | {0x00BF,0x00BF},␊ |
439 | {0x00AE,0x00AE},␊ |
440 | {0x00AC,0x00AC},␊ |
441 | {0x00BD,0x00BD},␊ |
442 | {0x00BC,0x00BC},␊ |
443 | {0x00A1,0x00A1},␊ |
444 | {0x00AB,0x00AB},␊ |
445 | {0x00BB,0x00BB},␊ |
446 | {0x2591,0x2591},␊ |
447 | {0x2592,0x2592},␊ |
448 | {0x2593,0x2593},␊ |
449 | {0x2502,0x2502},␊ |
450 | {0x2524,0x2524},␊ |
451 | {0x00E1,0x00C1},␊ |
452 | {0x00E2,0x00C2},␊ |
453 | {0x00E0,0x00C0},␊ |
454 | {0x00A9,0x00A9},␊ |
455 | {0x2563,0x2563},␊ |
456 | {0x2551,0x2551},␊ |
457 | {0x2557,0x2557},␊ |
458 | {0x255D,0x255D},␊ |
459 | {0x00A2,0x00A2},␊ |
460 | {0x00A5,0x00A5},␊ |
461 | {0x2510,0x2510},␊ |
462 | {0x2514,0x2514},␊ |
463 | {0x2534,0x2534},␊ |
464 | {0x252C,0x252C},␊ |
465 | {0x251C,0x251C},␊ |
466 | {0x2500,0x2500},␊ |
467 | {0x253C,0x253C},␊ |
468 | {0x00E3,0x00C3},␊ |
469 | {0x00E3,0x00C3},␊ |
470 | {0x255A,0x255A},␊ |
471 | {0x2554,0x2554},␊ |
472 | {0x2569,0x2569},␊ |
473 | {0x2566,0x2566},␊ |
474 | {0x2560,0x2560},␊ |
475 | {0x2550,0x2550},␊ |
476 | {0x256C,0x256C},␊ |
477 | {0x00A4,0x00A4},␊ |
478 | {0x00F0,0x00D0},␊ |
479 | {0x00F0,0x00D0},␊ |
480 | {0x00EA,0x00CA},␊ |
481 | {0x00EB,0x00CB},␊ |
482 | {0x00E8,0x00C8},␊ |
483 | {0x0131,0x0049},␊ |
484 | {0x00ED,0x00CD},␊ |
485 | {0x00EE,0x00CE},␊ |
486 | {0x00EF,0x00CF},␊ |
487 | {0x2518,0x2518},␊ |
488 | {0x250C,0x250C},␊ |
489 | {0x2588,0x2588},␊ |
490 | {0x2584,0x2584},␊ |
491 | {0x00A6,0x00A6},␊ |
492 | {0x00EC,0x00CC},␊ |
493 | {0x2580,0x2580},␊ |
494 | {0x00F3,0x00D3},␊ |
495 | {0x00DF,0x00DF},␊ |
496 | {0x00F4,0x00D4},␊ |
497 | {0x00F2,0x00D2},␊ |
498 | {0x00F5,0x00D5},␊ |
499 | {0x00F5,0x00D5},␊ |
500 | {0x00B5,0x00B5},␊ |
501 | {0x00FE,0x00DE},␊ |
502 | {0x00FE,0x00DE},␊ |
503 | {0x00FA,0x00DA},␊ |
504 | {0x00FB,0x00DB},␊ |
505 | {0x00F9,0x00D9},␊ |
506 | {0x00FD,0x00DD},␊ |
507 | {0x00FD,0x00DD},␊ |
508 | {0x00AF,0x00AF},␊ |
509 | {0x00B4,0x00B4},␊ |
510 | {0x00AD,0x00AD},␊ |
511 | {0x00B1,0x00B1},␊ |
512 | {0x2017,0x2017},␊ |
513 | {0x00BE,0x00BE},␊ |
514 | {0x00B6,0x00B6},␊ |
515 | {0x00A7,0x00A7},␊ |
516 | {0x00F7,0x00F7},␊ |
517 | {0x00B8,0x00B8},␊ |
518 | {0x00B0,0x00B0},␊ |
519 | {0x00A8,0x00A8},␊ |
520 | {0x00B7,0x00B7},␊ |
521 | {0x00B9,0x00B9},␊ |
522 | {0x00B3,0x00B3},␊ |
523 | {0x00B2,0x00B2},␊ |
524 | {0x25A0,0x25A0},␊ |
525 | {0x00A0,0x00A0}␊ |
526 | };␊ |
527 | ␊ |
528 | static int␊ |
529 | checkname (uint16_t *ucsname, int ucslen, struct direntry *dirp, uint16_t *vfatname)␊ |
530 | {␊ |
531 | ␉uint16_t tmp[15];␊ |
532 | ␉if (vfatname[0])␊ |
533 | ␉{␊ |
534 | ␉␉int i;␊ |
535 | ␉␉for (i=0;vfatname[i];i++);␊ |
536 | ␉␉return !FastUnicodeCompare (ucsname, ucslen, vfatname, i, OSLittleEndian);␊ |
537 | ␉}␊ |
538 | ␉else␊ |
539 | ␉{␊ |
540 | ␉␉int i, j, k;␊ |
541 | ␉␉for (i=7;i>=0;i--)␊ |
542 | ␉␉␉if (dirp->deName[i]!=' ')␊ |
543 | ␉␉␉␉break;␊ |
544 | ␉␉j=i+1;␊ |
545 | ␉␉tmp[i+1]=0;␊ |
546 | ␉␉for(;i>=0;i--)␊ |
547 | ␉␉␉tmp[i]=SWAP_LE16((dirp->deName[i]>=128)?cp850[dirp->deName[i]-128][0]:tolower(dirp->deName[i]));␊ |
548 | ␉␉for (i=2;i>=0;i--)␊ |
549 | ␉␉␉if (dirp->deName[8+i]!=' ')␊ |
550 | ␉␉␉␉break;␊ |
551 | ␉␉if (i>=0)␊ |
552 | ␉␉{␊ |
553 | ␉␉␉tmp[j++]='.';␊ |
554 | ␉␉␉tmp[j+i+1]=0;␊ |
555 | ␉␉␉k=j+i+1;␊ |
556 | ␉␉␉for(;i>=0;i--)␊ |
557 | ␉␉␉␉tmp[j+i]=SWAP_LE16((dirp->deName[i+8]>=128)?cp850[dirp->deName[i+8]-128][0]:tolower(dirp->deName[i+8]));␊ |
558 | ␉␉␉j=k;␊ |
559 | ␉␉}␊ |
560 | ␉␉return !FastUnicodeCompare (ucsname, ucslen, tmp, j, OSLittleEndian);␊ |
561 | ␉}␊ |
562 | ␉␊ |
563 | }␊ |
564 | ␊ |
565 | static struct direntry *␊ |
566 | getdirpfrompath (CICell ih, char *dirspec, uint8_t *buf)␊ |
567 | {␊ |
568 | ␉struct msdosdirstate st;␊ |
569 | ␉struct direntry *dirp;␊ |
570 | ␉uint8_t * ptr;␊ |
571 | ␉uint8_t *slash;␊ |
572 | ␉char c;␊ |
573 | ␉uint16_t␉␉vfatname[WIN_MAXLEN+2*WIN_CHARS];␊ |
574 | ␉uint16_t ucsname[WIN_MAXLEN+1];␊ |
575 | ␉uint16_t ucslen;␊ |
576 | ␉int ucslenhost;␊ |
577 | ␉initRoot (&st);␊ |
578 | ␉st.buf = (struct direntry *)buf;␊ |
579 | ␉ptr=(uint8_t*)dirspec;␊ |
580 | ␉for (slash=ptr;*slash && *slash!='/';slash++);␊ |
581 | ␉c=*slash;␊ |
582 | ␉*slash=0;␊ |
583 | ␉utf_decodestr (ptr, ucsname, &ucslen, WIN_MAXLEN, OSLittleEndian);␊ |
584 | ␉ucslenhost = OSReadLittleInt16 (&ucslen,0);␊ |
585 | ␉ucsname[ucslenhost]=0;␊ |
586 | ␉*slash=c;␉␊ |
587 | ␉while ((dirp = getnextdirent (ih, vfatname, &st)))␊ |
588 | ␉{␊ |
589 | ␉␉if (checkname (ucsname, ucslenhost, dirp, vfatname))␊ |
590 | ␉␉{␊ |
591 | ␉␉␉for (;*ptr && *ptr!='/';ptr++);␊ |
592 | ␉␉␉if (!*ptr)␊ |
593 | ␉␉␉␉return dirp;␊ |
594 | ␉␉␉ptr++;␊ |
595 | ␉␉␉if (!*ptr)␊ |
596 | ␉␉␉␉return dirp;␊ |
597 | ␉␉␉for (slash=ptr;*slash && *slash!='/';slash++);␊ |
598 | ␉␉␉c=*slash;␊ |
599 | ␉␉␉*slash=0;␊ |
600 | ␉␉␉utf_decodestr (ptr, ucsname, &ucslen, WIN_MAXLEN, OSLittleEndian);␊ |
601 | ␉␉␉ucslenhost = OSReadLittleInt16 (&ucslen,0);␊ |
602 | ␉␉␉ucsname[ucslenhost]=0;␊ |
603 | ␉␉␉*slash=c;␊ |
604 | ␉␉␉if (!(dirp->deAttributes & ATTR_DIRECTORY))␊ |
605 | ␉␉␉␉return 0;␊ |
606 | ␉␉␉st.root16 = 0;␊ |
607 | ␉␉␉st.vfatchecksum = 0;␊ |
608 | ␉␉␉st.nument = 0;␊ |
609 | ␉␉␉st.cluster = OSReadLittleInt16 ((dirp->deStartCluster),0);␊ |
610 | ␉␉␉if (msdosfatbits == 32)␊ |
611 | ␉␉␉␉st.cluster |= ((uint32_t)OSReadLittleInt16 ((dirp->deHighClust),0)) <<16;␊ |
612 | ␉␉␉st.vfatnumber = 0;␊ |
613 | ␉␉}␊ |
614 | ␉}␊ |
615 | ␉return 0;␊ |
616 | }␊ |
617 | ␊ |
618 | long MSDOSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,␊ |
619 | ␉␉␉␉␉ char ** name, long * flags, long * time,␊ |
620 | ␉␉␉␉␉ FinderInfo * finderInfo, long * infoValid)␊ |
621 | {␊ |
622 | ␉struct msdosdirstate *st;␊ |
623 | ␉struct direntry *dirp;␊ |
624 | ␉uint16_t␉␉vfatname[WIN_MAXLEN+2*WIN_CHARS];␊ |
625 | ␉if (MSDOSInitPartition (ih)<0)␊ |
626 | ␉␉return -1;␊ |
627 | ␉if (dirPath[0] == '/')␊ |
628 | ␉␉dirPath++;␊ |
629 | ␉st = (struct msdosdirstate *)*dirIndex;␊ |
630 | ␉if (!st)␊ |
631 | ␉{␊ |
632 | ␉␉st=malloc (sizeof (*st));␊ |
633 | ␉␉if (dirPath[0])␊ |
634 | ␉␉{␊ |
635 | ␉␉␉uint8_t *buf=malloc(msdosclustersize);␊ |
636 | ␉␉␉dirp = getdirpfrompath (ih, dirPath, buf);␊ |
637 | ␉␉␉if (!dirp || !(dirp->deAttributes & ATTR_DIRECTORY))␊ |
638 | ␉␉␉{␊ |
639 | ␉␉␉␉free (buf);␊ |
640 | ␉␉␉␉free (st);␊ |
641 | ␉␉␉␉return -1;␊ |
642 | ␉␉␉}␊ |
643 | ␉␉␉st->buf = (struct direntry *)buf;␊ |
644 | ␉␉␉st->root16 = 0;␊ |
645 | ␉␉␉st->vfatchecksum = 0;␊ |
646 | ␉␉␉st->nument = 0;␊ |
647 | ␉␉␉st->cluster = OSReadLittleInt16 ((dirp->deStartCluster),0);␊ |
648 | ␉␉␉st->vfatnumber = 0;␊ |
649 | ␉␉␉if (msdosfatbits == 32)␊ |
650 | ␉␉␉␉st->cluster |= ((uint32_t)OSReadLittleInt16 ((dirp->deHighClust),0)) <<16;␊ |
651 | ␉␉}␊ |
652 | ␉␉else␊ |
653 | ␉␉␉initRoot (st);␊ |
654 | ␉␉*dirIndex = (long)st;␊ |
655 | ␉}␊ |
656 | ␉while((dirp = getnextdirent (ih, vfatname, st))&& (dirp->deAttributes & ATTR_VOLUME));␊ |
657 | ␉if (!dirp)␊ |
658 | ␉{␊ |
659 | ␉␉free (st->buf);␊ |
660 | ␉␉free (st);␊ |
661 | ␉␉return -1;␊ |
662 | ␉}␊ |
663 | ␉if (vfatname[0])␊ |
664 | ␉{␊ |
665 | ␉␉int i;␊ |
666 | ␉␉for (i=0;vfatname[i];i++);␊ |
667 | ␉␉*name = malloc (256);␊ |
668 | ␉␉utf_encodestr(vfatname, i, (u_int8_t *)*name, 255, OSLittleEndian );␉␊ |
669 | ␉}␊ |
670 | ␉else␊ |
671 | ␉{␊ |
672 | ␉␉int i, j, k;␊ |
673 | ␉␉uint16_t tmp[13];␊ |
674 | ␉␉*name = malloc (26);␊ |
675 | ␉␉for (i=7;i>=0;i--)␊ |
676 | ␉␉␉if (dirp->deName[i]!=' ')␊ |
677 | ␉␉␉␉break;␊ |
678 | ␉␉j=i+1;␊ |
679 | ␉␉tmp[i+1]=0;␊ |
680 | ␉␉for(;i>=0;i--)␊ |
681 | ␉␉␉tmp[i]=(dirp->deName[i]>=128)?cp850[dirp->deName[i]-128][0]:tolower(dirp->deName[i]);␊ |
682 | ␉␉for (i=2;i>=0;i--)␊ |
683 | ␉␉␉if (dirp->deName[8+i]!=' ')␊ |
684 | ␉␉␉␉break;␊ |
685 | ␉␉␊ |
686 | ␉␉if (i>=0)␊ |
687 | ␉␉{␊ |
688 | ␉␉␉tmp[j++]='.';␊ |
689 | ␉␉␉tmp[j+i+1]=0;␊ |
690 | ␉␉␉k=j+i+1;␊ |
691 | ␉␉␉for(;i>=0;i--)␊ |
692 | ␉␉␉␉tmp[j+i]=(dirp->deName[i]>=128)?cp850[dirp->deName[i+8]-128][0]:tolower(dirp->deName[i+8]);␊ |
693 | ␉␉␉j=k;␊ |
694 | ␉␉}␊ |
695 | ␉␉␊ |
696 | ␉␉utf_encodestr(tmp, j, (uint8_t*)*name, 25, OSHostByteOrder() );␊ |
697 | ␉}␊ |
698 | ␉if (dirp->deAttributes & ATTR_DIRECTORY)␊ |
699 | ␉␉*flags = kFileTypeDirectory;␊ |
700 | ␉else␊ |
701 | ␉␉*flags = kFileTypeFlat;␊ |
702 | ␉␊ |
703 | ␉// Calculate a fake timestamp using modification date and time values.␊ |
704 | ␉*time = (dirp->deMDate & 0x7FFF) << 16 + dirp->deMTime;␊ |
705 | ␉␊ |
706 | ␉if (infoValid)␊ |
707 | ␉␉*infoValid = 1;␊ |
708 | ␊ |
709 | ␉return 0;␊ |
710 | }␊ |
711 | ␊ |
712 | long ␊ |
713 | MSDOSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length)␊ |
714 | {␊ |
715 | ␉uint8_t *buf;␊ |
716 | ␉off_t cluster;␊ |
717 | ␉uint64_t size;␊ |
718 | ␉uint64_t nskip;␊ |
719 | ␉int toread, wastoread;␊ |
720 | ␉char *ptr = (char *)base;␊ |
721 | ␉struct direntry *dirp;␊ |
722 | ␉int i;␊ |
723 | ␉if (MSDOSInitPartition (ih)<0)␊ |
724 | ␉␉return -1;␊ |
725 | ␉if (filePath[0] == '/')␊ |
726 | ␉␉filePath++;␊ |
727 | ␉buf = malloc(msdosclustersize);␊ |
728 | ␉dirp = getdirpfrompath (ih, filePath, buf);␊ |
729 | ␉␊ |
730 | ␉if (!dirp || (dirp->deAttributes & ATTR_DIRECTORY))␊ |
731 | ␉{␊ |
732 | ␉␉free (buf);␊ |
733 | ␉␉return -1;␊ |
734 | ␉}␊ |
735 | ␉cluster = OSReadLittleInt16 ((dirp->deStartCluster),0);␊ |
736 | ␉if (msdosfatbits == 32)␊ |
737 | ␉␉cluster |= ((uint32_t)OSReadLittleInt16 ((dirp->deHighClust),0)) <<16;␊ |
738 | ␉size = (uint32_t)OSReadLittleInt32 ((dirp->deFileSize),0);␊ |
739 | ␉if (size<=offset)␊ |
740 | ␉␉return -1;␊ |
741 | ␉nskip=offset/msdosclustersize;␊ |
742 | ␉for (i=0;i<nskip;i++)␊ |
743 | ␉␉msdosreadcluster (ih, 0, 0, &cluster);␊ |
744 | ␉msdosreadcluster (ih, buf, msdosclustersize, &cluster);␊ |
745 | ␉toread=length;␊ |
746 | ␉if (length==0 || length>size-offset)␊ |
747 | ␉␉toread=size-offset;␊ |
748 | ␉wastoread=toread;␊ |
749 | ␉bcopy (buf+(offset%msdosclustersize),ptr,min(msdosclustersize-(offset%msdosclustersize), toread));␊ |
750 | ␉ptr+=msdosclustersize-(offset%msdosclustersize);␊ |
751 | ␉toread-=msdosclustersize-(offset%msdosclustersize);␊ |
752 | ␉while (toread>0 && msdosreadcluster (ih, (uint8_t *)ptr, min(msdosclustersize,toread), &cluster))␊ |
753 | ␉{␊ |
754 | ␉␉ptr+=msdosclustersize;␊ |
755 | ␉␉toread-=msdosclustersize;␊ |
756 | ␉}␊ |
757 | ␉verbose("Loaded FAT%d file: [%s] %d bytes from %x.\n",␊ |
758 | msdosfatbits, filePath, (uint32_t)( toread<0 ) ? wastoread : wastoread-toread, ih);␊ |
759 | ␉free (buf);␊ |
760 | ␉if (toread<0)␊ |
761 | ␉␉return wastoread;␊ |
762 | ␉else␊ |
763 | ␉␉return wastoread-toread;␊ |
764 | }␊ |
765 | ␊ |
766 | long ␊ |
767 | MSDOSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock)␊ |
768 | {␊ |
769 | ␉uint8_t *buf;␊ |
770 | ␉off_t cluster;␊ |
771 | ␉struct direntry *dirp;␊ |
772 | ␉if (MSDOSInitPartition (ih)<0)␊ |
773 | ␉␉return -1;␊ |
774 | ␉if (filePath[0] == '/')␊ |
775 | ␉␉filePath++;␊ |
776 | ␉buf = malloc(msdosclustersize);␊ |
777 | ␉dirp = getdirpfrompath (ih, filePath, buf);␊ |
778 | ␉if (!dirp || (dirp->deAttributes & ATTR_DIRECTORY))␊ |
779 | ␉{␊ |
780 | ␉␉free (buf);␊ |
781 | ␉␉return -1;␊ |
782 | ␉}␊ |
783 | ␉cluster = OSReadLittleInt16 ((dirp->deStartCluster),0);␊ |
784 | ␉if (msdosfatbits == 32)␊ |
785 | ␉␉cluster |= ((uint32_t)OSReadLittleInt16 ((dirp->deHighClust),0)) <<16;␊ |
786 | ␉␊ |
787 | ␉off_t clusn;␊ |
788 | ␉␊ |
789 | ␉switch (msdosfatbits) {␊ |
790 | ␉␉case 32:␊ |
791 | ␉␉␉if (cluster < CLUST_FIRST ||cluster >= CLUST_RSRVD32)␊ |
792 | ␉␉␉␉return -1;␊ |
793 | ␉␉␉clusn = cluster - CLUST_FIRST;␊ |
794 | ␉␉␉break;␊ |
795 | ␉␉case 16:␊ |
796 | ␉␉␉if (cluster < CLUST_FIRST ||cluster >= CLUST_RSRVD16)␊ |
797 | ␉␉␉␉return 0;␊ |
798 | ␉␉␉clusn = cluster - CLUST_FIRST;␊ |
799 | ␉␉␉break;␉␉␉␊ |
800 | ␉␉case 12:␊ |
801 | ␉␉␉␊ |
802 | ␉␉␉if (cluster < CLUST_FIRST ||cluster >= CLUST_RSRVD12)␊ |
803 | ␉␉␉␉return 0;␊ |
804 | ␉␉␉clusn = cluster - CLUST_FIRST;␊ |
805 | ␉␉␉break;␊ |
806 | ␉␉default:␊ |
807 | ␉␉␉return 0;␊ |
808 | ␉}␊ |
809 | ␉␊ |
810 | ␉*firstBlock = ((msdosressector +␊ |
811 | ␉␉␉␉ (msdosnfats * msdosfatsecs))*msdosbps + clusn * msdosclustersize)/512;␊ |
812 | ␉free (buf);␊ |
813 | ␉return 0;␊ |
814 | }␊ |
815 | ␊ |
816 | ␊ |
817 | long MSDOSLoadFile(CICell ih, char * filePath)␊ |
818 | {␊ |
819 | return MSDOSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);␊ |
820 | }␊ |
821 | ␊ |
822 | /* Fix up volume label. */␊ |
823 | static void␊ |
824 | fixLabel(uint8_t *label, char *str, long strMaxLen)␊ |
825 | {␊ |
826 | int␉␉␉i, len;␊ |
827 | ␉uint16_t␉labelucs[13];␊ |
828 | //unsigned char␉labelUTF8[LABEL_LENGTH*3];␊ |
829 | ␉␊ |
830 | /* Convert leading 0x05 to 0xE5 for multibyte languages like Japanese */␊ |
831 | if (label[0] == 0x05)␊ |
832 | label[0] = 0xE5;␊ |
833 | ␉␊ |
834 | /* Remove any trailing spaces */␊ |
835 | for (i=LABEL_LENGTH-1; i>=0; --i) {␊ |
836 | if (label[i] == ' ')␊ |
837 | label[i] = 0;␊ |
838 | else␊ |
839 | break;␊ |
840 | }␊ |
841 | ␉labelucs[i++]=0;␊ |
842 | ␉len=i;␊ |
843 | ␉for (;i>=0;--i)␊ |
844 | ␉␉labelucs[i]=label[i]>=128?cp850[label[i]-128][1]:(label[i]);␊ |
845 | ␉␊ |
846 | ␉utf_encodestr(labelucs, len, (uint8_t *)str, strMaxLen, OSHostByteOrder() );␊ |
847 | }␊ |
848 | ␊ |
849 | ␊ |
850 | void␊ |
851 | MSDOSGetDescription(CICell ih, char *str, long strMaxLen)␊ |
852 | {␊ |
853 | struct direntry *dirp;␊ |
854 | uint8_t␉ label[LABEL_LENGTH+1];␊ |
855 | ␉uint16_t␉␉vfatlabel[WIN_MAXLEN+2*WIN_CHARS];␊ |
856 | ␉struct msdosdirstate st;␊ |
857 | ␉int labelfound = 0;␊ |
858 | ␊ |
859 | ␉if (MSDOSInitPartition (ih)<0)␊ |
860 | ␉{␊ |
861 | ␉␉str[0]=0;␊ |
862 | ␉␉return;␊ |
863 | ␉}␊ |
864 | ␊ |
865 | ␉label[0] = '\0';␊ |
866 | ␉␊ |
867 | ␉initRoot (&st);␊ |
868 | ␉st.buf = malloc(msdosclustersize);␊ |
869 | ␉while ((dirp = getnextdirent (ih, vfatlabel, &st)))␊ |
870 | ␉␉if (dirp->deAttributes & ATTR_VOLUME) {␊ |
871 | ␉␉␉strncpy((char *)label, (char *)dirp->deName, LABEL_LENGTH);␊ |
872 | ␉␉␉labelfound = 1;␊ |
873 | ␉␉␉break;␊ |
874 | ␉␉}␊ |
875 | ␉␉␊ |
876 | ␉free(st.buf);␉␉␊ |
877 | ␊ |
878 | ␉if (vfatlabel[0] && labelfound)␊ |
879 | ␉{␊ |
880 | ␉␉int i;␊ |
881 | ␉␉for (i=0;vfatlabel[i];i++);␊ |
882 | ␉␉utf_encodestr(vfatlabel, i, (u_int8_t *)str, strMaxLen, OSLittleEndian );␉␉␊ |
883 | ␉}␉␊ |
884 | ␉else if (labelfound)␊ |
885 | ␉␉fixLabel(label, str, strMaxLen);␊ |
886 | ␉␊ |
887 | /* else look in the boot blocks */␊ |
888 | if (!labelfound || str[0] == '\0') {␊ |
889 | ␉␉char *buf = malloc (512);␊ |
890 | ␉␉union bootsector *bsp = (union bootsector *)buf;␊ |
891 | ␉␉Seek(ih, 0);␊ |
892 | ␉␉Read(ih, (long)buf, 512);␊ |
893 | if (msdosfatbits == 32) { /* It's FAT32 */␊ |
894 | strncpy((char *)label, (char *)((struct extboot *)bsp->bs710.bsExt)->exVolumeLabel, LABEL_LENGTH);␊ |
895 | }␊ |
896 | else if (msdosfatbits == 16) {␊ |
897 | strncpy((char *)label, (char *)((struct extboot *)bsp->bs50.bsExt)->exVolumeLabel, LABEL_LENGTH);␊ |
898 | }␊ |
899 | ␉␉free (buf);␊ |
900 | ␉␉fixLabel(label, str, strMaxLen);␊ |
901 | }␊ |
902 | ␊ |
903 | return;␊ |
904 | }␊ |
905 | ␊ |
906 | long ␊ |
907 | MSDOSGetUUID(CICell ih, char *uuidStr)␊ |
908 | {␊ |
909 | ␉char *buf = malloc (512);␊ |
910 | ␉union bootsector *bsp = (union bootsector *)buf;␊ |
911 | ␉␊ |
912 | ␉if (MSDOSInitPartition (ih)<0)␊ |
913 | ␉{␊ |
914 | ␉␉return -1;␊ |
915 | ␉}␊ |
916 | ␉bzero (uuidStr, 16);␊ |
917 | ␉Seek(ih, 0);␊ |
918 | ␉Read(ih, (long)buf, 512);␊ |
919 | ␉if (msdosfatbits == 32) { /* It's FAT32 */␊ |
920 | ␉␉memcpy(uuidStr+12, (char *)((struct extboot *)bsp->bs710.bsExt)->exVolumeID, 4);␊ |
921 | ␉}␊ |
922 | ␉else if (msdosfatbits == 16) {␊ |
923 | ␉␉memcpy(uuidStr+12, (char *)((struct extboot *)bsp->bs50.bsExt)->exVolumeID, 4);␊ |
924 | ␉}␊ |
925 | ␉free (buf);␊ |
926 | return 0;␊ |
927 | ␉␊ |
928 | }␊ |
929 |