winpr: add GetFileInformationByHandle
This commit is contained in:
parent
14568872a9
commit
e62aaff319
@ -216,6 +216,20 @@ typedef struct
|
||||
WCHAR cAlternateFileName[14];
|
||||
} WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
DWORD dwVolumeSerialNumber;
|
||||
DWORD nFileSizeHigh;
|
||||
DWORD nFileSizeLow;
|
||||
DWORD nNumberOfLinks;
|
||||
DWORD nFileIndexHigh;
|
||||
DWORD nFileIndexLow;
|
||||
} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FindExInfoStandard,
|
||||
@ -312,6 +326,9 @@ extern "C"
|
||||
|
||||
WINPR_API DWORD GetFileAttributesW(LPCWSTR lpFileName);
|
||||
|
||||
WINPR_API BOOL GetFileInformationByHandle(HANDLE hFile,
|
||||
LPBY_HANDLE_FILE_INFORMATION lpFileInformation);
|
||||
|
||||
WINPR_API BOOL SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes);
|
||||
|
||||
WINPR_API BOOL SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes);
|
||||
|
@ -325,6 +325,69 @@ static DWORD FileGetFileSize(HANDLE Object, LPDWORD lpFileSizeHigh)
|
||||
return (UINT32)(size & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static BOOL FileGetFileInformationByHandle(HANDLE hFile,
|
||||
LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
|
||||
{
|
||||
WINPR_FILE* pFile = (WINPR_FILE*)hFile;
|
||||
struct stat st;
|
||||
UINT64 ft;
|
||||
const char* lastSep;
|
||||
|
||||
if (!pFile)
|
||||
return FALSE;
|
||||
if (!lpFileInformation)
|
||||
return FALSE;
|
||||
|
||||
if (fstat(fileno(pFile->fp), &st) == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "fstat failed with %s [%#08X]", errno, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lpFileInformation->dwFileAttributes = 0;
|
||||
|
||||
if (S_ISDIR(st.st_mode))
|
||||
lpFileInformation->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
||||
if (lpFileInformation->dwFileAttributes == 0)
|
||||
lpFileInformation->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
|
||||
|
||||
lastSep = strrchr(pFile->lpFileName, '/');
|
||||
|
||||
if (lastSep)
|
||||
{
|
||||
const char* name = lastSep + 1;
|
||||
const size_t namelen = strlen(name);
|
||||
|
||||
if ((namelen > 1) && (name[0] == '.') && (name[1] != '.'))
|
||||
lpFileInformation->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||
}
|
||||
|
||||
if (!(st.st_mode & S_IWUSR))
|
||||
lpFileInformation->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||
|
||||
#ifdef _DARWIN_FEATURE_64_BIT_INODE
|
||||
ft = STAT_TIME_TO_FILETIME(st.st_birthtime);
|
||||
#else
|
||||
ft = STAT_TIME_TO_FILETIME(st.st_ctime);
|
||||
#endif
|
||||
lpFileInformation->ftCreationTime.dwHighDateTime = ((UINT64)ft) >> 32ULL;
|
||||
lpFileInformation->ftCreationTime.dwLowDateTime = ft & 0xFFFFFFFF;
|
||||
ft = STAT_TIME_TO_FILETIME(st.st_mtime);
|
||||
lpFileInformation->ftLastWriteTime.dwHighDateTime = ((UINT64)ft) >> 32ULL;
|
||||
lpFileInformation->ftLastWriteTime.dwLowDateTime = ft & 0xFFFFFFFF;
|
||||
ft = STAT_TIME_TO_FILETIME(st.st_atime);
|
||||
lpFileInformation->ftLastAccessTime.dwHighDateTime = ((UINT64)ft) >> 32ULL;
|
||||
lpFileInformation->ftLastAccessTime.dwLowDateTime = ft & 0xFFFFFFFF;
|
||||
lpFileInformation->nFileSizeHigh = ((UINT64)st.st_size) >> 32ULL;
|
||||
lpFileInformation->nFileSizeLow = st.st_size & 0xFFFFFFFF;
|
||||
lpFileInformation->dwVolumeSerialNumber = st.st_dev;
|
||||
lpFileInformation->nNumberOfLinks = st.st_nlink;
|
||||
lpFileInformation->nFileIndexHigh = (st.st_ino >> 4) & 0xFFFFFFFF;
|
||||
lpFileInformation->nFileIndexLow = st.st_ino & 0xFFFFFFFF;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL FileLockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
|
||||
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
|
||||
LPOVERLAPPED lpOverlapped)
|
||||
@ -484,10 +547,10 @@ static BOOL FileUnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfByte
|
||||
|
||||
static UINT64 FileTimeToUS(const FILETIME* ft)
|
||||
{
|
||||
const UINT64 EPOCH_DIFF = 11644473600ULL * 1000000ULL;
|
||||
const UINT64 EPOCH_DIFF_US = EPOCH_DIFF * 1000000ULL;
|
||||
UINT64 tmp = ((UINT64)ft->dwHighDateTime) << 32 | ft->dwLowDateTime;
|
||||
tmp /= 10; /* 100ns steps to 1us step */
|
||||
tmp -= EPOCH_DIFF;
|
||||
tmp -= EPOCH_DIFF_US;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -586,44 +649,52 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HANDLE_OPS fileOps = { FileIsHandled,
|
||||
FileCloseHandle,
|
||||
FileGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
FileRead,
|
||||
NULL, /* FileReadEx */
|
||||
NULL, /* FileReadScatter */
|
||||
FileWrite,
|
||||
NULL, /* FileWriteEx */
|
||||
NULL, /* FileWriteGather */
|
||||
FileGetFileSize,
|
||||
NULL, /* FlushFileBuffers */
|
||||
FileSetEndOfFile,
|
||||
FileSetFilePointer,
|
||||
FileSetFilePointerEx,
|
||||
NULL, /* FileLockFile */
|
||||
FileLockFileEx,
|
||||
FileUnlockFile,
|
||||
FileUnlockFileEx,
|
||||
FileSetFileTime };
|
||||
static HANDLE_OPS fileOps = {
|
||||
FileIsHandled,
|
||||
FileCloseHandle,
|
||||
FileGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
FileRead,
|
||||
NULL, /* FileReadEx */
|
||||
NULL, /* FileReadScatter */
|
||||
FileWrite,
|
||||
NULL, /* FileWriteEx */
|
||||
NULL, /* FileWriteGather */
|
||||
FileGetFileSize,
|
||||
NULL, /* FlushFileBuffers */
|
||||
FileSetEndOfFile,
|
||||
FileSetFilePointer,
|
||||
FileSetFilePointerEx,
|
||||
NULL, /* FileLockFile */
|
||||
FileLockFileEx,
|
||||
FileUnlockFile,
|
||||
FileUnlockFileEx,
|
||||
FileSetFileTime,
|
||||
FileGetFileInformationByHandle,
|
||||
};
|
||||
|
||||
static HANDLE_OPS shmOps = {
|
||||
FileIsHandled, FileCloseHandle,
|
||||
FileGetFd, NULL, /* CleanupHandle */
|
||||
FileRead, NULL, /* FileReadEx */
|
||||
NULL, /* FileReadScatter */
|
||||
FileWrite, NULL, /* FileWriteEx */
|
||||
NULL, /* FileWriteGather */
|
||||
NULL, /* FileGetFileSize */
|
||||
NULL, /* FlushFileBuffers */
|
||||
NULL, /* FileSetEndOfFile */
|
||||
NULL, /* FileSetFilePointer */
|
||||
NULL, /* SetFilePointerEx */
|
||||
NULL, /* FileLockFile */
|
||||
NULL, /* FileLockFileEx */
|
||||
NULL, /* FileUnlockFile */
|
||||
NULL, /* FileUnlockFileEx */
|
||||
NULL /* FileSetFileTime */
|
||||
FileIsHandled,
|
||||
FileCloseHandle,
|
||||
FileGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
FileRead,
|
||||
NULL, /* FileReadEx */
|
||||
NULL, /* FileReadScatter */
|
||||
FileWrite,
|
||||
NULL, /* FileWriteEx */
|
||||
NULL, /* FileWriteGather */
|
||||
NULL, /* FileGetFileSize */
|
||||
NULL, /* FlushFileBuffers */
|
||||
NULL, /* FileSetEndOfFile */
|
||||
NULL, /* FileSetFilePointer */
|
||||
NULL, /* SetFilePointerEx */
|
||||
NULL, /* FileLockFile */
|
||||
NULL, /* FileLockFileEx */
|
||||
NULL, /* FileUnlockFile */
|
||||
NULL, /* FileUnlockFileEx */
|
||||
NULL, /* FileSetFileTime */
|
||||
FileGetFileInformationByHandle,
|
||||
};
|
||||
|
||||
static const char* FileGetMode(DWORD dwDesiredAccess, DWORD dwCreationDisposition, BOOL* create)
|
||||
|
@ -34,6 +34,9 @@
|
||||
#include <stdio.h>
|
||||
#include "../handle/handle.h"
|
||||
|
||||
#define EPOCH_DIFF 11644473600LL
|
||||
#define STAT_TIME_TO_FILETIME(_t) (((UINT64)(_t) + EPOCH_DIFF) * 10000000LL)
|
||||
|
||||
struct winpr_file
|
||||
{
|
||||
WINPR_HANDLE_DEF();
|
||||
|
@ -173,10 +173,6 @@
|
||||
* Asynchronous I/O User Guide:
|
||||
* http://code.google.com/p/kernel/wiki/AIOUserGuide
|
||||
*/
|
||||
|
||||
#define EPOCH_DIFF 11644473600LL
|
||||
#define STAT_TIME_TO_FILETIME(_t) (((UINT64)(_t) + EPOCH_DIFF) * 10000000LL)
|
||||
|
||||
static wArrayList* _HandleCreators;
|
||||
|
||||
static pthread_once_t _HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
|
||||
@ -537,6 +533,26 @@ DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
|
||||
{
|
||||
ULONG Type;
|
||||
WINPR_HANDLE* handle;
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
|
||||
return FALSE;
|
||||
|
||||
handle = (WINPR_HANDLE*)hFile;
|
||||
|
||||
if (handle->ops->GetFileInformationByHandle)
|
||||
return handle->ops->GetFileInformationByHandle(handle, lpFileInformation);
|
||||
|
||||
WLog_ERR(TAG, "GetFileInformationByHandle operation not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char* append(char* buffer, size_t size, const char* append)
|
||||
{
|
||||
const size_t len = strnlen(buffer, size);
|
||||
|
@ -121,7 +121,8 @@ static HANDLE_OPS ops = {
|
||||
NULL, /* FileLockFileEx */
|
||||
NULL, /* FileUnlockFile */
|
||||
NULL, /* FileUnlockFileEx */
|
||||
NULL /* SetFileTime */
|
||||
NULL, /* SetFileTime */
|
||||
NULL, /* FileGetFileInformationByHandle */
|
||||
};
|
||||
|
||||
static HANDLE NamedPipeClientCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess,
|
||||
|
@ -66,6 +66,8 @@ typedef BOOL (*pcWriteFileGather)(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArr
|
||||
DWORD nNumberOfBytesToWrite, LPDWORD lpReserved,
|
||||
LPOVERLAPPED lpOverlapped);
|
||||
typedef DWORD (*pcGetFileSize)(HANDLE handle, LPDWORD lpFileSizeHigh);
|
||||
typedef BOOL (*pcGetFileInformationByHandle)(HANDLE handle,
|
||||
LPBY_HANDLE_FILE_INFORMATION lpFileInformation);
|
||||
typedef BOOL (*pcFlushFileBuffers)(HANDLE hFile);
|
||||
typedef BOOL (*pcSetEndOfFile)(HANDLE handle);
|
||||
typedef DWORD (*pcSetFilePointer)(HANDLE handle, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,
|
||||
@ -106,6 +108,7 @@ typedef struct
|
||||
pcUnlockFile UnlockFile;
|
||||
pcUnlockFileEx UnlockFileEx;
|
||||
pcSetFileTime SetFileTime;
|
||||
pcGetFileInformationByHandle GetFileInformationByHandle;
|
||||
} HANDLE_OPS;
|
||||
|
||||
struct winpr_handle
|
||||
|
Loading…
x
Reference in New Issue
Block a user