mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
drive: Fix an issue when redirecting drives on Windows
CreateFile/GetFileInformationByHandle will fail if used with just a drive letter i.e. C:/. This PR fixes that case by using GetFileAttributesExW as a fallback in case CreateFileW fails.
This commit is contained in:
parent
fbbcd9b8ef
commit
b5e8b419b8
@ -461,50 +461,28 @@ BOOL drive_file_write(DRIVE_FILE* file, BYTE* buffer, UINT32 Length)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, wStream* output)
|
static BOOL drive_file_query_from_handle_information(const DRIVE_FILE* file,
|
||||||
|
const BY_HANDLE_FILE_INFORMATION* info,
|
||||||
|
UINT32 FsInformationClass, wStream* output)
|
||||||
{
|
{
|
||||||
BY_HANDLE_FILE_INFORMATION fileInformation;
|
|
||||||
BOOL status;
|
|
||||||
HANDLE hFile;
|
|
||||||
|
|
||||||
if (!file || !output)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
hFile = CreateFileW(file->fullpath, 0, FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
|
||||||
goto out_fail;
|
|
||||||
status = GetFileInformationByHandle(hFile, &fileInformation);
|
|
||||||
CloseHandle(hFile);
|
|
||||||
if (!status)
|
|
||||||
goto out_fail;
|
|
||||||
|
|
||||||
switch (FsInformationClass)
|
switch (FsInformationClass)
|
||||||
{
|
{
|
||||||
case FileBasicInformation:
|
case FileBasicInformation:
|
||||||
|
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
|
/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
|
||||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 36))
|
if (!Stream_EnsureRemainingCapacity(output, 4 + 36))
|
||||||
goto out_fail;
|
return FALSE;
|
||||||
|
|
||||||
Stream_Write_UINT32(output, 36); /* Length */
|
Stream_Write_UINT32(output, 36); /* Length */
|
||||||
Stream_Write_UINT32(output,
|
Stream_Write_UINT32(output, info->ftCreationTime.dwLowDateTime); /* CreationTime */
|
||||||
fileInformation.ftCreationTime.dwLowDateTime); /* CreationTime */
|
Stream_Write_UINT32(output, info->ftCreationTime.dwHighDateTime); /* CreationTime */
|
||||||
Stream_Write_UINT32(output,
|
Stream_Write_UINT32(output, info->ftLastAccessTime.dwLowDateTime); /* LastAccessTime */
|
||||||
fileInformation.ftCreationTime.dwHighDateTime); /* CreationTime */
|
Stream_Write_UINT32(output, info->ftLastAccessTime.dwHighDateTime); /* LastAccessTime */
|
||||||
Stream_Write_UINT32(
|
Stream_Write_UINT32(output, info->ftLastWriteTime.dwLowDateTime); /* LastWriteTime */
|
||||||
output, fileInformation.ftLastAccessTime.dwLowDateTime); /* LastAccessTime */
|
Stream_Write_UINT32(output, info->ftLastWriteTime.dwHighDateTime); /* LastWriteTime */
|
||||||
Stream_Write_UINT32(
|
Stream_Write_UINT32(output, info->ftLastWriteTime.dwLowDateTime); /* ChangeTime */
|
||||||
output, fileInformation.ftLastAccessTime.dwHighDateTime); /* LastAccessTime */
|
Stream_Write_UINT32(output, info->ftLastWriteTime.dwHighDateTime); /* ChangeTime */
|
||||||
Stream_Write_UINT32(output,
|
Stream_Write_UINT32(output, info->dwFileAttributes); /* FileAttributes */
|
||||||
fileInformation.ftLastWriteTime.dwLowDateTime); /* LastWriteTime */
|
|
||||||
Stream_Write_UINT32(output,
|
|
||||||
fileInformation.ftLastWriteTime.dwHighDateTime); /* LastWriteTime */
|
|
||||||
Stream_Write_UINT32(output,
|
|
||||||
fileInformation.ftLastWriteTime.dwLowDateTime); /* ChangeTime */
|
|
||||||
Stream_Write_UINT32(output,
|
|
||||||
fileInformation.ftLastWriteTime.dwHighDateTime); /* ChangeTime */
|
|
||||||
Stream_Write_UINT32(output, fileInformation.dwFileAttributes); /* FileAttributes */
|
|
||||||
/* Reserved(4), MUST NOT be added! */
|
/* Reserved(4), MUST NOT be added! */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -512,16 +490,16 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
|||||||
|
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232088.aspx */
|
/* http://msdn.microsoft.com/en-us/library/cc232088.aspx */
|
||||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 22))
|
if (!Stream_EnsureRemainingCapacity(output, 4 + 22))
|
||||||
goto out_fail;
|
return FALSE;
|
||||||
|
|
||||||
Stream_Write_UINT32(output, 22); /* Length */
|
Stream_Write_UINT32(output, 22); /* Length */
|
||||||
Stream_Write_UINT32(output, fileInformation.nFileSizeLow); /* AllocationSize */
|
Stream_Write_UINT32(output, info->nFileSizeLow); /* AllocationSize */
|
||||||
Stream_Write_UINT32(output, fileInformation.nFileSizeHigh); /* AllocationSize */
|
Stream_Write_UINT32(output, info->nFileSizeHigh); /* AllocationSize */
|
||||||
Stream_Write_UINT32(output, fileInformation.nFileSizeLow); /* EndOfFile */
|
Stream_Write_UINT32(output, info->nFileSizeLow); /* EndOfFile */
|
||||||
Stream_Write_UINT32(output, fileInformation.nFileSizeHigh); /* EndOfFile */
|
Stream_Write_UINT32(output, info->nFileSizeHigh); /* EndOfFile */
|
||||||
Stream_Write_UINT32(output, fileInformation.nNumberOfLinks); /* NumberOfLinks */
|
Stream_Write_UINT32(output, info->nNumberOfLinks); /* NumberOfLinks */
|
||||||
Stream_Write_UINT8(output, file->delete_pending ? 1 : 0); /* DeletePending */
|
Stream_Write_UINT8(output, file->delete_pending ? 1 : 0); /* DeletePending */
|
||||||
Stream_Write_UINT8(output, fileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
|
Stream_Write_UINT8(output, info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
|
||||||
? TRUE
|
? TRUE
|
||||||
: FALSE); /* Directory */
|
: FALSE); /* Directory */
|
||||||
/* Reserved(2), MUST NOT be added! */
|
/* Reserved(2), MUST NOT be added! */
|
||||||
@ -531,18 +509,120 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
|||||||
|
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232093.aspx */
|
/* http://msdn.microsoft.com/en-us/library/cc232093.aspx */
|
||||||
if (!Stream_EnsureRemainingCapacity(output, 4 + 8))
|
if (!Stream_EnsureRemainingCapacity(output, 4 + 8))
|
||||||
goto out_fail;
|
return FALSE;
|
||||||
|
|
||||||
Stream_Write_UINT32(output, 8); /* Length */
|
Stream_Write_UINT32(output, 8); /* Length */
|
||||||
Stream_Write_UINT32(output, fileInformation.dwFileAttributes); /* FileAttributes */
|
Stream_Write_UINT32(output, info->dwFileAttributes); /* FileAttributes */
|
||||||
Stream_Write_UINT32(output, 0); /* ReparseTag */
|
Stream_Write_UINT32(output, 0); /* ReparseTag */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Unhandled FsInformationClass */
|
/* Unhandled FsInformationClass */
|
||||||
goto out_fail;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL drive_file_query_from_attributes(const DRIVE_FILE* file,
|
||||||
|
const WIN32_FILE_ATTRIBUTE_DATA* attrib,
|
||||||
|
UINT32 FsInformationClass, wStream* output)
|
||||||
|
{
|
||||||
|
switch (FsInformationClass)
|
||||||
|
{
|
||||||
|
case FileBasicInformation:
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
|
||||||
|
if (!Stream_EnsureRemainingCapacity(output, 4 + 36))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Stream_Write_UINT32(output, 36); /* Length */
|
||||||
|
Stream_Write_UINT32(output, attrib->ftCreationTime.dwLowDateTime); /* CreationTime */
|
||||||
|
Stream_Write_UINT32(output, attrib->ftCreationTime.dwHighDateTime); /* CreationTime */
|
||||||
|
Stream_Write_UINT32(output,
|
||||||
|
attrib->ftLastAccessTime.dwLowDateTime); /* LastAccessTime */
|
||||||
|
Stream_Write_UINT32(output,
|
||||||
|
attrib->ftLastAccessTime.dwHighDateTime); /* LastAccessTime */
|
||||||
|
Stream_Write_UINT32(output, attrib->ftLastWriteTime.dwLowDateTime); /* LastWriteTime */
|
||||||
|
Stream_Write_UINT32(output, attrib->ftLastWriteTime.dwHighDateTime); /* LastWriteTime */
|
||||||
|
Stream_Write_UINT32(output, attrib->ftLastWriteTime.dwLowDateTime); /* ChangeTime */
|
||||||
|
Stream_Write_UINT32(output, attrib->ftLastWriteTime.dwHighDateTime); /* ChangeTime */
|
||||||
|
Stream_Write_UINT32(output, attrib->dwFileAttributes); /* FileAttributes */
|
||||||
|
/* Reserved(4), MUST NOT be added! */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileStandardInformation:
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/cc232088.aspx */
|
||||||
|
if (!Stream_EnsureRemainingCapacity(output, 4 + 22))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Stream_Write_UINT32(output, 22); /* Length */
|
||||||
|
Stream_Write_UINT32(output, attrib->nFileSizeLow); /* AllocationSize */
|
||||||
|
Stream_Write_UINT32(output, attrib->nFileSizeHigh); /* AllocationSize */
|
||||||
|
Stream_Write_UINT32(output, attrib->nFileSizeLow); /* EndOfFile */
|
||||||
|
Stream_Write_UINT32(output, attrib->nFileSizeHigh); /* EndOfFile */
|
||||||
|
Stream_Write_UINT32(output, 0); /* NumberOfLinks */
|
||||||
|
Stream_Write_UINT8(output, file->delete_pending ? 1 : 0); /* DeletePending */
|
||||||
|
Stream_Write_UINT8(output, attrib->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
|
||||||
|
? TRUE
|
||||||
|
: FALSE); /* Directory */
|
||||||
|
/* Reserved(2), MUST NOT be added! */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileAttributeTagInformation:
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/cc232093.aspx */
|
||||||
|
if (!Stream_EnsureRemainingCapacity(output, 4 + 8))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Stream_Write_UINT32(output, 8); /* Length */
|
||||||
|
Stream_Write_UINT32(output, attrib->dwFileAttributes); /* FileAttributes */
|
||||||
|
Stream_Write_UINT32(output, 0); /* ReparseTag */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Unhandled FsInformationClass */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, wStream* output)
|
||||||
|
{
|
||||||
|
BY_HANDLE_FILE_INFORMATION fileInformation = { 0 };
|
||||||
|
BOOL status;
|
||||||
|
HANDLE hFile;
|
||||||
|
|
||||||
|
if (!file || !output)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
hFile = CreateFileW(file->fullpath, 0, FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
status = GetFileInformationByHandle(hFile, &fileInformation);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
if (!status)
|
||||||
|
goto out_fail;
|
||||||
|
|
||||||
|
if (!drive_file_query_from_handle_information(file, &fileInformation, FsInformationClass,
|
||||||
|
output))
|
||||||
|
goto out_fail;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we failed before (i.e. if information for a drive is queried) fall back to
|
||||||
|
* GetFileAttributesExW */
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA fileAttributes = { 0 };
|
||||||
|
if (!GetFileAttributesExW(file->fullpath, GetFileExInfoStandard, &fileAttributes))
|
||||||
|
goto out_fail;
|
||||||
|
|
||||||
|
if (!drive_file_query_from_attributes(file, &fileAttributes, FsInformationClass, output))
|
||||||
|
goto out_fail;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
out_fail:
|
out_fail:
|
||||||
Stream_Write_UINT32(output, 0); /* Length */
|
Stream_Write_UINT32(output, 0); /* Length */
|
||||||
|
Loading…
Reference in New Issue
Block a user