summaryrefslogtreecommitdiff
path: root/src/lib/eina/eina_file_win32.c
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 /src/lib/eina/eina_file_win32.c
parent0e61c08c2b38eaf88f0d8078fbba41e63e1f00cf (diff)
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
Diffstat (limited to '')
-rw-r--r--src/lib/eina/eina_file_win32.c66
1 files changed, 44 insertions, 22 deletions
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,
900 if (offset + length > file->length) 900 if (offset + length > file->length)
901 return NULL; 901 return NULL;
902 902
903 if (offset == 0 && length == file->length) 903 if (offset == 0UL && length == file->length)
904 return eina_file_map_all(file, rule); 904 return eina_file_map_all(file, rule);
905 905
906 if (file->virtual) 906 if (file->virtual)
@@ -914,40 +914,56 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
914 map = eina_hash_find(file->map, &key); 914 map = eina_hash_find(file->map, &key);
915 if (!map) 915 if (!map)
916 { 916 {
917 SYSTEM_INFO si;
917 HANDLE fm; 918 HANDLE fm;
919 __int64 map_size;
920 DWORD view_offset;
921 DWORD view_length;
922 DWORD granularity;
923
918 map = malloc(sizeof (Eina_File_Map)); 924 map = malloc(sizeof (Eina_File_Map));
919 if (!map) 925 if (!map)
920 { 926 goto on_error;
921 eina_lock_release(&file->lock);
922 return NULL;
923 }
924 927
925 /* the length parameter is unsigned long, that is a DWORD */ 928 /*
926 /* so the max size high parameter of CreateFileMapping is 0 */ 929 * the size of the mapping object is the offset plus the length,
930 * which might be greater than a DWORD
931 */
932 map_size = (__int64)offset + (__int64)length;
927 fm = CreateFileMapping(file->handle, NULL, PAGE_READONLY, 933 fm = CreateFileMapping(file->handle, NULL, PAGE_READONLY,
928 0, (DWORD)length, NULL); 934 (DWORD)((map_size >> 32) & 0x00000000ffffffffULL),
935 (DWORD)(map_size & 0x00000000ffffffffULL),
936 NULL);
929 if (!fm) 937 if (!fm)
930 return NULL; 938 goto on_error;
931 939
940 /*
941 * get the system allocation granularity as the
942 * offset passed to MapViewOfFile() must be a
943 * multiple of this granularity
944 */
945 GetSystemInfo(&si);
946 granularity = si.dwAllocationGranularity;
947
948 /*
949 * view_offset is the greatest multiple of granularity, less or equal
950 * than offset (and can be stored in a DWORD)
951 */
952 view_offset = (offset / granularity) * granularity;
953 view_length = (offset - view_offset) + length;
932 map->map = MapViewOfFile(fm, FILE_MAP_READ, 954 map->map = MapViewOfFile(fm, FILE_MAP_READ,
933 offset & 0xffff0000, 955 0,
934 offset & 0x0000ffff, 956 view_offset,
935 length); 957 view_length);
936 CloseHandle(fm); 958 CloseHandle(fm);
937 if (!map->map) 959 if (!map->map)
938 map->map = MAP_FAILED; 960 goto on_error;
939 961
962 map->ret = (unsigned char *)map->map + (offset - view_offset);
940 map->offset = offset; 963 map->offset = offset;
941 map->length = length; 964 map->length = length;
942 map->refcount = 0; 965 map->refcount = 0;
943 966
944 if (map->map == MAP_FAILED)
945 {
946 free(map);
947 eina_lock_release(&file->lock);
948 return NULL;
949 }
950
951 eina_hash_add(file->map, &key, map); 967 eina_hash_add(file->map, &key, map);
952 eina_hash_direct_add(file->rmap, map->map, map); 968 eina_hash_direct_add(file->rmap, map->map, map);
953 } 969 }
@@ -956,7 +972,13 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
956 972
957 eina_lock_release(&file->lock); 973 eina_lock_release(&file->lock);
958 974
959 return map->map; 975 return map->ret;
976
977 on_error:
978 free(map);
979 eina_lock_release(&file->lock);
980
981 return NULL;
960} 982}
961 983
962EAPI void 984EAPI void