summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2020-06-25 14:44:15 +0000
committerStefan Schmidt <s.schmidt@samsung.com>2020-06-26 15:40:57 +0200
commitcdaac43d3a9f339ccf0f27c2fdab7f7b191d0ebd (patch)
tree1f05210a92010ae750e210b161ecfa4d56949cac
parent0e61c08c2b38eaf88f0d8078fbba41e63e1f00cf (diff)
downloadefl-cdaac43d3a9f339ccf0f27c2fdab7f7b191d0ebd.tar.gz
Windows: fix eina_file_map_new()
the offset passed to MapViewOfFile() must be a multiple of the granularity. https://docs.microsoft.com/en-us/windows/win32/memory/creating-a-view-within-a-file is taken as basis for this patch Reviewed-by: Stefan Schmidt <stefan@datenfreihafen.org> Reviewed-by: Wander Lairson Costa <wander.lairson@gmail.com> Differential Revision: https://phab.enlightenment.org/D12031
-rw-r--r--src/lib/eina/eina_file_common.h3
-rw-r--r--src/lib/eina/eina_file_win32.c66
2 files changed, 47 insertions, 22 deletions
diff --git a/src/lib/eina/eina_file_common.h b/src/lib/eina/eina_file_common.h
index 9aedfae755..16fb772c4d 100644
--- a/src/lib/eina/eina_file_common.h
+++ b/src/lib/eina/eina_file_common.h
@@ -124,6 +124,9 @@ struct _Eina_File_Map
Eina_Bool hugetlb : 1; /**< Indicates if we are using HugeTLB */
Eina_Bool faulty : 1; /**< Indicates if this region was not mapped correctly (i.e. the call to mmap(2) failed). */
+#ifdef _WIN32
+ void *ret; /**< A pointer to the mapped region */
+#endif
};
/**
diff --git a/src/lib/eina/eina_file_win32.c b/src/lib/eina/eina_file_win32.c
index ca8e78b83e..46449fdb57 100644
--- a/src/lib/eina/eina_file_win32.c
+++ b/src/lib/eina/eina_file_win32.c
@@ -900,7 +900,7 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
if (offset + length > file->length)
return NULL;
- if (offset == 0 && length == file->length)
+ if (offset == 0UL && length == file->length)
return eina_file_map_all(file, rule);
if (file->virtual)
@@ -914,40 +914,56 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
map = eina_hash_find(file->map, &key);
if (!map)
{
+ SYSTEM_INFO si;
HANDLE fm;
+ __int64 map_size;
+ DWORD view_offset;
+ DWORD view_length;
+ DWORD granularity;
+
map = malloc(sizeof (Eina_File_Map));
if (!map)
- {
- eina_lock_release(&file->lock);
- return NULL;
- }
+ goto on_error;
- /* the length parameter is unsigned long, that is a DWORD */
- /* so the max size high parameter of CreateFileMapping is 0 */
+ /*
+ * the size of the mapping object is the offset plus the length,
+ * which might be greater than a DWORD
+ */
+ map_size = (__int64)offset + (__int64)length;
fm = CreateFileMapping(file->handle, NULL, PAGE_READONLY,
- 0, (DWORD)length, NULL);
+ (DWORD)((map_size >> 32) & 0x00000000ffffffffULL),
+ (DWORD)(map_size & 0x00000000ffffffffULL),
+ NULL);
if (!fm)
- return NULL;
-
+ goto on_error;
+
+ /*
+ * get the system allocation granularity as the
+ * offset passed to MapViewOfFile() must be a
+ * multiple of this granularity
+ */
+ GetSystemInfo(&si);
+ granularity = si.dwAllocationGranularity;
+
+ /*
+ * view_offset is the greatest multiple of granularity, less or equal
+ * than offset (and can be stored in a DWORD)
+ */
+ view_offset = (offset / granularity) * granularity;
+ view_length = (offset - view_offset) + length;
map->map = MapViewOfFile(fm, FILE_MAP_READ,
- offset & 0xffff0000,
- offset & 0x0000ffff,
- length);
+ 0,
+ view_offset,
+ view_length);
CloseHandle(fm);
if (!map->map)
- map->map = MAP_FAILED;
+ goto on_error;
+ map->ret = (unsigned char *)map->map + (offset - view_offset);
map->offset = offset;
map->length = length;
map->refcount = 0;
- if (map->map == MAP_FAILED)
- {
- free(map);
- eina_lock_release(&file->lock);
- return NULL;
- }
-
eina_hash_add(file->map, &key, map);
eina_hash_direct_add(file->rmap, map->map, map);
}
@@ -956,7 +972,13 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
eina_lock_release(&file->lock);
- return map->map;
+ return map->ret;
+
+ on_error:
+ free(map);
+ eina_lock_release(&file->lock);
+
+ return NULL;
}
EAPI void