Index: ChangeLog
===================================================================
--- ChangeLog	(.../sd-reader_release_20070120)	(Revision 106)
+++ ChangeLog	(.../sd-reader_release_20070301)	(Revision 106)
@@ -1,4 +1,11 @@
 
+2007-03-01 sd-reader
+	* Avoid LFN directory entries for the "." and ".." directory references.
+	  This prevented Windows from deleting directories.
+	* Handle special case where the 8.3 filename begins with 0xe5.
+	* Fix return value of fat16_delete_file() when deleting empty files.
+	* Fix fat16_clear_cluster() which was zeroing only 16 of every 32 bytes.
+
 2007-01-20 sd-reader
 	* fix directory creation
 	  - correctly create "." and ".." directory entries (8.3 <-> lfn versions)
Index: fat16.c
===================================================================
--- fat16.c	(.../sd-reader_release_20070120)	(Revision 106)
+++ fat16.c	(.../sd-reader_release_20070301)	(Revision 106)
@@ -597,6 +597,9 @@
                     break;
                 long_name[i] = raw_entry[i];
             }
+            if(long_name[0] == 0x05)
+                long_name[0] = (char) FAT16_DIRENTRY_DELETED;
+
             if(raw_entry[8] != ' ')
             {
                 long_name[i++] = '.';
@@ -962,7 +965,7 @@
 {
 #if FAT16_WRITE_SUPPORT
     memset(buffer, 0, 16);
-    return 32;
+    return 16;
 #else
     return 0;
 #endif
@@ -1545,7 +1548,7 @@
         return 0;
 
     /* search for a place where to write the directory entry to disk */
-    uint8_t free_dir_entries_needed = strlen(dir_entry->long_name) / 13 + 1 + 1;
+    uint8_t free_dir_entries_needed = (strlen(dir_entry->long_name) + 12) / 13 + 1;
     uint8_t free_dir_entries_found = 0;
     uint16_t cluster_num = parent->dir_entry.cluster;
     uint32_t dir_entry_offset = 0;
@@ -1659,7 +1662,8 @@
     
     device_write_t device_write = fs->partition->device_write;
     uint32_t offset = dir_entry->entry_offset;
-    uint8_t name_len = strlen(dir_entry->long_name);
+    const char* name = dir_entry->long_name;
+    uint8_t name_len = strlen(name);
     uint8_t lfn_entry_count = (name_len + 12) / 13;
     uint8_t buffer[32];
 
@@ -1667,7 +1671,7 @@
 
     /* generate 8.3 file name */
     memset(&buffer[0], ' ', 11);
-    char* name_ext = strrchr(dir_entry->long_name, '.');
+    char* name_ext = strrchr(name, '.');
     if(name_ext && *++name_ext)
     {
         uint8_t name_ext_len = strlen(name_ext);
@@ -1681,11 +1685,26 @@
     
     if(name_len <= 8)
     {
-        memcpy(buffer, dir_entry->long_name, name_len);
+        memcpy(buffer, name, name_len);
+
+        /* For now, we create lfn entries for all files,
+         * except the "." and ".." directory references.
+         * This is to avoid difficulties with capitalization,
+         * as 8.3 filenames allow uppercase letters only.
+         *
+         * Theoretically it would be possible to leave
+         * the 8.3 entry alone if the basename and the
+         * extension have no mixed capitalization.
+         */
+        if(name[0] == '.' &&
+           ((name[1] == '.' && name[2] == '\0') ||
+            name[1] == '\0')
+          )
+            lfn_entry_count = 0;
     }
     else
     {
-        memcpy(buffer, dir_entry->long_name, 8);
+        memcpy(buffer, name, 8);
 
         /* Minimize 8.3 name clashes by appending
          * the lower byte of the cluster number.
@@ -1696,6 +1715,8 @@
         num &= 0x0f;
         buffer[7] = (num < 0x0a) ? ('0' + num) : ('a' + num);
     }
+    if(buffer[0] == FAT16_DIRENTRY_DELETED)
+        buffer[0] = 0x05;
 
     /* fill directory entry buffer */
     memset(&buffer[11], 0, sizeof(buffer) - 11);
@@ -1719,17 +1740,10 @@
     /* write lfn entries */
     for(uint8_t lfn_entry = lfn_entry_count; lfn_entry > 0; --lfn_entry)
     {
-        memset(buffer, 0, sizeof(buffer));
-        memset(&buffer[0x01], 0xff, 10);
-        memset(&buffer[0x0e], 0xff, 12);
-        memset(&buffer[0x1c], 0xff, 4);
+        memset(buffer, 0xff, sizeof(buffer));
         
-        buffer[0x00] = lfn_entry;
-        if(lfn_entry == lfn_entry_count)
-            buffer[0x00] |= FAT16_DIRENTRY_LFNLAST;
-
         /* set file name */
-        const char* long_name_curr = dir_entry->long_name + (lfn_entry - 1) * 13;
+        const char* long_name_curr = name + (lfn_entry - 1) * 13;
         uint8_t i = 1;
         while(i < 0x1f)
         {
@@ -1750,12 +1764,22 @@
                 break;
         }
         
+        /* set index of lfn entry */
+        buffer[0x00] = lfn_entry;
+        if(lfn_entry == lfn_entry_count)
+            buffer[0x00] |= FAT16_DIRENTRY_LFNLAST;
+
         /* mark as lfn entry */
         buffer[0x0b] = 0x0f;
 
-        /* set checksum */
+        /* set 8.3 checksum */
         buffer[0x0d] = checksum;
 
+        /* clear reserved bytes */
+        buffer[0x0c] = 0;
+        buffer[0x1a] = 0;
+        buffer[0x1b] = 0;
+
         /* write entry */
         device_write(offset, buffer, sizeof(buffer));
     
@@ -1883,7 +1907,7 @@
     /* We deleted the directory entry. The next thing to do is
      * marking all occupied clusters as free.
      */
-    return fat16_free_clusters(fs, dir_entry->cluster);
+    return (dir_entry->cluster == 0 || fat16_free_clusters(fs, dir_entry->cluster));
 #else
     return 0;
 #endif
@@ -1951,7 +1975,7 @@
     }
 
     /* create ".." parent directory reference */
-    dir_entry->entry_offset += 2 * 32;
+    dir_entry->entry_offset += 32;
     dir_entry->long_name[1] = '.';
     dir_entry->cluster = parent->dir_entry.cluster;
     if(!fat16_write_dir_entry(fs, dir_entry))
