Changes in tools/mkfat.py [cc1a727:67435b1] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
tools/mkfat.py
rcc1a727 r67435b1 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 = b'' 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 # Splitting works only on strings, not on bytes 208 ascii_parts = ascii_name.decode('utf8').split('.') 209 210 short_name = '' 211 short_ext = '' 212 213 if len(ascii_name) > 11: 214 lfn = True 215 216 if len(ascii_parts) > 0: 217 short_name = ascii_parts[0] 218 if len(short_name) > 8: 219 lfn = True 220 221 if len(ascii_parts) > 1: 222 short_ext = ascii_parts[-1] 223 if len(short_ext) > 3: 224 lfn = True 225 226 if len(ascii_parts) > 2: 227 lfn = True 228 229 if lfn == False: 230 name83_list.append(short_name + '.' + short_ext) 231 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], False) 232 233 # For filenames with multiple extensions, we treat the last one 234 # as the actual extension. The rest of the filename is stripped 235 # of dots and concatenated to form the short name 236 for part in ascii_parts[1:-1]: 237 short_name += part 238 239 for number in range(1, 999999): 240 number_str = ('~' + str(number)).upper() 241 242 if len(short_name) + len(number_str) > 8: 243 short_name = short_name[0:8 - len(number_str)] 244 245 short_name += number_str; 246 247 if not (short_name + '.' + short_ext) in name83_list: 248 break 249 250 name83_list.append(short_name + '.' + short_ext) 251 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], True) 252 253 def create_lfn_dirent(name, seq, checksum): 254 "Create LFN directory entry" 255 256 entry = xstruct.create(LFN_DIR_ENTRY) 257 name_rest = name[26:] 258 259 if len(name_rest) > 0: 260 entry.seq = seq 261 else: 262 entry.seq = seq | 0x40 263 264 entry.name1 = name[0:10] 265 entry.name2 = name[10:22] 266 entry.name3 = name[22:26] 267 268 entry.attr = 0x0F 269 entry.rec_type = 0 270 entry.checksum = checksum 271 entry.cluster = 0 272 273 return (entry, name_rest) 274 275 def lfn_checksum(name): 276 "Calculate LFN checksum" 277 278 checksum = 0 279 for i in range(0, 11): 280 checksum = (((checksum & 1) << 7) + (checksum >> 1) + ord(name[i])) & 0xFF 281 282 return checksum 283 284 def create_dirent(name, name83_list, directory, cluster, size): 285 short_name, short_ext, lfn = fat_name83(name, name83_list) 286 208 287 dir_entry = xstruct.create(DIR_ENTRY) 209 288 210 dir_entry.name = mangle_fname(name).encode('ascii')211 dir_entry.ext = mangle_ext(name).encode('ascii')289 dir_entry.name = short_name 290 dir_entry.ext = short_ext 212 291 213 292 if (directory): … … 230 309 dir_entry.size = size 231 310 232 return dir_entry 311 if not lfn: 312 return [dir_entry] 313 314 long_name = name.encode('utf_16_le') 315 entries = [dir_entry] 316 317 seq = 1 318 checksum = lfn_checksum(dir_entry.name + dir_entry.ext) 319 320 while len(long_name) > 0: 321 long_entry, long_name = create_lfn_dirent(long_name, seq, checksum) 322 entries.append(long_entry) 323 seq += 1 324 325 entries.reverse() 326 return entries 233 327 234 328 def create_dot_dirent(empty_cluster): … … 274 368 275 369 directory = [] 276 277 if (not head): 370 name83_list = [] 371 372 if not head: 278 373 # Directory cluster preallocation 279 374 empty_cluster = fat.index(0) 280 fat[empty_cluster] = 0x ffff375 fat[empty_cluster] = 0xFFFF 281 376 282 377 directory.append(create_dot_dirent(empty_cluster)) … … 285 380 empty_cluster = 0 286 381 287 for item in listdir_items(root): 382 for item in listdir_items(root): 288 383 if item.is_file: 289 384 rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters) 290 directory. append(create_dirent(item.name, False, rv[0], rv[1]))385 directory.extend(create_dirent(item.name, name83_list, False, rv[0], rv[1])) 291 386 elif item.is_dir: 292 387 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):388 directory.extend(create_dirent(item.name, name83_list, True, rv[0], rv[1])) 389 390 if head: 296 391 outf.seek(root_start) 297 392 for dir_entry in directory: … … 448 543 449 544 outf.close() 450 545 451 546 if __name__ == '__main__': 452 547 main()
Note:
See TracChangeset
for help on using the changeset viewer.