Index: ChangeLog
===================================================================
--- ChangeLog	(.../sd-reader_release_20110205)	(Revision 180)
+++ ChangeLog	(.../sd-reader_release_20110423)	(Revision 180)
@@ -1,4 +1,10 @@
 
+2011-04-23 sd-reader
+	* fix FAT access for cluster numbers beyond 2^15 (for FAT16) and 2^30 (for FAT32) (thanks to Darwin Engwer for testing)
+	* correctly return disk-full condition from fat_write_file() on certain conditions
+	* use byteorder memory access functions for fat_fs_get_free()
+	* be more specific on the return value of fat_write_file()
+
 2011-02-05 sd-reader
 	* implement renaming a file or directory
 	* rewrite byteorder handling to fix unaligned memory accesses on 32-bit and probably 16-bit architectures
Index: fat.c
===================================================================
--- fat.c	(.../sd-reader_release_20110205)	(Revision 180)
+++ fat.c	(.../sd-reader_release_20110423)	(Revision 180)
@@ -445,7 +445,7 @@
     {
         /* read appropriate fat entry */
         uint32_t fat_entry;
-        if(!fs->partition->device_read(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
+        if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
             return 0;
 
         /* determine next cluster from fat */
@@ -462,7 +462,7 @@
     {
         /* read appropriate fat entry */
         uint16_t fat_entry;
-        if(!fs->partition->device_read(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
+        if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
             return 0;
 
         /* determine next cluster from fat */
@@ -522,13 +522,13 @@
 #if FAT_FAT32_SUPPORT
         if(is_fat32)
         {
-            if(!device_read(fat_offset + cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
+            if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
                 return 0;
         }
         else
 #endif
         {
-            if(!device_read(fat_offset + cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
+            if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
                 return 0;
         }
 
@@ -555,7 +555,7 @@
             else
                 fat_entry32 = htol32(cluster_next);
 
-            if(!device_write(fat_offset + cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
+            if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
                 break;
         }
         else
@@ -581,7 +581,7 @@
             else
                 fat_entry16 = htol16((uint16_t) cluster_next);
 
-            if(!device_write(fat_offset + cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
+            if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
                 break;
         }
 
@@ -604,7 +604,7 @@
             {
                 fat_entry32 = htol32(cluster_next);
 
-                if(!device_write(fat_offset + cluster_num * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
+                if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
                     break;
             }
             else
@@ -612,7 +612,7 @@
             {
                 fat_entry16 = htol16((uint16_t) cluster_next);
 
-                if(!device_write(fat_offset + cluster_num * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
+                if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
                     break;
             }
         }
@@ -660,7 +660,7 @@
         uint32_t fat_entry;
         while(cluster_num)
         {
-            if(!fs->partition->device_read(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
+            if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
                 return 0;
 
             /* get next cluster of current cluster before freeing current cluster */
@@ -685,7 +685,7 @@
 
             /* free cluster */
             fat_entry = HTOL32(FAT32_CLUSTER_FREE);
-            fs->partition->device_write(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
+            fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
 
             /* We continue in any case here, even if freeing the cluster failed.
              * The cluster is lost, but maybe we can still free up some later ones.
@@ -700,7 +700,7 @@
         uint16_t fat_entry;
         while(cluster_num)
         {
-            if(!fs->partition->device_read(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
+            if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
                 return 0;
 
             /* get next cluster of current cluster before freeing current cluster */
@@ -719,7 +719,7 @@
 
             /* free cluster */
             fat_entry = HTOL16(FAT16_CLUSTER_FREE);
-            fs->partition->device_write(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
+            fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
 
             /* We continue in any case here, even if freeing the cluster failed.
              * The cluster is lost, but maybe we can still free up some later ones.
@@ -759,14 +759,14 @@
     if(fs->partition->type == PARTITION_TYPE_FAT32)
     {
         uint32_t fat_entry = HTOL32(FAT32_CLUSTER_LAST_MAX);
-        if(!fs->partition->device_write(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
+        if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
             return 0;
     }
     else
 #endif
     {
         uint16_t fat_entry = HTOL16(FAT16_CLUSTER_LAST_MAX);
-        if(!fs->partition->device_write(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
+        if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
             return 0;
     }
 
@@ -1081,7 +1081,7 @@
  * \param[in] fd The file handle of the file to which to write.
  * \param[in] buffer The buffer from which to read the data to be written.
  * \param[in] buffer_len The amount of data to write.
- * \returns The number of bytes written, 0 on disk full, or -1 on failure.
+ * \returns The number of bytes written (0 or something less than \c buffer_len on disk full) or -1 on failure.
  * \see fat_read_file
  */
 intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintptr_t buffer_len)
@@ -1109,7 +1109,7 @@
                 /* empty file */
                 fd->dir_entry.cluster = cluster_num = fat_append_clusters(fd->fs, 0, 1);
                 if(!cluster_num)
-                    return -1;
+                    return 0;
             }
             else
             {
@@ -1125,11 +1125,16 @@
             {
                 pos -= cluster_size;
                 cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num);
-                if(!cluster_num_next && pos == 0)
+                if(!cluster_num_next)
+                {
+                    if(pos != 0)
+                        return -1; /* current file position points beyond end of file */
+
                     /* the file exactly ends on a cluster boundary, and we append to it */
                     cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1);
-                if(!cluster_num_next)
-                    return -1;
+                    if(!cluster_num_next)
+                        return 0;
+                }
 
                 cluster_num = cluster_num_next;
             }
@@ -2515,7 +2520,7 @@
 
     for(uintptr_t i = 0; i < buffer_size; i += 2, buffer += 2)
     {
-        uint16_t cluster = *((uint16_t*) &buffer[0]);
+        uint16_t cluster = read16(buffer);
         if(cluster == HTOL16(FAT16_CLUSTER_FREE))
             ++(count_arg->cluster_count);
     }
@@ -2535,7 +2540,7 @@
 
     for(uintptr_t i = 0; i < buffer_size; i += 4, buffer += 4)
     {
-        uint32_t cluster = *((uint32_t*) &buffer[0]);
+        uint32_t cluster = read32(buffer);
         if(cluster == HTOL32(FAT32_CLUSTER_FREE))
             ++(count_arg->cluster_count);
     }
