mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 08:24:16 +09:00
[channels,drive] Small performance improvements in drive channel
This commit fixes following performance issues in the drive channel: - `GetFileAttributes` functions where using `FindFirstFile` to query attributes. The same can be achieved with `stat` and reusing the existing stat <-> file info conversion code. - `drive_file_query_information` was calling `CreateFile` on directories which will always fail with the given parameters.
This commit is contained in:
@@ -587,7 +587,6 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
||||
{
|
||||
BY_HANDLE_FILE_INFORMATION fileInformation = { 0 };
|
||||
BOOL status = 0;
|
||||
HANDLE hFile = NULL;
|
||||
|
||||
if (!file || !output)
|
||||
return FALSE;
|
||||
@@ -597,20 +596,23 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
||||
return drive_file_query_from_handle_information(file, &fileInformation, FsInformationClass,
|
||||
output);
|
||||
|
||||
hFile = CreateFileW(file->fullpath, 0, FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
if (!file->is_dir)
|
||||
{
|
||||
status = GetFileInformationByHandle(hFile, &fileInformation);
|
||||
(void)CloseHandle(hFile);
|
||||
if (!status)
|
||||
goto out_fail;
|
||||
HANDLE hFile = CreateFileW(file->fullpath, 0, FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
status = GetFileInformationByHandle(hFile, &fileInformation);
|
||||
(void)CloseHandle(hFile);
|
||||
if (!status)
|
||||
goto out_fail;
|
||||
|
||||
if (!drive_file_query_from_handle_information(file, &fileInformation, FsInformationClass,
|
||||
output))
|
||||
goto out_fail;
|
||||
if (!drive_file_query_from_handle_information(file, &fileInformation,
|
||||
FsInformationClass, output))
|
||||
goto out_fail;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we failed before (i.e. if information for a drive is queried) fall back to
|
||||
|
||||
@@ -182,6 +182,10 @@ static pthread_once_t HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
|
||||
#include "../comm/comm.h"
|
||||
#include "namedPipeClient.h"
|
||||
|
||||
static DWORD FileAttributesFromStat(const char* path, const struct stat* fileStat);
|
||||
static BOOL FindDataFromStat(const char* path, const struct stat* fileStat,
|
||||
LPWIN32_FIND_DATAA lpFindFileData);
|
||||
|
||||
static void HandleCreatorsInit(void)
|
||||
{
|
||||
WINPR_ASSERT(HandleCreators == NULL);
|
||||
@@ -476,16 +480,17 @@ BOOL WINAPI GetFileAttributesExA(LPCSTR lpFileName,
|
||||
LPVOID lpFileInformation)
|
||||
{
|
||||
LPWIN32_FILE_ATTRIBUTE_DATA fd = lpFileInformation;
|
||||
WIN32_FIND_DATAA findFileData = { 0 };
|
||||
|
||||
if (!fd)
|
||||
return FALSE;
|
||||
|
||||
HANDLE hFind = FindFirstFileA(lpFileName, &findFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
struct stat fileStat = { 0 };
|
||||
if (stat(lpFileName, &fileStat) != 0)
|
||||
return FALSE;
|
||||
|
||||
WIN32_FIND_DATAA findFileData = { 0 };
|
||||
if (!FindDataFromStat(lpFileName, &fileStat, &findFileData))
|
||||
return FALSE;
|
||||
|
||||
FindClose(hFind);
|
||||
fd->dwFileAttributes = findFileData.dwFileAttributes;
|
||||
fd->ftCreationTime = findFileData.ftCreationTime;
|
||||
fd->ftLastAccessTime = findFileData.ftLastAccessTime;
|
||||
@@ -516,14 +521,11 @@ BOOL WINAPI GetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInf
|
||||
|
||||
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
|
||||
{
|
||||
WIN32_FIND_DATAA findFileData = { 0 };
|
||||
HANDLE hFind = FindFirstFileA(lpFileName, &findFileData);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
struct stat fileStat = { 0 };
|
||||
if (stat(lpFileName, &fileStat) != 0)
|
||||
return INVALID_FILE_ATTRIBUTES;
|
||||
|
||||
FindClose(hFind);
|
||||
return findFileData.dwFileAttributes;
|
||||
return FileAttributesFromStat(lpFileName, &fileStat);
|
||||
}
|
||||
|
||||
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
|
||||
@@ -935,32 +937,39 @@ static BOOL is_valid_file_search_handle(HANDLE handle)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL FindDataFromStat(const char* path, const struct stat* fileStat,
|
||||
LPWIN32_FIND_DATAA lpFindFileData)
|
||||
|
||||
static DWORD FileAttributesFromStat(const char* path, const struct stat* fileStat)
|
||||
{
|
||||
UINT64 ft = 0;
|
||||
char* lastSep = NULL;
|
||||
lpFindFileData->dwFileAttributes = 0;
|
||||
DWORD dwFileAttributes = 0;
|
||||
|
||||
if (S_ISDIR(fileStat->st_mode))
|
||||
lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
||||
if (lpFindFileData->dwFileAttributes == 0)
|
||||
lpFindFileData->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
|
||||
if (dwFileAttributes == 0)
|
||||
dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
|
||||
|
||||
lastSep = strrchr(path, '/');
|
||||
|
||||
if (lastSep)
|
||||
{
|
||||
const char* name = lastSep + 1;
|
||||
const size_t namelen = strlen(name);
|
||||
|
||||
if ((namelen > 1) && (name[0] == '.') && (name[1] != '.'))
|
||||
lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||
dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||
}
|
||||
|
||||
if (!(fileStat->st_mode & S_IWUSR))
|
||||
lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||
dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||
|
||||
return dwFileAttributes;
|
||||
}
|
||||
|
||||
static BOOL FindDataFromStat(const char* path, const struct stat* fileStat,
|
||||
LPWIN32_FIND_DATAA lpFindFileData)
|
||||
{
|
||||
UINT64 ft = 0;
|
||||
lpFindFileData->dwFileAttributes = FileAttributesFromStat(path, fileStat);
|
||||
|
||||
#ifdef _DARWIN_FEATURE_64_BIT_INODE
|
||||
ft = STAT_TIME_TO_FILETIME(fileStat->st_birthtime);
|
||||
@@ -1205,9 +1214,9 @@ BOOL FindClose(HANDLE hFindFile)
|
||||
if (!pFileSearch)
|
||||
return FALSE;
|
||||
|
||||
/* Since INVALID_HANDLE_VALUE != NULL the analyzer guesses that there
|
||||
* is a initialized HANDLE that is not freed properly.
|
||||
* Disable this return to stop confusing the analyzer. */
|
||||
/* Since INVALID_HANDLE_VALUE != NULL the analyzer guesses that there
|
||||
* is a initialized HANDLE that is not freed properly.
|
||||
* Disable this return to stop confusing the analyzer. */
|
||||
#ifndef __clang_analyzer__
|
||||
if (!is_valid_file_search_handle(hFindFile))
|
||||
return FALSE;
|
||||
|
||||
Reference in New Issue
Block a user