Changes in tools/mkfat.py [87608a5:cc1a727] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
tools/mkfat.py
r87608a5 rcc1a727 168 168 """ 169 169 170 LFN_DIR_ENTRY = """little: 171 uint8_t seq /* sequence number */ 172 char name1[10] /* first part of the name */ 173 uint8_t attr /* attributes */ 174 uint8_t rec_type /* LFN record type */ 175 uint8_t checksum /* LFN checksum */ 176 char name2[12] /* second part of the name */ 177 uint16_t cluster /* cluster */ 178 char name3[4] /* third part of the name */ 179 """ 180 181 lchars = set(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 182 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 183 'U', 'V', 'W', 'X', 'Y', 'Z', 184 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 185 '!', '#', '$', '%', '&', '\'', '(', ')', '-', '@', 186 '^', '_', '`', '{', '}', '~', '.']) 187 188 def fat_lchars(name): 189 "Filter FAT legal characters" 190 191 filtered_name = '' 192 filtered = False 193 194 for char in name.encode('ascii', 'replace').upper(): 195 if char in lchars: 196 filtered_name += char 197 else: 198 filtered_name += b'_' 199 filtered = True 200 201 return (filtered_name, filtered) 202 203 def fat_name83(name, name83_list): 204 "Create a 8.3 name for the given name" 205 206 ascii_name, lfn = fat_lchars(name) 207 ascii_parts = ascii_name.split('.') 208 209 short_name = '' 210 short_ext = '' 211 212 if len(ascii_name) > 11: 213 lfn = True 214 215 if len(ascii_parts) > 0: 216 short_name = ascii_parts[0] 217 if len(short_name) > 8: 218 lfn = True 219 220 if len(ascii_parts) > 1: 221 short_ext = ascii_parts[-1] 222 if len(short_ext) > 3: 223 lfn = True 224 225 if len(ascii_parts) > 2: 226 lfn = True 227 228 if lfn == False: 229 name83_list.append(short_name + '.' + short_ext) 230 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], False) 231 232 # For filenames with multiple extensions, we treat the last one 233 # as the actual extension. The rest of the filename is stripped 234 # of dots and concatenated to form the short name 235 for part in ascii_parts[1:-1]: 236 short_name += part 237 238 for number in range(1, 999999): 239 number_str = ('~' + str(number)).upper() 240 241 if len(short_name) + len(number_str) > 8: 242 short_name = short_name[0:8 - len(number_str)] 243 244 short_name += number_str; 245 246 if not (short_name + '.' + short_ext) in name83_list: 247 break 248 249 name83_list.append(short_name + '.' + short_ext) 250 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], True) 251 252 def create_lfn_dirent(name, seq, checksum): 253 "Create LFN directory entry" 254 255 entry = xstruct.create(LFN_DIR_ENTRY) 256 name_rest = name[26:] 257 258 if len(name_rest) > 0: 259 entry.seq = seq 260 else: 261 entry.seq = seq | 0x40 262 263 entry.name1 = name[0:10] 264 entry.name2 = name[10:22] 265 entry.name3 = name[22:26] 266 267 entry.attr = 0x0F 268 entry.rec_type = 0 269 entry.checksum = checksum 270 entry.cluster = 0 271 272 return (entry, name_rest) 273 274 def lfn_checksum(name): 275 "Calculate LFN checksum" 276 277 checksum = 0 278 for i in range(0, 11): 279 checksum = (((checksum & 1) << 7) + (checksum >> 1) + ord(name[i])) & 0xFF 280 281 return checksum 282 283 def create_dirent(name, name83_list, directory, cluster, size): 284 short_name, short_ext, lfn = fat_name83(name, name83_list) 285 170 def mangle_fname(name): 171 # FIXME: filter illegal characters 172 parts = name.split('.') 173 174 if len(parts) > 0: 175 fname = parts[0] 176 else: 177 fname = '' 178 179 if len(fname) > 8: 180 sys.stdout.write("mkfat.py: error: Directory entry " + name + 181 " base name is longer than 8 characters\n") 182 sys.exit(1); 183 184 return (fname + ' ').upper()[0:8] 185 186 def mangle_ext(name): 187 # FIXME: filter illegal characters 188 parts = name.split('.') 189 190 if len(parts) > 1: 191 ext = parts[1] 192 else: 193 ext = '' 194 195 if len(parts) > 2: 196 sys.stdout.write("mkfat.py: error: Directory entry " + name + 197 " has more than one extension\n") 198 sys.exit(1); 199 200 if len(ext) > 3: 201 sys.stdout.write("mkfat.py: error: Directory entry " + name + 202 " extension is longer than 3 characters\n") 203 sys.exit(1); 204 205 return (ext + ' ').upper()[0:3] 206 207 def create_dirent(name, directory, cluster, size): 286 208 dir_entry = xstruct.create(DIR_ENTRY) 287 209 288 dir_entry.name = short_name289 dir_entry.ext = short_ext210 dir_entry.name = mangle_fname(name).encode('ascii') 211 dir_entry.ext = mangle_ext(name).encode('ascii') 290 212 291 213 if (directory): … … 308 230 dir_entry.size = size 309 231 310 if not lfn: 311 return [dir_entry] 312 313 long_name = name.encode('utf_16_le') 314 entries = [dir_entry] 315 316 seq = 1 317 checksum = lfn_checksum(dir_entry.name + dir_entry.ext) 318 319 while len(long_name) > 0: 320 long_entry, long_name = create_lfn_dirent(long_name, seq, checksum) 321 entries.append(long_entry) 322 seq += 1 323 324 entries.reverse() 325 return entries 232 return dir_entry 326 233 327 234 def create_dot_dirent(empty_cluster): … … 367 274 368 275 directory = [] 369 name83_list = [] 370 371 if not head: 276 277 if (not head): 372 278 # Directory cluster preallocation 373 279 empty_cluster = fat.index(0) 374 fat[empty_cluster] = 0x FFFF280 fat[empty_cluster] = 0xffff 375 281 376 282 directory.append(create_dot_dirent(empty_cluster)) … … 379 285 empty_cluster = 0 380 286 381 for item in listdir_items(root): 287 for item in listdir_items(root): 382 288 if item.is_file: 383 289 rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters) 384 directory. extend(create_dirent(item.name, name83_list, False, rv[0], rv[1]))290 directory.append(create_dirent(item.name, False, rv[0], rv[1])) 385 291 elif item.is_dir: 386 292 rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster) 387 directory. extend(create_dirent(item.name, name83_list, True, rv[0], rv[1]))388 389 if head:293 directory.append(create_dirent(item.name, True, rv[0], rv[1])) 294 295 if (head): 390 296 outf.seek(root_start) 391 297 for dir_entry in directory: … … 444 350 extra_bytes = int(sys.argv[1]) 445 351 446 path = os.path.abspath(sys.argv[2] .decode())352 path = os.path.abspath(sys.argv[2]) 447 353 if (not os.path.isdir(path)): 448 354 print("<PATH> must be a directory") … … 542 448 543 449 outf.close() 544 450 545 451 if __name__ == '__main__': 546 452 main()
Note:
See TracChangeset
for help on using the changeset viewer.