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