Changes in / [3e72e41:d11a181] in mainline


Ignore:
Location:
tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • tools/imgutil.py

    r3e72e41 rd11a181  
    9292                if name in exclude_names:
    9393                        continue
    94                
    9594                item = ItemToPack(path, name)
    96                
    9795                if not (item.is_dir or item.is_file):
    9896                        continue
    99                
    10097                yield item
    10198
     
    105102        inf = open(item.path, 'rb')
    106103        rd = 0
    107        
    108104        while (rd < item.size):
    109105                data = bytes(inf.read(chunk_size))
    110106                yield data
    111107                rd += len(data)
    112        
    113108        inf.close()
  • tools/mkfat.py

    r3e72e41 rd11a181  
    168168"""
    169169
    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        
    193         for char in name.encode('ascii', 'ignore').upper():
    194                 if not char in lchars:
    195                         continue
    196                
    197                 filtered_name += char
    198        
    199         return filtered_name
    200 
    201 def fat_name83(name, name83_list):
    202         "Create a 8.3 name for the given name"
    203        
    204         ascii_name = fat_lchars(name)
    205         ascii_parts = ascii_name.split('.')
    206        
    207         short_name = ''
    208         short_ext = ''
     170LFN_ENTRY = """little:
     171        uint8_t pos
     172        uint16_t name1[5]
     173        uint8_t attr
     174        uint8_t type
     175        uint8_t csum
     176        uint16_t name2[6]
     177        uint16_t fc
     178        uint16_t name3[2]
     179"""
     180
     181# Global variable to hold the file names in 8.3 format. Needed to
     182# keep track of "number" when creating a short fname from a LFN.
     183name83_list = []
     184
     185def name83(fname):
     186        "Create a 8.3 name for the given fname"
     187
     188        # FIXME: filter illegal characters
     189        parts = fname.split('.')
     190       
     191        name = ''
     192        ext = ''
    209193        lfn = False
    210        
    211         if len(ascii_name) > 11:
     194
     195        if len(fname) > 11 :
    212196                lfn = True
    213        
    214         if len(ascii_parts) > 0:
    215                 short_name = ascii_parts[0]
    216                 if len(short_name) > 8:
     197
     198        if len(parts) > 0:
     199                name = parts[0]
     200                if len(name) > 8 :
    217201                        lfn = True
    218        
    219         if len(ascii_parts) > 1:
    220                 short_ext = ascii_parts[-1]
    221                 if len(short_ext) > 3:
     202
     203        if len(parts) > 1 :
     204                ext = parts[-1]
     205                if len(ext) > 3 :
    222206                        lfn = True
    223        
    224         if len(ascii_parts) > 2:
     207
     208        if len(parts) > 2 :
    225209                lfn = True
    226        
    227         if lfn == False:
    228                 name83_list.append(short_name + '.' + short_ext)
    229                 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], False)
    230        
     210
     211        if (lfn == False) :
     212                return (name.ljust(8)[0:8], ext.ljust(3)[0:3], False)
     213
    231214        # For filenames with multiple extensions, we treat the last one
    232215        # as the actual extension. The rest of the filename is stripped
    233216        # of dots and concatenated to form the short name
    234         for part in ascii_parts[1:-1]:
    235                 short_name += part
    236        
    237         for number in range(1, 999999):
    238                 number_str = ('~' + str(number)).upper()
    239                
    240                 if len(short_name) + len(number_str) > 8:
    241                         short_name = short_name[0:8 - len(number_str)]
    242                
    243                 short_name += number_str;
    244                
    245                 if not (short_name + '.' + short_ext) in name83_list:
     217        for _name in parts[1:-1]:
     218                name = name + _name             
     219
     220        global name83_list
     221        for number in range(1, 10000) :
     222                number_str = '~' + str(number)
     223
     224                if len(name) + len(number_str) > 8 :
     225                        name = name[0:8 - len(number_str)]
     226
     227                name = name + number_str;
     228
     229                if (name + ext) not in name83_list :
    246230                        break
    247        
    248         name83_list.append(short_name + '.' + short_ext)
    249         return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], True)
    250 
    251 def create_lfn_dirent(name, seq, checksum):
    252         "Create LFN directory entry"
    253        
    254         entry = xstruct.create(LFN_DIR_ENTRY)
    255         name_rest = name[26:]
    256        
    257         if len(name_rest) > 0:
    258                 entry.seq = seq
    259         else:
    260                 entry.seq = seq | 0x40
    261        
    262         entry.name1 = name[0:10]
    263         entry.name2 = name[10:22]
    264         entry.name3 = name[22:26]
    265        
    266         entry.attr = 0x0F
    267         entry.rec_type = 0
    268         entry.checksum = checksum
    269         entry.cluster = 0
    270        
    271         return (entry, name_rest)
    272 
    273 def lfn_checksum(name):
    274         "Calculate LFN checksum"
    275        
    276         checksum = 0
    277         for i in range(0, 11):
    278                 checksum = (((checksum & 1) << 7) + (checksum >> 1) + ord(name[i])) & 0xFF
    279        
    280         return checksum
    281 
    282 def create_dirent(name, name83_list, directory, cluster, size):
    283         short_name, short_ext, lfn = fat_name83(name, name83_list)
     231                       
     232        name83_list.append(name + ext) 
     233
     234        return (name.ljust(8)[0:8], ext.ljust(3)[0:3], True)
     235
     236def get_utf16(name, l) :
     237        "Create a int array out of a string which we can store in uint16_t arrays"
     238
     239        bs = [0xFFFF for i in range(l)]
     240
     241        for i in range(len(name)) :
     242                bs[i] = ord(name[i])
     243       
     244        if (len(name) < l) :
     245                bs[len(name)] = 0;
     246       
     247        return bs
     248
     249def create_lfn_entry((name, index)) :
     250        entry = xstruct.create(LFN_ENTRY)
     251
     252        entry.name1 = get_utf16(name[0:5], 5)
     253        entry.name2 = get_utf16(name[5:11], 6)
     254        entry.name3 = get_utf16(name[11:13], 2)
     255        entry.pos = index
     256
     257        entry.attr = 0xF
     258        entry.fc = 0
     259        entry.type = 0
     260
     261        return entry
     262
     263def create_dirent(name, directory, cluster, size):
    284264       
    285265        dir_entry = xstruct.create(DIR_ENTRY)
    286266       
    287         dir_entry.name = short_name
    288         dir_entry.ext = short_ext
    289        
     267        dir_entry.name, dir_entry.ext, lfn = name83(name)
     268
     269        dir_entry.name = dir_entry.name.upper().encode('ascii')
     270        dir_entry.ext = dir_entry.ext.upper().encode('ascii')
     271
    290272        if (directory):
    291273                dir_entry.attr = 0x30
     
    307289                dir_entry.size = size
    308290       
     291
    309292        if not lfn:
    310293                return [dir_entry]
    311        
    312         long_name = name.encode('utf_16_le')
    313         entries = [dir_entry]
    314        
    315         seq = 1
    316         checksum = lfn_checksum(dir_entry.name + dir_entry.ext)
    317        
    318         while len(long_name) > 0:
    319                 long_entry, long_name = create_lfn_dirent(long_name, seq, checksum)
    320                 entries.append(long_entry)
    321                 seq += 1
    322        
    323         entries.reverse()
     294
     295        n = len(name) / 13 + 1
     296        names = [(name[i * 13: (i + 1) * 13 + 1], i + 1) for i in range(n)]
     297
     298        entries = sorted(map (create_lfn_entry, names), reverse = True, key = lambda e : e.pos)
     299        entries[0].pos |= 0x40
     300
     301        fname11 = dir_entry.name + dir_entry.ext
     302
     303        csum = 0
     304        for i in range(0, 11) :
     305                csum = ((csum & 1) << 7) + (csum  >> 1) + ord(fname11[i])
     306                csum = csum & 0xFF
     307       
     308        for e in entries :
     309                e.csum = csum;
     310       
     311        entries.append(dir_entry)
     312
    324313        return entries
    325314
     
    366355       
    367356        directory = []
    368         name83_list = []
    369        
    370         if not head:
     357       
     358        if (not head):
    371359                # Directory cluster preallocation
    372360                empty_cluster = fat.index(0)
    373                 fat[empty_cluster] = 0xFFFF
     361                fat[empty_cluster] = 0xffff
    374362               
    375363                directory.append(create_dot_dirent(empty_cluster))
     
    378366                empty_cluster = 0
    379367       
    380         for item in listdir_items(root):
     368        for item in listdir_items(root):               
    381369                if item.is_file:
    382370                        rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters)
    383                         directory.extend(create_dirent(item.name, name83_list, False, rv[0], rv[1]))
     371                        directory.extend(create_dirent(item.name, False, rv[0], rv[1]))
    384372                elif item.is_dir:
    385373                        rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster)
    386                         directory.extend(create_dirent(item.name, name83_list, True, rv[0], rv[1]))
    387        
    388         if head:
     374                        directory.extend(create_dirent(item.name, True, rv[0], rv[1]))
     375       
     376        if (head):
    389377                outf.seek(root_start)
    390378                for dir_entry in directory:
     
    443431        extra_bytes = int(sys.argv[1])
    444432       
    445         path = os.path.abspath(sys.argv[2].decode())
     433        path = os.path.abspath(sys.argv[2])
    446434        if (not os.path.isdir(path)):
    447435                print("<PATH> must be a directory")
     
    541529       
    542530        outf.close()
    543 
     531       
    544532if __name__ == '__main__':
    545533        main()
Note: See TracChangeset for help on using the changeset viewer.