* Moved clipboard utils to core library, fixes #6760 (cherry picked from commit4fb686d40f
) * Fixed compilation warnings in cliprdr_utils (cherry picked from commit8b7a086411
) * Fixed backport API mismatch * Added C++ guards to header (cherry picked from commit7626a2ce6a
)
This commit is contained in:
parent
f344d1d481
commit
26a83e6ccd
@ -173,198 +173,3 @@ UINT cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static UINT64 filetime_to_uint64(FILETIME value)
|
||||
{
|
||||
UINT64 converted = 0;
|
||||
converted |= (UINT32)value.dwHighDateTime;
|
||||
converted <<= 32;
|
||||
converted |= (UINT32)value.dwLowDateTime;
|
||||
return converted;
|
||||
}
|
||||
|
||||
static FILETIME uint64_to_filetime(UINT64 value)
|
||||
{
|
||||
FILETIME converted;
|
||||
converted.dwLowDateTime = (UINT32)(value >> 0);
|
||||
converted.dwHighDateTime = (UINT32)(value >> 32);
|
||||
return converted;
|
||||
}
|
||||
|
||||
#define CLIPRDR_FILEDESCRIPTOR_SIZE (4 + 32 + 4 + 16 + 8 + 8 + 520)
|
||||
|
||||
/**
|
||||
* Parse a packed file list.
|
||||
*
|
||||
* The resulting array must be freed with the `free()` function.
|
||||
*
|
||||
* @param [in] format_data packed `CLIPRDR_FILELIST` to parse.
|
||||
* @param [in] format_data_length length of `format_data` in bytes.
|
||||
* @param [out] file_descriptor_array parsed array of `FILEDESCRIPTOR` structs.
|
||||
* @param [out] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
*
|
||||
* @returns 0 on success, otherwise a Win32 error code.
|
||||
*/
|
||||
UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
FILEDESCRIPTORW** file_descriptor_array, UINT32* file_descriptor_count)
|
||||
{
|
||||
UINT result = NO_ERROR;
|
||||
UINT32 i;
|
||||
UINT32 count = 0;
|
||||
wStream* s = NULL;
|
||||
|
||||
if (!format_data || !file_descriptor_array || !file_descriptor_count)
|
||||
return ERROR_BAD_ARGUMENTS;
|
||||
|
||||
s = Stream_New((BYTE*)format_data, format_data_length);
|
||||
if (!s)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid packed file list");
|
||||
|
||||
result = ERROR_INCORRECT_SIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, count); /* cItems (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) / CLIPRDR_FILEDESCRIPTOR_SIZE < count)
|
||||
{
|
||||
WLog_ERR(TAG, "packed file list is too short: expected %" PRIuz ", have %" PRIuz,
|
||||
((size_t)count) * CLIPRDR_FILEDESCRIPTOR_SIZE, Stream_GetRemainingLength(s));
|
||||
|
||||
result = ERROR_INCORRECT_SIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*file_descriptor_count = count;
|
||||
*file_descriptor_array = calloc(count, sizeof(FILEDESCRIPTORW));
|
||||
if (!*file_descriptor_array)
|
||||
{
|
||||
result = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
int c;
|
||||
UINT64 lastWriteTime;
|
||||
FILEDESCRIPTORW* file = &((*file_descriptor_array)[i]);
|
||||
|
||||
Stream_Read_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
Stream_Seek(s, 32); /* reserved1 (32 bytes) */
|
||||
Stream_Read_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
Stream_Seek(s, 16); /* reserved2 (16 bytes) */
|
||||
Stream_Read_UINT64(s, lastWriteTime); /* lastWriteTime (8 bytes) */
|
||||
file->ftLastWriteTime = uint64_to_filetime(lastWriteTime);
|
||||
Stream_Read_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
Stream_Read_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
for (c = 0; c < 260; c++) /* cFileName (520 bytes) */
|
||||
Stream_Read_UINT16(s, file->cFileName[c]);
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) > 0)
|
||||
WLog_WARN(TAG, "packed file list has %" PRIuz " excess bytes",
|
||||
Stream_GetRemainingLength(s));
|
||||
out:
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define CLIPRDR_MAX_FILE_SIZE (2U * 1024 * 1024 * 1024)
|
||||
|
||||
/**
|
||||
* Serialize a packed file list.
|
||||
*
|
||||
* The resulting format data must be freed with the `free()` function.
|
||||
*
|
||||
* @param [in] file_descriptor_array array of `FILEDESCRIPTOR` structs to serialize.
|
||||
* @param [in] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
* @param [out] format_data serialized CLIPRDR_FILELIST.
|
||||
* @param [out] format_data_length length of `format_data` in bytes.
|
||||
*
|
||||
* @returns 0 on success, otherwise a Win32 error code.
|
||||
*/
|
||||
UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count, BYTE** format_data,
|
||||
UINT32* format_data_length)
|
||||
{
|
||||
return cliprdr_serialize_file_list_ex(CB_STREAM_FILECLIP_ENABLED, file_descriptor_array,
|
||||
file_descriptor_count, format_data, format_data_length);
|
||||
}
|
||||
|
||||
UINT cliprdr_serialize_file_list_ex(UINT32 flags, const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count, BYTE** format_data,
|
||||
UINT32* format_data_length)
|
||||
{
|
||||
UINT result = NO_ERROR;
|
||||
UINT32 i;
|
||||
wStream* s = NULL;
|
||||
|
||||
if (!file_descriptor_array || !format_data || !format_data_length)
|
||||
return ERROR_BAD_ARGUMENTS;
|
||||
|
||||
if ((flags & CB_STREAM_FILECLIP_ENABLED) == 0)
|
||||
{
|
||||
WLog_WARN(TAG, "No file clipboard support annouonced!");
|
||||
return ERROR_BAD_ARGUMENTS;
|
||||
}
|
||||
|
||||
s = Stream_New(NULL, 4 + file_descriptor_count * CLIPRDR_FILEDESCRIPTOR_SIZE);
|
||||
if (!s)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
Stream_Write_UINT32(s, file_descriptor_count); /* cItems (4 bytes) */
|
||||
|
||||
for (i = 0; i < file_descriptor_count; i++)
|
||||
{
|
||||
int c;
|
||||
UINT64 lastWriteTime;
|
||||
const FILEDESCRIPTORW* file = &file_descriptor_array[i];
|
||||
|
||||
/*
|
||||
* There is a known issue with Windows server getting stuck in
|
||||
* an infinite loop when downloading files that are larger than
|
||||
* 2 gigabytes. Do not allow clients to send such file lists.
|
||||
*
|
||||
* https://support.microsoft.com/en-us/help/2258090
|
||||
*/
|
||||
if ((flags & CB_HUGE_FILE_SUPPORT_ENABLED) == 0)
|
||||
{
|
||||
if ((file->nFileSizeHigh > 0) || (file->nFileSizeLow >= CLIPRDR_MAX_FILE_SIZE))
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr does not support files over 2 GB");
|
||||
result = ERROR_FILE_TOO_LARGE;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
Stream_Zero(s, 32); /* reserved1 (32 bytes) */
|
||||
Stream_Write_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
Stream_Zero(s, 16); /* reserved2 (16 bytes) */
|
||||
lastWriteTime = filetime_to_uint64(file->ftLastWriteTime);
|
||||
Stream_Write_UINT64(s, lastWriteTime); /* lastWriteTime (8 bytes) */
|
||||
Stream_Write_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
Stream_Write_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
for (c = 0; c < 260; c++) /* cFileName (520 bytes) */
|
||||
Stream_Write_UINT16(s, file->cFileName[c]);
|
||||
}
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
Stream_GetBuffer(s, *format_data);
|
||||
Stream_GetLength(s, *format_data_length);
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return result;
|
||||
|
||||
error:
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/cliprdr_utils.h>
|
||||
|
||||
#include <winpr/shell.h>
|
||||
|
||||
@ -93,17 +94,6 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
FREERDP_API UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
FILEDESCRIPTORW** file_descriptor_array,
|
||||
UINT32* file_descriptor_count);
|
||||
FREERDP_API UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count, BYTE** format_data,
|
||||
UINT32* format_data_length);
|
||||
FREERDP_API UINT cliprdr_serialize_file_list_ex(UINT32 flags,
|
||||
const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count,
|
||||
BYTE** format_data, UINT32* format_data_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
48
include/freerdp/utils/cliprdr_utils.h
Normal file
48
include/freerdp/utils/cliprdr_utils.h
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RDPDR utility functions
|
||||
*
|
||||
* Copyright 2022 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2022 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_UTILS_CLIPRDR_H
|
||||
#define FREERDP_UTILS_CLIPRDR_H
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/shell.h>
|
||||
#include <freerdp/api.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
FREERDP_API UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
FILEDESCRIPTORW** file_descriptor_array,
|
||||
UINT32* file_descriptor_count);
|
||||
FREERDP_API UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count, BYTE** format_data,
|
||||
UINT32* format_data_length);
|
||||
FREERDP_API UINT cliprdr_serialize_file_list_ex(UINT32 flags,
|
||||
const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count,
|
||||
BYTE** format_data, UINT32* format_data_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@ set(MODULE_PREFIX "FREERDP_UTILS")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
passphrase.c
|
||||
cliprdr_utils.c
|
||||
pcap.c
|
||||
profiler.c
|
||||
ringbuffer.c
|
||||
|
235
libfreerdp/utils/cliprdr_utils.c
Normal file
235
libfreerdp/utils/cliprdr_utils.c
Normal file
@ -0,0 +1,235 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Clipboard Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2022 Armin Novak <anovak@thincast.com
|
||||
* Copyright 2022 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/cliprdr_utils.h>
|
||||
#include <freerdp/channels/cliprdr.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#define TAG FREERDP_TAG("utils." CLIPRDR_SVC_CHANNEL_NAME)
|
||||
|
||||
#define CLIPRDR_FILEDESCRIPTOR_SIZE (4 + 32 + 4 + 16 + 8 + 8 + 520)
|
||||
#define CLIPRDR_MAX_FILE_SIZE (2U * 1024 * 1024 * 1024)
|
||||
|
||||
static UINT64 filetime_to_uint64(FILETIME value)
|
||||
{
|
||||
UINT64 converted = 0;
|
||||
converted |= (UINT32)value.dwHighDateTime;
|
||||
converted <<= 32;
|
||||
converted |= (UINT32)value.dwLowDateTime;
|
||||
return converted;
|
||||
}
|
||||
|
||||
static FILETIME uint64_to_filetime(UINT64 value)
|
||||
{
|
||||
FILETIME converted;
|
||||
converted.dwLowDateTime = (UINT32)(value >> 0);
|
||||
converted.dwHighDateTime = (UINT32)(value >> 32);
|
||||
return converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a packed file list.
|
||||
*
|
||||
* The resulting array must be freed with the `free()` function.
|
||||
*
|
||||
* @param [in] format_data packed `CLIPRDR_FILELIST` to parse.
|
||||
* @param [in] format_data_length length of `format_data` in bytes.
|
||||
* @param [out] file_descriptor_array parsed array of `FILEDESCRIPTOR` structs.
|
||||
* @param [out] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
*
|
||||
* @returns 0 on success, otherwise a Win32 error code.
|
||||
*/
|
||||
UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
FILEDESCRIPTORW** file_descriptor_array, UINT32* file_descriptor_count)
|
||||
{
|
||||
UINT result = NO_ERROR;
|
||||
UINT32 i;
|
||||
UINT32 count = 0;
|
||||
wStream sbuffer;
|
||||
wStream* s = &sbuffer;
|
||||
|
||||
if (!format_data || !file_descriptor_array || !file_descriptor_count)
|
||||
return ERROR_BAD_ARGUMENTS;
|
||||
|
||||
Stream_StaticInit(&sbuffer, format_data, format_data_length);
|
||||
if (!s)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid packed file list");
|
||||
|
||||
result = ERROR_INCORRECT_SIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, count); /* cItems (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) / CLIPRDR_FILEDESCRIPTOR_SIZE < count)
|
||||
{
|
||||
WLog_ERR(TAG, "packed file list is too short: expected %" PRIuz ", have %" PRIuz,
|
||||
((size_t)count) * CLIPRDR_FILEDESCRIPTOR_SIZE, Stream_GetRemainingLength(s));
|
||||
|
||||
result = ERROR_INCORRECT_SIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*file_descriptor_count = count;
|
||||
*file_descriptor_array = calloc(count, sizeof(FILEDESCRIPTORW));
|
||||
if (!*file_descriptor_array)
|
||||
{
|
||||
result = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
UINT64 tmp;
|
||||
FILEDESCRIPTORW* file = &((*file_descriptor_array)[i]);
|
||||
|
||||
Stream_Read_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
Stream_Read_UINT32(s, file->clsid.Data1);
|
||||
Stream_Read_UINT16(s, file->clsid.Data2);
|
||||
Stream_Read_UINT16(s, file->clsid.Data3);
|
||||
Stream_Read(s, &file->clsid.Data4, sizeof(file->clsid.Data4));
|
||||
Stream_Read_INT32(s, file->sizel.cx);
|
||||
Stream_Read_INT32(s, file->sizel.cy);
|
||||
Stream_Read_INT32(s, file->pointl.x);
|
||||
Stream_Read_INT32(s, file->pointl.y);
|
||||
Stream_Read_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
Stream_Read_UINT64(s, tmp); /* ftCreationTime (8 bytes) */
|
||||
file->ftCreationTime = uint64_to_filetime(tmp);
|
||||
Stream_Read_UINT64(s, tmp); /* ftLastAccessTime (8 bytes) */
|
||||
file->ftLastAccessTime = uint64_to_filetime(tmp);
|
||||
Stream_Read_UINT64(s, tmp); /* lastWriteTime (8 bytes) */
|
||||
file->ftLastWriteTime = uint64_to_filetime(tmp);
|
||||
Stream_Read_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
Stream_Read_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
Stream_Read_UTF16_String(s, file->cFileName,
|
||||
ARRAYSIZE(file->cFileName)); /* cFileName (520 bytes) */
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) > 0)
|
||||
WLog_WARN(TAG, "packed file list has %" PRIuz " excess bytes",
|
||||
Stream_GetRemainingLength(s));
|
||||
out:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize a packed file list.
|
||||
*
|
||||
* The resulting format data must be freed with the `free()` function.
|
||||
*
|
||||
* @param [in] file_descriptor_array array of `FILEDESCRIPTOR` structs to serialize.
|
||||
* @param [in] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
* @param [out] format_data serialized CLIPRDR_FILELIST.
|
||||
* @param [out] format_data_length length of `format_data` in bytes.
|
||||
*
|
||||
* @returns 0 on success, otherwise a Win32 error code.
|
||||
*/
|
||||
UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count, BYTE** format_data,
|
||||
UINT32* format_data_length)
|
||||
{
|
||||
return cliprdr_serialize_file_list_ex(CB_STREAM_FILECLIP_ENABLED, file_descriptor_array,
|
||||
file_descriptor_count, format_data, format_data_length);
|
||||
}
|
||||
|
||||
UINT cliprdr_serialize_file_list_ex(UINT32 flags, const FILEDESCRIPTORW* file_descriptor_array,
|
||||
UINT32 file_descriptor_count, BYTE** format_data,
|
||||
UINT32* format_data_length)
|
||||
{
|
||||
UINT result = NO_ERROR;
|
||||
UINT32 i;
|
||||
size_t len;
|
||||
wStream* s = NULL;
|
||||
|
||||
if (!file_descriptor_array || !format_data || !format_data_length)
|
||||
return ERROR_BAD_ARGUMENTS;
|
||||
|
||||
if ((flags & CB_STREAM_FILECLIP_ENABLED) == 0)
|
||||
{
|
||||
WLog_WARN(TAG, "No file clipboard support annouonced!");
|
||||
return ERROR_BAD_ARGUMENTS;
|
||||
}
|
||||
|
||||
s = Stream_New(NULL, 4 + file_descriptor_count * CLIPRDR_FILEDESCRIPTOR_SIZE);
|
||||
if (!s)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
Stream_Write_UINT32(s, file_descriptor_count); /* cItems (4 bytes) */
|
||||
|
||||
for (i = 0; i < file_descriptor_count; i++)
|
||||
{
|
||||
int c;
|
||||
UINT64 lastWriteTime;
|
||||
const FILEDESCRIPTORW* file = &file_descriptor_array[i];
|
||||
|
||||
/*
|
||||
* There is a known issue with Windows server getting stuck in
|
||||
* an infinite loop when downloading files that are larger than
|
||||
* 2 gigabytes. Do not allow clients to send such file lists.
|
||||
*
|
||||
* https://support.microsoft.com/en-us/help/2258090
|
||||
*/
|
||||
if ((flags & CB_HUGE_FILE_SUPPORT_ENABLED) == 0)
|
||||
{
|
||||
if ((file->nFileSizeHigh > 0) || (file->nFileSizeLow >= CLIPRDR_MAX_FILE_SIZE))
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr does not support files over 2 GB");
|
||||
result = ERROR_FILE_TOO_LARGE;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
Stream_Zero(s, 32); /* reserved1 (32 bytes) */
|
||||
Stream_Write_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
Stream_Zero(s, 16); /* reserved2 (16 bytes) */
|
||||
lastWriteTime = filetime_to_uint64(file->ftLastWriteTime);
|
||||
Stream_Write_UINT64(s, lastWriteTime); /* lastWriteTime (8 bytes) */
|
||||
Stream_Write_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
Stream_Write_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
for (c = 0; c < 260; c++) /* cFileName (520 bytes) */
|
||||
Stream_Write_UINT16(s, file->cFileName[c]);
|
||||
}
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
Stream_GetBuffer(s, *format_data);
|
||||
Stream_GetLength(s, len);
|
||||
if (len > UINT32_MAX)
|
||||
goto error;
|
||||
|
||||
*format_data_length = (UINT32)len;
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return result;
|
||||
|
||||
error:
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue
Block a user