3 exFAT file system implementation library.
5 Free exFAT implementation.
6 Copyright (C) 2010-2018 Andrew Nayenko
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 void exfat_stat(const struct exfat
* ef
, const struct exfat_node
* node
,
31 memset(stbuf
, 0, sizeof(struct stat
));
32 if (node
->attrib
& EXFAT_ATTRIB_DIR
)
33 stbuf
->st_mode
= S_IFDIR
| (0777 & ~ef
->dmask
);
35 stbuf
->st_mode
= S_IFREG
| (0777 & ~ef
->fmask
);
37 stbuf
->st_uid
= ef
->uid
;
38 stbuf
->st_gid
= ef
->gid
;
39 stbuf
->st_size
= node
->size
;
40 stbuf
->st_blocks
= ROUND_UP(node
->size
, CLUSTER_SIZE(*ef
->sb
)) / 512;
41 stbuf
->st_mtime
= node
->mtime
;
42 stbuf
->st_atime
= node
->atime
;
43 /* set ctime to mtime to ensure we don't break programs that rely on ctime
45 stbuf
->st_ctime
= node
->mtime
;
48 void exfat_get_name(const struct exfat_node
* node
,
49 char buffer
[EXFAT_UTF8_NAME_BUFFER_MAX
])
51 if (utf16_to_utf8(buffer
, node
->name
, EXFAT_UTF8_NAME_BUFFER_MAX
,
53 exfat_bug("failed to convert name to UTF-8");
56 static uint16_t add_checksum_byte(uint16_t sum
, uint8_t byte
)
58 return ((sum
<< 15) | (sum
>> 1)) + byte
;
61 static uint16_t add_checksum_bytes(uint16_t sum
, const void* buffer
, size_t n
)
65 for (i
= 0; i
< n
; i
++)
66 sum
= add_checksum_byte(sum
, ((const uint8_t*) buffer
)[i
]);
70 uint16_t exfat_start_checksum(const struct exfat_entry_meta1
* entry
)
75 for (i
= 0; i
< sizeof(struct exfat_entry
); i
++)
76 if (i
!= 2 && i
!= 3) /* skip checksum field itself */
77 sum
= add_checksum_byte(sum
, ((const uint8_t*) entry
)[i
]);
81 uint16_t exfat_add_checksum(const void* entry
, uint16_t sum
)
83 return add_checksum_bytes(sum
, entry
, sizeof(struct exfat_entry
));
86 le16_t
exfat_calc_checksum(const struct exfat_entry
* entries
, int n
)
91 checksum
= exfat_start_checksum((const struct exfat_entry_meta1
*) entries
);
92 for (i
= 1; i
< n
; i
++)
93 checksum
= exfat_add_checksum(entries
+ i
, checksum
);
94 return cpu_to_le16(checksum
);
97 uint32_t exfat_vbr_start_checksum(const void* sector
, size_t size
)
102 for (i
= 0; i
< size
; i
++)
103 /* skip volume_state and allocated_percent fields */
104 if (i
!= 0x6a && i
!= 0x6b && i
!= 0x70)
105 sum
= ((sum
<< 31) | (sum
>> 1)) + ((const uint8_t*) sector
)[i
];
109 uint32_t exfat_vbr_add_checksum(const void* sector
, size_t size
, uint32_t sum
)
113 for (i
= 0; i
< size
; i
++)
114 sum
= ((sum
<< 31) | (sum
>> 1)) + ((const uint8_t*) sector
)[i
];
118 le16_t
exfat_calc_name_hash(const struct exfat
* ef
, const le16_t
* name
,
124 for (i
= 0; i
< length
; i
++)
126 uint16_t c
= le16_to_cpu(name
[i
]);
128 /* convert to upper case */
131 hash
= ((hash
<< 15) | (hash
>> 1)) + (c
& 0xff);
132 hash
= ((hash
<< 15) | (hash
>> 1)) + (c
>> 8);
134 return cpu_to_le16(hash
);
137 void exfat_humanize_bytes(uint64_t value
, struct exfat_human_bytes
* hb
)
140 /* 16 EB (minus 1 byte) is the largest size that can be represented by
142 const char* units
[] = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB"};
143 uint64_t divisor
= 1;
146 for (i
= 0; ; i
++, divisor
*= 1024)
148 temp
= (value
+ divisor
/ 2) / divisor
;
152 if (temp
/ 1024 * 1024 == temp
)
161 void exfat_print_info(const struct exfat_super_block
* sb
,
162 uint32_t free_clusters
)
164 struct exfat_human_bytes hb
;
165 off_t total_space
= le64_to_cpu(sb
->sector_count
) * SECTOR_SIZE(*sb
);
166 off_t avail_space
= (off_t
) free_clusters
* CLUSTER_SIZE(*sb
);
168 printf("File system version %hhu.%hhu\n",
169 sb
->version
.major
, sb
->version
.minor
);
170 exfat_humanize_bytes(SECTOR_SIZE(*sb
), &hb
);
171 printf("Sector size %10"PRIu64
" %s\n", hb
.value
, hb
.unit
);
172 exfat_humanize_bytes(CLUSTER_SIZE(*sb
), &hb
);
173 printf("Cluster size %10"PRIu64
" %s\n", hb
.value
, hb
.unit
);
174 exfat_humanize_bytes(total_space
, &hb
);
175 printf("Volume size %10"PRIu64
" %s\n", hb
.value
, hb
.unit
);
176 exfat_humanize_bytes(total_space
- avail_space
, &hb
);
177 printf("Used space %10"PRIu64
" %s\n", hb
.value
, hb
.unit
);
178 exfat_humanize_bytes(avail_space
, &hb
);
179 printf("Available space %10"PRIu64
" %s\n", hb
.value
, hb
.unit
);