mimic access() behavior on Windows
This commit is contained in:
parent
34e25ac568
commit
096c21f233
|
@ -549,93 +549,6 @@ eina_file_cleanup(Eina_Tmpstr *path)
|
|||
return result;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_file_is_binary(const char *path)
|
||||
{
|
||||
HANDLE h;
|
||||
HANDLE fm;
|
||||
unsigned char *base;
|
||||
unsigned char *base_nt;
|
||||
LARGE_INTEGER sz;
|
||||
WORD characteristics;
|
||||
Eina_Bool res;
|
||||
|
||||
res = EINA_FALSE;
|
||||
|
||||
/*
|
||||
* we parse the file to check if it is a PE file (EXE or DLL)
|
||||
* and we finally check whether it's a DLL or not.
|
||||
* Reference :
|
||||
* https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
|
||||
*/
|
||||
|
||||
h = CreateFile(path,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (!GetFileSizeEx(h, &sz))
|
||||
goto close_h;
|
||||
|
||||
/* a PE file must contain at least the DOS and NT headers */
|
||||
if (sz.QuadPart < (LONGLONG)(sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS)))
|
||||
goto close_h;
|
||||
|
||||
fm = CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
if (fm == NULL)
|
||||
goto close_h;
|
||||
|
||||
base = (unsigned char *)MapViewOfFile(fm, FILE_MAP_READ, 0, 0, 0);
|
||||
CloseHandle(fm);
|
||||
if (base == NULL)
|
||||
goto close_h;
|
||||
|
||||
/*
|
||||
* the PE file begins with the DOS header.
|
||||
* First magic number : the DOS header must begin with a DOS magic
|
||||
* number, that is "MZ", that is 0x5a4d, stored in a WORD.
|
||||
*/
|
||||
if (*((WORD *)base) != 0x5a4d)
|
||||
goto unmap_view;
|
||||
|
||||
/*
|
||||
* The position of the NT header is located at the offset 0x3c.
|
||||
*/
|
||||
base_nt = base + *((DWORD *)(base + 0x3c));
|
||||
|
||||
/*
|
||||
* The NT header begins with the magic number "PE\0\0", that is
|
||||
* 0x00004550, stored in a DWORD.
|
||||
*/
|
||||
if (*((DWORD *)base_nt) != 0x00004550)
|
||||
goto unmap_view;
|
||||
|
||||
/*
|
||||
* to get informations about executable (EXE or DLL), we look at
|
||||
* the 'Characteristics' member of the NT header, located at the offset
|
||||
* 22 (4 for the magic number, 18 for the offset) from base_nt.
|
||||
* https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#characteristics
|
||||
*/
|
||||
characteristics = *((WORD *)(base_nt + 4 + 18));
|
||||
|
||||
/*
|
||||
* 0x0002 : if set, EXE or DLL
|
||||
* 0x2000 : if set, DLL
|
||||
*/
|
||||
res = (characteristics & 0x0002) && !(characteristics & 0x2000);
|
||||
|
||||
unmap_view:
|
||||
UnmapViewOfFile(base);
|
||||
close_h:
|
||||
CloseHandle(h);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*============================================================================*
|
||||
* API *
|
||||
*============================================================================*/
|
||||
|
@ -1401,42 +1314,14 @@ eina_file_access(const char *path, Eina_File_Access_Mode mode)
|
|||
|
||||
if (mode & EINA_FILE_ACCESS_MODE_EXEC)
|
||||
{
|
||||
if (attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
/*
|
||||
* Some directories have restricted access, like
|
||||
* c:\Windows\System32\WDI
|
||||
*/
|
||||
HANDLE h;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
h = CreateFile(path,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_ARCHIVE | FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
ret = (h == INVALID_HANDLE_VALUE);
|
||||
CloseHandle(h);
|
||||
if (ret)
|
||||
if (!(attr & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
!eina_str_has_extension(path, ".exe") &&
|
||||
!eina_str_has_extension(path, ".bat"))
|
||||
return EINA_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* For files, check if it is a binary.
|
||||
*/
|
||||
if (!_eina_file_is_binary(path))
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode & EINA_FILE_ACCESS_MODE_WRITE)
|
||||
{
|
||||
DWORD attr;
|
||||
|
||||
attr = GetFileAttributes(path);
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
return EINA_FALSE;
|
||||
|
||||
|
|
|
@ -910,7 +910,6 @@ EFL_START_TEST(eina_test_file_access)
|
|||
#ifdef _WIN32
|
||||
{ "c:\\Windows", EINA_FILE_ACCESS_MODE_EXIST, EINA_TRUE },
|
||||
{ "c:\\Windows", EINA_FILE_ACCESS_MODE_EXEC, EINA_TRUE },
|
||||
{ "c:\\Windows\\System32\\WDI", EINA_FILE_ACCESS_MODE_EXEC, EINA_FALSE },
|
||||
{ "c:\\Windows\\notepad.exe", EINA_FILE_ACCESS_MODE_EXIST, EINA_TRUE },
|
||||
{ "c:\\Windows\\notepad.exe", EINA_FILE_ACCESS_MODE_EXEC, EINA_TRUE },
|
||||
{ "c:\\Windows\\notepad.exe", EINA_FILE_ACCESS_MODE_WRITE, EINA_TRUE },
|
||||
|
|
Loading…
Reference in New Issue