Ignore:
Timestamp:
2011-08-15T21:45:28Z (13 years ago)
Author:
Oleg Romanenko <romanenko.oleg@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
93e12f3
Parents:
b4af128
Message:

exFAT: implement exfat_directory_write_file !
Now exFAT ready for reading and writing and passed all basic tests

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/exfat/exfat_directory.c

    rb4af128 rbca3eac  
    3636 */
    3737
     38#include "exfat.h"
    3839#include "exfat_directory.h"
    3940#include "exfat_fat.h"
     
    4445#include <malloc.h>
    4546#include <str.h>
    46 
     47#include <align.h>
    4748
    4849void exfat_directory_init(exfat_directory_t *di)
     
    7071
    7172        di->bs = block_bb_get(di->devmap_handle);
    72         di->blocks = nodep->size / BPS(di->bs);
     73/*      di->blocks = nodep->size / BPS(di->bs); */
     74        di->blocks = ROUND_UP(nodep->size, BPS(di->bs))/BPS(di->bs);
    7375        return EOK;
    7476}
     
    300302        array[1].stream.valid_data_size = ds->valid_data_size;
    301303        array[1].stream.data_size = ds->data_size;
    302         array[0].file.checksum = exfat_directory_set_checksum((uint8_t *)array,
    303             count*sizeof(exfat_dentry_t));
     304        array[0].file.checksum = host2uint16_t_le(exfat_directory_set_checksum((uint8_t *)array,
     305            count*sizeof(exfat_dentry_t)));
    304306
    305307        /* Store */
     
    320322}
    321323
     324int exfat_directory_print(exfat_directory_t *di)
     325{
     326        int rc;
     327        exfat_dentry_t *de;
     328        exfat_directory_seek(di, 0);
     329        do
     330        {
     331                rc = exfat_directory_get(di, &de);
     332                if (rc != EOK)
     333                        return rc;
     334                switch (de->type) {
     335                case EXFAT_TYPE_VOLLABEL:
     336                        printf("EXFAT_DENTRY_VOLLABEL\n"); break;
     337                case EXFAT_TYPE_BITMAP:
     338                        printf("EXFAT_DENTRY_BITMAP\n"); break;
     339                case EXFAT_TYPE_UCTABLE:
     340                        printf("EXFAT_DENTRY_UCTABLE\n"); break;
     341                case EXFAT_TYPE_GUID:
     342                        printf("EXFAT_DENTRY_GUID\n"); break;
     343                case EXFAT_TYPE_FILE:
     344                        printf("EXFAT_DENTRY_FILE\n"); break;
     345                case EXFAT_TYPE_STREAM:
     346                        printf("EXFAT_DENTRY_STREAM\n"); break;
     347                case EXFAT_TYPE_NAME:
     348                        printf("EXFAT_DENTRY_NAME\n"); break;
     349                case EXFAT_TYPE_UNUSED:
     350                        printf("EXFAT_DENTRY_LAST\n");
     351                        return EOK;
     352                default:
     353                        if (de->type & EXFAT_TYPE_USED)
     354                                printf("EXFAT_DENTRY_SKIP\n");
     355                        else
     356                                printf("EXFAT_DENTRY_FREE\n");
     357                }
     358        } while (exfat_directory_next(di) == EOK);
     359        exfat_directory_seek(di, 0);
     360        return EOK;
     361}
     362
    322363int exfat_directory_write_file(exfat_directory_t *di, const char *name)
    323364{
    324         /* TODO */
    325         return EOK;
     365        fs_node_t *fn;
     366        exfat_node_t *uctablep;
     367        uint16_t *uctable;
     368        exfat_dentry_t df, ds, *de;
     369        uint16_t wname[EXFAT_FILENAME_LEN+1];
     370        int rc, i;
     371        size_t uctable_chars;
     372        aoff64_t pos;
     373
     374        rc = str_to_utf16(wname, EXFAT_FILENAME_LEN, name);
     375        if (rc != EOK)
     376                return rc;
     377        rc = exfat_uctable_get(&fn, di->devmap_handle);
     378        if (rc != EOK)
     379                return rc;
     380        uctablep = EXFAT_NODE(fn);
     381
     382        uctable_chars = ALIGN_DOWN(uctablep->size, sizeof(uint16_t)) / sizeof(uint16_t);
     383        uctable = (uint16_t *) malloc(uctable_chars * sizeof(uint16_t));
     384        rc = exfat_read_uctable(di->bs, uctablep, (uint8_t *)uctable);
     385        if (rc != EOK) {
     386                (void) exfat_node_put(fn);
     387                free(uctable);
     388                return rc;
     389        }
     390
     391        /* Fill stream entry */
     392        ds.type = EXFAT_TYPE_STREAM;
     393        ds.stream.flags = 0;
     394        ds.stream.valid_data_size = 0;
     395        ds.stream.data_size = 0;
     396        ds.stream.name_size = utf16_length(wname);
     397        ds.stream.hash = host2uint16_t_le(exfat_name_hash(wname, uctable,
     398            uctable_chars));
     399
     400        /* Fill file entry */
     401        df.type = EXFAT_TYPE_FILE;
     402        df.file.attr = 0;
     403        df.file.count = ROUND_UP(ds.stream.name_size, EXFAT_NAME_PART_LEN) /
     404            EXFAT_NAME_PART_LEN + 1;
     405        df.file.checksum = 0;
     406
     407        free(uctable);
     408        rc = exfat_node_put(fn);
     409        if (rc != EOK)
     410                return rc;
     411
     412        /* Looking for set of free entries */
     413        rc = exfat_directory_lookup_free(di, df.file.count+1);
     414        if (rc != EOK)
     415                return rc;
     416        pos = di->pos;
     417
     418        /* Write file entry */
     419        rc = exfat_directory_get(di, &de);
     420        if (rc != EOK)
     421                return rc;
     422        memcpy(de, &df, sizeof(exfat_dentry_t));
     423        di->b->dirty = true;
     424        rc = exfat_directory_next(di);
     425        if (rc != EOK)
     426                return rc;
     427
     428        /* Write stream entry */
     429        rc = exfat_directory_get(di, &de);
     430        if (rc != EOK)
     431                return rc;
     432        memcpy(de, &ds, sizeof(exfat_dentry_t));
     433        di->b->dirty = true;
     434
     435        /* Write file name */
     436        size_t chars = EXFAT_NAME_PART_LEN;
     437        uint16_t *sname = wname;
     438
     439        for (i=0; i<ds.stream.name_size; i++)
     440                wname[i] = host2uint16_t_le(wname[i]);
     441
     442        for (i=0; i < df.file.count-1; i++) {
     443                rc = exfat_directory_next(di);
     444                if (rc != EOK)
     445                        return rc;
     446
     447                if (i == df.file.count-2)
     448                        chars = ds.stream.name_size - EXFAT_NAME_PART_LEN*(df.file.count-2);
     449                rc = exfat_directory_get(di, &de);
     450                if (rc != EOK)
     451                        return rc;
     452                de->type = EXFAT_TYPE_NAME;
     453                memcpy((uint8_t*)de->name.name, (uint8_t*)sname, sizeof(uint16_t)*chars);
     454                di->b->dirty = true;
     455                sname += chars;
     456        }
     457       
     458        return exfat_directory_seek(di, pos);
    326459}
    327460
Note: See TracChangeset for help on using the changeset viewer.