summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/fat.c88
1 files changed, 73 insertions, 15 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 02d472ceeb..55e6fa30cf 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -811,7 +811,8 @@ static int write_long_name(struct fat_file* file,
811 unsigned int firstentry, 811 unsigned int firstentry,
812 unsigned int numentries, 812 unsigned int numentries,
813 unsigned char* name, 813 unsigned char* name,
814 unsigned char* shortname) 814 unsigned char* shortname,
815 bool is_directory)
815{ 816{
816 unsigned char buf[SECTOR_SIZE]; 817 unsigned char buf[SECTOR_SIZE];
817 unsigned char* entry; 818 unsigned char* entry;
@@ -918,7 +919,7 @@ static int write_long_name(struct fat_file* file,
918 unsigned short date=0, time=0, tenth=0; 919 unsigned short date=0, time=0, tenth=0;
919 LDEBUGF("Shortname entry: %.13s\n", shortname); 920 LDEBUGF("Shortname entry: %.13s\n", shortname);
920 strncpy(entry + FATDIR_NAME, shortname, 11); 921 strncpy(entry + FATDIR_NAME, shortname, 11);
921 entry[FATDIR_ATTR] = 0; 922 entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0;
922 entry[FATDIR_NTRES] = 0; 923 entry[FATDIR_NTRES] = 0;
923 924
924 fat_time(&date, &time, &tenth); 925 fat_time(&date, &time, &tenth);
@@ -947,7 +948,9 @@ static int write_long_name(struct fat_file* file,
947 948
948static int add_dir_entry(struct fat_dir* dir, 949static int add_dir_entry(struct fat_dir* dir,
949 struct fat_file* file, 950 struct fat_file* file,
950 char* name) 951 char* name,
952 bool is_directory,
953 bool dotdir)
951{ 954{
952 unsigned char buf[SECTOR_SIZE]; 955 unsigned char buf[SECTOR_SIZE];
953 unsigned char shortname[16]; 956 unsigned char shortname[16];
@@ -963,16 +966,26 @@ static int add_dir_entry(struct fat_dir* dir,
963 LDEBUGF( "add_dir_entry(%s,%x)\n", 966 LDEBUGF( "add_dir_entry(%s,%x)\n",
964 name, file->firstcluster); 967 name, file->firstcluster);
965 968
966 /* create dos name */ 969 /* The "." and ".." directory entries must not be long names */
967 rc = create_dos_name(name, shortname); 970 if(dotdir) {
968 if (rc < 0) 971 int i;
969 return rc * 10 - 0; 972 strncpy(shortname, name, 16);
973 for(i = strlen(shortname);i < 12;i++)
974 shortname[i] = ' ';
975
976 entries_needed = 1;
977 } else {
978 /* create dos name */
979 rc = create_dos_name(name, shortname);
980 if (rc < 0)
981 return rc * 10 - 0;
970 982
971 /* one dir entry needed for every 13 bytes of filename, 983 /* one dir entry needed for every 13 bytes of filename,
972 plus one entry for the short name */ 984 plus one entry for the short name */
973 entries_needed = namelen / NAME_BYTES_PER_ENTRY + 1; 985 entries_needed = namelen / NAME_BYTES_PER_ENTRY + 1;
974 if (namelen % NAME_BYTES_PER_ENTRY) 986 if (namelen % NAME_BYTES_PER_ENTRY)
975 entries_needed++; 987 entries_needed++;
988 }
976 989
977 restart: 990 restart:
978 firstentry = 0; 991 firstentry = 0;
@@ -1065,7 +1078,7 @@ static int add_dir_entry(struct fat_dir* dir,
1065 firstentry, sector); 1078 firstentry, sector);
1066 1079
1067 rc = write_long_name(&dir->file, firstentry, 1080 rc = write_long_name(&dir->file, firstentry,
1068 entries_needed, name, shortname); 1081 entries_needed, name, shortname, is_directory);
1069 if (rc < 0) 1082 if (rc < 0)
1070 return rc * 10 - 5; 1083 return rc * 10 - 5;
1071 1084
@@ -1304,7 +1317,7 @@ int fat_create_file(char* name,
1304 int rc; 1317 int rc;
1305 1318
1306 LDEBUGF("fat_create_file(\"%s\",%x,%x)\n",name,file,dir); 1319 LDEBUGF("fat_create_file(\"%s\",%x,%x)\n",name,file,dir);
1307 rc = add_dir_entry(dir, file, name); 1320 rc = add_dir_entry(dir, file, name, false, false);
1308 if (!rc) { 1321 if (!rc) {
1309 file->firstcluster = 0; 1322 file->firstcluster = 0;
1310 file->lastcluster = 0; 1323 file->lastcluster = 0;
@@ -1317,6 +1330,51 @@ int fat_create_file(char* name,
1317 return rc; 1330 return rc;
1318} 1331}
1319 1332
1333int fat_create_dir(char* name,
1334 struct fat_dir* newdir,
1335 struct fat_dir* dir)
1336{
1337 int rc;
1338 struct fat_file dummyfile;
1339
1340 LDEBUGF("fat_create_dir(\"%s\",%x,%x)\n",name,newdir,dir);
1341
1342 memset(newdir, sizeof(struct fat_dir), 0);
1343
1344 /* First, add the entry in the parent directory */
1345 rc = add_dir_entry(dir, &newdir->file, name, true, false);
1346 if (rc < 0)
1347 return rc * 10 - 1;
1348
1349 /* Then add the "." entry */
1350 rc = add_dir_entry(newdir, &dummyfile, ".", true, true);
1351 if (rc < 0)
1352 return rc * 10 - 2;
1353 dummyfile.firstcluster = newdir->file.firstcluster;
1354 update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY);
1355
1356 /* and the ".." entry */
1357 rc = add_dir_entry(newdir, &dummyfile, "..", true, true);
1358 if (rc < 0)
1359 return rc * 10 - 3;
1360
1361 /* The root cluster is cluster 0 in the ".." entry */
1362 if(dir->file.firstcluster == fat_bpb.bpb_rootclus)
1363 dummyfile.firstcluster = 0;
1364 else
1365 dummyfile.firstcluster = dir->file.firstcluster;
1366 update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY);
1367
1368 /* Set the firstcluster field in the direntry */
1369 update_short_entry(&newdir->file, 0, FAT_ATTR_DIRECTORY);
1370
1371 rc = flush_fat();
1372 if (rc < 0)
1373 return rc * 10 - 4;
1374
1375 return rc;
1376}
1377
1320int fat_truncate(struct fat_file *file) 1378int fat_truncate(struct fat_file *file)
1321{ 1379{
1322 /* truncate trailing clusters */ 1380 /* truncate trailing clusters */
@@ -1487,7 +1545,7 @@ int fat_rename(struct fat_file* file,
1487 return rc * 10 - 2; 1545 return rc * 10 - 2;
1488 1546
1489 /* create new name */ 1547 /* create new name */
1490 rc = add_dir_entry(&dir, &newfile, newname); 1548 rc = add_dir_entry(&dir, &newfile, newname, false, false);
1491 if (rc < 0) 1549 if (rc < 0)
1492 return rc * 10 - 3; 1550 return rc * 10 - 3;
1493 1551