Index: ChangeLog
===================================================================
--- ChangeLog	(.../sd-reader_release_20100110)	(Revision 162)
+++ ChangeLog	(.../sd-reader_release_20101010)	(Revision 162)
@@ -1,4 +1,9 @@
 
+2010-10-10 sd-reader
+	* Fix equal file names when reading two successive 8.3 directory entries.
+	* Fix calculation of cluster positions beyond 4GB (32 bit integer overflow).
+	* Fix endless looping of directory listing (occured with valid entry at end of last cluster).
+
 2010-01-10 sd-reader
 	* Make LFN support configurable.
 	* Ignore LFN directory entries without 8.3 name.
Index: fat.c
===================================================================
--- fat.c	(.../sd-reader_release_20100110)	(Revision 162)
+++ fat.c	(.../sd-reader_release_20101010)	(Revision 162)
@@ -1446,8 +1446,20 @@
     uint16_t cluster_offset = dd->entry_offset;
     struct fat_read_dir_callback_arg arg;
 
+    if(cluster_offset >= cluster_size)
+    {
+        /* The latest call hit the border of the last cluster in
+         * the chain, but it still returned a directory entry.
+         * So we now reset the handle and signal the caller the
+         * end of the listing.
+         */
+        fat_reset_dir(dd);
+        return 0;
+    }
+
     /* reset callback arguments */
     memset(&arg, 0, sizeof(arg));
+    memset(dir_entry, 0, sizeof(*dir_entry));
     arg.dir_entry = dir_entry;
 
     /* check if we read from the root directory */
@@ -1467,7 +1479,7 @@
     {
         /* read directory entries up to the cluster border */
         uint16_t cluster_left = cluster_size - cluster_offset;
-        uint32_t pos = cluster_offset;
+        offset_t pos = cluster_offset;
         if(cluster_num == 0)
             pos += header->root_dir_offset;
         else
@@ -1488,15 +1500,32 @@
         if(cluster_offset >= cluster_size)
         {
             /* we reached the cluster border and switch to the next cluster */
-            cluster_offset = 0;
 
             /* get number of next cluster */
-            if(!(cluster_num = fat_get_next_cluster(fs, cluster_num)))
+            if((cluster_num = fat_get_next_cluster(fs, cluster_num)) != 0)
             {
+                cluster_offset = 0;
+                continue;
+            }
+
+            /* we are at the end of the cluster chain */
+            if(!arg.finished)
+            {
                 /* directory entry not found, reset directory handle */
-                cluster_num = dd->dir_entry.cluster;
-                break;
+                fat_reset_dir(dd);
+                return 0;
             }
+            else
+            {
+                /* The current execution of the function has been successful,
+                 * so we can not signal an end of the directory listing to
+                 * the caller, but must wait for the next call. So we keep an
+                 * invalid cluster offset to mark this directory handle's
+                 * traversal as finished.
+                 */
+            }
+
+            break;
         }
     }
 
