forked from enlightenment/efl
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:
parent
0e61c08c2b
commit
cdaac43d3a
|
@ -124,6 +124,9 @@ struct _Eina_File_Map
|
||||||
|
|
||||||
Eina_Bool hugetlb : 1; /**< Indicates if we are using HugeTLB */
|
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). */
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -900,7 +900,7 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
|
||||||
if (offset + length > file->length)
|
if (offset + length > file->length)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (offset == 0 && length == file->length)
|
if (offset == 0UL && length == file->length)
|
||||||
return eina_file_map_all(file, rule);
|
return eina_file_map_all(file, rule);
|
||||||
|
|
||||||
if (file->virtual)
|
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);
|
map = eina_hash_find(file->map, &key);
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
{
|
||||||
|
SYSTEM_INFO si;
|
||||||
HANDLE fm;
|
HANDLE fm;
|
||||||
|
__int64 map_size;
|
||||||
|
DWORD view_offset;
|
||||||
|
DWORD view_length;
|
||||||
|
DWORD granularity;
|
||||||
|
|
||||||
map = malloc(sizeof (Eina_File_Map));
|
map = malloc(sizeof (Eina_File_Map));
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
goto on_error;
|
||||||
eina_lock_release(&file->lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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,
|
fm = CreateFileMapping(file->handle, NULL, PAGE_READONLY,
|
||||||
0, (DWORD)length, NULL);
|
(DWORD)((map_size >> 32) & 0x00000000ffffffffULL),
|
||||||
|
(DWORD)(map_size & 0x00000000ffffffffULL),
|
||||||
|
NULL);
|
||||||
if (!fm)
|
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,
|
map->map = MapViewOfFile(fm, FILE_MAP_READ,
|
||||||
offset & 0xffff0000,
|
0,
|
||||||
offset & 0x0000ffff,
|
view_offset,
|
||||||
length);
|
view_length);
|
||||||
CloseHandle(fm);
|
CloseHandle(fm);
|
||||||
if (!map->map)
|
if (!map->map)
|
||||||
map->map = MAP_FAILED;
|
goto on_error;
|
||||||
|
|
||||||
|
map->ret = (unsigned char *)map->map + (offset - view_offset);
|
||||||
map->offset = offset;
|
map->offset = offset;
|
||||||
map->length = length;
|
map->length = length;
|
||||||
map->refcount = 0;
|
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_add(file->map, &key, map);
|
||||||
eina_hash_direct_add(file->rmap, map->map, 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);
|
eina_lock_release(&file->lock);
|
||||||
|
|
||||||
return map->map;
|
return map->ret;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
free(map);
|
||||||
|
eina_lock_release(&file->lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
|
Loading…
Reference in New Issue