Chameleon

Chameleon Commit Details

Date:2012-06-07 23:17:32 (2 years 5 months ago)
Author:ErmaC
Commit:1994
Parents: 1993
Message:Complete the exfat patch in the previous commit (r1989) Two(2) file was missed [exfat.c exfat.h] from original dmazar stuff. Now the compiling process end fine.
Changes:
A/trunk/i386/libsaio/exfat.c
A/trunk/i386/libsaio/exfat.h

File differences

trunk/i386/libsaio/exfat.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 1999-2004 Apple Computer, Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* dmazar, 14/7/2011
* support for EXFAT volume label reading
* EXFAT info from: http://www.ntfs.com/exfat-overview.htm
*
* EXFAT shares partition type with NTFS (0x7) and easiest way of
* adding it was through ntfs.c module. All functions here are called
* from similar ntfs.c funcs as fallback (if not NTFS, maybe it's EXFAT).
*/
#include "libsaio.h"
#include "sl.h"
#ifndef DEBUG_EXFAT
#define DEBUG_EXFAT 0
#endif
#if DEBUG_EXFAT
#define DBG(x...)printf(x)
#define PAUSE()getchar()
#else
#define DBG(x...)
#define PAUSE()
#endif
#defineEXFAT_BBID"EXFAT "
#defineEXFAT_BBIDLEN8
#define MAX_BLOCK_SIZE4096
#define MAX_CLUSTER_SIZE32 * 1024 * 1024
#define ERROR -1
/*
* boot sector of the partition
* http://www.ntfs.com/exfat-boot-sector.htm
*/
struct exfatbootfile {
u_int8_t reserved1[3];/* JumpBoot: 0xEB7690 */
u_int8_t bf_sysid[8];/* FileSystemName: 'EXFAT ' */
u_int8_t reserved2[53];/* MustBeZero */
u_int64_t bf_prtoff;/* PartitionOffset: In sectors; if 0, shall be ignored */
u_int64_t bf_vollen;/* VolumeLength: Size of exFAT volume in sectors */
u_int32_t bf_fatoff;/* FatOffset: In sectors */
u_int32_t bf_fatlen;/* FatLength: In sectors. May exceed the required space in order to align the second FAT */
u_int32_t bf_cloff;/* ClusterHeapOffset: In sectors. */
u_int32_t bf_clcnt;/* ClusterCount: 2^32-11 is the maximum number of clusters could be described. */
u_int32_t bf_rdircl;/* RootDirectoryCluster. */
u_int32_t bf_volsn;/* VolumeSerialNumber. */
u_int16_t bf_fsrev;/* FileSystemRevision: as MAJOR.minor, major revision is high byte, minor is low byte; currently 01.00. */
u_int16_t bf_volflags;/* VolumeFlags. */
u_int8_t bf_bpss;/* BytesPerSectorShift: Power of 2. Minimum 9 (512 bytes per sector), maximum 12 (4096 bytes per sector) */
u_int8_t bf_nfats;/* NumberOfFats: 2 is for TexFAT only */
u_int8_t bf_drvs;/* DriveSelect: Extended INT 13h drive number; typically 0x80 */
u_int8_t reserved3[7];/* Reserved */
u_int8_t bootcode[390];/* BootCode */
u_int16_t bf_bsig;/* BootSignature: 0xAA55 */
};
struct direntry_label {
u_int8_t type;/* EntryType: 0x83 (or 0x03 if label is empty) */
u_int8_t llen;/* CharacterCount: Length in Unicode characters (max 11) */
u_int16_t label[11];/* VolumeLabel: Unicode characters (max 11) */
u_int8_t reserved1[8];/* Reserved */
};
/**
* Reads volume label into str.
* Reads boot sector, performs dome checking, loads root dir
* and parses volume label.
*/
void
EXFATGetDescription(CICell ih, char *str, long strMaxLen)
{
struct exfatbootfile *boot;
u_int32_t bytesPerSector = 0;
u_int32_t sectorsPerCluster = 0;
long long rdirOffset = 0;
char *buf = NULL;
struct direntry_label *dire = NULL;
int loopControl = 0;
DBG("EXFAT: start %x:%x\n", ih->biosdev, ih->part_no);
buf = (char *)malloc(MAX_BLOCK_SIZE);
if (buf == 0)
{
goto error;
}
/*
* Read the boot sector, check signatures, and do some minimal
* sanity checking. NOTE: the size of the read below is intended
* to be a multiple of all supported block sizes, so we don't
* have to determine or change the device's block size.
*/
Seek(ih, 0);
Read(ih, (long)buf, MAX_BLOCK_SIZE);
// take our boot structure
boot = (struct exfatbootfile *) buf;
/*
* The first three bytes are an Intel x86 jump instruction. I assume it
* can be the same forms as DOS FAT:
* 0xE9 0x?? 0x??
* 0xEC 0x?? 0x90
* where 0x?? means any byte value is OK.
*/
if (boot->reserved1[0] != 0xE9
&& (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90))
{
goto error;
}
// Check the "EXFAT " signature.
if (memcmp((const char *)boot->bf_sysid, EXFAT_BBID, EXFAT_BBIDLEN) != 0)
{
goto error;
}
/*
* Make sure the bytes per sector and sectors per cluster are
* powers of two, and within reasonable ranges.
*/
bytesPerSector = 1 << boot->bf_bpss;/* Just one byte; no swapping needed */
DBG("EXFAT: bpss=%d, bytesPerSector=%d\n", boot->bf_bpss, bytesPerSector);
if (boot->bf_bpss < 9 || boot->bf_bpss > 12)
{
DBG("EXFAT: invalid bytes per sector shift(%d)\n", boot->bf_bpss);
goto error;
}
sectorsPerCluster = 1 << boot->bf_spcs;/* Just one byte; no swapping needed */
DBG("EXFAT: spcs=%d, sectorsPerCluster=%d\n", boot->bf_spcs, sectorsPerCluster);
if (boot->bf_spcs > (25 - boot->bf_bpss))
{
DBG("EXFAT: invalid sectors per cluster shift (%d)\n", boot->bf_spcs);
goto error;
}
// calculate root dir cluster offset
rdirOffset = boot->bf_cloff + (boot->bf_rdircl - 2) * sectorsPerCluster;
DBG("EXFAT: rdirOffset=%d\n", rdirOffset);
// load MAX_BLOCK_SIZE bytes of root dir
Seek(ih, rdirOffset * bytesPerSector);
Read(ih, (long)buf, MAX_BLOCK_SIZE);
DBG("buf 0 1 2 = %x %x %x\n", 0x00ff & buf[0], 0x00ff & buf[1], 0x00ff & buf[2]);
str[0] = '\0';
/*
* Search for volume label dir entry (type 0x83), convert from unicode and put to str.
* Set loopControl var to avoid searching outside of buf.
*/
loopControl = MAX_BLOCK_SIZE / sizeof(struct direntry_label);
dire = (struct direntry_label *)buf;
while (loopControl && dire->type && dire->type != 0x83)
{
dire++;
loopControl--;
}
if (dire->type == 0x83 && dire->llen > 0 && dire->llen <= 11)
{
utf_encodestr( dire->label, (int)dire->llen, (u_int8_t *)str, strMaxLen, OSLittleEndian );
}
DBG("EXFAT: label=%s\n", str);
free(buf);
PAUSE();
return;
error:
if (buf) free(buf);
DBG("EXFAT: error\n");
PAUSE();
return;
}
/**
* Sets UUID to uuidStr.
* Reads the boot sector, does some checking, generates UUID
* (like the one you get on Windows???)
*/
long EXFATGetUUID(CICell ih, char *uuidStr)
{
struct exfatbootfile *boot;
void *buf = malloc(MAX_BLOCK_SIZE);
if ( !buf )
return -1;
/*
* Read the boot sector, check signatures, and do some minimal
* sanity checking. NOTE: the size of the read below is intended
* to be a multiple of all supported block sizes, so we don't
* have to determine or change the device's block size.
*/
Seek(ih, 0);
Read(ih, (long)buf, MAX_BLOCK_SIZE);
boot = (struct exfatbootfile *) buf;
/*
* Check the "EXFAT " signature.
*/
if (memcmp((const char *)boot->bf_sysid, EXFAT_BBID, EXFAT_BBIDLEN) != 0)
return -1;
// Check for non-null volume serial number
if( !boot->bf_volsn )
return -1;
// Use UUID like the one you get on Windows
sprintf(uuidStr, "%04X-%04X", (unsigned short)(boot->bf_volsn >> 16) & 0xFFFF,
(unsigned short)boot->bf_volsn & 0xFFFF);
DBG("EXFATGetUUID: %x:%x = %s\n", ih->biosdev, ih->part_no, uuidStr);
return 0;
}
/**
* Returns true if given buffer is the boot rec of the EXFAT volume.
*/
bool EXFATProbe(const void * buffer)
{
bool result = false;
// boot sector structure
const struct exfatbootfile* boot = buffer;
// Looking for EXFAT signature.
if (memcmp((const char *)boot->bf_sysid, EXFAT_BBID, EXFAT_BBIDLEN) == 0)
result = true;
DBG("EXFATProbe: %d\n", result ? 1 : 0);
return result;
}
trunk/i386/libsaio/exfat.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* dmazar, 14/7/2011
* support for EXFAT volume label reading
*
*/
extern void EXFATGetDescription(CICell ih, char *str, long strMaxLen);
extern bool EXFATProbe (const void *buf);
extern long EXFATGetUUID(CICell ih, char *uuidStr);

Archive Download the corresponding diff file

Revision: 1994