Changes in tools/mkfat.py [cc1a727:87608a5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
tools/mkfat.py
rcc1a727 r87608a5 168 168 """ 169 169 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): 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 208 286 dir_entry = xstruct.create(DIR_ENTRY) 209 287 210 dir_entry.name = mangle_fname(name).encode('ascii')211 dir_entry.ext = mangle_ext(name).encode('ascii')288 dir_entry.name = short_name 289 dir_entry.ext = short_ext 212 290 213 291 if (directory): … … 230 308 dir_entry.size = size 231 309 232 return dir_entry 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 233 326 234 327 def create_dot_dirent(empty_cluster): … … 274 367 275 368 directory = [] 276 277 if (not head): 369 name83_list = [] 370 371 if not head: 278 372 # Directory cluster preallocation 279 373 empty_cluster = fat.index(0) 280 fat[empty_cluster] = 0x ffff374 fat[empty_cluster] = 0xFFFF 281 375 282 376 directory.append(create_dot_dirent(empty_cluster)) … … 285 379 empty_cluster = 0 286 380 287 for item in listdir_items(root): 381 for item in listdir_items(root): 288 382 if item.is_file: 289 383 rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters) 290 directory. append(create_dirent(item.name, False, rv[0], rv[1]))384 directory.extend(create_dirent(item.name, name83_list, False, rv[0], rv[1])) 291 385 elif item.is_dir: 292 386 rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster) 293 directory. append(create_dirent(item.name, True, rv[0], rv[1]))294 295 if (head):387 directory.extend(create_dirent(item.name, name83_list, True, rv[0], rv[1])) 388 389 if head: 296 390 outf.seek(root_start) 297 391 for dir_entry in directory: … … 350 444 extra_bytes = int(sys.argv[1]) 351 445 352 path = os.path.abspath(sys.argv[2] )446 path = os.path.abspath(sys.argv[2].decode()) 353 447 if (not os.path.isdir(path)): 354 448 print("<PATH> must be a directory") … … 448 542 449 543 outf.close() 450 544 451 545 if __name__ == '__main__': 452 546 main()
Note:
See TracChangeset
for help on using the changeset viewer.