diff --git a/tsk/img/raw.c b/tsk/img/raw.c
index 861e1ff8db7334336c306e60e40aab344fb1b2d0..daf19babeb0bc585a65f564ddbcc37bb304dec6a 100755
--- a/tsk/img/raw.c
+++ b/tsk/img/raw.c
@@ -39,6 +39,17 @@
 #define S_IFDIR __S_IFDIR
 #endif
 
+/**
+ * \internal
+ * Test if the image is a Windows device
+ * @param The path to test
+ *
+ * Return 1 if the path represents a Windows device, 0 otherwise
+ */
+static int
+is_windows_device_path(const TSK_TCHAR * image_name) {
+    return (TSTRNCMP(image_name, _TSK_T("\\\\.\\"), 4) == 0);
+}
 
 /** 
  * \internal
@@ -133,7 +144,7 @@ raw_read_segment(IMG_RAW_INFO * raw_info, int idx, char *buf,
         // If the offset to seek to isn't sector-aligned and this is a device, we need to start at the previous sector boundary and
         // read some extra data.
         if ((offset_to_read % raw_info->img_info.sector_size != 0)
-                && (TSTRNCMP(raw_info->img_info.images[idx], _TSK_T("\\\\.\\"), 4) == 0)) {
+                && is_windows_device_path(raw_info->img_info.images[idx])) {
             offset_to_read = (offset_to_read / raw_info->img_info.sector_size) * raw_info->img_info.sector_size;
             len_to_read += raw_info->img_info.sector_size; // this length will already be a multiple of sector size
             sector_aligned_buf = (char *)tsk_malloc(len_to_read);
@@ -630,6 +641,119 @@ get_size(const TSK_TCHAR * a_file, uint8_t a_is_winobj)
     return size;
 }
 
+#ifdef TSK_WIN32
+/**
+* \internal
+* Test seeking to the given offset and then reading a sector.
+* @param file_handle The open file handle to the image
+* @param offset      The offset to seek to (in bytes)
+* @param len         The length to read (in bytes). Should be a multiple of the sector size.
+* @param buf         An allocated buffer large enough to hold len bytes
+*
+* @return 1 if the seek/read is successful, 0 if not
+*/
+static int
+test_sector_read(HANDLE file_handle, TSK_OFF_T offset, DWORD len, char * buf) {
+    LARGE_INTEGER li;
+    li.QuadPart = offset;
+
+    // Seek to the given offset
+    li.LowPart = SetFilePointer(file_handle, li.LowPart,
+        &li.HighPart, FILE_BEGIN);
+    if ((li.LowPart == INVALID_SET_FILE_POINTER) &&
+        (GetLastError() != NO_ERROR)) {
+        return 0;
+    }
+
+    // Read a byte at the given offset
+    DWORD nread;
+    if (FALSE == ReadFile(file_handle, buf, len, &nread, NULL)) {
+        return 0;
+    }
+    if (nread != len) {
+        return 0;
+    }
+
+    // Success
+    return 1;
+}
+
+/**
+ * Attempts to calculate the actual sector size needed for reading the image.
+ * If successful, the calculated sector size will be stored in raw_info. If it
+ * fails the sector_size field will not be updated.
+ * @param raw_info    The incomplete IMG_RAW_INFO object. The sector_size field may be updated by this method.
+ * @param image_name  Image file name
+ * @param image_size  Image size
+*/
+static void
+set_device_sector_size(IMG_RAW_INFO * raw_info, const TSK_TCHAR * image_name, TSK_OFF_T image_size) {
+    unsigned int min_sector_size = 512;
+    unsigned int max_sector_size = 4096;
+
+    HANDLE file_handle = CreateFile(image_name, FILE_READ_DATA,
+        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
+        NULL);
+    if (file_handle == INVALID_HANDLE_VALUE) {
+        if (tsk_verbose) {
+            tsk_fprintf(stderr,
+                "find_sector_size: failed to open image \"%" PRIttocTSK "\"\n", image_name);
+        }
+        return;
+    }
+
+    // First test whether we need to align on sector boundaries
+    char* buf = malloc(max_sector_size);
+    int needs_sector_alignment = 0;
+    if (image_size > raw_info->img_info.sector_size) {
+        if (test_sector_read(file_handle, 1, raw_info->img_info.sector_size, buf)) {
+            needs_sector_alignment = 0;
+        }
+        else {
+            needs_sector_alignment = 1;
+        }
+    }
+
+    // If reading a sector starting at offset 1 failed, the assumption is that we have a device
+    // that requires reads to be sector-aligned. 
+    if (needs_sector_alignment) {
+        // Start at the minimum (512) and double up to max_sector_size (4096)
+        unsigned int sector_size = min_sector_size;
+
+        while (sector_size <= max_sector_size) {
+            // If we don't have enough data to do the test just stop
+            if (image_size < sector_size * 2) {
+                break;
+            }
+
+            if (test_sector_read(file_handle, sector_size, sector_size, buf)) {
+                // Found a valid sector size
+                if (tsk_verbose) {
+                    tsk_fprintf(stderr,
+                        "find_sector_size: using sector size %d\n", sector_size);
+                }
+                raw_info->img_info.sector_size = sector_size;
+
+                if (file_handle != 0) {
+                    CloseHandle(file_handle);
+                }
+                free(buf);
+                return;
+            }
+            sector_size *= 2;
+        }
+        if (tsk_verbose) {
+            tsk_fprintf(stderr,
+                "find_sector_size: failed to determine correct sector size. Reverting to default %d\n", raw_info->img_info.sector_size);
+        }
+        free(buf);
+    }
+
+    if (file_handle != 0) {
+        CloseHandle(file_handle);
+    }
+}
+#endif
 
 /** 
  * \internal
@@ -661,9 +785,6 @@ raw_open(int a_num_img, const TSK_TCHAR * const a_images[],
     img_info->close = raw_close;
     img_info->imgstat = raw_imgstat;
 
-    img_info->sector_size = 512;
-    if (a_ssize)
-        img_info->sector_size = a_ssize;
     raw_info->is_winobj = 0;
 
 #if defined(TSK_WIN32) || defined(__CYGWIN__)
@@ -683,6 +804,20 @@ raw_open(int a_num_img, const TSK_TCHAR * const a_images[],
         return NULL;
     }
 
+    /* Set the sector size */
+    img_info->sector_size = 512;
+    if (a_ssize) {
+        img_info->sector_size = a_ssize;
+    }
+#ifdef TSK_WIN32
+    else if (is_windows_device_path(a_images[0])) {
+        /* On Windows, figure out the actual sector size if one was not given and this is a device.
+         * This is to prevent problems reading later. */
+        set_device_sector_size(raw_info, a_images[0], first_seg_size);
+    }
+#endif
+
+
     /* see if there are more of them... */
     if ((a_num_img == 1) && (raw_info->is_winobj == 0)) {
         if ((raw_info->img_info.images =