folder auth implemented master
authorNIIBE Yutaka <gniibe@fsij.org>
Tue, 6 Dec 2011 08:36:48 +0000 (17:36 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Tue, 6 Dec 2011 08:36:48 +0000 (17:36 +0900)
src/main.c
src/virtual_block_device.c

index 8a33917..c28430b 100644 (file)
@@ -1054,6 +1054,7 @@ main (int argc, char **argv)
                set_led (0);
                msc_media_insert_change (0);
                pushed--;
+               emit_key_strokes (datetime_string);
              }
        }
 #if 0
index b2a7772..400937b 100644 (file)
@@ -109,7 +109,7 @@ static const uint8_t d0_0_sector[512] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
 };
 
-static uint8_t d0_fat0_sector[512] = {
+static const uint8_t d0_fat0_sector[512] = {
   0xf8, 0xff, 0xff,    /* Media descriptor: fixed disk */ /* EOC */
   0xff, 0xff, 0xff,    /* cluster 2: used */ /* cluster 3: used */
   0xff, 0xff, 0xff,    /* cluster 4: used */ /* cluster 5: used */
@@ -118,490 +118,143 @@ static uint8_t d0_fat0_sector[512] = {
   0x00,
 };
 
-static uint8_t d0_fat1_sector[512] = {
-  0xf8, 0xff, 0xff,    /* Media descriptor: fixed disk */ /* EOC */
-  0xff, 0xff, 0xff,    /* cluster 2: used */ /* cluster 3: used */
-  0xff, 0xff, 0xff,    /* cluster 4: used */ /* cluster 5: used */
-  0xff, 0xff, 0xff,    /* cluster 6: used */ /* cluster 7: used */
-  0xff, 0x0f, 0x00,    /* cluster 8: used */ /* cluster 9: free */
-  0x00,
-};
-
-static uint8_t d0_rootdir_sector[512] = {
-  /* directory "A" */
-  0x41, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* filename */
-  0x20, 0x20, 0x20, /* extension */
-  0x10, /* sub directory */
-  0x00, /* reserved */
-  0x64, 0x3b, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x3b, 0xa7, 0x61, 0x3f, /* last modified */
-  0x02, 0x00, /* start cluster */
-  0x00, 0x00, 0x00, 0x00, /* file size */
-  /* directory "B" */
-  0x42, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* filename */
-  0x20, 0x20, 0x20, /* extension */
-  0x10, /* sub directory */
-  0x00, /* reserved */
-  0x64, 0x3b, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x3b, 0xa7, 0x61, 0x3f, /* last modified */
-  0x03, 0x00, /* start cluster */
-  0x00, 0x00, 0x00, 0x00, /* file size */
-  /* directory "C" */
-  0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* filename */
-  0x20, 0x20, 0x20, /* extension */
-  0x10, /* sub directory */
-  0x00, /* reserved */
-  0x64, 0x3b, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x3b, 0xa7, 0x61, 0x3f, /* last modified */
-  0x04, 0x00, /* start cluster */
-  0x00, 0x00, 0x00, 0x00, /* file size */
-  /* directory "D" */
-  0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* filename */
-  0x20, 0x20, 0x20, /* extension */
-  0x10, /* sub directory */
-  0x00, /* reserved */
-  0x64, 0x3b, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x3b, 0xa7, 0x61, 0x3f, /* last modified */
-  0x05, 0x00, /* start cluster */
-  0x00, 0x00, 0x00, 0x00, /* file size */
-  /* directory "E" */
-  0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* filename */
-  0x20, 0x20, 0x20, /* extension */
-  0x10, /* sub directory */
-  0x00, /* reserved */
-  0x64, 0x3b, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x3b, 0xa7, 0x61, 0x3f, /* last modified */
-  0x06, 0x00, /* start cluster */
-  0x00, 0x00, 0x00, 0x00, /* file size */
-  /* directory "F" */
-  0x46, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* filename */
-  0x20, 0x20, 0x20, /* extension */
-  0x10, /* sub directory */
-  0x00, /* reserved */
-  0x64, 0x3b, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x3b, 0xa7, 0x61, 0x3f, /* last modified */
-  0x07, 0x00, /* start cluster */
-  0x00, 0x00, 0x00, 0x00, /* file size */
-  /* directory "G" */
-  0x47, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* filename */
-  0x20, 0x20, 0x20, /* extension */
-  0x10, /* sub directory */
-  0x00, /* reserved */
-  0x64, 0x3b, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x3b, 0xa7, 0x61, 0x3f, /* last modified */
-  0x08, 0x00, /* start cluster */
-  0x00, 0x00, 0x00, 0x00, /* file size */
-
-  0x00,
-};
-
-static uint8_t directory_a_sector[512] = {
-  /* . */
-  0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x02, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  /* .. */
-  0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  0x00,
-};
-
-static uint8_t directory_b_sector[512] = {
-  /* . */
-  0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x03, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  /* .. */
-  0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  0x00,
-};
-
-static uint8_t directory_c_sector[512] = {
-  /* . */
-  0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x04, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  /* .. */
-  0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  0x00,
-};
-
-static uint8_t directory_d_sector[512] = {
-  /* . */
-  0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x05, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  /* .. */
-  0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  0x00,
-};
-
-static uint8_t directory_e_sector[512] = {
-  /* . */
-  0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x06, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  /* .. */
-  0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  0x00,
-};
-
-static uint8_t directory_f_sector[512] = {
-  /* . */
-  0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x07, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  /* .. */
-  0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
+static const uint8_t zero_sector[] = {
   0x00,
-};
+}; 
 
-static uint8_t directory_g_sector[512] = {
-  /* . */
-  0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x08, 0x00,
-  0x00, 0x00, 0x00, 0x00,
-
-  /* .. */
-  0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20,
-  0x10,
-  0x00,
-  0x64, 0x3b, 0xa7, 0x61, 0x3f,
-  0x61, 0x3f,
-  0x00, 0x00,
-  0x3b, 0xa7, 0x61, 0x3f,
-  0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00,
+static uint8_t the_sector[512];
 
-  0x00,
+struct folder {
+  uint8_t parent;
+  uint8_t children[7];
 };
 
-static const uint8_t d1_0_sector[512] = {
-  0xeb, 0x3c,                         /* Jump instruction */
-  0x90, /* NOP */
+static struct folder folders[8] = { { 0, { 1, 2, 3, 4, 5, 6, 7 } }, };
+#define FOLDER_INDEX_TO_CLUSTER_NO(i) (i+1)
+#define CLUSTER_NO_TO_FOLDER_INDEX(n) (n-1)
+#define FOLDER_INDEX_TO_LBA(i) (i+3)
+#define LBA_TO_FOLDER_INDEX(lba) (lba-3)
+#define FOLDER_INDEX_TO_DIRCHAR(i) ('A'+i-1)
+#define DIRCHAR_TO_FOLDER_INDEX(c) (c - 'A' + 1)
 
-  0x6d, 0x6b, 0x64, 0x6f, 0x73, 0x66, 0x73, 0x20, /* "mkdosfs " */
+static uint8_t *fill_file_entry (uint8_t *p, const uint8_t *filename,
+                                uint16_t cluster_no)
+{
+  memcpy (p, filename, 8+3);
+  p += 11;
+  *p++ = 0x10;                 /* directory */
+  *p++ = 0x00;                 /* reserved */
+  memcpy (p, "\x64\x3b\xa7\x61\x3f", 5); /* create time */
+  p += 5;
+  memcpy (p, "\x61\x3f", 2);   /* last access */
+  p += 2;
+  *p++ = 0x00;  *p++ = 0x00;   /* ea-index */
+  memcpy (p, "\x3b\xa7\x61\x3f", 4); /* last modified */
+  p += 4;
+  memcpy (p, &cluster_no, 2);          /* cluster # */
+  p += 2;
+  *p++ = 0x00;  *p++ = 0x00;  *p++ = 0x00;  *p++ = 0x00; /* file size */
+  return p;
+}
 
-  0x00, 0x02,                  /* Bytes per sector: 512 */
+static const uint8_t *build_directory_sector (uint8_t *p, uint8_t index)
+{
+  uint16_t cluster_no = FOLDER_INDEX_TO_CLUSTER_NO (index);
+  int i;
+  uint8_t filename[11] = { 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+                          0x20, 0x20, 0x20 };
+  uint8_t child;
+  uint8_t *p_orig = p;
 
-  0x01,                                /* sectors per cluster: 1 */
-  0x01, 0x00,                  /* reserved sector count: 1 */
-  0x02,                        /* Number of FATs: 2 */
-  0x10, 0x00,                  /* Max. root directory entries: 16 (1 sector) */
-  0x44, 0x00,                  /* total sectors: 68 */
-  0xf8,                                /* media descriptor: fixed disk */
-  0x01, 0x00,                  /* sectors per FAT: 1 */
-  0x04, 0x00,                  /* sectors per track: 4 */
-  0x01, 0x00,                  /* number of heads: 1 */
-  0x00, 0x00, 0x00, 0x00,      /* hidden sectors: 0 */
-  0x00, 0x00, 0x00, 0x00,      /* total sectors (long) */
-  0x01,                        /* drive number */
-  0x00,                                /* reserved */
-  0x29,                        /* extended boot signature */
-  0xc0, 0x86, 0x75, 0xea, /* Volume ID (serial number) (Little endian) */
+  memset (p, 0, 512);
 
-  /* Volume label */
-  'G', 'O', 'N', 'E', '1', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  if (index != 0)
+    {
+      p = fill_file_entry (p, filename, cluster_no);
+      filename[1] = 0x2e;
+      p = fill_file_entry (p, filename, 0);
+      filename[1] = 0x20;
+    }
 
-  0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, /* FAT12 */
+  for (i = 0; i < 7; i++)
+    if ((child = folders[index].children[i]) != 0)
+      {
+       filename[0] = FOLDER_INDEX_TO_DIRCHAR (child);
+       p = fill_file_entry (p, filename, FOLDER_INDEX_TO_CLUSTER_NO (child));
+      }
+    else
+      break;
 
-  0x0e, 0x1f,
-  0xbe, 0x5b, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b,
-  0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10,
-  0x5e, 0xeb, 0xf0, 0x32, 0xe4, 0xcd, 0x16, 0xcd,
-  0x19,
-  0xeb, 0xfe,                  /* loop: jmp loop */
+  return p_orig;
+}
 
-  /* "Thisis not a bootable disk... \r\n" */
-  0x54, 0x68, 0x69, 0x73, 0x20,
-  0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61,
-  0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
-  0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2e, 0x20,
-  0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20,
-  0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61,
-  0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
-  0x65, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79,
-  0x20, 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x70, 0x72,
-  0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20,
-  0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74,
-  0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e,
-  0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x0d, 0x0a, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
-};
+const uint8_t *
+msc_scsi_read (uint8_t lun, uint32_t lba)
+{
+  switch (lba)
+    {
+    case 0:
+      return d0_0_sector;
+    case 1:
+    case 2:
+      return d0_fat0_sector;
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+      return build_directory_sector (the_sector, LBA_TO_FOLDER_INDEX (lba));
+    default:
+      return zero_sector;
+    }
+}
 
-static uint8_t d1_fat0_sector[512] = {
-  0xf8, 0xff, 0xff,    /* Media descriptor: fixed disk */ /* EOC */
-  0xff, 0x0f, 0x00,    /* cluster 2: EOC */ /* cluster 3: free */
-  0x00, 0x00, 0x00,    /* cluster 4: free */ /* cluster 5: free */
-  0x00,
-};
+uint8_t datetime_string[29];
+static uint8_t *dts = datetime_string;
 
-static uint8_t d1_fat1_sector[512] = {
-  0xf8, 0xff, 0xff,    /* Media descriptor: fixed disk */ /* EOC */
-  0xff, 0x0f, 0x00,    /* cluster 2: EOC */ /* cluster 3: free */
-  0x00, 0x00, 0x00,    /* cluster 4: free */ /* cluster 5: free */
-  0x00,
-};
+static void parse_directory_sector (const uint8_t *p, uint8_t index)
+{
+  uint16_t cluster_no = FOLDER_INDEX_TO_CLUSTER_NO (index);
+  int i;
+  uint8_t filename[11] = { 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+                          0x20, 0x20, 0x20 };
+  uint8_t child;
+  uint8_t *p_orig = p;
 
-static uint8_t d1_rootdir_sector[512] = {
-  /* file "DROPME.TXT" */
-  0x44, 0x52, 0x4f, 0x50, 0x4d, 0x45, 0x20, 0x20,
-  0x54, 0x58, 0x54,
-  0x01,                                /* Read-only */
-  0x00,                                /* reserved */
-  0x00, 0x41, 0xa7, 0x61, 0x3f, /* create time */
-  0x61, 0x3f, /* last access */
-  0x00, 0x00, /* ea-index */
-  0x41, 0xa7, 0x61, 0x3f, /* last modified */
-  0x02, 0x00, /* start cluster: 2 */
-  0x28, 0x00, 0x00, 0x00, /* file size */
+  if (index != 0)
+    {
+      uint16_t cluster_no;
+      uint8_t dest_index;
 
-  0x00,
-};
+      p += 32;         /* skip "." */
 
-/* fat cluster #2 */
-static const uint8_t d1_file_sector[512] = {
-  'P', 'l', 'e', 'a', 's', 'e', ' ', 'd',
-  'r', 'o', 'p', ' ', 't', 'h', 'i', 's',
-  ' ', 'f', 'i', 'l', 'e', ' ', 't', 'o',
-  ' ', 't', 'h', 'e', ' ', 'f', 'o', 'l',
-  'd', 'e', 'r', ' ', 'A', '.', 0x0d, 0x0a,
-  0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+      /* ".." */
+      cluster_no = p[26] | (p[27] << 8);
+      dest_index = CLUSTER_NO_TO_FOLDER_INDEX (cluster_no);
 
-static const uint8_t zero_sector[] = {
-  0x00,
-}; 
+      if (dest_index >= 1 && dest_index <= 7)
+       dts += sprintf (dts, "%c%c ", FOLDER_INDEX_TO_DIRCHAR (index),
+                       FOLDER_INDEX_TO_DIRCHAR (dest_index));
+      else
+       ; /* can be 255 : root_dir */
 
-static uint8_t new_sector[] = {
-  0x00, 
-}; 
+      p += 32;
+    }
 
-static uint8_t *get_sector (uint8_t lun, uint32_t lba)
-{
-  if (lun == 0)
-    switch (lba)
+  for (i = 0; i < 7; i++)
+    if (*p)
       {
-      case 0:
-       return (uint8_t *)d0_0_sector;
-      case 1:
-       return d0_fat0_sector;
-      case 2:
-       return d0_fat1_sector;
-      case 3:
-       return d0_rootdir_sector;
-      case 4:
-       return directory_a_sector;
-      case 5:
-       return directory_b_sector;
-      case 6:
-       return directory_c_sector;
-      case 7:
-       return directory_d_sector;
-      case 8:
-       return directory_e_sector;
-      case 9:
-       return directory_f_sector;
-      case 10:
-       return directory_g_sector;
-      default:
-       set_led (1);
-       return new_sector;
-      }
-  else
-    switch (lba)
-      {
-      case 0:
-       return (uint8_t *)d1_0_sector;
-      case 1:
-       return d1_fat0_sector;
-      case 2:
-       return d1_fat1_sector;
-      case 3:
-       return d1_rootdir_sector;
-      case 4:
-       return (uint8_t *)d1_file_sector;
-      default:
-       set_led (1);
-       return new_sector;
+       child = DIRCHAR_TO_FOLDER_INDEX (*p);
+       folders[index].children[i] = child;
+       p += 32;
       }
+    else
+      break;
 }
 
-const uint8_t *
-msc_scsi_read (uint8_t lun, uint32_t lba)
-{
-  return get_sector (lun, lba);
-}
 
 #include "ch.h"
 #include "hal.h"
@@ -611,18 +264,11 @@ msc_scsi_read (uint8_t lun, uint32_t lba)
 extern SerialUSBDriver SDU1;
 #endif
 
-uint8_t datetime_string[29];
-
 int
 msc_scsi_write (uint8_t lun, uint32_t lba, const uint8_t *buf, size_t size)
 {
   uint8_t s[50];
   int i;
-  uint8_t *sector = get_sector (lun, lba); 
-
-  (void)lba;
-  (void)buf;
-  (void)size;
 
 #if defined(SERIAL_DEBUG)
   sprintf (s, "LBA: %08x, SIZE: %04d\r\n", lba, size);
@@ -635,37 +281,13 @@ msc_scsi_write (uint8_t lun, uint32_t lba, const uint8_t *buf, size_t size)
     }
 #endif
 
-  if (sector != zero_sector)
-    memcpy (sector, buf, size);
-
-  if (lun == 0 && lba == 3) /* D0 Root dir */
+  if (lba <= 2)
+    return 1;                          /* error */
+  else
     {
-      uint16_t ymd, hms;
-      uint8_t year, month, day;
-      uint8_t hour, minute, sec;
-
-      set_led (1);
-
-#if 0
-      hms = (buf[0x17] << 8) | buf[0x16];
-      ymd = (buf[0x19] << 8) | buf[0x18];
-#else
-      /* creation time */
-      hms = (buf[0x0f] << 8) | buf[0x0e];
-      ymd = (buf[0x11] << 8) | buf[0x10];
-#endif
-
-      year = (ymd >> 9);
-      month = (ymd >> 5)&0x0f;
-      day = ymd & 0x1f;
-
-      hour = (hms >> 11);
-      minute = (hms >> 5)&0x3f;
-      sec = (hms & 0x1f)*2;
+      uint8_t index = LBA_TO_FOLDER_INDEX (lba);
 
-      sprintf (datetime_string, "%04d-%02d-%02d %02d:%02d:%02d",
-              1980+year, month, day,
-              hour, minute, sec);
+      parse_directory_sector (buf, index);
     }
 
   return 1;