[channels,drive] encapsulate drive information processing

This commit is contained in:
akallabeth 2025-06-02 11:02:10 +02:00
parent 8978c9cefe
commit 0a854001f7

View File

@ -628,42 +628,23 @@ out_fail:
return FALSE;
}
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
wStream* input)
static BOOL drive_file_set_basic_information(DRIVE_FILE* file, UINT32 Length, wStream* input)
{
INT64 size = 0;
ULARGE_INTEGER liCreationTime = { 0 };
ULARGE_INTEGER liLastAccessTime = { 0 };
ULARGE_INTEGER liLastWriteTime = { 0 };
ULARGE_INTEGER liChangeTime = { 0 };
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
FILETIME* pftCreationTime = NULL;
FILETIME* pftLastAccessTime = NULL;
FILETIME* pftLastWriteTime = NULL;
UINT32 FileAttributes = 0;
UINT32 FileNameLength = 0;
LARGE_INTEGER liSize = { 0 };
UINT8 delete_pending = 0;
UINT8 ReplaceIfExists = 0;
DWORD attr = 0;
WINPR_ASSERT(file);
if (!file || !input)
return FALSE;
switch (FsInformationClass)
const uint32_t expect = 36;
if (Length != expect)
{
case FileBasicInformation:
if (!Stream_CheckAndLogRequiredLength(TAG, input, 36))
WLog_WARN(TAG, "Unexpected Length=%" PRIu32 ", expected %" PRIu32, Length, expect);
return FALSE;
}
/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
Stream_Read_UINT64(input, liCreationTime.QuadPart);
Stream_Read_UINT64(input, liLastAccessTime.QuadPart);
Stream_Read_UINT64(input, liLastWriteTime.QuadPart);
Stream_Read_UINT64(input, liChangeTime.QuadPart);
Stream_Read_UINT32(input, FileAttributes);
const ULARGE_INTEGER liCreationTime = { .QuadPart = Stream_Get_UINT64(input) };
const ULARGE_INTEGER liLastAccessTime = { .QuadPart = Stream_Get_UINT64(input) };
const ULARGE_INTEGER liLastWriteTime = { .QuadPart = Stream_Get_UINT64(input) };
const ULARGE_INTEGER liChangeTime = { .QuadPart = Stream_Get_UINT64(input) };
const uint32_t FileAttributes = Stream_Get_UINT32(input);
if (!PathFileExistsW(file->fullpath))
return FALSE;
@ -677,6 +658,12 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
return FALSE;
}
FILETIME ftCreationTime = { 0 };
FILETIME ftLastAccessTime = { 0 };
FILETIME ftLastWriteTime = { 0 };
FILETIME* pftCreationTime = NULL;
FILETIME* pftLastAccessTime = NULL;
FILETIME* pftLastWriteTime = NULL;
if (liCreationTime.QuadPart != 0)
{
ftCreationTime.dwHighDateTime = liCreationTime.u.HighPart;
@ -715,26 +702,28 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
return FALSE;
}
if (!SetFileTime(file->file_handle, pftCreationTime, pftLastAccessTime,
pftLastWriteTime))
if (!SetFileTime(file->file_handle, pftCreationTime, pftLastAccessTime, pftLastWriteTime))
{
char fullpath[MAX_PATH] = { 0 };
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
WLog_ERR(TAG, "Unable to set file time for %s", fullpath);
return FALSE;
}
return TRUE;
}
break;
case FileEndOfFileInformation:
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
case FileAllocationInformation:
if (!Stream_CheckAndLogRequiredLength(TAG, input, 8))
static BOOL drive_file_set_alloc_information(DRIVE_FILE* file, UINT32 Length, wStream* input)
{
WINPR_ASSERT(file);
const uint32_t expect = 8;
if (Length != expect)
{
WLog_WARN(TAG, "Unexpected Length=%" PRIu32 ", expected %" PRIu32, Length, expect);
return FALSE;
}
/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
Stream_Read_INT64(input, size);
const int64_t size = Stream_Get_INT64(input);
if (file->file_handle == INVALID_HANDLE_VALUE)
{
@ -745,7 +734,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
return FALSE;
}
liSize.QuadPart = size;
LARGE_INTEGER liSize = { .QuadPart = size };
if (!SetFilePointerEx(file->file_handle, liSize, NULL, FILE_BEGIN))
{
@ -767,10 +756,13 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
return FALSE;
}
break;
case FileDispositionInformation:
return TRUE;
}
static BOOL drive_file_set_disposition_information(DRIVE_FILE* file, UINT32 Length, wStream* input)
{
WINPR_ASSERT(file);
uint8_t delete_pending = 0;
/* http://msdn.microsoft.com/en-us/library/cc232098.aspx */
/* http://msdn.microsoft.com/en-us/library/cc241371.aspx */
if (file->is_dir && !PathIsDirectoryEmptyW(file->fullpath))
@ -781,10 +773,14 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
if (Length)
{
if (!Stream_CheckAndLogRequiredLength(TAG, input, 1))
const uint32_t expect = 1;
if (Length != expect)
{
WLog_WARN(TAG, "Unexpected Length=%" PRIu32 ", expected %" PRIu32, Length, expect);
return FALSE;
}
Stream_Read_UINT8(input, delete_pending);
delete_pending = Stream_Get_UINT8(input);
}
else
delete_pending = 1;
@ -792,7 +788,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
if (delete_pending)
{
DEBUG_WSTR("SetDeletePending %s", file->fullpath);
attr = GetFileAttributesW(file->fullpath);
const uint32_t attr = GetFileAttributesW(file->fullpath);
if (attr & FILE_ATTRIBUTE_READONLY)
{
@ -802,23 +798,30 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
}
file->delete_pending = delete_pending;
break;
return TRUE;
}
case FileRenameInformation:
static BOOL drive_file_set_rename_information(DRIVE_FILE* file, UINT32 Length, wStream* input)
{
WINPR_ASSERT(file);
const uint32_t expect = 6;
if (Length != expect)
{
if (!Stream_CheckAndLogRequiredLength(TAG, input, 6))
WLog_WARN(TAG, "Unexpected Length=%" PRIu32 ", expected %" PRIu32, Length, expect);
return FALSE;
}
/* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
Stream_Read_UINT8(input, ReplaceIfExists);
const uint8_t ReplaceIfExists = Stream_Get_UINT8(input);
Stream_Seek_UINT8(input); /* RootDirectory */
Stream_Read_UINT32(input, FileNameLength);
const uint32_t FileNameLength = Stream_Get_UINT32(input);
if (!Stream_CheckAndLogRequiredLength(TAG, input, FileNameLength))
return FALSE;
WCHAR* fullpath = drive_file_combine_fullpath(
file->basepath, Stream_ConstPointer(input), FileNameLength / sizeof(WCHAR));
WCHAR* fullpath = drive_file_combine_fullpath(file->basepath, Stream_ConstPointer(input),
FileNameLength / sizeof(WCHAR));
if (!fullpath)
return FALSE;
@ -835,8 +838,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
DEBUG_WSTR("MoveFileExW %s", file->fullpath);
if (MoveFileExW(file->fullpath, fullpath,
MOVEFILE_COPY_ALLOWED |
(ReplaceIfExists ? MOVEFILE_REPLACE_EXISTING : 0)))
MOVEFILE_COPY_ALLOWED | (ReplaceIfExists ? MOVEFILE_REPLACE_EXISTING : 0)))
{
const BOOL rc = drive_file_set_fullpath(file, fullpath);
free(fullpath);
@ -852,8 +854,33 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
#ifdef _WIN32
drive_file_init(file);
#endif
}
break;
return TRUE;
}
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
wStream* input)
{
if (!file || !input)
return FALSE;
if (!Stream_CheckAndLogRequiredLength(TAG, input, Length))
return FALSE;
switch (FsInformationClass)
{
case FileBasicInformation:
return drive_file_set_basic_information(file, Length, input);
case FileEndOfFileInformation:
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
case FileAllocationInformation:
return drive_file_set_alloc_information(file, Length, input);
case FileDispositionInformation:
return drive_file_set_disposition_information(file, Length, input);
case FileRenameInformation:
return drive_file_set_rename_information(file, Length, input);
default:
WLog_WARN(TAG, "Unhandled FSInformationClass %s [0x%08" PRIx32 "]",