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
This commit is contained in:
Vincent Torri 2020-06-25 14:44:15 +00:00 committed by Stefan Schmidt
parent 0e61c08c2b
commit cdaac43d3a
2 changed files with 46 additions and 21 deletions

View File

@ -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
};
/**

View File

@ -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