mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
[channels,drive] encapsulate drive information processing
This commit is contained in:
parent
8978c9cefe
commit
0a854001f7
@ -628,232 +628,259 @@ 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 };
|
const uint32_t expect = 36;
|
||||||
ULARGE_INTEGER liLastWriteTime = { 0 };
|
if (Length != expect)
|
||||||
ULARGE_INTEGER liChangeTime = { 0 };
|
{
|
||||||
FILETIME ftCreationTime;
|
WLog_WARN(TAG, "Unexpected Length=%" PRIu32 ", expected %" PRIu32, Length, expect);
|
||||||
FILETIME ftLastAccessTime;
|
return FALSE;
|
||||||
FILETIME ftLastWriteTime;
|
}
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (file->file_handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
char fullpath[MAX_PATH] = { 0 };
|
||||||
|
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath) - 1);
|
||||||
|
|
||||||
|
WLog_ERR(TAG, "Unable to set file time %s (%" PRId32 ")", fullpath, GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILETIME ftCreationTime = { 0 };
|
||||||
|
FILETIME ftLastAccessTime = { 0 };
|
||||||
|
FILETIME ftLastWriteTime = { 0 };
|
||||||
FILETIME* pftCreationTime = NULL;
|
FILETIME* pftCreationTime = NULL;
|
||||||
FILETIME* pftLastAccessTime = NULL;
|
FILETIME* pftLastAccessTime = NULL;
|
||||||
FILETIME* pftLastWriteTime = NULL;
|
FILETIME* pftLastWriteTime = NULL;
|
||||||
UINT32 FileAttributes = 0;
|
if (liCreationTime.QuadPart != 0)
|
||||||
UINT32 FileNameLength = 0;
|
{
|
||||||
LARGE_INTEGER liSize = { 0 };
|
ftCreationTime.dwHighDateTime = liCreationTime.u.HighPart;
|
||||||
UINT8 delete_pending = 0;
|
ftCreationTime.dwLowDateTime = liCreationTime.u.LowPart;
|
||||||
UINT8 ReplaceIfExists = 0;
|
pftCreationTime = &ftCreationTime;
|
||||||
DWORD attr = 0;
|
}
|
||||||
|
|
||||||
|
if (liLastAccessTime.QuadPart != 0)
|
||||||
|
{
|
||||||
|
ftLastAccessTime.dwHighDateTime = liLastAccessTime.u.HighPart;
|
||||||
|
ftLastAccessTime.dwLowDateTime = liLastAccessTime.u.LowPart;
|
||||||
|
pftLastAccessTime = &ftLastAccessTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (liLastWriteTime.QuadPart != 0)
|
||||||
|
{
|
||||||
|
ftLastWriteTime.dwHighDateTime = liLastWriteTime.u.HighPart;
|
||||||
|
ftLastWriteTime.dwLowDateTime = liLastWriteTime.u.LowPart;
|
||||||
|
pftLastWriteTime = &ftLastWriteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (liChangeTime.QuadPart != 0 && liChangeTime.QuadPart > liLastWriteTime.QuadPart)
|
||||||
|
{
|
||||||
|
ftLastWriteTime.dwHighDateTime = liChangeTime.u.HighPart;
|
||||||
|
ftLastWriteTime.dwLowDateTime = liChangeTime.u.LowPart;
|
||||||
|
pftLastWriteTime = &ftLastWriteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_WSTR("SetFileTime %s", file->fullpath);
|
||||||
|
|
||||||
|
if (!SetFileAttributesW(file->fullpath, FileAttributes))
|
||||||
|
{
|
||||||
|
char fullpath[MAX_PATH] = { 0 };
|
||||||
|
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
||||||
|
WLog_ERR(TAG, "Unable to set file attributes for %s", fullpath);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
const int64_t size = Stream_Get_INT64(input);
|
||||||
|
|
||||||
|
if (file->file_handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
char fullpath[MAX_PATH] = { 0 };
|
||||||
|
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
||||||
|
WLog_ERR(TAG, "Unable to truncate %s to %" PRId64 " (%" PRId32 ")", fullpath, size,
|
||||||
|
GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LARGE_INTEGER liSize = { .QuadPart = size };
|
||||||
|
|
||||||
|
if (!SetFilePointerEx(file->file_handle, liSize, NULL, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
char fullpath[MAX_PATH] = { 0 };
|
||||||
|
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
||||||
|
WLog_ERR(TAG, "Unable to truncate %s to %" PRId64 " (%" PRId32 ")", fullpath, size,
|
||||||
|
GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_WSTR("Truncate %s", file->fullpath);
|
||||||
|
|
||||||
|
if (SetEndOfFile(file->file_handle) == 0)
|
||||||
|
{
|
||||||
|
char fullpath[MAX_PATH] = { 0 };
|
||||||
|
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
||||||
|
WLog_ERR(TAG, "Unable to truncate %s to %" PRId64 " (%" PRId32 ")", fullpath, size,
|
||||||
|
GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_DIR_NOT_EMPTY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length)
|
||||||
|
{
|
||||||
|
const uint32_t expect = 1;
|
||||||
|
if (Length != expect)
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "Unexpected Length=%" PRIu32 ", expected %" PRIu32, Length, expect);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_pending = Stream_Get_UINT8(input);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delete_pending = 1;
|
||||||
|
|
||||||
|
if (delete_pending)
|
||||||
|
{
|
||||||
|
DEBUG_WSTR("SetDeletePending %s", file->fullpath);
|
||||||
|
const uint32_t attr = GetFileAttributesW(file->fullpath);
|
||||||
|
|
||||||
|
if (attr & FILE_ATTRIBUTE_READONLY)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file->delete_pending = delete_pending;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "Unexpected Length=%" PRIu32 ", expected %" PRIu32, Length, expect);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
|
||||||
|
const uint8_t ReplaceIfExists = Stream_Get_UINT8(input);
|
||||||
|
Stream_Seek_UINT8(input); /* RootDirectory */
|
||||||
|
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));
|
||||||
|
|
||||||
|
if (!fullpath)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
if (file->file_handle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
(void)CloseHandle(file->file_handle);
|
||||||
|
file->file_handle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
DEBUG_WSTR("MoveFileExW %s", file->fullpath);
|
||||||
|
|
||||||
|
if (MoveFileExW(file->fullpath, fullpath,
|
||||||
|
MOVEFILE_COPY_ALLOWED | (ReplaceIfExists ? MOVEFILE_REPLACE_EXISTING : 0)))
|
||||||
|
{
|
||||||
|
const BOOL rc = drive_file_set_fullpath(file, fullpath);
|
||||||
|
free(fullpath);
|
||||||
|
if (!rc)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(fullpath);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
drive_file_init(file);
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
|
||||||
|
wStream* input)
|
||||||
|
{
|
||||||
if (!file || !input)
|
if (!file || !input)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (!Stream_CheckAndLogRequiredLength(TAG, input, Length))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
switch (FsInformationClass)
|
switch (FsInformationClass)
|
||||||
{
|
{
|
||||||
case FileBasicInformation:
|
case FileBasicInformation:
|
||||||
if (!Stream_CheckAndLogRequiredLength(TAG, input, 36))
|
return drive_file_set_basic_information(file, Length, input);
|
||||||
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);
|
|
||||||
|
|
||||||
if (!PathFileExistsW(file->fullpath))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (file->file_handle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
char fullpath[MAX_PATH] = { 0 };
|
|
||||||
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath) - 1);
|
|
||||||
|
|
||||||
WLog_ERR(TAG, "Unable to set file time %s (%" PRId32 ")", fullpath, GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (liCreationTime.QuadPart != 0)
|
|
||||||
{
|
|
||||||
ftCreationTime.dwHighDateTime = liCreationTime.u.HighPart;
|
|
||||||
ftCreationTime.dwLowDateTime = liCreationTime.u.LowPart;
|
|
||||||
pftCreationTime = &ftCreationTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (liLastAccessTime.QuadPart != 0)
|
|
||||||
{
|
|
||||||
ftLastAccessTime.dwHighDateTime = liLastAccessTime.u.HighPart;
|
|
||||||
ftLastAccessTime.dwLowDateTime = liLastAccessTime.u.LowPart;
|
|
||||||
pftLastAccessTime = &ftLastAccessTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (liLastWriteTime.QuadPart != 0)
|
|
||||||
{
|
|
||||||
ftLastWriteTime.dwHighDateTime = liLastWriteTime.u.HighPart;
|
|
||||||
ftLastWriteTime.dwLowDateTime = liLastWriteTime.u.LowPart;
|
|
||||||
pftLastWriteTime = &ftLastWriteTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (liChangeTime.QuadPart != 0 && liChangeTime.QuadPart > liLastWriteTime.QuadPart)
|
|
||||||
{
|
|
||||||
ftLastWriteTime.dwHighDateTime = liChangeTime.u.HighPart;
|
|
||||||
ftLastWriteTime.dwLowDateTime = liChangeTime.u.LowPart;
|
|
||||||
pftLastWriteTime = &ftLastWriteTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_WSTR("SetFileTime %s", file->fullpath);
|
|
||||||
|
|
||||||
if (!SetFileAttributesW(file->fullpath, FileAttributes))
|
|
||||||
{
|
|
||||||
char fullpath[MAX_PATH] = { 0 };
|
|
||||||
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
|
||||||
WLog_ERR(TAG, "Unable to set file attributes for %s", fullpath);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FileEndOfFileInformation:
|
case FileEndOfFileInformation:
|
||||||
|
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
|
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
|
||||||
case FileAllocationInformation:
|
case FileAllocationInformation:
|
||||||
if (!Stream_CheckAndLogRequiredLength(TAG, input, 8))
|
return drive_file_set_alloc_information(file, Length, input);
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
|
|
||||||
Stream_Read_INT64(input, size);
|
|
||||||
|
|
||||||
if (file->file_handle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
char fullpath[MAX_PATH] = { 0 };
|
|
||||||
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
|
||||||
WLog_ERR(TAG, "Unable to truncate %s to %" PRId64 " (%" PRId32 ")", fullpath, size,
|
|
||||||
GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
liSize.QuadPart = size;
|
|
||||||
|
|
||||||
if (!SetFilePointerEx(file->file_handle, liSize, NULL, FILE_BEGIN))
|
|
||||||
{
|
|
||||||
char fullpath[MAX_PATH] = { 0 };
|
|
||||||
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
|
||||||
WLog_ERR(TAG, "Unable to truncate %s to %" PRId64 " (%" PRId32 ")", fullpath, size,
|
|
||||||
GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_WSTR("Truncate %s", file->fullpath);
|
|
||||||
|
|
||||||
if (SetEndOfFile(file->file_handle) == 0)
|
|
||||||
{
|
|
||||||
char fullpath[MAX_PATH] = { 0 };
|
|
||||||
(void)ConvertWCharToUtf8(file->fullpath, fullpath, sizeof(fullpath));
|
|
||||||
WLog_ERR(TAG, "Unable to truncate %s to %" PRId64 " (%" PRId32 ")", fullpath, size,
|
|
||||||
GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FileDispositionInformation:
|
case FileDispositionInformation:
|
||||||
|
return drive_file_set_disposition_information(file, Length, input);
|
||||||
/* 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))
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_DIR_NOT_EMPTY);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Length)
|
|
||||||
{
|
|
||||||
if (!Stream_CheckAndLogRequiredLength(TAG, input, 1))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
Stream_Read_UINT8(input, delete_pending);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete_pending = 1;
|
|
||||||
|
|
||||||
if (delete_pending)
|
|
||||||
{
|
|
||||||
DEBUG_WSTR("SetDeletePending %s", file->fullpath);
|
|
||||||
attr = GetFileAttributesW(file->fullpath);
|
|
||||||
|
|
||||||
if (attr & FILE_ATTRIBUTE_READONLY)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_ACCESS_DENIED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file->delete_pending = delete_pending;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FileRenameInformation:
|
case FileRenameInformation:
|
||||||
{
|
return drive_file_set_rename_information(file, Length, input);
|
||||||
if (!Stream_CheckAndLogRequiredLength(TAG, input, 6))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
|
|
||||||
Stream_Read_UINT8(input, ReplaceIfExists);
|
|
||||||
Stream_Seek_UINT8(input); /* RootDirectory */
|
|
||||||
Stream_Read_UINT32(input, FileNameLength);
|
|
||||||
|
|
||||||
if (!Stream_CheckAndLogRequiredLength(TAG, input, FileNameLength))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
WCHAR* fullpath = drive_file_combine_fullpath(
|
|
||||||
file->basepath, Stream_ConstPointer(input), FileNameLength / sizeof(WCHAR));
|
|
||||||
|
|
||||||
if (!fullpath)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
if (file->file_handle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
(void)CloseHandle(file->file_handle);
|
|
||||||
file->file_handle = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
DEBUG_WSTR("MoveFileExW %s", file->fullpath);
|
|
||||||
|
|
||||||
if (MoveFileExW(file->fullpath, fullpath,
|
|
||||||
MOVEFILE_COPY_ALLOWED |
|
|
||||||
(ReplaceIfExists ? MOVEFILE_REPLACE_EXISTING : 0)))
|
|
||||||
{
|
|
||||||
const BOOL rc = drive_file_set_fullpath(file, fullpath);
|
|
||||||
free(fullpath);
|
|
||||||
if (!rc)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free(fullpath);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
drive_file_init(file);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WLog_WARN(TAG, "Unhandled FSInformationClass %s [0x%08" PRIx32 "]",
|
WLog_WARN(TAG, "Unhandled FSInformationClass %s [0x%08" PRIx32 "]",
|
||||||
|
Loading…
Reference in New Issue
Block a user