Merge branch 'egfx' of github.com:awakecoding/FreeRDP into shadow

This commit is contained in:
Marc-André Moreau 2014-09-13 12:04:02 -04:00
commit b7351e0795
142 changed files with 5543 additions and 5293 deletions

View File

@ -30,12 +30,15 @@
#include <winpr/print.h>
#include <freerdp/types.h>
#include <freerdp/channels/log.h>
#include <freerdp/constants.h>
#include <freerdp/client/cliprdr.h>
#include "cliprdr_main.h"
#include "cliprdr_format.h"
#define TAG CHANNELS_TAG("cliprdr.client")
#ifdef WITH_DEBUG_CLIPRDR
static const char* const CB_MSG_TYPE_STRINGS[] =
{
@ -65,13 +68,11 @@ CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr)
wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen)
{
wStream* s;
s = Stream_New(NULL, dataLen + 8);
Stream_Write_UINT16(s, msgType);
Stream_Write_UINT16(s, msgFlags);
/* Write actual length after the entire packet has been constructed. */
Stream_Seek(s, 4);
return s;
}
@ -79,18 +80,15 @@ void cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s)
{
int pos;
UINT32 dataLen;
pos = Stream_GetPosition(s);
dataLen = pos - 8;
Stream_SetPosition(s, 4);
Stream_Write_UINT32(s, dataLen);
Stream_SetPosition(s, pos);
#ifdef WITH_DEBUG_CLIPRDR
CLOG_DBG("Cliprdr Sending (%d bytes)\n", dataLen + 8);
winpr_HexDump(Stream_Buffer(s), dataLen + 8);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8);
#endif
svc_plugin_send((rdpSvcPlugin*) cliprdr, s);
}
@ -101,18 +99,21 @@ static void cliprdr_process_connect(rdpSvcPlugin* plugin)
void cliprdr_print_general_capability_flags(UINT32 flags)
{
CLOG_ERR( "generalFlags (0x%08X) {\n", flags);
CLOG_ERR("generalFlags (0x%08X) {\n", flags);
if (flags & CB_USE_LONG_FORMAT_NAMES)
CLOG_ERR( "\tCB_USE_LONG_FORMAT_NAMES\n");
if (flags & CB_STREAM_FILECLIP_ENABLED)
CLOG_ERR( "\tCB_STREAM_FILECLIP_ENABLED\n");
if (flags & CB_FILECLIP_NO_FILE_PATHS)
CLOG_ERR( "\tCB_FILECLIP_NO_FILE_PATHS\n");
if (flags & CB_CAN_LOCK_CLIPDATA)
CLOG_ERR( "\tCB_CAN_LOCK_CLIPDATA\n");
CLOG_ERR("\tCB_USE_LONG_FORMAT_NAMES\n");
CLOG_ERR( "}\n");
if (flags & CB_STREAM_FILECLIP_ENABLED)
CLOG_ERR("\tCB_STREAM_FILECLIP_ENABLED\n");
if (flags & CB_FILECLIP_NO_FILE_PATHS)
CLOG_ERR("\tCB_FILECLIP_NO_FILE_PATHS\n");
if (flags & CB_CAN_LOCK_CLIPDATA)
CLOG_ERR("\tCB_CAN_LOCK_CLIPDATA\n");
CLOG_ERR("}\n");
}
static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s)
@ -120,14 +121,10 @@ static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream*
UINT32 version;
UINT32 generalFlags;
CliprdrClientContext* context;
context = cliprdr_get_client_interface(cliprdr);
Stream_Read_UINT32(s, version); /* version (4 bytes) */
Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */
DEBUG_CLIPRDR("Version: %d", version);
#ifdef WITH_DEBUG_CLIPRDR
cliprdr_print_general_capability_flags(generalFlags);
#endif
@ -150,13 +147,10 @@ static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream*
{
CLIPRDR_CAPABILITIES capabilities;
CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
capabilities.cCapabilitiesSets = 1;
capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet);
generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
generalCapabilitySet.capabilitySetLength = 12;
generalCapabilitySet.version = version;
generalCapabilitySet.generalFlags = generalFlags;
@ -166,10 +160,8 @@ static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream*
else
{
RDP_CB_CLIP_CAPS* caps_event;
caps_event = (RDP_CB_CLIP_CAPS*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_ClipCaps, NULL, NULL);
caps_event->capabilities = generalFlags;
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) caps_event);
}
}
@ -180,10 +172,8 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16
UINT16 lengthCapability;
UINT16 cCapabilitiesSets;
UINT16 capabilitySetType;
Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
Stream_Seek_UINT16(s); /* pad1 (2 bytes) */
DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets);
for (i = 0; i < cCapabilitiesSets; i++)
@ -196,7 +186,6 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16
case CB_CAPSTYPE_GENERAL:
cliprdr_process_general_capability(cliprdr, s);
break;
default:
CLOG_ERR("unknown cliprdr capability set: %d", capabilitySetType);
break;
@ -208,25 +197,20 @@ static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr)
{
wStream* s;
UINT32 flags;
s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);
DEBUG_CLIPRDR("Sending Capabilities");
flags = CB_USE_LONG_FORMAT_NAMES
#ifdef _WIN32
| CB_STREAM_FILECLIP_ENABLED
| CB_FILECLIP_NO_FILE_PATHS
#endif
;
;
Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */
Stream_Write_UINT16(s, 0); /* pad1 */
Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType */
Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */
Stream_Write_UINT32(s, CB_CAPS_VERSION_2); /* version */
Stream_Write_UINT32(s, flags); /* generalFlags */
cliprdr_packet_send(cliprdr, s);
}
@ -237,7 +221,6 @@ static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI
if (context->custom)
{
CLIPRDR_MONITOR_READY monitorReady;
monitorReady.msgType = CB_MONITOR_READY;
monitorReady.msgFlags = flags;
monitorReady.dataLen = length;
@ -253,7 +236,6 @@ static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI
cliprdr_send_clip_caps(cliprdr);
event = (RDP_CB_MONITOR_READY_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) event);
}
}
@ -261,10 +243,8 @@ static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI
static void cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_FILECONTENTS_REQUEST_EVENT* cb_event;
cb_event = (RDP_CB_FILECONTENTS_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FilecontentsRequest, NULL, NULL);
CliprdrChannel_FilecontentsRequest, NULL, NULL);
Stream_Read_UINT32(s, cb_event->streamId);
Stream_Read_UINT32(s, cb_event->lindex);
Stream_Read_UINT32(s, cb_event->dwFlags);
@ -272,17 +252,14 @@ static void cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream
Stream_Read_UINT32(s, cb_event->nPositionHigh);
Stream_Read_UINT32(s, cb_event->cbRequested);
//Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
static void cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_FILECONTENTS_RESPONSE_EVENT* cb_event;
cb_event = (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FilecontentsResponse, NULL, NULL);
CliprdrChannel_FilecontentsResponse, NULL, NULL);
Stream_Read_UINT32(s, cb_event->streamId);
if (length > 0)
@ -298,24 +275,18 @@ static void cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStrea
static void cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_LOCK_CLIPDATA_EVENT* cb_event;
cb_event = (RDP_CB_LOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_LockClipdata, NULL, NULL);
CliprdrChannel_LockClipdata, NULL, NULL);
Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
static void cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
RDP_CB_UNLOCK_CLIPDATA_EVENT* cb_event;
cb_event = (RDP_CB_UNLOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_UnLockClipdata, NULL, NULL);
CliprdrChannel_UnLockClipdata, NULL, NULL);
Stream_Read_UINT32(s, cb_event->clipDataId);
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
}
@ -325,16 +296,13 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
UINT16 msgFlags;
UINT32 dataLen;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) plugin;
Stream_Read_UINT16(s, msgType);
Stream_Read_UINT16(s, msgFlags);
Stream_Read_UINT32(s, dataLen);
DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d",
CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);
CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);
#ifdef WITH_DEBUG_CLIPRDR
winpr_HexDump(Stream_Buffer(s), dataLen + 8);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8);
#endif
switch (msgType)
@ -342,56 +310,44 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
case CB_CLIP_CAPS:
cliprdr_process_clip_caps(cliprdr, s, dataLen, msgFlags);
break;
case CB_MONITOR_READY:
cliprdr_process_monitor_ready(cliprdr, s, dataLen, msgFlags);
break;
case CB_FORMAT_LIST:
cliprdr_process_format_list(cliprdr, s, dataLen, msgFlags);
break;
case CB_FORMAT_LIST_RESPONSE:
cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags);
break;
case CB_FORMAT_DATA_REQUEST:
cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags);
break;
case CB_FORMAT_DATA_RESPONSE:
cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags);
break;
case CB_FILECONTENTS_REQUEST:
cliprdr_process_filecontents_request(cliprdr, s, dataLen, msgFlags);
break;
case CB_FILECONTENTS_RESPONSE:
cliprdr_process_filecontents_response(cliprdr, s, dataLen, msgFlags);
break;
case CB_LOCK_CLIPDATA:
cliprdr_process_lock_clipdata(cliprdr, s, dataLen, msgFlags);
break;
case CB_UNLOCK_CLIPDATA:
cliprdr_process_unlock_clipdata(cliprdr, s, dataLen, msgFlags);
break;
default:
CLOG_ERR("unknown msgType %d", msgType);
break;
}
}
static void cliprdr_process_filecontents_request_event(cliprdrPlugin* plugin, RDP_CB_FILECONTENTS_REQUEST_EVENT * event)
static void cliprdr_process_filecontents_request_event(cliprdrPlugin* plugin, RDP_CB_FILECONTENTS_REQUEST_EVENT* event)
{
wStream *s;
wStream* s;
DEBUG_CLIPRDR("Sending File Contents Request.");
s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 24);
Stream_Write_UINT32(s, event->streamId);
Stream_Write_UINT32(s, event->lindex);
Stream_Write_UINT32(s, event->dwFlags);
@ -399,14 +355,12 @@ static void cliprdr_process_filecontents_request_event(cliprdrPlugin* plugin, RD
Stream_Write_UINT32(s, event->nPositionHigh);
Stream_Write_UINT32(s, event->cbRequested);
//Stream_Write_UINT32(s, event->clipDataId);
cliprdr_packet_send(plugin, s);
}
static void cliprdr_process_filecontents_response_event(cliprdrPlugin* plugin, RDP_CB_FILECONTENTS_RESPONSE_EVENT * event)
static void cliprdr_process_filecontents_response_event(cliprdrPlugin* plugin, RDP_CB_FILECONTENTS_RESPONSE_EVENT* event)
{
wStream* s;
DEBUG_CLIPRDR("Sending file contents response with size = %d", event->size);
if (event->size > 0)
@ -423,39 +377,30 @@ static void cliprdr_process_filecontents_response_event(cliprdrPlugin* plugin, R
cliprdr_packet_send(plugin, s);
}
static void cliprdr_process_lock_clipdata_event(cliprdrPlugin* plugin, RDP_CB_LOCK_CLIPDATA_EVENT * event)
static void cliprdr_process_lock_clipdata_event(cliprdrPlugin* plugin, RDP_CB_LOCK_CLIPDATA_EVENT* event)
{
wStream* s;
DEBUG_CLIPRDR("Sending Lock Request");
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4);
Stream_Write_UINT32(s, event->clipDataId);
cliprdr_packet_send(plugin, s);
}
static void cliprdr_process_unlock_clipdata_event(cliprdrPlugin* plugin, RDP_CB_UNLOCK_CLIPDATA_EVENT * event)
static void cliprdr_process_unlock_clipdata_event(cliprdrPlugin* plugin, RDP_CB_UNLOCK_CLIPDATA_EVENT* event)
{
wStream* s;
DEBUG_CLIPRDR("Sending UnLock Request");
s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4);
Stream_Write_UINT32(s, event->clipDataId);
cliprdr_packet_send(plugin, s);
}
static void cliprdr_process_tempdir_event(cliprdrPlugin* plugin, RDP_CB_TEMPDIR_EVENT * event)
static void cliprdr_process_tempdir_event(cliprdrPlugin* plugin, RDP_CB_TEMPDIR_EVENT* event)
{
wStream* s;
DEBUG_CLIPRDR("Sending Temporary Directory.");
s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, 520);
Stream_Write(s, event->dirname, 520);
cliprdr_packet_send(plugin, s);
}
@ -466,35 +411,27 @@ static void cliprdr_process_event(rdpSvcPlugin* plugin, wMessage* event)
case CliprdrChannel_FormatList:
cliprdr_process_format_list_event((cliprdrPlugin*) plugin, (RDP_CB_FORMAT_LIST_EVENT*) event);
break;
case CliprdrChannel_DataRequest:
cliprdr_process_format_data_request_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_REQUEST_EVENT*) event);
break;
case CliprdrChannel_DataResponse:
cliprdr_process_format_data_response_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_RESPONSE_EVENT*) event);
break;
case CliprdrChannel_FilecontentsRequest:
cliprdr_process_filecontents_request_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_REQUEST_EVENT *) event);
cliprdr_process_filecontents_request_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_REQUEST_EVENT*) event);
break;
case CliprdrChannel_FilecontentsResponse:
cliprdr_process_filecontents_response_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_RESPONSE_EVENT *) event);
cliprdr_process_filecontents_response_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) event);
break;
case CliprdrChannel_LockClipdata:
cliprdr_process_lock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_LOCK_CLIPDATA_EVENT *) event);
cliprdr_process_lock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_LOCK_CLIPDATA_EVENT*) event);
break;
case CliprdrChannel_UnLockClipdata:
cliprdr_process_unlock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_UNLOCK_CLIPDATA_EVENT *) event);
cliprdr_process_unlock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_UNLOCK_CLIPDATA_EVENT*) event);
break;
case CliprdrChannel_TemporaryDirectory:
cliprdr_process_tempdir_event((cliprdrPlugin*) plugin, (RDP_CB_TEMPDIR_EVENT *) event);
cliprdr_process_tempdir_event((cliprdrPlugin*) plugin, (RDP_CB_TEMPDIR_EVENT*) event);
break;
default:
CLOG_ERR("unknown event type %d", GetMessageType(event->id));
break;
@ -518,21 +455,15 @@ int cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILIT
wStream* s;
CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);
Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */
Stream_Write_UINT16(s, 0); /* pad1 */
generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilities->capabilitySets;
Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetType); /* capabilitySetType */
Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetLength); /* lengthCapability */
Stream_Write_UINT32(s, generalCapabilitySet->version); /* version */
Stream_Write_UINT32(s, generalCapabilitySet->generalFlags); /* generalFlags */
cliprdr_packet_send(cliprdr, s);
return 0;
}
@ -548,9 +479,7 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
for (index = 0; index < formatList->cFormats; index++)
{
format = (CLIPRDR_FORMAT*) &(formatList->formats[index]);
length += 4;
formatNameSize = 2;
if (format->formatName)
@ -564,20 +493,16 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
for (index = 0; index < formatList->cFormats; index++)
{
format = (CLIPRDR_FORMAT*) &(formatList->formats[index]);
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
if (format->formatName)
{
int cchWideChar;
LPWSTR lpWideCharStr;
lpWideCharStr = (LPWSTR) Stream_Pointer(s);
cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2;
formatNameSize = MultiByteToWideChar(CP_UTF8, 0,
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
Stream_Seek(s, formatNameSize);
}
else
@ -587,7 +512,6 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
}
cliprdr_packet_send(cliprdr, s);
return 0;
}
@ -595,13 +519,10 @@ int cliprdr_client_format_list_response(CliprdrClientContext* context, CLIPRDR_F
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
formatListResponse->msgType = CB_FORMAT_LIST_RESPONSE;
formatListResponse->dataLen = 0;
s = cliprdr_packet_new(formatListResponse->msgType, formatListResponse->msgFlags, formatListResponse->dataLen);
cliprdr_packet_send(cliprdr, s);
return 0;
}
@ -609,16 +530,12 @@ int cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_FO
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
formatDataRequest->msgType = CB_FORMAT_DATA_REQUEST;
formatDataRequest->msgFlags = 0;
formatDataRequest->dataLen = 4;
s = cliprdr_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, formatDataRequest->dataLen);
Stream_Write_UINT32(s, formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */
cliprdr_packet_send(cliprdr, s);
return 0;
}
@ -626,14 +543,10 @@ int cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_F
{
wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
formatDataResponse->msgType = CB_FORMAT_DATA_RESPONSE;
s = cliprdr_packet_new(formatDataResponse->msgType, formatDataResponse->msgFlags, formatDataResponse->dataLen);
Stream_Write(s, formatDataResponse->requestedFormatData, formatDataResponse->dataLen);
cliprdr_packet_send(cliprdr, s);
return 0;
}
@ -645,41 +558,32 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
cliprdrPlugin* cliprdr;
CliprdrClientContext* context;
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin));
cliprdr->plugin.channel_def.options =
CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL;
CHANNEL_OPTION_INITIALIZED |
CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP |
CHANNEL_OPTION_SHOW_PROTOCOL;
strcpy(cliprdr->plugin.channel_def.name, "cliprdr");
cliprdr->plugin.connect_callback = cliprdr_process_connect;
cliprdr->plugin.receive_callback = cliprdr_process_receive;
cliprdr->plugin.event_callback = cliprdr_process_event;
cliprdr->plugin.terminate_callback = cliprdr_process_terminate;
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
{
context = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext));
context->handle = (void*) cliprdr;
context->ClientCapabilities = cliprdr_client_capabilities;
context->ClientFormatList = cliprdr_client_format_list;
context->ClientFormatListResponse = cliprdr_client_format_list_response;
context->ClientFormatDataRequest = cliprdr_client_format_data_request;
context->ClientFormatDataResponse = cliprdr_client_format_data_response;
*(pEntryPointsEx->ppInterface) = (void*) context;
}
svc_plugin_init((rdpSvcPlugin*) cliprdr, pEntryPoints);
return 1;
}

View File

@ -28,6 +28,8 @@
#include <freerdp/channels/log.h>
#include "rdpdr_main.h"
#define TAG "rdpdr.server"
static UINT32 g_ClientId = 0;
static int rdpdr_server_send_announce_request(RdpdrServerContext* context)
@ -36,27 +38,18 @@ static int rdpdr_server_send_announce_request(RdpdrServerContext* context)
BOOL status;
RDPDR_HEADER header;
ULONG written;
CLOG_DBG("RdpdrServerSendAnnounceRequest\n");
header.Component = RDPDR_CTYP_CORE;
header.PacketId = PAKID_CORE_SERVER_ANNOUNCE;
s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8);
Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
Stream_Write_UINT16(s, context->priv->VersionMajor); /* VersionMajor (2 bytes) */
Stream_Write_UINT16(s, context->priv->VersionMinor); /* VersionMinor (2 bytes) */
Stream_Write_UINT32(s, context->priv->ClientId); /* ClientId (4 bytes) */
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
return 0;
}
@ -65,16 +58,12 @@ static int rdpdr_server_receive_announce_response(RdpdrServerContext* context, w
UINT32 ClientId;
UINT16 VersionMajor;
UINT16 VersionMinor;
Stream_Read_UINT16(s, VersionMajor); /* VersionMajor (2 bytes) */
Stream_Read_UINT16(s, VersionMinor); /* VersionMinor (2 bytes) */
Stream_Read_UINT32(s, ClientId); /* ClientId (4 bytes) */
CLOG_DBG("Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X\n",
VersionMajor, VersionMinor, ClientId);
VersionMajor, VersionMinor, ClientId);
context->priv->ClientId = ClientId;
return 0;
}
@ -82,7 +71,6 @@ static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context,
{
UINT32 UnicodeFlag;
UINT32 ComputerNameLen;
Stream_Read_UINT32(s, UnicodeFlag); /* UnicodeFlag (4 bytes) */
Stream_Seek_UINT32(s); /* CodePage (4 bytes), MUST be set to zero */
Stream_Read_UINT32(s, ComputerNameLen); /* ComputerNameLen (4 bytes) */
@ -101,7 +89,7 @@ static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context,
if (UnicodeFlag)
{
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
-1, &(context->priv->ClientComputerName), 0, NULL, NULL);
-1, &(context->priv->ClientComputerName), 0, NULL, NULL);
}
else
{
@ -109,9 +97,7 @@ static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context,
}
Stream_Seek(s, ComputerNameLen);
CLOG_DBG("ClientComputerName: %s\n", context->priv->ClientComputerName);
return 0;
}
@ -139,7 +125,6 @@ static int rdpdr_server_read_general_capability_set(RdpdrServerContext* context,
UINT16 VersionMajor;
UINT16 VersionMinor;
UINT32 SpecialTypeDeviceCap;
Stream_Seek_UINT32(s); /* osType (4 bytes), ignored on receipt */
Stream_Seek_UINT32(s); /* osVersion (4 bytes), unused and must be set to zero */
Stream_Read_UINT16(s, VersionMajor); /* protocolMajorVersion (2 bytes) */
@ -150,9 +135,7 @@ static int rdpdr_server_read_general_capability_set(RdpdrServerContext* context,
Stream_Read_UINT32(s, extraFlags1); /* extraFlags1 (4 bytes) */
Stream_Seek_UINT32(s); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */
Stream_Read_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */
context->priv->UserLoggedOnPdu = (extendedPdu & RDPDR_USER_LOGGEDON_PDU) ? TRUE : FALSE;
return 0;
}
@ -163,11 +146,9 @@ static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context
UINT32 extraFlags1;
UINT32 SpecialTypeDeviceCap;
RDPDR_CAPABILITY_HEADER header;
header.CapabilityType = CAP_GENERAL_TYPE;
header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH + 36;
header.Version = GENERAL_CAPABILITY_VERSION_02;
ioCode1 = 0;
ioCode1 |= RDPDR_IRP_MJ_CREATE; /* always set */
ioCode1 |= RDPDR_IRP_MJ_CLEANUP; /* always set */
@ -185,7 +166,6 @@ static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context
ioCode1 |= RDPDR_IRP_MJ_LOCK_CONTROL; /* always set */
ioCode1 |= RDPDR_IRP_MJ_QUERY_SECURITY; /* optional */
ioCode1 |= RDPDR_IRP_MJ_SET_SECURITY; /* optional */
extendedPdu = 0;
extendedPdu |= RDPDR_CLIENT_DISPLAY_NAME_PDU; /* always set */
extendedPdu |= RDPDR_DEVICE_REMOVE_PDUS; /* optional */
@ -195,12 +175,9 @@ static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context
extraFlags1 = 0;
extraFlags1 |= ENABLE_ASYNCIO; /* optional */
SpecialTypeDeviceCap = 0;
Stream_EnsureRemainingCapacity(s, header.CapabilityLength);
rdpdr_server_write_capability_set_header(s, &header);
Stream_Write_UINT32(s, 0); /* osType (4 bytes), ignored on receipt */
Stream_Write_UINT32(s, 0); /* osVersion (4 bytes), unused and must be set to zero */
Stream_Write_UINT16(s, context->priv->VersionMajor); /* protocolMajorVersion (2 bytes) */
@ -211,7 +188,6 @@ static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context
Stream_Write_UINT32(s, extraFlags1); /* extraFlags1 (4 bytes) */
Stream_Write_UINT32(s, 0); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */
Stream_Write_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */
return 0;
}
@ -223,14 +199,11 @@ static int rdpdr_server_read_printer_capability_set(RdpdrServerContext* context,
static int rdpdr_server_write_printer_capability_set(RdpdrServerContext* context, wStream* s)
{
RDPDR_CAPABILITY_HEADER header;
header.CapabilityType = CAP_PRINTER_TYPE;
header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH;
header.Version = PRINT_CAPABILITY_VERSION_01;
Stream_EnsureRemainingCapacity(s, header.CapabilityLength);
rdpdr_server_write_capability_set_header(s, &header);
return 0;
}
@ -242,14 +215,11 @@ static int rdpdr_server_read_port_capability_set(RdpdrServerContext* context, wS
static int rdpdr_server_write_port_capability_set(RdpdrServerContext* context, wStream* s)
{
RDPDR_CAPABILITY_HEADER header;
header.CapabilityType = CAP_PORT_TYPE;
header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH;
header.Version = PORT_CAPABILITY_VERSION_01;
Stream_EnsureRemainingCapacity(s, header.CapabilityLength);
rdpdr_server_write_capability_set_header(s, &header);
return 0;
}
@ -261,14 +231,11 @@ static int rdpdr_server_read_drive_capability_set(RdpdrServerContext* context, w
static int rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, wStream* s)
{
RDPDR_CAPABILITY_HEADER header;
header.CapabilityType = CAP_DRIVE_TYPE;
header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH;
header.Version = DRIVE_CAPABILITY_VERSION_02;
Stream_EnsureRemainingCapacity(s, header.CapabilityLength);
rdpdr_server_write_capability_set_header(s, &header);
return 0;
}
@ -280,14 +247,11 @@ static int rdpdr_server_read_smartcard_capability_set(RdpdrServerContext* contex
static int rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* context, wStream* s)
{
RDPDR_CAPABILITY_HEADER header;
header.CapabilityType = CAP_SMARTCARD_TYPE;
header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH;
header.Version = SMARTCARD_CAPABILITY_VERSION_01;
Stream_EnsureRemainingCapacity(s, header.CapabilityLength);
rdpdr_server_write_capability_set_header(s, &header);
return 0;
}
@ -298,34 +262,23 @@ static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context
RDPDR_HEADER header;
UINT16 numCapabilities;
ULONG written;
CLOG_DBG("RdpdrServerSendCoreCapabilityRequest\n");
header.Component = RDPDR_CTYP_CORE;
header.PacketId = PAKID_CORE_SERVER_CAPABILITY;
numCapabilities = 5;
s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 512);
Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
Stream_Write_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */
Stream_Write_UINT16(s, 0); /* Padding (2 bytes) */
rdpdr_server_write_general_capability_set(context, s);
rdpdr_server_write_printer_capability_set(context, s);
rdpdr_server_write_port_capability_set(context, s);
rdpdr_server_write_drive_capability_set(context, s);
rdpdr_server_write_smartcard_capability_set(context, s);
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
return 0;
}
@ -334,7 +287,6 @@ static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* con
int i;
UINT16 numCapabilities;
RDPDR_CAPABILITY_HEADER capabilityHeader;
Stream_Read_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */
Stream_Seek_UINT16(s); /* Padding (2 bytes) */
@ -380,27 +332,18 @@ static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context)
BOOL status;
RDPDR_HEADER header;
ULONG written;
CLOG_DBG("RdpdrServerSendClientIdConfirm\n");
header.Component = RDPDR_CTYP_CORE;
header.PacketId = PAKID_CORE_CLIENTID_CONFIRM;
s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8);
Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
Stream_Write_UINT16(s, context->priv->VersionMajor); /* VersionMajor (2 bytes) */
Stream_Write_UINT16(s, context->priv->VersionMinor); /* VersionMinor (2 bytes) */
Stream_Write_UINT32(s, context->priv->ClientId); /* ClientId (4 bytes) */
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
return 0;
}
@ -412,11 +355,8 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext*
UINT32 DeviceId;
char PreferredDosName[9];
UINT32 DeviceDataLength;
PreferredDosName[8] = 0;
Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */
CLOG_DBG("%s: DeviceCount: %d\n", __FUNCTION__, DeviceCount);
for (i = 0; i < DeviceCount; i++)
@ -425,9 +365,8 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext*
Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
Stream_Read(s, PreferredDosName, 8); /* PreferredDosName (8 bytes) */
Stream_Read_UINT32(s, DeviceDataLength); /* DeviceDataLength (4 bytes) */
CLOG_DBG("Device %d Name: %s Id: 0x%04X DataLength: %d\n",
i, PreferredDosName, DeviceId, DeviceDataLength);
i, PreferredDosName, DeviceId, DeviceDataLength);
switch (DeviceId)
{
@ -462,32 +401,23 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context)
BOOL status;
RDPDR_HEADER header;
ULONG written;
CLOG_DBG("%s\n", __FUNCTION__);
header.Component = RDPDR_CTYP_CORE;
header.PacketId = PAKID_CORE_USER_LOGGEDON;
s = Stream_New(NULL, RDPDR_HEADER_LENGTH);
Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */
Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
Stream_SealLength(s);
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written);
Stream_Free(s, TRUE);
return 0;
}
static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header)
{
CLOG_DBG("RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X\n",
header->Component, header->PacketId);
winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
header->Component, header->PacketId);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), Stream_Length(s));
if (header->Component == RDPDR_CTYP_CORE)
{
@ -508,6 +438,7 @@ static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDP
if (context->priv->UserLoggedOnPdu)
rdpdr_server_send_user_logged_on(context);
break;
case PAKID_CORE_DEVICELIST_ANNOUNCE:
@ -565,13 +496,10 @@ static void* rdpdr_server_thread(void* arg)
HANDLE ChannelEvent;
DWORD BytesReturned;
RdpdrServerContext* context;
context = (RdpdrServerContext*) arg;
buffer = NULL;
BytesReturned = 0;
ChannelEvent = NULL;
s = Stream_New(NULL, 4096);
if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
@ -585,13 +513,11 @@ static void* rdpdr_server_thread(void* arg)
nCount = 0;
events[nCount++] = ChannelEvent;
events[nCount++] = context->priv->StopEvent;
rdpdr_server_send_announce_request(context);
while (1)
{
BytesReturned = 0;
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
@ -600,11 +526,14 @@ static void* rdpdr_server_thread(void* arg)
}
WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
if (BytesReturned < 1)
continue;
Stream_EnsureRemainingCapacity(s, BytesReturned);
if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
{
break;
}
@ -613,22 +542,17 @@ static void* rdpdr_server_thread(void* arg)
{
position = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
Stream_Read_UINT16(s, header.Component); /* Component (2 bytes) */
Stream_Read_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
Stream_SetPosition(s, position);
Stream_SealLength(s);
Stream_SetPosition(s, RDPDR_HEADER_LENGTH);
rdpdr_server_receive_pdu(context, s, &header);
Stream_SetPosition(s, 0);
}
}
Stream_Free(s, TRUE);
return NULL;
}
@ -640,48 +564,38 @@ static int rdpdr_server_start(RdpdrServerContext* context)
return -1;
context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
context->priv->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rdpdr_server_thread, (void*) context, 0, NULL);
(LPTHREAD_START_ROUTINE) rdpdr_server_thread, (void*) context, 0, NULL);
return 0;
}
static int rdpdr_server_stop(RdpdrServerContext* context)
{
SetEvent(context->priv->StopEvent);
WaitForSingleObject(context->priv->Thread, INFINITE);
CloseHandle(context->priv->Thread);
return 0;
}
RdpdrServerContext* rdpdr_server_context_new(HANDLE vcm)
{
RdpdrServerContext* context;
context = (RdpdrServerContext*) malloc(sizeof(RdpdrServerContext));
if (context)
{
ZeroMemory(context, sizeof(RdpdrServerContext));
context->vcm = vcm;
context->Start = rdpdr_server_start;
context->Stop = rdpdr_server_stop;
context->priv = (RdpdrServerPrivate*) malloc(sizeof(RdpdrServerPrivate));
if (context->priv)
{
ZeroMemory(context->priv, sizeof(RdpdrServerPrivate));
context->priv->VersionMajor = RDPDR_VERSION_MAJOR;
context->priv->VersionMinor = RDPDR_VERSION_MINOR_RDP6X;
context->priv->ClientId = g_ClientId++;
context->priv->UserLoggedOnPdu = TRUE;
}
}

View File

@ -118,7 +118,7 @@ static BOOL rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
{
int i, num_known_format = 0;
UINT32 flags, vol, pitch;
UINT16 udpPort, version;
UINT16 udpPort;
BYTE lastblock;
if (Stream_GetRemainingLength(s) < 20)
@ -130,7 +130,7 @@ static BOOL rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
Stream_Read_UINT16(s, udpPort); /* wDGramPort */
Stream_Read_UINT16(s, context->num_client_formats); /* wNumberOfFormats */
Stream_Read_UINT8(s, lastblock); /* cLastBlockConfirmed */
Stream_Read_UINT16(s, version); /* wVersion */
Stream_Read_UINT16(s, context->clientVersion); /* wVersion */
Stream_Seek_UINT8(s); /* bPad */
/* this check is only a guess as cbSize can influence the size of a format record */
@ -210,7 +210,7 @@ static void* rdpsnd_server_thread(void* arg)
if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
break;
if (!rdpsnd_server_handle_messages(context))
if (rdpsnd_server_handle_messages(context) == 0)
break;
}
@ -620,7 +620,16 @@ HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext *context)
return context->priv->channelEvent;
}
BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
/*
* Handle rpdsnd messages - server side
*
* @param Server side context
*
* @return -1 if no data could be read,
* 0 on error (like connection close),
* 1 on succsess (also if further bytes need to be read)
*/
int rdpsnd_server_handle_messages(RdpsndServerContext *context)
{
DWORD bytesReturned;
BOOL ret;
@ -631,17 +640,18 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned))
{
if (GetLastError() == ERROR_NO_DATA)
return TRUE;
return -1;
CLOG_ERR( "%s: channel connection closed\n", __FUNCTION__);
return FALSE;
return 0;
}
priv->expectedBytes -= bytesReturned;
Stream_Seek(s, bytesReturned);
if (priv->expectedBytes)
return TRUE;
return 1;
Stream_SealLength(s);
Stream_SetPosition(s, 0);
if (priv->waitingHeader)
{
@ -655,7 +665,7 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
if (priv->expectedBytes)
{
Stream_EnsureCapacity(s, priv->expectedBytes);
return TRUE;
return 1;
}
}
@ -674,16 +684,18 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
case SNDC_FORMATS:
ret = rdpsnd_server_recv_formats(context, s);
if (ret && context->clientVersion < 6)
IFCALL(context->Activated, context);
break;
case SNDC_QUALITYMODE:
ret = rdpsnd_server_recv_quality_mode(context, s);
Stream_SetPosition(s, 0); /* in case the Activated callback tries to treat some messages */
if (ret)
{
if (ret && context->clientVersion >= 6)
IFCALL(context->Activated, context);
}
break;
default:
@ -693,5 +705,8 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context)
}
Stream_SetPosition(s, 0);
return ret;
if (ret)
return 1;
else
return 0;
}

View File

@ -38,106 +38,156 @@
#include "smartcard_main.h"
#define TAG "smartcard.client"
const char* smartcard_get_ioctl_string(UINT32 ioControlCode, BOOL funcName)
{
switch (ioControlCode)
{
case SCARD_IOCTL_ESTABLISHCONTEXT:
return funcName ? "SCardEstablishContext" : "SCARD_IOCTL_ESTABLISHCONTEXT";
case SCARD_IOCTL_RELEASECONTEXT:
return funcName ? "SCardReleaseContext" : "SCARD_IOCTL_RELEASECONTEXT";
case SCARD_IOCTL_ISVALIDCONTEXT:
return funcName ? "SCardIsValidContext" : "SCARD_IOCTL_ISVALIDCONTEXT";
case SCARD_IOCTL_LISTREADERGROUPSA:
return funcName ? "SCardListReaderGroupsA" : "SCARD_IOCTL_LISTREADERGROUPSA";
case SCARD_IOCTL_LISTREADERGROUPSW:
return funcName ? "SCardListReaderGroupsW" : "SCARD_IOCTL_LISTREADERGROUPSW";
case SCARD_IOCTL_LISTREADERSA:
return funcName ? "SCardListReadersA" : "SCARD_IOCTL_LISTREADERSA";
case SCARD_IOCTL_LISTREADERSW:
return funcName ? "SCardListReadersW" : "SCARD_IOCTL_LISTREADERSW";
case SCARD_IOCTL_INTRODUCEREADERGROUPA:
return funcName ? "SCardIntroduceReaderGroupA" : "SCARD_IOCTL_INTRODUCEREADERGROUPA";
case SCARD_IOCTL_INTRODUCEREADERGROUPW:
return funcName ? "SCardIntroduceReaderGroupW" : "SCARD_IOCTL_INTRODUCEREADERGROUPW";
case SCARD_IOCTL_FORGETREADERGROUPA:
return funcName ? "SCardForgetReaderGroupA" : "SCARD_IOCTL_FORGETREADERGROUPA";
case SCARD_IOCTL_FORGETREADERGROUPW:
return funcName ? "SCardForgetReaderGroupW" : "SCARD_IOCTL_FORGETREADERGROUPW";
case SCARD_IOCTL_INTRODUCEREADERA:
return funcName ? "SCardIntroduceReaderA" : "SCARD_IOCTL_INTRODUCEREADERA";
case SCARD_IOCTL_INTRODUCEREADERW:
return funcName ? "SCardIntroduceReaderW" : "SCARD_IOCTL_INTRODUCEREADERW";
case SCARD_IOCTL_FORGETREADERA:
return funcName ? "SCardForgetReaderA" : "SCARD_IOCTL_FORGETREADERA";
case SCARD_IOCTL_FORGETREADERW:
return funcName ? "SCardForgetReaderW" : "SCARD_IOCTL_FORGETREADERW";
case SCARD_IOCTL_ADDREADERTOGROUPA:
return funcName ? "SCardAddReaderToGroupA" : "SCARD_IOCTL_ADDREADERTOGROUPA";
case SCARD_IOCTL_ADDREADERTOGROUPW:
return funcName ? "SCardAddReaderToGroupW" : "SCARD_IOCTL_ADDREADERTOGROUPW";
case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
return funcName ? "SCardRemoveReaderFromGroupA" : "SCARD_IOCTL_REMOVEREADERFROMGROUPA";
case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
return funcName ? "SCardRemoveReaderFromGroupW" : "SCARD_IOCTL_REMOVEREADERFROMGROUPW";
case SCARD_IOCTL_LOCATECARDSA:
return funcName ? "SCardLocateCardsA" : "SCARD_IOCTL_LOCATECARDSA";
case SCARD_IOCTL_LOCATECARDSW:
return funcName ? "SCardLocateCardsW" : "SCARD_IOCTL_LOCATECARDSW";
case SCARD_IOCTL_GETSTATUSCHANGEA:
return funcName ? "SCardGetStatusChangeA" : "SCARD_IOCTL_GETSTATUSCHANGEA";
case SCARD_IOCTL_GETSTATUSCHANGEW:
return funcName ? "SCardGetStatusChangeW" : "SCARD_IOCTL_GETSTATUSCHANGEW";
case SCARD_IOCTL_CANCEL:
return funcName ? "SCardCancel" : "SCARD_IOCTL_CANCEL";
case SCARD_IOCTL_CONNECTA:
return funcName ? "SCardConnectA" : "SCARD_IOCTL_CONNECTA";
case SCARD_IOCTL_CONNECTW:
return funcName ? "SCardConnectW" : "SCARD_IOCTL_CONNECTW";
case SCARD_IOCTL_RECONNECT:
return funcName ? "SCardReconnect" : "SCARD_IOCTL_RECONNECT";
case SCARD_IOCTL_DISCONNECT:
return funcName ? "SCardDisconnect" : "SCARD_IOCTL_DISCONNECT";
case SCARD_IOCTL_BEGINTRANSACTION:
return funcName ? "SCardBeginTransaction" : "SCARD_IOCTL_BEGINTRANSACTION";
case SCARD_IOCTL_ENDTRANSACTION:
return funcName ? "SCardEndTransaction" : "SCARD_IOCTL_ENDTRANSACTION";
case SCARD_IOCTL_STATE:
return funcName ? "SCardState" : "SCARD_IOCTL_STATE";
case SCARD_IOCTL_STATUSA:
return funcName ? "SCardStatusA" : "SCARD_IOCTL_STATUSA";
case SCARD_IOCTL_STATUSW:
return funcName ? "SCardStatusW" : "SCARD_IOCTL_STATUSW";
case SCARD_IOCTL_TRANSMIT:
return funcName ? "SCardTransmit" : "SCARD_IOCTL_TRANSMIT";
case SCARD_IOCTL_CONTROL:
return funcName ? "SCardControl" : "SCARD_IOCTL_CONTROL";
case SCARD_IOCTL_GETATTRIB:
return funcName ? "SCardGetAttrib" : "SCARD_IOCTL_GETATTRIB";
case SCARD_IOCTL_SETATTRIB:
return funcName ? "SCardSetAttrib" : "SCARD_IOCTL_SETATTRIB";
case SCARD_IOCTL_ACCESSSTARTEDEVENT:
return funcName ? "SCardAccessStartedEvent" : "SCARD_IOCTL_ACCESSSTARTEDEVENT";
case SCARD_IOCTL_LOCATECARDSBYATRA:
return funcName ? "SCardLocateCardsByATRA" : "SCARD_IOCTL_LOCATECARDSBYATRA";
case SCARD_IOCTL_LOCATECARDSBYATRW:
return funcName ? "SCardLocateCardsByATRB" : "SCARD_IOCTL_LOCATECARDSBYATRW";
case SCARD_IOCTL_READCACHEA:
return funcName ? "SCardReadCacheA" : "SCARD_IOCTL_READCACHEA";
case SCARD_IOCTL_READCACHEW:
return funcName ? "SCardReadCacheW" : "SCARD_IOCTL_READCACHEW";
case SCARD_IOCTL_WRITECACHEA:
return funcName ? "SCardWriteCacheA" : "SCARD_IOCTL_WRITECACHEA";
case SCARD_IOCTL_WRITECACHEW:
return funcName ? "SCardWriteCacheW" : "SCARD_IOCTL_WRITECACHEW";
case SCARD_IOCTL_GETTRANSMITCOUNT:
return funcName ? "SCardGetTransmitCount" : "SCARD_IOCTL_GETTRANSMITCOUNT";
case SCARD_IOCTL_RELEASESTARTEDEVENT:
return funcName ? "SCardReleaseStartedEvent" : "SCARD_IOCTL_RELEASESTARTEDEVENT";
case SCARD_IOCTL_GETREADERICON:
return funcName ? "SCardGetReaderIcon" : "SCARD_IOCTL_GETREADERICON";
case SCARD_IOCTL_GETDEVICETYPEID:
return funcName ? "SCardGetDeviceTypeId" : "SCARD_IOCTL_GETDEVICETYPEID";
default:
return funcName ? "SCardUnknown" : "SCARD_IOCTL_UNKNOWN";
}
@ -154,9 +204,7 @@ static UINT32 smartcard_EstablishContext_Decode(SMARTCARD_DEVICE* smartcard, SMA
return STATUS_NO_MEMORY;
status = smartcard_unpack_establish_context_call(smartcard, irp->input, call);
smartcard_trace_establish_context_call(smartcard, call);
return status;
}
@ -166,23 +214,18 @@ static UINT32 smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMART
SCARDCONTEXT hContext = -1;
EstablishContext_Return ret;
IRP* irp = operation->irp;
status = ret.ReturnCode = SCardEstablishContext(call->dwScope, NULL, NULL, &hContext);
if (ret.ReturnCode == SCARD_S_SUCCESS)
{
SMARTCARD_CONTEXT* pContext;
void* key = (void*) (size_t) hContext;
void* key = (void*)(size_t) hContext;
pContext = smartcard_context_new(smartcard, hContext);
ListDictionary_Add(smartcard->rgSCardContextList, key, (void*) pContext);
}
smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext);
smartcard_trace_establish_context_return(smartcard, &ret);
status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret);
if (status)
@ -200,11 +243,8 @@ static UINT32 smartcard_ReleaseContext_Decode(SMARTCARD_DEVICE* smartcard, SMART
return STATUS_NO_MEMORY;
status = smartcard_unpack_context_call(smartcard, irp->input, call);
smartcard_trace_context_call(smartcard, call, "ReleaseContext");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
}
@ -212,21 +252,17 @@ static UINT32 smartcard_ReleaseContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
{
UINT32 status;
Long_Return ret;
status = ret.ReturnCode = SCardReleaseContext(operation->hContext);
if (ret.ReturnCode == SCARD_S_SUCCESS)
{
SMARTCARD_CONTEXT* pContext;
void* key = (void*) (size_t) operation->hContext;
void* key = (void*)(size_t) operation->hContext;
pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove(smartcard->rgSCardContextList, key);
smartcard_context_free(pContext);
}
smartcard_trace_long_return(smartcard, &ret, "ReleaseContext");
return ret.ReturnCode;
}
@ -239,11 +275,8 @@ static UINT32 smartcard_IsValidContext_Decode(SMARTCARD_DEVICE* smartcard, SMART
return STATUS_NO_MEMORY;
status = smartcard_unpack_context_call(smartcard, irp->input, call);
smartcard_trace_context_call(smartcard, call, "IsValidContext");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
}
@ -251,11 +284,8 @@ static UINT32 smartcard_IsValidContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
{
UINT32 status;
Long_Return ret;
status = ret.ReturnCode = SCardIsValidContext(operation->hContext);
smartcard_trace_long_return(smartcard, &ret, "IsValidContext");
return ret.ReturnCode;
}
@ -268,11 +298,8 @@ static UINT32 smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA
return STATUS_NO_MEMORY;
status = smartcard_unpack_list_readers_call(smartcard, irp->input, call);
smartcard_trace_list_readers_call(smartcard, call, FALSE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
}
@ -283,11 +310,8 @@ static UINT32 smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD
LPSTR mszReaders = NULL;
DWORD cchReaders = 0;
IRP* irp = operation->irp;
cchReaders = SCARD_AUTOALLOCATE;
status = ret.ReturnCode = SCardListReadersA(operation->hContext, (LPCSTR) call->mszGroups, (LPSTR) &mszReaders, &cchReaders);
ret.msz = (BYTE*) mszReaders;
ret.cBytes = cchReaders;
@ -295,7 +319,6 @@ static UINT32 smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD
return status;
smartcard_trace_list_readers_return(smartcard, &ret, FALSE);
status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret);
if (status)
@ -319,11 +342,8 @@ static UINT32 smartcard_ListReadersW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA
return STATUS_NO_MEMORY;
status = smartcard_unpack_list_readers_call(smartcard, irp->input, call);
smartcard_trace_list_readers_call(smartcard, call, TRUE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
}
@ -334,11 +354,8 @@ static UINT32 smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD
LPWSTR mszReaders = NULL;
DWORD cchReaders = 0;
IRP* irp = operation->irp;
cchReaders = SCARD_AUTOALLOCATE;
status = ret.ReturnCode = SCardListReadersW(operation->hContext, (LPCWSTR) call->mszGroups, (LPWSTR) &mszReaders, &cchReaders);
ret.msz = (BYTE*) mszReaders;
ret.cBytes = cchReaders * 2;
@ -346,7 +363,6 @@ static UINT32 smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD
return status;
smartcard_trace_list_readers_return(smartcard, &ret, TRUE);
status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
@ -370,11 +386,8 @@ static UINT32 smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard, SMA
return STATUS_NO_MEMORY;
status = smartcard_unpack_get_status_change_a_call(smartcard, irp->input, call);
smartcard_trace_get_status_change_a_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
}
@ -385,10 +398,10 @@ static UINT32 smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, SMART
GetStatusChange_Return ret;
LPSCARD_READERSTATEA rgReaderState = NULL;
IRP* irp = operation->irp;
status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, call->dwTimeOut, call->rgReaderStates, call->cReaders);
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED)){
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED))
{
call->cReaders=0;
}
@ -404,7 +417,6 @@ static UINT32 smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, SMART
}
smartcard_trace_get_status_change_return(smartcard, &ret, FALSE);
status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
if (status)
@ -419,11 +431,11 @@ static UINT32 smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, SMART
if (rgReaderState->szReader)
free((void*) rgReaderState->szReader);
}
free(call->rgReaderStates);
}
free(ret.rgReaderStates);
return ret.ReturnCode;
}
@ -436,11 +448,8 @@ static UINT32 smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard, SMA
return STATUS_NO_MEMORY;
status = smartcard_unpack_get_status_change_w_call(smartcard, irp->input, call);
smartcard_trace_get_status_change_w_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
}
@ -451,10 +460,10 @@ static UINT32 smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, SMART
GetStatusChange_Return ret;
LPSCARD_READERSTATEW rgReaderState = NULL;
IRP* irp = operation->irp;
status = ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut, call->rgReaderStates, call->cReaders);
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED)){
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED))
{
call->cReaders=0;
}
@ -470,7 +479,6 @@ static UINT32 smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, SMART
}
smartcard_trace_get_status_change_return(smartcard, &ret, TRUE);
status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
if (status)
@ -485,11 +493,11 @@ static UINT32 smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, SMART
if (rgReaderState->szReader)
free((void*) rgReaderState->szReader);
}
free(call->rgReaderStates);
}
free(ret.rgReaderStates);
return ret.ReturnCode;
}
@ -502,11 +510,8 @@ static UINT32 smartcard_Cancel_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
return STATUS_NO_MEMORY;
status = smartcard_unpack_context_call(smartcard, irp->input, call);
smartcard_trace_context_call(smartcard, call, "Cancel");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
return status;
}
@ -514,11 +519,8 @@ static UINT32 smartcard_Cancel_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
{
LONG status;
Long_Return ret;
status = ret.ReturnCode = SCardCancel(operation->hContext);
smartcard_trace_long_return(smartcard, &ret, "Cancel");
return ret.ReturnCode;
}
@ -531,11 +533,8 @@ static UINT32 smartcard_ConnectA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
return STATUS_NO_MEMORY;
status = smartcard_unpack_connect_a_call(smartcard, irp->input, call);
smartcard_trace_connect_a_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext));
return status;
}
@ -553,11 +552,9 @@ static UINT32 smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
}
status = ret.ReturnCode = SCardConnectA(operation->hContext, (char*) call->szReader, call->Common.dwShareMode,
call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext);
smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard);
smartcard_trace_connect_return(smartcard, &ret);
if (status)
@ -583,11 +580,8 @@ static UINT32 smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
return STATUS_NO_MEMORY;
status = smartcard_unpack_connect_w_call(smartcard, irp->input, call);
smartcard_trace_connect_w_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext));
return status;
}
@ -605,11 +599,9 @@ static UINT32 smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
}
status = ret.ReturnCode = SCardConnectW(operation->hContext, (WCHAR*) call->szReader, call->Common.dwShareMode,
call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext);
smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard);
smartcard_trace_connect_return(smartcard, &ret);
if (status)
@ -635,12 +627,9 @@ static UINT32 smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_
return STATUS_NO_MEMORY;
status = smartcard_unpack_reconnect_call(smartcard, irp->input, call);
smartcard_trace_reconnect_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -649,12 +638,9 @@ static UINT32 smartcard_Reconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
LONG status;
Reconnect_Return ret;
IRP* irp = operation->irp;
status = ret.ReturnCode = SCardReconnect(operation->hCard, call->dwShareMode,
call->dwPreferredProtocols, call->dwInitialization, &ret.dwActiveProtocol);
call->dwPreferredProtocols, call->dwInitialization, &ret.dwActiveProtocol);
smartcard_trace_reconnect_return(smartcard, &ret);
status = smartcard_pack_reconnect_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
@ -672,12 +658,9 @@ static UINT32 smartcard_Disconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD
return STATUS_NO_MEMORY;
status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call);
smartcard_trace_hcard_and_disposition_call(smartcard, call, "Disconnect");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -685,9 +668,7 @@ static UINT32 smartcard_Disconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
{
LONG status;
Long_Return ret;
status = ret.ReturnCode = SCardDisconnect(operation->hCard, call->dwDisposition);
smartcard_trace_long_return(smartcard, &ret, "Disconnect");
if (status != SCARD_S_SUCCESS)
@ -705,12 +686,9 @@ static UINT32 smartcard_BeginTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMA
return STATUS_NO_MEMORY;
status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call);
smartcard_trace_hcard_and_disposition_call(smartcard, call, "BeginTransaction");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -718,11 +696,8 @@ static UINT32 smartcard_BeginTransaction_Call(SMARTCARD_DEVICE* smartcard, SMART
{
LONG status;
Long_Return ret;
status = ret.ReturnCode = SCardBeginTransaction(operation->hCard);
smartcard_trace_long_return(smartcard, &ret, "BeginTransaction");
return ret.ReturnCode;
}
@ -735,12 +710,9 @@ static UINT32 smartcard_EndTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMART
return STATUS_NO_MEMORY;
status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call);
smartcard_trace_hcard_and_disposition_call(smartcard, call, "EndTransaction");
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -748,11 +720,8 @@ static UINT32 smartcard_EndTransaction_Call(SMARTCARD_DEVICE* smartcard, SMARTCA
{
LONG status;
Long_Return ret;
status = ret.ReturnCode = SCardEndTransaction(operation->hCard, call->dwDisposition);
smartcard_trace_long_return(smartcard, &ret, "EndTransaction");
return ret.ReturnCode;
}
@ -765,10 +734,8 @@ static UINT32 smartcard_State_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
return STATUS_NO_MEMORY;
status = smartcard_unpack_state_call(smartcard, irp->input, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -777,11 +744,8 @@ static UINT32 smartcard_State_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
LONG status;
State_Return ret;
IRP* irp = operation->irp;
ret.cbAtrLen = SCARD_ATR_LENGTH;
status = ret.ReturnCode = SCardState(operation->hCard, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.rgAtr, &ret.cbAtrLen);
status = smartcard_pack_state_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
@ -799,12 +763,9 @@ static DWORD smartcard_StatusA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
return STATUS_NO_MEMORY;
status = smartcard_unpack_status_call(smartcard, irp->input, call);
smartcard_trace_status_call(smartcard, call, FALSE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -821,11 +782,9 @@ static DWORD smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
ret.cbAtrLen = call->cbAtrLen;
ZeroMemory(ret.pbAtr, 32);
cchReaderLen = SCARD_AUTOALLOCATE;
status = ret.ReturnCode = SCardStatusA(operation->hCard, (LPSTR) &mszReaderNames, &cchReaderLen,
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
if (status == SCARD_S_SUCCESS)
{
@ -834,7 +793,6 @@ static DWORD smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
}
smartcard_trace_status_return(smartcard, &ret, FALSE);
status = smartcard_pack_status_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
@ -855,12 +813,9 @@ static DWORD smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
return STATUS_NO_MEMORY;
status = smartcard_unpack_status_call(smartcard, irp->input, call);
smartcard_trace_status_call(smartcard, call, TRUE);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -877,17 +832,12 @@ static DWORD smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
ret.cbAtrLen = call->cbAtrLen;
ZeroMemory(ret.pbAtr, 32);
cchReaderLen = SCARD_AUTOALLOCATE;
status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen,
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
ret.mszReaderNames = (BYTE*) mszReaderNames;
ret.cBytes = cchReaderLen * 2;
smartcard_trace_status_return(smartcard, &ret, TRUE);
status = smartcard_pack_status_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
@ -908,12 +858,9 @@ static UINT32 smartcard_Transmit_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
return STATUS_NO_MEMORY;
status = smartcard_unpack_transmit_call(smartcard, irp->input, call);
smartcard_trace_transmit_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -922,7 +869,6 @@ static UINT32 smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
LONG status;
Transmit_Return ret;
IRP* irp = operation->irp;
ret.cbRecvLength = 0;
ret.pbRecvBuffer = NULL;
@ -936,12 +882,9 @@ static UINT32 smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
}
ret.pioRecvPci = call->pioRecvPci;
status = ret.ReturnCode = SCardTransmit(operation->hCard, call->pioSendPci, call->pbSendBuffer,
call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength));
call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength));
smartcard_trace_transmit_return(smartcard, &ret);
status = smartcard_pack_transmit_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
@ -949,10 +892,13 @@ static UINT32 smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
if (call->pbSendBuffer)
free(call->pbSendBuffer);
if (ret.pbRecvBuffer)
free(ret.pbRecvBuffer);
if (call->pioSendPci)
free(call->pioSendPci);
if (call->pioRecvPci)
free(call->pioRecvPci);
@ -968,12 +914,9 @@ static UINT32 smartcard_Control_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
return STATUS_NO_MEMORY;
status = smartcard_unpack_control_call(smartcard, irp->input, call);
smartcard_trace_control_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -982,7 +925,6 @@ static UINT32 smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
LONG status;
Control_Return ret;
IRP* irp = operation->irp;
ret.cbOutBufferSize = call->cbOutBufferSize;
ret.pvOutBuffer = (BYTE*) malloc(call->cbOutBufferSize);
@ -990,11 +932,9 @@ static UINT32 smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
return SCARD_E_NO_MEMORY;
status = ret.ReturnCode = SCardControl(operation->hCard,
call->dwControlCode, call->pvInBuffer, call->cbInBufferSize,
ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize);
call->dwControlCode, call->pvInBuffer, call->cbInBufferSize,
ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize);
smartcard_trace_control_return(smartcard, &ret);
status = smartcard_pack_control_return(smartcard, irp->output, &ret);
if (status != SCARD_S_SUCCESS)
@ -1002,6 +942,7 @@ static UINT32 smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
if (call->pvInBuffer)
free(call->pvInBuffer);
if (ret.pvOutBuffer)
free(ret.pvOutBuffer);
@ -1017,12 +958,9 @@ static UINT32 smartcard_GetAttrib_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_
return STATUS_NO_MEMORY;
status = smartcard_unpack_get_attrib_call(smartcard, irp->input, call);
smartcard_trace_get_attrib_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard));
return status;
}
@ -1032,7 +970,6 @@ static UINT32 smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
DWORD cbAttrLen;
GetAttrib_Return ret;
IRP* irp = operation->irp;
ret.pbAttr = NULL;
if (call->fpbAttrIsNULL)
@ -1042,19 +979,15 @@ static UINT32 smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
ret.pbAttr = (BYTE*) malloc(call->cbAttrLen);
cbAttrLen = call->cbAttrLen;
status = ret.ReturnCode = SCardGetAttrib(operation->hCard, call->dwAttrId, ret.pbAttr, &cbAttrLen);
ret.cbAttrLen = cbAttrLen;
smartcard_trace_get_attrib_return(smartcard, &ret, call->dwAttrId);
if (ret.ReturnCode)
{
WLog_Print(smartcard->log, WLOG_WARN,
"SCardGetAttrib: %s (0x%08X) cbAttrLen: %d\n",
SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen);
"SCardGetAttrib: %s (0x%08X) cbAttrLen: %d\n",
SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen);
Stream_Zero(irp->output, 256);
return ret.ReturnCode;
}
@ -1065,7 +998,6 @@ static UINT32 smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
return status;
free(ret.pbAttr);
return ret.ReturnCode;
}
@ -1079,12 +1011,11 @@ static UINT32 smartcard_AccessStartedEvent_Decode(SMARTCARD_DEVICE* smartcard, S
if (Stream_GetRemainingLength(irp->input) < 4)
{
WLog_Print(smartcard->log, WLOG_WARN, "AccessStartedEvent is too short: %d",
(int) Stream_GetRemainingLength(irp->input));
(int) Stream_GetRemainingLength(irp->input));
return SCARD_F_INTERNAL_ERROR;
}
Stream_Read_UINT32(irp->input, call->LongValue); /* Unused (4 bytes) */
return SCARD_S_SUCCESS;
}
@ -1092,7 +1023,6 @@ static UINT32 smartcard_AccessStartedEvent_Call(SMARTCARD_DEVICE* smartcard, SMA
{
UINT32 status;
Long_Return ret;
status = ret.ReturnCode = SCARD_S_SUCCESS;
if (!smartcard->StartedEvent)
@ -1119,7 +1049,7 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR
if (Stream_GetRemainingLength(irp->input) < 32)
{
WLog_Print(smartcard->log, WLOG_WARN, "Device Control Request is too short: %d",
(int) Stream_GetRemainingLength(irp->input));
(int) Stream_GetRemainingLength(irp->input));
return SCARD_F_INTERNAL_ERROR;
}
@ -1127,23 +1057,21 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR
Stream_Read_UINT32(irp->input, inputBufferLength); /* InputBufferLength (4 bytes) */
Stream_Read_UINT32(irp->input, ioControlCode); /* IoControlCode (4 bytes) */
Stream_Seek(irp->input, 20); /* Padding (20 bytes) */
operation->ioControlCode = ioControlCode;
if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength))
{
WLog_Print(smartcard->log, WLOG_WARN,
"InputBufferLength mismatch: Actual: %d Expected: %d\n",
Stream_Length(irp->input), Stream_GetPosition(irp->input) + inputBufferLength);
"InputBufferLength mismatch: Actual: %d Expected: %d\n",
Stream_Length(irp->input), Stream_GetPosition(irp->input) + inputBufferLength);
return SCARD_F_INTERNAL_ERROR;
}
WLog_Print(smartcard->log, WLOG_DEBUG, "%s (0x%08X) FileId: %d CompletionId: %d",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
#if 0
CLOG_DBG("%s (0x%08X) FileId: %d CompletionId: %d\n",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
#endif
if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
@ -1386,35 +1314,29 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR
(ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT))
{
offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH);
smartcard_unpack_read_size_align(smartcard, irp->input,
Stream_GetPosition(irp->input) - offset, 8);
Stream_GetPosition(irp->input) - offset, 8);
}
if (((size_t) Stream_GetPosition(irp->input)) < Stream_Length(irp->input))
{
UINT32 difference;
difference = (int) (Stream_Length(irp->input) - Stream_GetPosition(irp->input));
difference = (int)(Stream_Length(irp->input) - Stream_GetPosition(irp->input));
WLog_Print(smartcard->log, WLOG_WARN,
"IRP was not fully parsed %s (0x%08X): Actual: %d, Expected: %d, Difference: %d",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode,
(int) Stream_GetPosition(irp->input), (int) Stream_Length(irp->input), difference);
winpr_HexDump(Stream_Pointer(irp->input), difference);
"IRP was not fully parsed %s (0x%08X): Actual: %d, Expected: %d, Difference: %d",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode,
(int) Stream_GetPosition(irp->input), (int) Stream_Length(irp->input), difference);
winpr_HexDump(TAG, WLOG_WARN, Stream_Pointer(irp->input), difference);
}
if (((size_t) Stream_GetPosition(irp->input)) > Stream_Length(irp->input))
{
UINT32 difference;
difference = (int) (Stream_GetPosition(irp->input) - Stream_Length(irp->input));
difference = (int)(Stream_GetPosition(irp->input) - Stream_Length(irp->input));
WLog_Print(smartcard->log, WLOG_WARN,
"IRP was parsed beyond its end %s (0x%08X): Actual: %d, Expected: %d, Difference: %d",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode,
(int) Stream_GetPosition(irp->input), (int) Stream_Length(irp->input), difference);
"IRP was parsed beyond its end %s (0x%08X): Actual: %d, Expected: %d, Difference: %d",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode,
(int) Stream_GetPosition(irp->input), (int) Stream_Length(irp->input), difference);
}
if (status != SCARD_S_SUCCESS)
@ -1424,7 +1346,6 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR
}
operation->call = call;
return status;
}
@ -1437,11 +1358,9 @@ UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_
UINT32 ioControlCode;
UINT32 outputBufferLength;
UINT32 objectBufferLength;
irp = operation->irp;
call = operation->call;
ioControlCode = operation->ioControlCode;
/**
* [MS-RDPESC] 3.2.5.1: Sending Outgoing Messages:
* the output buffer length SHOULD be set to 2048
@ -1450,13 +1369,10 @@ UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_
* about it, but we still reserve at least 2048 bytes.
*/
Stream_EnsureRemainingCapacity(irp->output, 2048);
/* Device Control Response */
Stream_Seek_UINT32(irp->output); /* OutputBufferLength (4 bytes) */
Stream_Seek(irp->output, SMARTCARD_COMMON_TYPE_HEADER_LENGTH); /* CommonTypeHeader (8 bytes) */
Stream_Seek(irp->output, SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH); /* PrivateTypeHeader (8 bytes) */
Stream_Seek_UINT32(irp->output); /* Result (4 bytes) */
/* Call */
@ -1672,18 +1588,17 @@ UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_
(ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT))
{
offset = (RDPDR_DEVICE_IO_RESPONSE_LENGTH + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH);
smartcard_pack_write_size_align(smartcard, irp->output,
Stream_GetPosition(irp->output) - offset, 8);
Stream_GetPosition(irp->output) - offset, 8);
}
if ((result != SCARD_S_SUCCESS) && (result != SCARD_E_TIMEOUT) &&
(result != SCARD_E_NO_READERS_AVAILABLE) && (result != SCARD_E_NO_SERVICE))
{
WLog_Print(smartcard->log, WLOG_WARN,
"IRP failure: %s (0x%08X), status: %s (0x%08X)",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode,
SCardGetErrorString(result), result);
"IRP failure: %s (0x%08X), status: %s (0x%08X)",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode,
SCardGetErrorString(result), result);
}
irp->IoStatus = 0;
@ -1691,31 +1606,23 @@ UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_
if ((result & 0xC0000000) == 0xC0000000)
{
/* NTSTATUS error */
irp->IoStatus = result;
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH);
WLog_Print(smartcard->log, WLOG_WARN,
"IRP failure: %s (0x%08X), ntstatus: 0x%08X",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result);
"IRP failure: %s (0x%08X), ntstatus: 0x%08X",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result);
}
Stream_SealLength(irp->output);
outputBufferLength = Stream_Length(irp->output) - RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4;
objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH;
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH);
/* Device Control Response */
Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */
smartcard_pack_common_type_header(smartcard, irp->output); /* CommonTypeHeader (8 bytes) */
smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength); /* PrivateTypeHeader (8 bytes) */
Stream_Write_UINT32(irp->output, result); /* Result (4 bytes) */
Stream_SetPosition(irp->output, Stream_Length(irp->output));
return SCARD_S_SUCCESS;
}

View File

@ -34,10 +34,14 @@
#include "tsmf_codec.h"
#include <freerdp/log.h>
#define TAG CHANNELS_TAG("tsmf.client")
typedef struct _TSMFMediaTypeMap
{
BYTE guid[16];
const char *name;
const char* name;
int type;
} TSMFMediaTypeMap;
@ -259,31 +263,40 @@ static const TSMFMediaTypeMap tsmf_format_type_map[] =
}
};
static void tsmf_print_guid(const BYTE *guid)
static void tsmf_print_guid(const BYTE* guid)
{
#ifdef WITH_DEBUG_TSMF
int i;
for(i = 3; i >= 0; i--)
CLOG_ERR( "%02X", guid[i]);
CLOG_ERR( "-");
for(i = 5; i >= 4; i--)
CLOG_ERR( "%02X", guid[i]);
CLOG_ERR( "-");
for(i = 7; i >= 6; i--)
CLOG_ERR( "%02X", guid[i]);
CLOG_ERR( "-");
for(i = 8; i < 16; i++)
for (i = 3; i >= 0; i--)
CLOG_ERR("%02X", guid[i]);
CLOG_ERR("-");
for (i = 5; i >= 4; i--)
CLOG_ERR("%02X", guid[i]);
CLOG_ERR("-");
for (i = 7; i >= 6; i--)
CLOG_ERR("%02X", guid[i]);
CLOG_ERR("-");
for (i = 8; i < 16; i++)
{
CLOG_ERR( "%02X", guid[i]);
if(i == 9)
CLOG_ERR( "-");
CLOG_ERR("%02X", guid[i]);
if (i == 9)
CLOG_ERR("-");
}
CLOG_ERR( "\n");
CLOG_ERR("\n");
#endif
}
/* http://msdn.microsoft.com/en-us/library/dd318229.aspx */
static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE *mediatype, wStream *s, BOOL bypass)
static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, wStream* s, BOOL bypass)
{
UINT32 biSize;
UINT32 biWidth;
@ -292,18 +305,22 @@ static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE *mediatype, wSt
Stream_Read_UINT32(s, biWidth);
Stream_Read_UINT32(s, biHeight);
Stream_Seek(s, 28);
if(mediatype->Width == 0)
if (mediatype->Width == 0)
mediatype->Width = biWidth;
if(mediatype->Height == 0)
if (mediatype->Height == 0)
mediatype->Height = biHeight;
/* Assume there will be no color table for video? */
if(bypass && biSize > 40)
if (bypass && biSize > 40)
Stream_Seek(s, biSize - 40);
return (bypass ? biSize : 40);
}
/* http://msdn.microsoft.com/en-us/library/dd407326.aspx */
static UINT32 tsmf_codec_parse_VIDEOINFOHEADER2(TS_AM_MEDIA_TYPE *mediatype, wStream *s)
static UINT32 tsmf_codec_parse_VIDEOINFOHEADER2(TS_AM_MEDIA_TYPE* mediatype, wStream* s)
{
UINT64 AvgTimePerFrame;
/* VIDEOINFOHEADER2.rcSource, RECT(LONG left, LONG top, LONG right, LONG bottom) */
@ -327,7 +344,7 @@ static UINT32 tsmf_codec_parse_VIDEOINFOHEADER2(TS_AM_MEDIA_TYPE *mediatype, wSt
}
/* http://msdn.microsoft.com/en-us/library/dd390700.aspx */
static UINT32 tsmf_codec_parse_VIDEOINFOHEADER(TS_AM_MEDIA_TYPE *mediatype, wStream *s)
static UINT32 tsmf_codec_parse_VIDEOINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, wStream* s)
{
/*
typedef struct tagVIDEOINFOHEADER {
@ -358,7 +375,7 @@ static UINT32 tsmf_codec_parse_VIDEOINFOHEADER(TS_AM_MEDIA_TYPE *mediatype, wStr
return 48;
}
BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE *mediatype, wStream *s)
BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s)
{
int i;
UINT32 cbFormat;
@ -367,27 +384,35 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE *mediatype, wStream *s)
/* MajorType */
DEBUG_TSMF("MajorType:");
tsmf_print_guid(Stream_Pointer(s));
for(i = 0; tsmf_major_type_map[i].type != TSMF_MAJOR_TYPE_UNKNOWN; i++)
for (i = 0; tsmf_major_type_map[i].type != TSMF_MAJOR_TYPE_UNKNOWN; i++)
{
if(memcmp(tsmf_major_type_map[i].guid, Stream_Pointer(s), 16) == 0)
if (memcmp(tsmf_major_type_map[i].guid, Stream_Pointer(s), 16) == 0)
break;
}
mediatype->MajorType = tsmf_major_type_map[i].type;
if(mediatype->MajorType == TSMF_MAJOR_TYPE_UNKNOWN)
if (mediatype->MajorType == TSMF_MAJOR_TYPE_UNKNOWN)
ret = FALSE;
DEBUG_TSMF("MajorType %s", tsmf_major_type_map[i].name);
Stream_Seek(s, 16);
/* SubType */
DEBUG_TSMF("SubType:");
tsmf_print_guid(Stream_Pointer(s));
for(i = 0; tsmf_sub_type_map[i].type != TSMF_SUB_TYPE_UNKNOWN; i++)
for (i = 0; tsmf_sub_type_map[i].type != TSMF_SUB_TYPE_UNKNOWN; i++)
{
if(memcmp(tsmf_sub_type_map[i].guid, Stream_Pointer(s), 16) == 0)
if (memcmp(tsmf_sub_type_map[i].guid, Stream_Pointer(s), 16) == 0)
break;
}
mediatype->SubType = tsmf_sub_type_map[i].type;
if(mediatype->SubType == TSMF_SUB_TYPE_UNKNOWN)
if (mediatype->SubType == TSMF_SUB_TYPE_UNKNOWN)
ret = FALSE;
DEBUG_TSMF("SubType %s", tsmf_sub_type_map[i].name);
Stream_Seek(s, 16);
/* bFixedSizeSamples, bTemporalCompression, SampleSize */
@ -395,23 +420,28 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE *mediatype, wStream *s)
/* FormatType */
DEBUG_TSMF("FormatType:");
tsmf_print_guid(Stream_Pointer(s));
for(i = 0; tsmf_format_type_map[i].type != TSMF_FORMAT_TYPE_UNKNOWN; i++)
for (i = 0; tsmf_format_type_map[i].type != TSMF_FORMAT_TYPE_UNKNOWN; i++)
{
if(memcmp(tsmf_format_type_map[i].guid, Stream_Pointer(s), 16) == 0)
if (memcmp(tsmf_format_type_map[i].guid, Stream_Pointer(s), 16) == 0)
break;
}
mediatype->FormatType = tsmf_format_type_map[i].type;
if(mediatype->FormatType == TSMF_FORMAT_TYPE_UNKNOWN)
if (mediatype->FormatType == TSMF_FORMAT_TYPE_UNKNOWN)
ret = FALSE;
DEBUG_TSMF("FormatType %s", tsmf_format_type_map[i].name);
Stream_Seek(s, 16);
/* cbFormat */
Stream_Read_UINT32(s, cbFormat);
DEBUG_TSMF("cbFormat %d", cbFormat);
#ifdef WITH_DEBUG_TSMF
winpr_HexDump(Stream_Pointer(s), cbFormat);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Pointer(s), cbFormat);
#endif
switch(mediatype->FormatType)
switch (mediatype->FormatType)
{
case TSMF_FORMAT_TYPE_MFVIDEOFORMAT:
/* http://msdn.microsoft.com/en-us/library/aa473808.aspx */
@ -425,11 +455,13 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE *mediatype, wStream *s)
Stream_Seek(s, 80);
Stream_Read_UINT32(s, mediatype->BitRate); /* compressedInfo.AvgBitrate */
Stream_Seek(s, 36);
if(cbFormat > 176)
if (cbFormat > 176)
{
mediatype->ExtraDataSize = cbFormat - 176;
mediatype->ExtraData = Stream_Pointer(s);
}
break;
case TSMF_FORMAT_TYPE_WAVEFORMATEX:
/* http://msdn.microsoft.com/en-us/library/dd757720.aspx */
@ -442,51 +474,62 @@ BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE *mediatype, wStream *s)
Stream_Read_UINT16(s, mediatype->BlockAlign);
Stream_Read_UINT16(s, mediatype->BitsPerSample);
Stream_Read_UINT16(s, mediatype->ExtraDataSize);
if(mediatype->ExtraDataSize > 0)
if (mediatype->ExtraDataSize > 0)
mediatype->ExtraData = Stream_Pointer(s);
break;
case TSMF_FORMAT_TYPE_MPEG1VIDEOINFO:
/* http://msdn.microsoft.com/en-us/library/dd390700.aspx */
i = tsmf_codec_parse_VIDEOINFOHEADER(mediatype, s);
i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, TRUE);
if(cbFormat > i)
if (cbFormat > i)
{
mediatype->ExtraDataSize = cbFormat - i;
mediatype->ExtraData = Stream_Pointer(s);
}
break;
case TSMF_FORMAT_TYPE_MPEG2VIDEOINFO:
/* http://msdn.microsoft.com/en-us/library/dd390707.aspx */
i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, s);
i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, TRUE);
if(cbFormat > i)
if (cbFormat > i)
{
mediatype->ExtraDataSize = cbFormat - i;
mediatype->ExtraData = Stream_Pointer(s);
}
break;
case TSMF_FORMAT_TYPE_VIDEOINFO2:
i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, s);
i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, FALSE);
if(cbFormat > i)
if (cbFormat > i)
{
mediatype->ExtraDataSize = cbFormat - i;
mediatype->ExtraData = Stream_Pointer(s);
}
break;
default:
break;
}
if(mediatype->SamplesPerSecond.Numerator == 0)
if (mediatype->SamplesPerSecond.Numerator == 0)
mediatype->SamplesPerSecond.Numerator = 1;
if(mediatype->SamplesPerSecond.Denominator == 0)
if (mediatype->SamplesPerSecond.Denominator == 0)
mediatype->SamplesPerSecond.Denominator = 1;
return ret;
}
BOOL tsmf_codec_check_media_type(wStream *s)
BOOL tsmf_codec_check_media_type(wStream* s)
{
BYTE *m;
BYTE* m;
BOOL ret;
TS_AM_MEDIA_TYPE mediatype;
Stream_GetPointer(s, m);

View File

@ -820,6 +820,44 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar, enum APPLE_KEYBOARD_TYPE type)
mfc->client_width = width;
}
void mac_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
{
rdpSettings* settings = context->settings;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_init(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
}
}
void mac_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
{
rdpSettings* settings = context->settings;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
}
}
BOOL mac_pre_connect(freerdp* instance)
{
rdpSettings* settings;
@ -867,6 +905,12 @@ BOOL mac_pre_connect(freerdp* instance)
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
PubSub_SubscribeChannelConnected(instance->context->pubSub,
(pChannelConnectedEventHandler) mac_OnChannelConnectedEventHandler);
PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
(pChannelDisconnectedEventHandler) mac_OnChannelDisconnectedEventHandler);
freerdp_client_load_addins(instance->context->channels, instance->settings);

View File

@ -10,11 +10,17 @@ typedef struct mf_context mfContext;
#include <freerdp/gdi/gdi.h>
#include <freerdp/gdi/dc.h>
#include <freerdp/gdi/gfx.h>
#include <freerdp/gdi/region.h>
#include <freerdp/rail/rail.h>
#include <freerdp/cache/cache.h>
#include <freerdp/channels/channels.h>
#include <freerdp/client/channels.h>
#include <freerdp/client/rdpei.h>
#include <freerdp/client/rdpgfx.h>
#include <freerdp/client/encomsp.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/thread.h>

View File

@ -29,16 +29,16 @@ set(${MODULE_PREFIX}_SRCS
wf_gdi.h
wf_event.c
wf_event.h
wf_channels.c
wf_channels.h
wf_graphics.c
wf_graphics.h
wf_cliprdr.c
wf_cliprdr.h
wf_window.c
wf_window.h
wf_rail.c
wf_rail.h
wf_interface.c
wf_interface.h
wf_client.c
wf_client.h
wf_floatbar.c
wf_floatbar.h
wfreerdp.rc

View File

@ -39,7 +39,7 @@
#include "resource.h"
#include "wf_interface.h"
#include "wf_client.h"
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
@ -63,6 +63,8 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
settings = context->settings;
wfc = (wfContext*) context;
settings->SoftwareGdi = TRUE;
context->argc = __argc;
context->argv = (char**) malloc(sizeof(char*) * __argc);

View File

@ -0,0 +1,65 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "wf_channels.h"
#include <freerdp/gdi/gfx.h>
void wf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
{
wfContext* wfc = (wfContext*) context;
rdpSettings* settings = context->settings;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_init(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
}
}
void wf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
{
wfContext* wfc = (wfContext*) context;
rdpSettings* settings = context->settings;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
}
}

View File

@ -0,0 +1,33 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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 __WF_CHANNELS_H
#define __WF_CHANNELS_H
#include <freerdp/freerdp.h>
#include <freerdp/client/channels.h>
#include <freerdp/client/rdpei.h>
#include <freerdp/client/rdpgfx.h>
#include <freerdp/client/encomsp.h>
#include "wf_client.h"
void wf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e);
void wf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e);
#endif

View File

@ -36,10 +36,6 @@
#include <assert.h>
#include <sys/types.h>
#ifdef _MSC_VER
#include <intrin.h>
#endif
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/utils/event.h>
@ -50,10 +46,11 @@
#include <freerdp/event.h>
#include "wf_gdi.h"
#include "wf_channels.h"
#include "wf_graphics.h"
#include "wf_cliprdr.h"
#include "wf_interface.h"
#include "wf_client.h"
#include "resource.h"
@ -104,8 +101,8 @@ void wf_sw_end_paint(wfContext* wfc)
update_rect.left = x;
update_rect.top = y;
update_rect.right = x + w - 1;
update_rect.bottom = y + h - 1;
update_rect.right = x + w;
update_rect.bottom = y + h;
InvalidateRect(wfc->hwnd, &update_rect, FALSE);
}
@ -237,9 +234,9 @@ BOOL wf_pre_connect(freerdp* instance)
settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE;
wfc->fullscreen = settings->Fullscreen;
if (wfc->fullscreen)
wfc->fs_toggle = 1;
wfc->sw_gdi = settings->SoftwareGdi;
wfc->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV));
ZeroMemory(wfc->clrconv, sizeof(CLRCONV));
@ -297,6 +294,13 @@ BOOL wf_pre_connect(freerdp* instance)
}
freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout, (int) GetKeyboardLayout(0) & 0x0000FFFF);
PubSub_SubscribeChannelConnected(instance->context->pubSub,
(pChannelConnectedEventHandler) wf_OnChannelConnectedEventHandler);
PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
(pChannelDisconnectedEventHandler) wf_OnChannelDisconnectedEventHandler);
freerdp_channels_pre_connect(instance->context->channels, instance);
return TRUE;
@ -345,12 +349,14 @@ BOOL wf_post_connect(freerdp* instance)
wfc->width = settings->DesktopWidth;
wfc->height = settings->DesktopHeight;
if (wfc->sw_gdi)
if (settings->SoftwareGdi)
{
gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_32BPP, NULL);
wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL);
gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, wfc->primary->pdata);
gdi = instance->context->gdi;
wfc->hdc = gdi->primary->hdc;
wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, gdi->primary_buffer);
}
else
{
@ -419,7 +425,7 @@ BOOL wf_post_connect(freerdp* instance)
ShowWindow(wfc->hwnd, SW_SHOWNORMAL);
UpdateWindow(wfc->hwnd);
if (wfc->sw_gdi)
if (settings->SoftwareGdi)
{
instance->update->BeginPaint = (pBeginPaint) wf_sw_begin_paint;
instance->update->EndPaint = (pEndPaint) wf_sw_end_paint;
@ -433,19 +439,21 @@ BOOL wf_post_connect(freerdp* instance)
}
pointer_cache_register_callbacks(instance->update);
wf_register_pointer(context->graphics);
if (wfc->sw_gdi != TRUE)
if (!settings->SoftwareGdi)
{
brush_cache_register_callbacks(instance->update);
bitmap_cache_register_callbacks(instance->update);
offscreen_cache_register_callbacks(instance->update);
wf_register_graphics(context->graphics);
instance->update->BitmapUpdate = wf_gdi_bitmap_update;
}
wf_register_graphics(instance->context->graphics);
freerdp_channels_post_connect(context->channels, instance);
freerdp_channels_post_connect(instance->context->channels, instance);
wf_cliprdr_init(wfc, context->channels);
wf_cliprdr_init(wfc, instance->context->channels);
if (wfc->fullscreen)
floatbar_window_create(wfc);
@ -1140,9 +1148,13 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context)
void wfreerdp_client_free(freerdp* instance, rdpContext* context)
{
wfContext* wfc = (wfContext*) context;
if (context->cache)
cache_free(context->cache);
_aligned_free(wfc->bitmap_buffer);
freerdp_channels_free(context->channels);
}

View File

@ -82,6 +82,8 @@ struct wf_context
int client_y;
int client_width;
int client_height;
UINT32 bitmap_size;
BYTE* bitmap_buffer;
HANDLE keyboardThread;
@ -112,7 +114,7 @@ struct wf_context
DWORD mainThreadId;
DWORD keyboardThreadId;
BOOL sw_gdi;
//BOOL sw_gdi;
rdpFile* connectionRdpFile;

View File

@ -20,11 +20,13 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/utils/event.h>
#include <winpr/stream.h>
#include <freerdp/client/cliprdr.h>
#include <Strsafe.h>

View File

@ -24,7 +24,8 @@
#include <Ole2.h>
#include <ShlObj.h>
#include "wf_interface.h"
#include "wf_client.h"
#ifdef WITH_DEBUG_CLIPRDR
#define DEBUG_CLIPRDR(fmt, ...) DEBUG_CLASS(WIN_CLIPRDR, fmt, ## __VA_ARGS__)

View File

@ -18,6 +18,7 @@
*/
#include <stdio.h>
#include "wf_cliprdr_EnumFORMATETC.h"
static void cliprdr_format_deep_copy(FORMATETC *dest, FORMATETC *source)

View File

@ -27,11 +27,12 @@
#include <freerdp/freerdp.h>
#include "wf_interface.h"
#include "wf_client.h"
#include "wf_gdi.h"
#include "wf_event.h"
#include "freerdp/event.h"
#include <freerdp/event.h>
static HWND g_focus_hWnd;

View File

@ -22,7 +22,7 @@
#ifndef __WF_EVENT_H
#define __WF_EVENT_H
#include "wf_interface.h"
#include "wf_client.h"
LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

View File

@ -17,15 +17,15 @@
* limitations under the License.
*/
#include <Windows.h>
#include <stdlib.h>
#include <winpr/crt.h>
#include <winpr/windows.h>
#include "wf_interface.h"
#include "wf_floatbar.h"
#include "wf_window.h"
#include "wf_gdi.h"
#include "resource.h"
#include "wf_client.h"
#include "wf_floatbar.h"
#include "wf_gdi.h"
typedef struct _Button Button;
/* TIMERs */

View File

@ -35,7 +35,7 @@
#include <freerdp/codec/rfx.h>
#include <freerdp/codec/nsc.h>
#include "wf_interface.h"
#include "wf_client.h"
#include "wf_graphics.h"
#include "wf_gdi.h"
@ -339,6 +339,106 @@ void wf_toggle_fullscreen(wfContext* wfc)
}
}
void wf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
HDC hdc;
int status;
int nXDst;
int nYDst;
int nXSrc;
int nYSrc;
int nWidth;
int nHeight;
HBITMAP dib;
UINT32 index;
BYTE* pSrcData;
BYTE* pDstData;
UINT32 SrcSize;
BOOL compressed;
UINT32 SrcFormat;
UINT32 bitsPerPixel;
UINT32 bytesPerPixel;
BITMAP_DATA* bitmap;
rdpCodecs* codecs = context->codecs;
wfContext* wfc = (wfContext*) context;
hdc = CreateCompatibleDC(GetDC(NULL));
for (index = 0; index < bitmapUpdate->number; index++)
{
bitmap = &(bitmapUpdate->rectangles[index]);
nXSrc = 0;
nYSrc = 0;
nXDst = bitmap->destLeft;
nYDst = bitmap->destTop;
nWidth = bitmap->width;
nHeight = bitmap->height;
pSrcData = bitmap->bitmapDataStream;
SrcSize = bitmap->bitmapLength;
compressed = bitmap->compressed;
bitsPerPixel = bitmap->bitsPerPixel;
bytesPerPixel = (bitsPerPixel + 7) / 8;
SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);
if (wfc->bitmap_size < (nWidth * nHeight * 4))
{
wfc->bitmap_size = nWidth * nHeight * 4;
wfc->bitmap_buffer = (BYTE*) _aligned_realloc(wfc->bitmap_buffer, wfc->bitmap_size, 16);
if (!wfc->bitmap_buffer)
return;
}
if (compressed)
{
pDstData = wfc->bitmap_buffer;
if (bitsPerPixel < 32)
{
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);
status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
&pDstData, PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight);
}
else
{
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);
status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight);
}
if (status < 0)
{
DEBUG_WARN("wf_gdi_bitmap_update: bitmap decompression failure\n");
return;
}
pSrcData = wfc->bitmap_buffer;
}
dib = wf_create_dib(wfc, nWidth, nHeight, 32, pSrcData, NULL);
SelectObject(hdc, dib);
nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */
nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */
BitBlt(wfc->primary->hdc, nXDst, nYDst, nWidth, nHeight, hdc, 0, 0, SRCCOPY);
gdi_InvalidateRegion(wfc->hdc, nXDst, nYDst, nWidth, nHeight);
DeleteObject(dib);
}
ReleaseDC(NULL, hdc);
}
void wf_gdi_palette_update(wfContext* wfc, PALETTE_UPDATE* palette)
{
@ -453,12 +553,12 @@ void wf_gdi_multi_opaque_rect(wfContext* wfc, MULTI_OPAQUE_RECT_ORDER* multi_opa
UINT32 brush_color;
DELTA_RECT* rectangle;
brush_color = freerdp_color_convert_var_rgb(multi_opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
for (i = 1; i < (int) multi_opaque_rect->numRectangles + 1; i++)
{
rectangle = &multi_opaque_rect->rectangles[i];
brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
rect.left = rectangle->left;
rect.top = rectangle->top;
rect.right = rectangle->left + rectangle->width;

View File

@ -22,7 +22,7 @@
#ifndef __WF_GDI_H
#define __WF_GDI_H
#include "wf_interface.h"
#include "wf_client.h"
void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height);
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data);
@ -31,6 +31,7 @@ void wf_update_offset(wfContext* wfc);
void wf_resize_window(wfContext* wfc);
void wf_toggle_fullscreen(wfContext* wfc);
void wf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate);
void wf_gdi_register_update_callbacks(rdpUpdate* update);
void wf_update_canvas_diff(wfContext* wfc);

View File

@ -146,55 +146,58 @@ void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap,
{
int status;
UINT16 size;
BYTE* pSrcData;
BYTE* pDstData;
UINT32 SrcSize;
UINT32 SrcFormat;
UINT32 bytesPerPixel;
size = width * height * (bpp / 8);
bytesPerPixel = (bpp + 7) / 8;
size = width * height * 4;
if (!bitmap->data)
bitmap->data = (BYTE*) _aligned_malloc(size, 16);
else
bitmap->data = (BYTE*) _aligned_realloc(bitmap->data, size, 16);
pSrcData = data;
SrcSize = (UINT32) length;
pDstData = bitmap->data;
if (compressed)
{
BYTE* pDstData;
UINT32 SrcSize;
SrcSize = (UINT32) length;
pDstData = bitmap->data;
if (bpp < 32)
{
freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED);
status = interleaved_decompress(wfc->codecs->interleaved, data, SrcSize, bpp,
&pDstData, PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
if (status < 0)
{
DEBUG_WARN("wf_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
status = interleaved_decompress(wfc->codecs->interleaved, pSrcData, SrcSize, bpp,
&pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height);
}
else
{
freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR);
status = planar_decompress(wfc->codecs->planar, data, SrcSize, &pDstData,
status = planar_decompress(wfc->codecs->planar, pSrcData, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
}
if (status < 0)
{
DEBUG_WARN("wf_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
if (status < 0)
{
DEBUG_WARN("wf_Bitmap_Decompress: Bitmap Decompression Failed\n");
return;
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
SrcFormat = gdi_get_pixel_format(bpp, TRUE);
status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0,
width, height, pSrcData, SrcFormat, width * bytesPerPixel, 0, 0);
}
bitmap->compressed = FALSE;
bitmap->length = size;
bitmap->bpp = bpp;
bitmap->bpp = 32;
}
void wf_Bitmap_SetSurface(wfContext* wfc, rdpBitmap* bitmap, BOOL primary)
@ -277,20 +280,12 @@ void wf_Pointer_SetDefault(wfContext* wfc)
}
/* Graphics Module */
void wf_register_graphics(rdpGraphics* graphics)
void wf_register_pointer(rdpGraphics* graphics)
{
rdpBitmap bitmap;
wfContext* wfc;
rdpPointer pointer;
ZeroMemory(&bitmap, sizeof(rdpBitmap));
bitmap.size = sizeof(wfBitmap);
bitmap.New = (pBitmap_New) wf_Bitmap_New;
bitmap.Free = (pBitmap_Free) wf_Bitmap_Free;
bitmap.Paint = (pBitmap_Paint) wf_Bitmap_Paint;
bitmap.Decompress = (pBitmap_Decompress) wf_Bitmap_Decompress;
bitmap.SetSurface = (pBitmap_SetSurface) wf_Bitmap_SetSurface;
wfc = (wfContext*) graphics->context;
ZeroMemory(&pointer, sizeof(rdpPointer));
pointer.size = sizeof(wfPointer);
@ -300,6 +295,25 @@ void wf_register_graphics(rdpGraphics* graphics)
pointer.SetNull = (pPointer_SetNull) wf_Pointer_SetNull;
pointer.SetDefault = (pPointer_SetDefault) wf_Pointer_SetDefault;
graphics_register_bitmap(graphics, &bitmap);
graphics_register_pointer(graphics, &pointer);
}
/* Graphics Module */
void wf_register_graphics(rdpGraphics* graphics)
{
wfContext* wfc;
rdpBitmap bitmap;
wfc = (wfContext*) graphics->context;
ZeroMemory(&bitmap, sizeof(rdpBitmap));
bitmap.size = sizeof(wfBitmap);
bitmap.New = (pBitmap_New) wf_Bitmap_New;
bitmap.Free = (pBitmap_Free) wf_Bitmap_Free;
bitmap.Paint = (pBitmap_Paint) wf_Bitmap_Paint;
bitmap.Decompress = (pBitmap_Decompress) wf_Bitmap_Decompress;
bitmap.SetSurface = (pBitmap_SetSurface) wf_Bitmap_SetSurface;
graphics_register_bitmap(graphics, &bitmap);
}

View File

@ -20,12 +20,13 @@
#ifndef __WF_GRAPHICS_H
#define __WF_GRAPHICS_H
#include "wf_interface.h"
#include "wf_client.h"
HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data, BYTE** pdata);
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data);
void wf_image_free(wfBitmap* image);
void wf_register_pointer(rdpGraphics* graphics);
void wf_register_graphics(rdpGraphics* graphics);
#endif /* WF_GRAPHICS */

View File

@ -21,12 +21,12 @@
#include "config.h"
#endif
#include <freerdp/utils/event.h>
#include <winpr/print.h>
#include <freerdp/utils/event.h>
#include <freerdp/utils/rail.h>
#include <freerdp/rail/rail.h>
#include "wf_window.h"
#include "wf_rail.h"
void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)

View File

@ -19,7 +19,7 @@
#ifndef __WF_RAIL_H
#define __WF_RAIL_H
#include "wf_interface.h"
#include "wf_client.h"
void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail);

View File

@ -31,6 +31,7 @@
void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
{
xfContext* xfc = (xfContext*) context;
rdpSettings* settings = context->settings;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
@ -38,7 +39,10 @@ void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEven
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
if (settings->SoftwareGdi)
gdi_graphics_pipeline_init(context->gdi, (RdpgfxClientContext*) e->pInterface);
else
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{
@ -49,6 +53,7 @@ void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEven
void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
{
xfContext* xfc = (xfContext*) context;
rdpSettings* settings = context->settings;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
@ -56,7 +61,10 @@ void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnect
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
if (settings->SoftwareGdi)
gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface);
else
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0)
{

View File

@ -863,16 +863,6 @@ BOOL xf_post_connect(freerdp *instance)
xfc->srcBpp = settings->ColorDepth;
xf_gdi_register_update_callbacks(instance->update);
xfc->hdc = gdi_CreateDC(xfc->clrconv, xfc->bpp);
if (settings->RemoteFxCodec)
{
xfc->codecs->rfx = rfx_context_new(FALSE);
}
if (settings->NSCodec)
{
xfc->codecs->nsc = nsc_context_new();
}
}
xfc->originalWidth = settings->DesktopWidth;
@ -892,7 +882,7 @@ BOOL xf_post_connect(freerdp *instance)
ZeroMemory(&gcv, sizeof(gcv));
if(xfc->modifierMap)
if (xfc->modifierMap)
XFreeModifiermap(xfc->modifierMap);
xfc->modifierMap = XGetModifierMapping(xfc->display);
@ -910,7 +900,7 @@ BOOL xf_post_connect(freerdp *instance)
(char*) xfc->primary_buffer, xfc->width, xfc->height, xfc->scanline_pad, 0);
xfc->bmp_codec_none = (BYTE *) malloc(64 * 64 * 4);
if (xfc->settings->SoftwareGdi)
if (settings->SoftwareGdi)
{
instance->update->BeginPaint = xf_sw_begin_paint;
instance->update->EndPaint = xf_sw_end_paint;
@ -925,13 +915,14 @@ BOOL xf_post_connect(freerdp *instance)
pointer_cache_register_callbacks(instance->update);
if (!xfc->settings->SoftwareGdi)
if (!settings->SoftwareGdi)
{
glyph_cache_register_callbacks(instance->update);
brush_cache_register_callbacks(instance->update);
bitmap_cache_register_callbacks(instance->update);
offscreen_cache_register_callbacks(instance->update);
palette_cache_register_callbacks(instance->update);
instance->update->BitmapUpdate = xf_gdi_bitmap_update;
}
instance->context->rail = rail_new(instance->settings);
@ -1108,24 +1099,6 @@ void xf_window_free(xfContext *xfc)
context->rail = NULL;
}
if (xfc->codecs->rfx)
{
rfx_context_free(xfc->codecs->rfx);
xfc->codecs->rfx = NULL;
}
if (xfc->codecs->nsc)
{
nsc_context_free(xfc->codecs->nsc);
xfc->codecs->nsc = NULL;
}
if (xfc->codecs->clear)
{
clear_context_free(xfc->codecs->clear);
xfc->codecs->clear = NULL;
}
if (xfc->clrconv)
{
freerdp_clrconv_free(xfc->clrconv);
@ -1505,22 +1478,29 @@ void xf_TerminateEventHandler(rdpContext *context, TerminateEventArgs *e)
static void xf_ScalingFactorChangeEventHandler(rdpContext *context, ScalingFactorChangeEventArgs *e)
{
xfContext *xfc = (xfContext *) context;
xfContext* xfc = (xfContext*) context;
xfc->settings->ScalingFactor += e->ScalingFactor;
if(xfc->settings->ScalingFactor > 1.2)
if (xfc->settings->ScalingFactor > 1.2)
xfc->settings->ScalingFactor = 1.2;
if(xfc->settings->ScalingFactor < 0.8)
if (xfc->settings->ScalingFactor < 0.8)
xfc->settings->ScalingFactor = 0.8;
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
xf_transform_window(xfc);
{
ResizeWindowEventArgs ev;
EventArgsInit(&ev, "xfreerdp");
ev.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
ev.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
PubSub_OnResizeWindow(((rdpContext *) xfc)->pubSub, xfc, &ev);
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &ev);
}
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
}
@ -1541,9 +1521,10 @@ static void xfreerdp_client_global_uninit()
static int xfreerdp_client_start(rdpContext *context)
{
xfContext *xfc = (xfContext *) context;
rdpSettings *settings = context->settings;
if(!settings->ServerHostname)
xfContext* xfc = (xfContext *) context;
rdpSettings* settings = context->settings;
if (!settings->ServerHostname)
{
DEBUG_WARN( "error: server hostname was not specified with /v:<server>[:port]\n");
return -1;
@ -1553,11 +1534,11 @@ static int xfreerdp_client_start(rdpContext *context)
return 0;
}
static int xfreerdp_client_stop(rdpContext *context)
static int xfreerdp_client_stop(rdpContext* context)
{
xfContext *xfc = (xfContext *) context;
assert(NULL != context);
if(context->settings->AsyncInput)
xfContext* xfc = (xfContext*) context;
if (context->settings->AsyncInput)
{
wMessageQueue *queue;
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
@ -1568,19 +1549,23 @@ static int xfreerdp_client_stop(rdpContext *context)
{
xfc->disconnect = TRUE;
}
if(xfc->thread)
if (xfc->thread)
{
CloseHandle(xfc->thread);
xfc->thread = NULL;
}
return 0;
}
static int xfreerdp_client_new(freerdp *instance, rdpContext *context)
static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
{
xfContext *xfc;
rdpSettings *settings;
xfc = (xfContext *) instance->context;
xfContext* xfc;
rdpSettings* settings;
xfc = (xfContext*) instance->context;
instance->PreConnect = xf_pre_connect;
instance->PostConnect = xf_post_connect;
instance->PostDisconnect = xf_post_disconnect;
@ -1588,27 +1573,36 @@ static int xfreerdp_client_new(freerdp *instance, rdpContext *context)
instance->VerifyCertificate = xf_verify_certificate;
instance->LogonErrorInfo = xf_logon_error_info;
context->channels = freerdp_channels_new();
settings = instance->settings;
xfc->settings = instance->context->settings;
PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler);
PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler);
return 0;
}
static void xfreerdp_client_free(freerdp *instance, rdpContext *context)
static void xfreerdp_client_free(freerdp* instance, rdpContext* context)
{
xfContext *xfc = (xfContext *) context;
if(context)
xfContext* xfc = (xfContext*) context;
if (context)
{
xf_window_free(xfc);
if(xfc->bmp_codec_none)
if (xfc->bmp_codec_none)
free(xfc->bmp_codec_none);
if(xfc->display)
if (xfc->bitmap_buffer)
_aligned_free(xfc->bitmap_buffer);
if (xfc->display)
XCloseDisplay(xfc->display);
}
}
int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS *pEntryPoints)
int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
{
pEntryPoints->Version = 1;
pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);

View File

@ -285,6 +285,108 @@ Pixmap xf_mono_bitmap_new(xfContext* xfc, int width, int height, BYTE* data)
return bitmap;
}
void xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
int status;
int nXDst;
int nYDst;
int nXSrc;
int nYSrc;
int nWidth;
int nHeight;
UINT32 index;
XImage* image;
BYTE* pSrcData;
BYTE* pDstData;
UINT32 SrcSize;
BOOL compressed;
UINT32 SrcFormat;
UINT32 bitsPerPixel;
UINT32 bytesPerPixel;
BITMAP_DATA* bitmap;
rdpCodecs* codecs = context->codecs;
xfContext* xfc = (xfContext*) context;
for (index = 0; index < bitmapUpdate->number; index++)
{
bitmap = &(bitmapUpdate->rectangles[index]);
nXSrc = 0;
nYSrc = 0;
nXDst = bitmap->destLeft;
nYDst = bitmap->destTop;
nWidth = bitmap->width;
nHeight = bitmap->height;
pSrcData = bitmap->bitmapDataStream;
SrcSize = bitmap->bitmapLength;
compressed = bitmap->compressed;
bitsPerPixel = bitmap->bitsPerPixel;
bytesPerPixel = (bitsPerPixel + 7) / 8;
SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);
if (xfc->bitmap_size < (nWidth * nHeight * 4))
{
xfc->bitmap_size = nWidth * nHeight * 4;
xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16);
if (!xfc->bitmap_buffer)
return;
}
if (compressed)
{
pDstData = xfc->bitmap_buffer;
if (bitsPerPixel < 32)
{
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);
status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
&pDstData, PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight);
}
else
{
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);
status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32_VF, nWidth * 4, 0, 0, nWidth, nHeight);
}
if (status < 0)
{
DEBUG_WARN("xf_gdi_bitmap_update: bitmap decompression failure\n");
return;
}
pSrcData = xfc->bitmap_buffer;
}
xf_lock_x11(xfc, FALSE);
XSetFunction(xfc->display, xfc->gc, GXcopy);
image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
(char*) pSrcData, nWidth, nHeight, xfc->scanline_pad, 0);
nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */
nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */
XPutImage(xfc->display, xfc->primary, xfc->gc,
image, 0, 0, nXDst, nYDst, nWidth, nHeight);
XFree(image);
gdi_InvalidateRegion(xfc->hdc, nXDst, nYDst, nWidth, nHeight);
xf_unlock_x11(xfc, FALSE);
}
}
void xf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
{
xfContext* xfc = (xfContext*) context;
@ -1022,7 +1124,7 @@ static void xf_gdi_surface_update_frame(xfContext* xfc, UINT16 tx, UINT16 ty, UI
}
}
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
{
int i, tx, ty;
XImage* image;
@ -1031,16 +1133,18 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
xf_lock_x11(xfc, FALSE);
if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
if (cmd->codecID == RDP_CODEC_ID_REMOTEFX)
{
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX);
message = rfx_process_message(xfc->codecs->rfx,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
cmd->bitmapData, cmd->bitmapDataLength);
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
XSetClipRectangles(xfc->display, xfc->gc,
surface_bits_command->destLeft, surface_bits_command->destTop,
cmd->destLeft, cmd->destTop,
(XRectangle*) message->rects, message->numRects, YXBanded);
/* Draw the tiles to primary surface, each is 64x64. */
@ -1049,8 +1153,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
(char*) message->tiles[i]->data, 64, 64, 32, 0);
tx = message->tiles[i]->x + surface_bits_command->destLeft;
ty = message->tiles[i]->y + surface_bits_command->destTop;
tx = message->tiles[i]->x + cmd->destLeft;
ty = message->tiles[i]->y + cmd->destTop;
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, tx, ty, 64, 64);
XFree(image);
@ -1059,8 +1163,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
/* Copy the updated region from backstore to the window. */
for (i = 0; i < message->numRects; i++)
{
tx = message->rects[i].x + surface_bits_command->destLeft;
ty = message->rects[i].y + surface_bits_command->destTop;
tx = message->rects[i].x + cmd->destLeft;
ty = message->rects[i].y + cmd->destTop;
if (xfc->remote_app != TRUE)
{
XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, tx, ty, message->rects[i].width, message->rects[i].height, tx, ty);
@ -1072,26 +1176,28 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
XSetClipMask(xfc->display, xfc->gc, None);
rfx_message_free(xfc->codecs->rfx, message);
}
else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC)
else if (cmd->codecID == RDP_CODEC_ID_NSCODEC)
{
nsc_process_message(xfc->codecs->nsc, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC);
nsc_process_message(xfc->codecs->nsc, cmd->bpp, cmd->width, cmd->height,
cmd->bitmapData, cmd->bitmapDataLength);
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
xfc->bmp_codec_nsc = (BYTE*) realloc(xfc->bmp_codec_nsc,
surface_bits_command->width * surface_bits_command->height * 4);
cmd->width * cmd->height * 4);
freerdp_image_flip(xfc->codecs->nsc->BitmapData, xfc->bmp_codec_nsc,
surface_bits_command->width, surface_bits_command->height, 32);
cmd->width, cmd->height, 32);
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
(char*) xfc->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0);
(char*) xfc->bmp_codec_nsc, cmd->width, cmd->height, 32, 0);
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
cmd->destLeft, cmd->destTop,
cmd->width, cmd->height);
XFree(image);
free(xfc->bmp_codec_nsc);
xfc->bmp_codec_nsc = NULL;
@ -1099,37 +1205,37 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
if (!xfc->remote_app)
{
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc,
surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height,
surface_bits_command->destLeft, surface_bits_command->destTop);
cmd->destLeft, cmd->destTop,
cmd->width, cmd->height,
cmd->destLeft, cmd->destTop);
}
xf_gdi_surface_update_frame(xfc,
surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
cmd->destLeft, cmd->destTop,
cmd->width, cmd->height);
XSetClipMask(xfc->display, xfc->gc, None);
}
else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)
else if (cmd->codecID == RDP_CODEC_ID_NONE)
{
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
/* Validate that the data received is large enough */
if ((surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8) <= (surface_bits_command->bitmapDataLength))
if ((cmd->width * cmd->height * cmd->bpp / 8) <= (cmd->bitmapDataLength))
{
xfc->bmp_codec_none = (BYTE*) realloc(xfc->bmp_codec_none,
surface_bits_command->width * surface_bits_command->height * 4);
cmd->width * cmd->height * 4);
freerdp_image_flip(surface_bits_command->bitmapData, xfc->bmp_codec_none,
surface_bits_command->width, surface_bits_command->height, 32);
freerdp_image_flip(cmd->bitmapData, xfc->bmp_codec_none,
cmd->width, cmd->height, 32);
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
(char*) xfc->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0);
(char*) xfc->bmp_codec_none, cmd->width, cmd->height, 32, 0);
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
cmd->destLeft, cmd->destTop,
cmd->width, cmd->height);
XFree(image);
free(xfc->bmp_codec_none);
xfc->bmp_codec_none = NULL;
@ -1137,24 +1243,25 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
if (xfc->remote_app != TRUE)
{
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc,
surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height,
surface_bits_command->destLeft, surface_bits_command->destTop);
cmd->destLeft, cmd->destTop,
cmd->width, cmd->height,
cmd->destLeft, cmd->destTop);
}
xf_gdi_surface_update_frame(xfc,
surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
cmd->destLeft, cmd->destTop,
cmd->width, cmd->height);
XSetClipMask(xfc->display, xfc->gc, None);
}
else
{
DEBUG_WARN( "Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height);
DEBUG_WARN("Invalid bitmap size - data is %d bytes for %dx%d\n update",
cmd->bitmapDataLength, cmd->width, cmd->height);
}
}
else
{
DEBUG_WARN( "Unsupported codecID %d\n", surface_bits_command->codecID);
DEBUG_WARN("Unsupported codecID %d\n", cmd->codecID);
}
xf_unlock_x11(xfc, FALSE);

View File

@ -26,5 +26,6 @@
#include "xfreerdp.h"
void xf_gdi_register_update_callbacks(rdpUpdate* update);
void xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate);
#endif /* __XF_GDI_H */

View File

@ -27,53 +27,7 @@ int xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* re
{
xfContext* xfc = (xfContext*) context->custom;
if (xfc->codecs->rfx)
{
rfx_context_free(xfc->codecs->rfx);
xfc->codecs->rfx = NULL;
}
xfc->codecs->rfx = rfx_context_new(FALSE);
xfc->codecs->rfx->width = resetGraphics->width;
xfc->codecs->rfx->height = resetGraphics->height;
rfx_context_set_pixel_format(xfc->codecs->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
if (xfc->codecs->nsc)
{
nsc_context_free(xfc->codecs->nsc);
xfc->codecs->nsc = NULL;
}
xfc->codecs->nsc = nsc_context_new();
xfc->codecs->nsc->width = resetGraphics->width;
xfc->codecs->nsc->height = resetGraphics->height;
nsc_context_set_pixel_format(xfc->codecs->nsc, RDP_PIXEL_FORMAT_B8G8R8A8);
if (xfc->codecs->clear)
{
clear_context_free(xfc->codecs->clear);
xfc->codecs->clear = NULL;
}
xfc->codecs->clear = clear_context_new(FALSE);
if (xfc->codecs->h264)
{
h264_context_free(xfc->codecs->h264);
xfc->codecs->h264 = NULL;
}
xfc->codecs->h264 = h264_context_new(FALSE);
if (xfc->codecs->progressive)
{
progressive_context_free(xfc->codecs->progressive);
xfc->codecs->progressive = NULL;
}
xfc->codecs->progressive = progressive_context_new(TRUE);
freerdp_client_codecs_reset(xfc->codecs, FREERDP_CODEC_ALL);
region16_init(&(xfc->invalidRegion));
@ -618,7 +572,8 @@ int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* de
context->SetSurfaceData(context, deleteSurface->surfaceId, NULL);
progressive_delete_surface_context(xfc->codecs->progressive, deleteSurface->surfaceId);
if (xfc->codecs->progressive)
progressive_delete_surface_context(xfc->codecs->progressive, deleteSurface->surfaceId);
return 1;
}

View File

@ -23,6 +23,8 @@
#include "xf_client.h"
#include "xfreerdp.h"
#include <freerdp/gdi/gfx.h>
struct xf_gfx_surface
{
UINT16 surfaceId;

View File

@ -40,39 +40,24 @@
void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
{
BYTE* data;
Pixmap pixmap;
XImage* image;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfc, FALSE);
XSetFunction(xfc->display, xfc->gc, GXcopy);
pixmap = XCreatePixmap(xfc->display, xfc->drawable, bitmap->width, bitmap->height, xfc->depth);
if (bitmap->data)
{
data = freerdp_image_convert(bitmap->data, NULL,
bitmap->width, bitmap->height, context->settings->ColorDepth, xfc->bpp, xfc->clrconv);
XSetFunction(xfc->display, xfc->gc, GXcopy);
if (bitmap->ephemeral != TRUE)
{
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
ZPixmap, 0, (char*) data, bitmap->width, bitmap->height, xfc->scanline_pad, 0);
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, xfc->scanline_pad, 0);
XPutImage(xfc->display, pixmap, xfc->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height);
XFree(image);
XPutImage(xfc->display, pixmap, xfc->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height);
if (data != bitmap->data)
_aligned_free(data);
}
else
{
if (data != bitmap->data)
_aligned_free(bitmap->data);
bitmap->data = data;
}
XFree(image);
}
((xfBitmap*) bitmap)->pixmap = pixmap;
@ -124,105 +109,59 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
{
int status;
UINT16 size;
BYTE* src;
BYTE* dst;
int yindex;
int xindex;
RFX_MESSAGE* msg;
BYTE* pSrcData;
BYTE* pDstData;
UINT32 SrcSize;
UINT32 SrcFormat;
UINT32 bytesPerPixel;
xfContext* xfc = (xfContext*) context;
size = width * height * ((bpp + 7) / 8);
bytesPerPixel = (bpp + 7) / 8;
size = width * height * 4;
if (!bitmap->data)
bitmap->data = (BYTE*) _aligned_malloc(size, 16);
else
bitmap->data = (BYTE*) _aligned_realloc(bitmap->data, size, 16);
switch (codecId)
pSrcData = data;
SrcSize = (UINT32) length;
pDstData = bitmap->data;
if (compressed)
{
case RDP_CODEC_ID_NSCODEC:
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC);
DEBUG_WARN("xf_Bitmap_Decompress: nsc not done\n");
break;
if (bpp < 32)
{
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_INTERLEAVED);
case RDP_CODEC_ID_REMOTEFX:
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX);
rfx_context_set_pixel_format(xfc->codecs->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(xfc->codecs->rfx, data, length);
status = interleaved_decompress(xfc->codecs->interleaved, pSrcData, SrcSize, bpp,
&pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height);
}
else
{
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR);
if (!msg)
{
DEBUG_WARN("xf_Bitmap_Decompress: rfx Decompression Failed\n");
}
else
{
for (yindex = 0; yindex < height; yindex++)
{
src = msg->tiles[0]->data + yindex * 64 * 4;
dst = bitmap->data + yindex * width * 3;
for (xindex = 0; xindex < width; xindex++)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
src++;
}
}
rfx_message_free(xfc->codecs->rfx, msg);
}
break;
status = planar_decompress(xfc->codecs->planar, pSrcData, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
}
case RDP_CODEC_ID_JPEG:
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
{
DEBUG_WARN( "xf_Bitmap_Decompress: jpeg Decompression Failed\n");
}
break;
if (status < 0)
{
DEBUG_WARN("xf_Bitmap_Decompress: Bitmap Decompression Failed\n");
return;
}
}
else
{
SrcFormat = gdi_get_pixel_format(bpp, TRUE);
default:
if (compressed)
{
BYTE* pDstData;
UINT32 SrcSize;
SrcSize = (UINT32) length;
pDstData = bitmap->data;
if (bpp < 32)
{
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_INTERLEAVED);
status = interleaved_decompress(xfc->codecs->interleaved, data, SrcSize, bpp,
&pDstData, PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
if (status < 0)
{
DEBUG_WARN("xf_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
}
else
{
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR);
status = planar_decompress(xfc->codecs->planar, data, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
if (status < 0)
{
DEBUG_WARN("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
}
break;
status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0,
width, height, pSrcData, SrcFormat, width * bytesPerPixel, 0, 0);
}
bitmap->compressed = FALSE;
bitmap->length = size;
bitmap->bpp = bpp;
bitmap->bpp = 32;
}
void xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)

View File

@ -24,6 +24,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <winpr/wlog.h>
#include <freerdp/utils/event.h>
#include <winpr/print.h>
#include <freerdp/utils/rail.h>
@ -32,6 +33,8 @@
#include "xf_window.h"
#include "xf_rail.h"
#define TAG "com.freerdp.client.X11"
#ifdef WITH_DEBUG_X11_LOCAL_MOVESIZE
#define DEBUG_X11_LMS(fmt, ...) DEBUG_CLASS(X11_LMS, fmt, ## __VA_ARGS__)
#else
@ -66,9 +69,8 @@ void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT3
UINT32 iwidth, iheight;
INT32 ileft, itop;
UINT32 iright, ibottom;
INT32 wleft, wtop;
INT32 wleft, wtop;
UINT32 wright, wbottom;
window_list_rewind(rail->list);
while (window_list_has_next(rail->list))
@ -76,26 +78,23 @@ void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT3
window = window_list_get_next(rail->list);
xfw = (xfWindow*) window->extra;
/* RDP can have zero width or height windows. X cannot, so we ignore these. */
/* RDP can have zero width or height windows. X cannot, so we ignore these. */
if ((window->windowWidth == 0) || (window->windowHeight == 0))
{
continue;
}
if ((window->windowWidth == 0) || (window->windowHeight == 0))
{
continue;
}
wleft = window->visibleOffsetX;
wtop = window->visibleOffsetY;
wright = window->visibleOffsetX + window->windowWidth - 1;
wbottom = window->visibleOffsetY + window->windowHeight - 1;
ileft = MAX(uleft, wleft);
itop = MAX(utop, wtop);
iright = MIN(uright, wright);
ibottom = MIN(ubottom, wbottom);
iwidth = iright - ileft + 1;
iheight = ibottom - itop + 1;
intersect = ((iright > ileft) && (ibottom > itop)) ? TRUE : FALSE;
if (intersect)
@ -105,10 +104,9 @@ void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT3
}
}
void xf_rail_DesktopNonMonitored(rdpRail *rail, rdpWindow* window)
void xf_rail_DesktopNonMonitored(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
xfc = (xfContext*) rail->extra;
xf_rail_disable_remoteapp_mode(xfc);
}
@ -117,19 +115,13 @@ static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
xfWindow* xfw;
xfc = (xfContext*) rail->extra;
xf_rail_enable_remoteapp_mode(xfc);
xfw = xf_CreateWindow(xfc, window,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight, window->windowId);
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight, window->windowId);
xf_SetWindowStyle(xfc, xfw, window->style, window->extendedStyle);
xf_SetWindowText(xfc, xfw, window->title);
window->extra = (void*) xfw;
window->extraId = (void*) xfw->handle;
}
@ -138,7 +130,6 @@ static void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
xfWindow* xfw;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
@ -148,35 +139,33 @@ static void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
* update our local window when that rail window state is minimized
*/
if (xfw->rail_state == WINDOW_SHOW_MINIMIZED)
return;
return;
/* Do nothing if window is already in the correct position */
if ( xfw->left == window->visibleOffsetX &&
xfw->top == window->visibleOffsetY &&
xfw->width == window->windowWidth &&
xfw->height == window->windowHeight)
{
/*
* Just ensure entire window area is updated to handle cases where we
* have drawn locally before getting new bitmap from the server
*/
xf_UpdateWindowArea(xfc, xfw, 0, 0, window->windowWidth, window->windowHeight);
return;
}
if (xfw->left == window->visibleOffsetX &&
xfw->top == window->visibleOffsetY &&
xfw->width == window->windowWidth &&
xfw->height == window->windowHeight)
{
/*
* Just ensure entire window area is updated to handle cases where we
* have drawn locally before getting new bitmap from the server
*/
xf_UpdateWindowArea(xfc, xfw, 0, 0, window->windowWidth, window->windowHeight);
return;
}
xf_MoveWindow(xfc, xfw,
window->visibleOffsetX, window->visibleOffsetY,
window->windowWidth, window->windowHeight);
window->visibleOffsetX, window->visibleOffsetY,
window->windowWidth, window->windowHeight);
}
static void xf_rail_ShowWindow(rdpRail* rail, rdpWindow* window, BYTE state)
{
xfContext* xfc;
xfWindow* xfw;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_ShowWindow(xfc, xfw, state);
}
@ -184,10 +173,8 @@ static void xf_rail_SetWindowText(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
xfWindow* xfw;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowText(xfc, xfw, window->title);
}
@ -195,13 +182,10 @@ static void xf_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* ico
{
xfContext* xfc;
xfWindow* xfw;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
icon->extra = freerdp_icon_convert(icon->entry->bitsColor, NULL, icon->entry->bitsMask,
icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv);
icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv);
xf_SetWindowIcon(xfc, xfw, icon);
}
@ -209,10 +193,8 @@ static void xf_rail_SetWindowRects(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
xfWindow* xfw;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowRects(xfc, xfw, window->windowRects, window->numWindowRects);
}
@ -220,10 +202,8 @@ static void xf_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window)
{
xfWindow* xfw;
xfContext* xfc;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowVisibilityRects(xfc, xfw, window->windowRects, window->numWindowRects);
}
@ -231,10 +211,8 @@ static void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
{
xfWindow* xfw;
xfContext* xfc;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_DestroyWindow(xfc, xfw);
}
@ -261,14 +239,12 @@ static void xf_send_rail_client_event(rdpChannels* channels, UINT16 event_type,
{
wMessage* out_event = NULL;
void* payload = NULL;
payload = rail_clone_order(event_type, param);
if (payload != NULL)
{
out_event = freerdp_event_new(RailChannel_Class, event_type,
xf_on_free_rail_client_event, payload);
xf_on_free_rail_client_event, payload);
freerdp_channels_send_event(channels, out_event);
}
}
@ -279,10 +255,8 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
rdpChannels* channels;
rdpWindow* rail_window;
RAIL_ACTIVATE_ORDER activate;
rail = ((rdpContext*) xfc)->rail;
channels = ((rdpContext*) xfc)->channels;
rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow);
if (rail_window == NULL)
@ -290,7 +264,6 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
activate.windowId = rail_window->windowId;
activate.enabled = enabled;
xf_send_rail_client_event(channels, RailChannel_ClientActivate, &activate);
}
@ -298,12 +271,9 @@ void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16
{
rdpChannels* channels;
RAIL_SYSCOMMAND_ORDER syscommand;
channels = ((rdpContext*) xfc)->channels;
syscommand.windowId = windowId;
syscommand.command = command;
xf_send_rail_client_event(channels, RailChannel_ClientSystemCommand, &syscommand);
}
@ -318,7 +288,6 @@ void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window)
xfWindow* xfw;
rdpChannels* channels;
RAIL_WINDOW_MOVE_ORDER window_move;
xfw = (xfWindow*) window->extra;
channels = ((rdpContext*) xfc)->channels;
@ -326,24 +295,24 @@ void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window)
return;
/* If current window position disagrees with RDP window position, send update to RDP server */
if ( xfw->left != window->visibleOffsetX ||
xfw->top != window->visibleOffsetY ||
xfw->width != window->windowWidth ||
xfw->height != window->windowHeight)
{
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0
* when attempting to adjust the rail window.
*/
UINT32 offsetX = 0;
UINT32 offsetY = 0;
if (xfw->left != window->visibleOffsetX ||
xfw->top != window->visibleOffsetY ||
xfw->width != window->windowWidth ||
xfw->height != window->windowHeight)
{
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0
* when attempting to adjust the rail window.
*/
UINT32 offsetX = 0;
UINT32 offsetY = 0;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
/*
* windowOffset corresponds to the window location on the rail server
@ -351,30 +320,26 @@ void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window)
* can result in blank areas for a maximized window
*/
window_move.windowId = window->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
window_move.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
window_move.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
window_move.right = window_move.left + xfw->width;
window_move.bottom = window_move.top + xfw->height;
window_move.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
window_move.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
window_move.right = window_move.left + xfw->width;
window_move.bottom = window_move.top + xfw->height;
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u"
" RDP=0x%X rc={l=%d t=%d} w=%d h=%d",
(UINT32) xfw->handle, window_move.left, window_move.top,
window_move.right, window_move.bottom, xfw->width, xfw->height,
window->windowId,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight);
" RDP=0x%X rc={l=%d t=%d} w=%d h=%d",
(UINT32) xfw->handle, window_move.left, window_move.top,
window_move.right, window_move.bottom, xfw->width, xfw->height,
window->windowId,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight);
xf_send_rail_client_event(channels, RailChannel_ClientWindowMove, &window_move);
}
}
}
void xf_rail_end_local_move(xfContext* xfc, rdpWindow *window)
void xf_rail_end_local_move(xfContext* xfc, rdpWindow* window)
{
xfWindow* xfw;
rdpChannels* channels;
@ -386,119 +351,103 @@ void xf_rail_end_local_move(xfContext* xfc, rdpWindow *window)
unsigned int mask;
int child_x;
int child_y;
xfw = (xfWindow*) window->extra;
channels = ((rdpContext*) xfc)->channels;
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d",
(UINT32) xfw->handle,
xfw->left, xfw->top, xfw->right, xfw->bottom,
xfw->width, xfw->height);
(UINT32) xfw->handle,
xfw->left, xfw->top, xfw->right, xfw->bottom,
xfw->width, xfw->height);
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0 when
* attempting to adjust the rail window.
*/
UINT32 offsetX = 0;
UINT32 offsetY = 0;
UINT32 offsetY = 0;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
/*
* For keyboard moves send and explicit update to RDP server
*/
/*
* For keyboard moves send and explicit update to RDP server
*/
window_move.windowId = window->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
window_move.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
window_move.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
window_move.right = window_move.left + xfw->width; /* In the update to RDP the position is one past the window */
window_move.bottom = window_move.top + xfw->height;
window_move.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
window_move.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
window_move.right = window_move.left + xfw->width; /* In the update to RDP the position is one past the window */
window_move.bottom = window_move.top + xfw->height;
xf_send_rail_client_event(channels, RailChannel_ClientWindowMove, &window_move);
/*
* Simulate button up at new position to end the local move (per RDP spec)
*/
XQueryPointer(xfc->display, xfw->handle,
&root_window, &child_window,
&x, &y, &child_x, &child_y, &mask);
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
XQueryPointer(xfc->display, xfw->handle,
&root_window, &child_window,
&x, &y, &child_x, &child_y, &mask);
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
/* only send the mouse coordinates if not a keyboard move or size */
if ((xfw->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
(xfw->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
{
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
DEBUG_X11_LMS("Mouse coordinates. x= %i, y= %i", x, y);
}
(xfw->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
{
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
DEBUG_X11_LMS("Mouse coordinates. x= %i, y= %i", x, y);
}
/*
* Proactively update the RAIL window dimensions. There is a race condition where
* we can start to receive GDI orders for the new window dimensions before we
* receive the RAIL ORDER for the new window size. This avoids that race condition.
*/
window->windowOffsetX = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
window->windowOffsetY = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
window->windowOffsetX = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
window->windowOffsetY = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
window->windowWidth = xfw->width;
window->windowHeight = xfw->height;
xfw->local_move.state = LMS_TERMINATING;
}
void xf_process_rail_get_sysparams_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_SYSPARAM_ORDER* sysparam;
sysparam = (RAIL_SYSPARAM_ORDER*) event->wParam;
sysparam->workArea.left = xfc->workArea.x;
sysparam->workArea.top = xfc->workArea.y;
sysparam->workArea.right = xfc->workArea.x + xfc->workArea.width;
sysparam->workArea.bottom = xfc->workArea.y + xfc->workArea.height;
sysparam->taskbarPos.left = 0;
sysparam->taskbarPos.top = 0;
sysparam->taskbarPos.right = 0;
sysparam->taskbarPos.bottom = 0;
sysparam->dragFullWindows = FALSE;
xf_send_rail_client_event(channels, RailChannel_ClientSystemParam, sysparam);
}
const char* error_code_names[] =
{
"RAIL_EXEC_S_OK",
"RAIL_EXEC_E_HOOK_NOT_LOADED",
"RAIL_EXEC_E_DECODE_FAILED",
"RAIL_EXEC_E_NOT_IN_ALLOWLIST",
"RAIL_EXEC_E_FILE_NOT_FOUND",
"RAIL_EXEC_E_FAIL",
"RAIL_EXEC_E_SESSION_LOCKED"
"RAIL_EXEC_S_OK",
"RAIL_EXEC_E_HOOK_NOT_LOADED",
"RAIL_EXEC_E_DECODE_FAILED",
"RAIL_EXEC_E_NOT_IN_ALLOWLIST",
"RAIL_EXEC_E_FILE_NOT_FOUND",
"RAIL_EXEC_E_FAIL",
"RAIL_EXEC_E_SESSION_LOCKED"
};
void xf_process_rail_exec_result_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_EXEC_RESULT_ORDER* exec_result;
exec_result = (RAIL_EXEC_RESULT_ORDER*) event->wParam;
if (exec_result->execResult != RAIL_EXEC_S_OK)
{
DEBUG_WARN( "RAIL exec error: execResult=%s NtError=0x%X\n",
error_code_names[exec_result->execResult], exec_result->rawResult);
DEBUG_WARN("RAIL exec error: execResult=%s NtError=0x%X\n",
error_code_names[exec_result->execResult], exec_result->rawResult);
xfc->disconnect = True;
}
else
@ -526,24 +475,21 @@ void xf_process_rail_server_minmaxinfo_event(xfContext* xfc, rdpChannels* channe
rdpRail* rail;
rdpWindow* rail_window = NULL;
RAIL_MINMAXINFO_ORDER* minmax = (RAIL_MINMAXINFO_ORDER*) event->wParam;
rail = ((rdpContext*) xfc)->rail;
rail_window = window_list_get_by_id(rail->list, minmax->windowId);
if (rail_window != NULL)
{
xfWindow * window = NULL;
window = (xfWindow *) rail_window->extra;
xfWindow* window = NULL;
window = (xfWindow*) rail_window->extra;
DEBUG_X11_LMS("windowId=0x%X maxWidth=%d maxHeight=%d maxPosX=%d maxPosY=%d "
"minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d",
minmax->windowId, minmax->maxWidth, minmax->maxHeight,
(INT16)minmax->maxPosX, (INT16)minmax->maxPosY,
minmax->minTrackWidth, minmax->minTrackHeight,
minmax->maxTrackWidth, minmax->maxTrackHeight);
"minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d",
minmax->windowId, minmax->maxWidth, minmax->maxHeight,
(INT16)minmax->maxPosX, (INT16)minmax->maxPosY,
minmax->minTrackWidth, minmax->minTrackHeight,
minmax->maxTrackWidth, minmax->maxTrackHeight);
xf_SetWindowMinMaxInfo(xfc, window, minmax->maxWidth, minmax->maxHeight, minmax->maxPosX, minmax->maxPosY,
minmax->minTrackWidth, minmax->minTrackHeight, minmax->maxTrackWidth, minmax->maxTrackHeight);
minmax->minTrackWidth, minmax->minTrackHeight, minmax->maxTrackWidth, minmax->maxTrackHeight);
}
}
@ -571,7 +517,6 @@ void xf_process_rail_server_localmovesize_event(xfContext* xfc, rdpChannels* cha
Window child_window;
rdpWindow* rail_window = NULL;
RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*) event->wParam;
rail = ((rdpContext*) xfc)->rail;
rail_window = window_list_get_by_id(rail->list, movesize->windowId);
@ -579,10 +524,9 @@ void xf_process_rail_server_localmovesize_event(xfContext* xfc, rdpChannels* cha
{
xfWindow* xfw = NULL;
xfw = (xfWindow*) rail_window->extra;
DEBUG_X11_LMS("windowId=0x%X isMoveSizeStart=%d moveSizeType=%s PosX=%d PosY=%d",
movesize->windowId, movesize->isMoveSizeStart,
movetype_names[movesize->moveSizeType], (INT16) movesize->posX, (INT16) movesize->posY);
movesize->windowId, movesize->isMoveSizeStart,
movetype_names[movesize->moveSizeType], (INT16) movesize->posX, (INT16) movesize->posY);
switch (movesize->moveSizeType)
{
@ -591,53 +535,63 @@ void xf_process_rail_server_localmovesize_event(xfContext* xfc, rdpChannels* cha
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_RIGHT: //0x2
direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_TOP: //0x3
direction = _NET_WM_MOVERESIZE_SIZE_TOP;
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_TOPLEFT: //0x4
direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_TOPRIGHT: //0x5
direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_BOTTOM: //0x6
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_BOTTOMLEFT: //0x7
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_BOTTOMRIGHT: //0x8
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
x = movesize->posX;
y = movesize->posY;
break;
case RAIL_WMSZ_MOVE: //0x9
direction = _NET_WM_MOVERESIZE_MOVE;
XTranslateCoordinates(xfc->display, xfw->handle,
RootWindowOfScreen(xfc->screen),
movesize->posX, movesize->posY, &x, &y, &child_window);
XTranslateCoordinates(xfc->display, xfw->handle,
RootWindowOfScreen(xfc->screen),
movesize->posX, movesize->posY, &x, &y, &child_window);
break;
case RAIL_WMSZ_KEYMOVE: //0xA
direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD;
x = movesize->posX;
y = movesize->posY;
/* FIXME: local keyboard moves not working */
return;
case RAIL_WMSZ_KEYSIZE: //0xB
direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
x = movesize->posX;
@ -649,7 +603,9 @@ void xf_process_rail_server_localmovesize_event(xfContext* xfc, rdpChannels* cha
if (movesize->isMoveSizeStart)
{
xf_StartLocalMoveSize(xfc, xfw, direction, x, y);
} else {
}
else
{
xf_EndLocalMoveSize(xfc, xfw);
}
}
@ -659,21 +615,18 @@ void xf_process_rail_appid_resp_event(xfContext* xfc, rdpChannels* channels, wMe
{
RAIL_GET_APPID_RESP_ORDER* appid_resp =
(RAIL_GET_APPID_RESP_ORDER*) event->wParam;
DEBUG_WARN( "Server Application ID Response PDU: windowId=0x%X "
"applicationId=(length=%d dump)\n",
appid_resp->windowId, 512);
winpr_HexDump((BYTE*) &appid_resp->applicationId, 512);
DEBUG_WARN("Server Application ID Response PDU: windowId=0x%X "
"applicationId=(length=%d dump)\n",
appid_resp->windowId, 512);
winpr_HexDump(TAG, WLOG_ERROR, (BYTE*) &appid_resp->applicationId, 512);
}
void xf_process_rail_langbarinfo_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_LANGBAR_INFO_ORDER* langbar =
(RAIL_LANGBAR_INFO_ORDER*) event->wParam;
DEBUG_WARN( "Language Bar Information PDU: languageBarStatus=0x%X\n",
langbar->languageBarStatus);
DEBUG_WARN("Language Bar Information PDU: languageBarStatus=0x%X\n",
langbar->languageBarStatus);
}
void xf_process_rail_event(xfContext* xfc, rdpChannels* channels, wMessage* event)

View File

@ -113,6 +113,8 @@ struct xf_context
BOOL cursorHidden;
HGDI_DC hdc;
UINT32 bitmap_size;
BYTE* bitmap_buffer;
BYTE* primary_buffer;
REGION16 invalidRegion;
BOOL inGfxFrame;

View File

@ -37,6 +37,8 @@
#include "test_mppc.h"
#include "test_mppc_enc.h"
#define TAG __FILE__
void dump_data(unsigned char * p, int len, int width, char* name)
{
unsigned char *line = p;
@ -77,10 +79,10 @@ void assert_stream(wStream* s, BYTE* data, int length, const char* func, int lin
printf("\n %s (%d): length mismatch, actual:%d, expected:%d\n", func, line, actual_length, length);
printf("\nActual:\n");
winpr_HexDump(actual_data, actual_length);
winpr_HexDump(TAG, WLOG_ERR, actual_data, actual_length);
printf("Expected:\n");
winpr_HexDump(data, length);
winpr_HexDump(TAG, WLOG_ERR, data, length);
CU_FAIL("assert_stream, length mismatch");
return;
@ -93,10 +95,10 @@ void assert_stream(wStream* s, BYTE* data, int length, const char* func, int lin
printf("\n %s (%d): buffer mismatch:\n", func, line);
printf("\nActual:\n");
winpr_HexDump(actual_data, length);
winpr_HexDump(TAG, WLOG_ERR, actual_data, length);
printf("Expected:\n");
winpr_HexDump(data, length);
winpr_HexDump(TAG, WLOG_ERR, data, length);
CU_FAIL("assert_stream, buffer mismatch");
return;

View File

@ -21,38 +21,23 @@
#define FREERDP_CHANNELS_LOG_H
#include <winpr/wlog.h>
#include <freerdp/log.h>
#define CLOG_PRINT(level, file, fkt, line, dbg_str, fmt, ...) \
do { \
char tag[1024] = { 0 }; \
wLogMessage msg; \
wLog *log; \
\
strncat(tag, "com.freerdp.channels.", sizeof(tag) - 1); \
strncat(tag, dbg_str, sizeof(tag) - 1 - sizeof("com.freerdp.channels.")); \
log = WLog_Get(tag); \
\
msg.Type = WLOG_MESSAGE_TEXT; \
msg.Level = level; \
msg.FormatString = fmt; \
msg.LineNumber = line; \
msg.FileName = file; \
msg.FunctionName = fkt; \
WLog_PrintMessage(log, &msg, ##__VA_ARGS__); \
} while (0 )
#define CHANNELS_TAG(tag) FREERDP_TAG("channels.") tag
/* NOTE: Do not use these defines, they will be removed soon! */
#define CLOG_NULL(fmt, ...) do { } while (0)
#define CLOG_CLASS(_dbg_class, fmt, ...) CLOG_PRINT(WLOG_ERROR, __FILE__, \
__FUNCTION__, __LINE__, #_dbg_class, fmt, ## __VA_ARGS__)
#define CLOG_DBG(fmt, ...) CLOG_PRINT(WLOG_DEBUG, __FILE__, __FUNCTION__, \
__LINE__, __FUNCTION__, fmt, ## __VA_ARGS__)
#define CLOG_INFO(fmt, ...) CLOG_PRINT(WLOG_INFO, __FILE__, __FUNCTION__, \
__LINE__, __FUNCTION__, fmt, ## __VA_ARGS__)
#define CLOG_WARN(fmt, ...) CLOG_PRINT(WLOG_WARN, __FILE__, __FUNCTION__, \
__LINE__, __FUNCTION__, fmt, ## __VA_ARGS__)
#define CLOG_ERR(fmt, ...) CLOG_PRINT(WLOG_ERROR, __FILE__, __FUNCTION__, \
__LINE__, __FUNCTION__, fmt, ## __VA_ARGS__)
#define CLOG_FATAL(fmt, ...) CLOG_PRINT(WLOG_FATAL, __FILE__, __FUNCTION__, \
__LINE__, __FUNCTION__, fmt, ## __VA_ARGS__)
#define CLOG_CLASS(_dbg_class, fmt, ...) WLog_LVL(CHANNELS_TAG("legacy." #_dbg_class), \
WLOG_ERROR, fmt, ## __VA_ARGS__)
#define CLOG_DBG(fmt, ...) WLog_LVL(CHANNELS_TAG("legacy"), \
WLOG_DEBUG, fmt, ## __VA_ARGS__)
#define CLOG_INFO(fmt, ...) WLog_LVL(CHANNELS_TAG("legacy"), \
WLOG_INFO, fmt, ## __VA_ARGS__)
#define CLOG_WARN(fmt, ...) WLog_LVL(CHANNELS_TAG("legacy"), \
WLOG_WARN, fmt, ## __VA_ARGS__)
#define CLOG_ERR(fmt, ...) WLog_LVL(CHANNELS_TAG("legacy"), \
WLOG_ERROR, fmt, ## __VA_ARGS__)
#define CLOG_FATAL(fmt, ...) WLog_LVL(CHANNELS_TAG("legacy"), \
WLOG_FATAL, fmt, ## __VA_ARGS__)
#endif /* FREERDP_UTILS_DEBUG_H */

View File

@ -71,7 +71,7 @@ FREERDP_API int clear_compress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcS
FREERDP_API int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
FREERDP_API void clear_context_reset(CLEAR_CONTEXT* clear);
FREERDP_API int clear_context_reset(CLEAR_CONTEXT* clear);
FREERDP_API CLEAR_CONTEXT* clear_context_new(BOOL Compressor);
FREERDP_API void clear_context_free(CLEAR_CONTEXT* clear);

View File

@ -108,56 +108,101 @@
/* 24bpp formats */
#define PIXEL_FORMAT_R8G8B8 FREERDP_PIXEL_FORMAT(0, 24, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8)
#define PIXEL_FORMAT_R8G8B8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 24, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8)
#define PIXEL_FORMAT_R8G8B8 PIXEL_FORMAT_R8G8B8_F(0)
#define PIXEL_FORMAT_RGB24 PIXEL_FORMAT_R8G8B8
#define PIXEL_FORMAT_R8G8B8_VF PIXEL_FORMAT_R8G8B8_F(1)
#define PIXEL_FORMAT_RGB24_VF PIXEL_FORMAT_R8G8B8_VF
#define PIXEL_FORMAT_B8G8R8 FREERDP_PIXEL_FORMAT(0, 24, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8)
#define PIXEL_FORMAT_B8G8R8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 24, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8)
#define PIXEL_FORMAT_B8G8R8 PIXEL_FORMAT_B8G8R8_F(0)
#define PIXEL_FORMAT_BGR24 PIXEL_FORMAT_B8G8R8
#define PIXEL_FORMAT_B8G8R8_VF PIXEL_FORMAT_B8G8R8_F(1)
#define PIXEL_FORMAT_BGR24_VF PIXEL_FORMAT_B8G8R8_VF
/* 16bpp formats */
#define PIXEL_FORMAT_R5G6B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 6, 5)
#define PIXEL_FORMAT_R5G6B5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 6, 5)
#define PIXEL_FORMAT_R5G6B5 PIXEL_FORMAT_R5G6B5_F(0)
#define PIXEL_FORMAT_RGB565 PIXEL_FORMAT_R5G6B5
#define PIXEL_FORMAT_RGB16 PIXEL_FORMAT_R5G6B5
#define PIXEL_FORMAT_R5G6B5_VF PIXEL_FORMAT_R5G6B5_F(1)
#define PIXEL_FORMAT_RGB565_VF PIXEL_FORMAT_R5G6B5_VF
#define PIXEL_FORMAT_RGB16_VF PIXEL_FORMAT_R5G6B5_VF
#define PIXEL_FORMAT_B5G6R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 6, 5)
#define PIXEL_FORMAT_B5G6R5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 6, 5)
#define PIXEL_FORMAT_B5G6R5 PIXEL_FORMAT_B5G6R5_F(0)
#define PIXEL_FORMAT_BGR565 PIXEL_FORMAT_B5G6R5
#define PIXEL_FORMAT_BGR16 PIXEL_FORMAT_B5G6R5
#define PIXEL_FORMAT_B5G6R5_VF PIXEL_FORMAT_B5G6R5_F(1)
#define PIXEL_FORMAT_BGR565_VF PIXEL_FORMAT_B5G6R5_VF
#define PIXEL_FORMAT_BGR16_VF PIXEL_FORMAT_B5G6R5_VF
#define PIXEL_FORMAT_A1R5G5B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 1, 5, 5, 5)
#define PIXEL_FORMAT_A1R5G5B5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 1, 5, 5, 5)
#define PIXEL_FORMAT_A1R5G5B5 PIXEL_FORMAT_A1R5G5B5_F(0)
#define PIXEL_FORMAT_ARGB555 PIXEL_FORMAT_A1R5G5B5
#define PIXEL_FORMAT_ARGB15 PIXEL_FORMAT_A1R5G5B5
#define PIXEL_FORMAT_A1R5G5B5_VF PIXEL_FORMAT_A1R5G5B5_F(1)
#define PIXEL_FORMAT_ARGB555_VF PIXEL_FORMAT_A1R5G5B5_VF
#define PIXEL_FORMAT_ARGB15_VF PIXEL_FORMAT_A1R5G5B5_VF
#define PIXEL_FORMAT_X1R5G5B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 5, 5)
#define PIXEL_FORMAT_X1R5G5B5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 5, 5)
#define PIXEL_FORMAT_X1R5G5B5 PIXEL_FORMAT_X1R5G5B5_F(0)
#define PIXEL_FORMAT_XRGB555 PIXEL_FORMAT_X1R5G5B5
#define PIXEL_FORMAT_RGB555 PIXEL_FORMAT_X1R5G5B5
#define PIXEL_FORMAT_RGB15 PIXEL_FORMAT_X1R5G5B5
#define PIXEL_FORMAT_X1R5G5B5_VF PIXEL_FORMAT_X1R5G5B5_F(1)
#define PIXEL_FORMAT_XRGB555_VF PIXEL_FORMAT_X1R5G5B5_VF
#define PIXEL_FORMAT_RGB555_VF PIXEL_FORMAT_X1R5G5B5_VF
#define PIXEL_FORMAT_RGB15_VF PIXEL_FORMAT_X1R5G5B5_VF
#define PIXEL_FORMAT_A1B5G5R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 1, 5, 5, 5)
#define PIXEL_FORMAT_A1B5G5R5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 1, 5, 5, 5)
#define PIXEL_FORMAT_A1B5G5R5 PIXEL_FORMAT_A1B5G5R5_F(0)
#define PIXEL_FORMAT_ABGR555 PIXEL_FORMAT_A1B5G5R5
#define PIXEL_FORMAT_ABGR15 PIXEL_FORMAT_A1B5G5R5
#define PIXEL_FORMAT_A1B5G5R5_VF PIXEL_FORMAT_A1B5G5R5_F(1)
#define PIXEL_FORMAT_ABGR555_VF PIXEL_FORMAT_A1B5G5R5_VF
#define PIXEL_FORMAT_ABGR15_VF PIXEL_FORMAT_A1B5G5R5_VF
#define PIXEL_FORMAT_X1B5G5R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 5, 5)
#define PIXEL_FORMAT_X1B5G5R5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 5, 5)
#define PIXEL_FORMAT_X1B5G5R5 PIXEL_FORMAT_X1B5G5R5_F(0)
#define PIXEL_FORMAT_XBGR555 PIXEL_FORMAT_X1B5G5R5
#define PIXEL_FORMAT_BGR555 PIXEL_FORMAT_X1B5G5R5
#define PIXEL_FORMAT_BGR15 PIXEL_FORMAT_X1B5G5R5
#define PIXEL_FORMAT_X1B5G5R5_VF PIXEL_FORMAT_X1B5G5R5_F(1)
#define PIXEL_FORMAT_XBGR555_VF PIXEL_FORMAT_X1B5G5R5_VF
#define PIXEL_FORMAT_BGR555_VF PIXEL_FORMAT_X1B5G5R5_VF
#define PIXEL_FORMAT_BGR15_VF PIXEL_FORMAT_X1B5G5R5_VF
/* 8bpp formats */
#define PIXEL_FORMAT_A8 FREERDP_PIXEL_FORMAT(0, 8, FREERDP_PIXEL_FORMAT_TYPE_A, 8, 0, 0, 0)
#define PIXEL_FORMAT_A8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 8, FREERDP_PIXEL_FORMAT_TYPE_A, 8, 0, 0, 0)
#define PIXEL_FORMAT_A8 PIXEL_FORMAT_A8_F(0)
#define PIXEL_FORMAT_8BPP PIXEL_FORMAT_A8
#define PIXEL_FORMAT_256 PIXEL_FORMAT_A8
#define PIXEL_FORMAT_RGB8 PIXEL_FORMAT_A8
#define PIXEL_FORMAT_A8_VF PIXEL_FORMAT_A8_F(1)
#define PIXEL_FORMAT_8BPP_VF PIXEL_FORMAT_A8_VF
#define PIXEL_FORMAT_256_VF PIXEL_FORMAT_A8_VF
#define PIXEL_FORMAT_RGB8_VF PIXEL_FORMAT_A8_VF
/* 4 bpp formats */
#define PIXEL_FORMAT_A4 FREERDP_PIXEL_FORMAT(0, 4, FREERDP_PIXEL_FORMAT_TYPE_A, 4, 0, 0, 0)
#define PIXEL_FORMAT_A4_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 4, FREERDP_PIXEL_FORMAT_TYPE_A, 4, 0, 0, 0)
#define PIXEL_FORMAT_A4 PIXEL_FORMAT_A4_F(0)
#define PIXEL_FORMAT_4BPP PIXEL_FORMAT_A4
#define PIXEL_FORMAT_A4_VF PIXEL_FORMAT_A4_F(1)
#define PIXEL_FORMAT_4BPP_VF PIXEL_FORMAT_A4_VF
/* 1bpp formats */
#define PIXEL_FORMAT_A1 FREERDP_PIXEL_FORMAT(0, 1, FREERDP_PIXEL_FORMAT_TYPE_A, 1, 0, 0, 0)
#define PIXEL_FORMAT_A1_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 1, FREERDP_PIXEL_FORMAT_TYPE_A, 1, 0, 0, 0)
#define PIXEL_FORMAT_A1 PIXEL_FORMAT_A1_F(0)
#define PIXEL_FORMAT_1BPP PIXEL_FORMAT_A1
#define PIXEL_FORMAT_MONO PIXEL_FORMAT_A1
#define PIXEL_FORMAT_A1_VF PIXEL_FORMAT_A1_F(1)
#define PIXEL_FORMAT_1BPP_VF PIXEL_FORMAT_A1_VF
#define PIXEL_FORMAT_MONO_VF PIXEL_FORMAT_A1_VF
#ifdef __cplusplus
extern "C" {

View File

@ -63,6 +63,8 @@ FREERDP_API int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize
FREERDP_API int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRect);
FREERDP_API int h264_context_reset(H264_CONTEXT* h264);
FREERDP_API H264_CONTEXT* h264_context_new(BOOL Compressor);
FREERDP_API void h264_context_free(H264_CONTEXT* h264);

View File

@ -32,13 +32,15 @@ struct _BITMAP_INTERLEAVED_CONTEXT
{
BOOL Compressor;
UINT32 FlipSize;
BYTE* FlipBuffer;
UINT32 TempSize;
BYTE* TempBuffer;
};
FREERDP_API int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcData, UINT32 SrcSize, int bpp,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
FREERDP_API int bitmap_interleaved_context_reset(BITMAP_INTERLEAVED_CONTEXT* interleaved);
FREERDP_API BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor);
FREERDP_API void bitmap_interleaved_context_free(BITMAP_INTERLEAVED_CONTEXT* interleaved);

View File

@ -82,19 +82,22 @@ struct _NSC_CONTEXT
NSC_CONTEXT_PRIV* priv;
};
FREERDP_API NSC_CONTEXT* nsc_context_new(void);
FREERDP_API void nsc_context_set_pixel_format(NSC_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format);
FREERDP_API int nsc_process_message(NSC_CONTEXT* context, UINT16 bpp,
UINT16 width, UINT16 height, BYTE* data, UINT32 length);
FREERDP_API void nsc_compose_message(NSC_CONTEXT* context, wStream* s,
BYTE* bmpdata, int width, int height, int rowstride);
FREERDP_API void nsc_context_free(NSC_CONTEXT* context);
FREERDP_API NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y,
int width, int height, int scanline, int* numMessages, int maxDataSize);
FREERDP_API int nsc_write_message(NSC_CONTEXT* context, wStream* s, NSC_MESSAGE* message);
FREERDP_API int nsc_message_free(NSC_CONTEXT* context, NSC_MESSAGE* message);
FREERDP_API int nsc_context_reset(NSC_CONTEXT* context);
FREERDP_API NSC_CONTEXT* nsc_context_new(void);
FREERDP_API void nsc_context_free(NSC_CONTEXT* context);
#ifdef __cplusplus
}
#endif

View File

@ -102,6 +102,8 @@ FREERDP_API int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int
FREERDP_API BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format,
int width, int height, int scanline, BYTE* dstData, int* dstSize);
FREERDP_API int freerdp_bitmap_planar_context_reset(BITMAP_PLANAR_CONTEXT* context);
FREERDP_API BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, int maxWidth, int maxHeight);
FREERDP_API void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context);

View File

@ -316,7 +316,7 @@ FREERDP_API int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* p
FREERDP_API int progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, UINT32 width, UINT32 height);
FREERDP_API int progressive_delete_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId);
FREERDP_API void progressive_context_reset(PROGRESSIVE_CONTEXT* progressive);
FREERDP_API int progressive_context_reset(PROGRESSIVE_CONTEXT* progressive);
FREERDP_API PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor);
FREERDP_API void progressive_context_free(PROGRESSIVE_CONTEXT* progressive);

View File

@ -153,10 +153,7 @@ struct _RFX_CONTEXT
RFX_CONTEXT_PRIV* priv;
};
FREERDP_API RFX_CONTEXT* rfx_context_new(BOOL encoder);
FREERDP_API void rfx_context_free(RFX_CONTEXT* context);
FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format);
FREERDP_API void rfx_context_reset(RFX_CONTEXT* context);
FREERDP_API int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode);
@ -177,6 +174,11 @@ FREERDP_API RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_REC
BYTE* data, int width, int height, int scanline, int* numMessages, int maxDataSize);
FREERDP_API void rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message);
FREERDP_API int rfx_context_reset(RFX_CONTEXT* context);
FREERDP_API RFX_CONTEXT* rfx_context_new(BOOL encoder);
FREERDP_API void rfx_context_free(RFX_CONTEXT* context);
#ifdef __cplusplus
}
#endif

View File

@ -40,6 +40,7 @@
#define FREERDP_CODEC_ALPHACODEC 0x00000020
#define FREERDP_CODEC_PROGRESSIVE 0x00000040
#define FREERDP_CODEC_H264 0x00000080
#define FREERDP_CODEC_ALL 0xFFFFFFFF
struct rdp_codecs
{
@ -55,6 +56,7 @@ struct rdp_codecs
};
FREERDP_API int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags);
FREERDP_API int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags);
FREERDP_API rdpCodecs* codecs_new(rdpContext* context);
FREERDP_API void codecs_free(rdpCodecs* codecs);

View File

@ -25,6 +25,9 @@
#include <freerdp/cache/cache.h>
#include <freerdp/utils/debug.h>
#include <freerdp/codec/color.h>
#include <freerdp/codec/region.h>
#include <freerdp/client/rdpgfx.h>
/* For more information, see [MS-RDPEGDI] */
@ -285,10 +288,18 @@ struct rdp_gdi
HCLRCONV clrconv;
gdiBitmap* primary;
gdiBitmap* drawing;
UINT32 bitmap_size;
BYTE* bitmap_buffer;
BYTE* primary_buffer;
GDI_COLOR textColor;
gdiBitmap* tile;
gdiBitmap* image;
BOOL inGfxFrame;
BOOL graphicsReset;
UINT16 outputSurfaceId;
REGION16 invalidRegion;
RdpgfxClientContext* gfx;
};
#ifdef __cplusplus
@ -296,6 +307,7 @@ extern "C" {
#endif
FREERDP_API UINT32 gdi_rop3_code(BYTE code);
FREERDP_API UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel, BOOL vFlip);
FREERDP_API BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y);
FREERDP_API BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y);
FREERDP_API int gdi_is_mono_pixel_set(BYTE* data, int x, int y, int width);

52
include/freerdp/gdi/gfx.h Normal file
View File

@ -0,0 +1,52 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* GDI Graphics Pipeline
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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_GDI_GFX_H
#define FREERDP_GDI_GFX_H
#include <freerdp/api.h>
#include <freerdp/gdi/gdi.h>
struct gdi_gfx_surface
{
UINT16 surfaceId;
UINT32 width;
UINT32 height;
BOOL alpha;
BYTE* data;
int scanline;
};
typedef struct gdi_gfx_surface gdiGfxSurface;
struct gdi_gfx_cache_entry
{
UINT64 cacheKey;
UINT32 width;
UINT32 height;
BOOL alpha;
BYTE* data;
int scanline;
};
typedef struct gdi_gfx_cache_entry gdiGfxCacheEntry;
FREERDP_API void gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx);
FREERDP_API void gdi_graphics_pipeline_uninit(rdpGdi* gdi, RdpgfxClientContext* gfx);
#endif /* FREERDP_GDI_GFX_H */

View File

@ -1,8 +1,8 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Windows RAIL
* FreeRDP log defines
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.com>
* Copyright 2014 Armin Novak <armin.novak@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,8 +17,13 @@
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef FREERDP_LOG_H
#define FREERDP_LOG_H
#include "wf_window.h"
#include <winpr/wlog.h>
#define FREERDP_TAG(tag) "com.freerdp." tag
#define SERVER_TAG(tag) FREERDP_TAG("server.") tag
#define CLIENT_TAG(tag) FREERDP_TAG("client.") tag
#endif /* FREERDP_UTILS_DEBUG_H */

View File

@ -105,6 +105,11 @@ struct _rdpsnd_server_context
* synchronization.
*/
psRdpsndServerActivated Activated;
/**
* MS-RDPEA channel version the client announces
*/
UINT16 clientVersion;
};
#ifdef __cplusplus
@ -115,7 +120,7 @@ FREERDP_API RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm);
FREERDP_API void rdpsnd_server_context_reset(RdpsndServerContext *);
FREERDP_API void rdpsnd_server_context_free(RdpsndServerContext* context);
FREERDP_API HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext *context);
FREERDP_API BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context);
FREERDP_API int rdpsnd_server_handle_messages(RdpsndServerContext *context);
FREERDP_API BOOL rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s);

View File

@ -24,7 +24,7 @@
#define DEBUG_PRINT(level, file, fkt, line, dbg_str, fmt, ...) \
do { \
wLog *log = WLog_Get("com.freerdp." dbg_str); \
wLog *log = WLog_Get("com.freerdp.legacy"); \
wLogMessage msg; \
\
msg.Type = WLOG_MESSAGE_TEXT; \
@ -38,10 +38,10 @@
#define DEBUG_NULL(fmt, ...) do { } while (0)
#define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT(WLOG_ERROR, __FILE__, \
__FUNCTION__, __LINE__, #_dbg_class, fmt, ## __VA_ARGS__)
__FUNCTION__, __LINE__, #_dbg_class, fmt, ## __VA_ARGS__)
#define DEBUG_MSG(fmt, ...) DEBUG_PRINT(WLOG_DEBUG, __FILE__, __FUNCTION__, \
__LINE__, "freerdp", fmt, ## __VA_ARGS__)
__LINE__, "freerdp", fmt, ## __VA_ARGS__)
#define DEBUG_WARN(fmt, ...) DEBUG_PRINT(WLOG_ERROR, __FILE__, __FUNCTION__, \
__LINE__, "freerdp", fmt, ## __VA_ARGS__)
__LINE__, "freerdp", fmt, ## __VA_ARGS__)
#endif /* FREERDP_UTILS_DEBUG_H */

View File

@ -41,8 +41,9 @@ void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex);
else
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) memblt->cacheId, memblt->cacheIndex);
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
if (bitmap == NULL) return;
if (!bitmap)
return; /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
memblt->bitmap = bitmap;
IFCALL(cache->bitmap->MemBlt, context, memblt);
@ -60,9 +61,8 @@ void update_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
else
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) mem3blt->cacheId, mem3blt->cacheIndex);
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
if (!bitmap)
return;
return; /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
style = brush->style;
@ -96,7 +96,7 @@ void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cacheBitma
prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmap->cacheId, cacheBitmap->cacheIndex);
if (prevBitmap != NULL)
if (prevBitmap)
Bitmap_Free(context, prevBitmap);
bitmap_cache_put(cache->bitmap, cacheBitmap->cacheId, cacheBitmap->cacheIndex, bitmap);
@ -107,16 +107,17 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
rdpCache* cache = context->cache;
rdpSettings* settings = context->settings;
bitmap = Bitmap_Alloc(context);
Bitmap_SetDimensions(context, bitmap, cacheBitmapV2->bitmapWidth, cacheBitmapV2->bitmapHeight);
if (cacheBitmapV2->bitmapBpp == 0)
{
/* Workaround for Windows 8 bug where bitmapBpp is not set */
cacheBitmapV2->bitmapBpp = context->instance->settings->ColorDepth;
}
if (!cacheBitmapV2->bitmapBpp)
cacheBitmapV2->bitmapBpp = settings->ColorDepth;
if ((settings->ColorDepth == 15) && (cacheBitmapV2->bitmapBpp == 16))
cacheBitmapV2->bitmapBpp = settings->ColorDepth;
bitmap->Decompress(context, bitmap,
cacheBitmapV2->bitmapDataStream, cacheBitmapV2->bitmapWidth, cacheBitmapV2->bitmapHeight,
@ -137,27 +138,23 @@ void update_gdi_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cach
{
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
BOOL isCompressed = TRUE;
BOOL compressed = TRUE;
rdpCache* cache = context->cache;
rdpSettings* settings = context->settings;
BITMAP_DATA_EX* bitmapData = &cacheBitmapV3->bitmapData;
bitmap = Bitmap_Alloc(context);
Bitmap_SetDimensions(context, bitmap, bitmapData->width, bitmapData->height);
if (cacheBitmapV3->bitmapData.bpp == 0)
{
/* Workaround for Windows 8 bug where bitmapBpp is not set */
cacheBitmapV3->bitmapData.bpp = context->instance->settings->ColorDepth;
}
if (!cacheBitmapV3->bpp)
cacheBitmapV3->bpp = settings->ColorDepth;
/* According to http://msdn.microsoft.com/en-us/library/gg441209.aspx
* CACHE_BITMAP_REV3_ORDER::bitmapData::codecID = 0x00 (uncompressed) */
isCompressed = (bitmapData->codecID != RDP_CODEC_ID_NONE);
compressed = (bitmapData->codecID != RDP_CODEC_ID_NONE);
bitmap->Decompress(context, bitmap,
bitmapData->data, bitmap->width, bitmap->height,
bitmapData->bpp, bitmapData->length, isCompressed,
bitmapData->bpp, bitmapData->length, compressed,
bitmapData->codecID);
bitmap->New(context, bitmap);
@ -173,9 +170,9 @@ void update_gdi_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cach
void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
int i;
rdpBitmap* bitmap;
BITMAP_DATA* bitmap_data;
BOOL reused = TRUE;
rdpBitmap* bitmap;
BITMAP_DATA* bitmapData;
rdpCache* cache = context->cache;
if (!cache->bitmap->bitmap)
@ -189,22 +186,22 @@ void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
for (i = 0; i < (int) bitmapUpdate->number; i++)
{
bitmap_data = &bitmapUpdate->rectangles[i];
bitmapData = &bitmapUpdate->rectangles[i];
bitmap->bpp = bitmap_data->bitsPerPixel;
bitmap->length = bitmap_data->bitmapLength;
bitmap->compressed = bitmap_data->compressed;
bitmap->bpp = bitmapData->bitsPerPixel;
bitmap->length = bitmapData->bitmapLength;
bitmap->compressed = bitmapData->compressed;
Bitmap_SetRectangle(context, bitmap,
bitmap_data->destLeft, bitmap_data->destTop,
bitmap_data->destRight, bitmap_data->destBottom);
bitmapData->destLeft, bitmapData->destTop,
bitmapData->destRight, bitmapData->destBottom);
Bitmap_SetDimensions(context, bitmap, bitmap_data->width, bitmap_data->height);
Bitmap_SetDimensions(context, bitmap, bitmapData->width, bitmapData->height);
bitmap->Decompress(context, bitmap,
bitmap_data->bitmapDataStream, bitmap_data->width, bitmap_data->height,
bitmap_data->bitsPerPixel, bitmap_data->bitmapLength,
bitmap_data->compressed, RDP_CODEC_ID_NONE);
bitmapData->bitmapDataStream, bitmapData->width, bitmapData->height,
bitmapData->bitsPerPixel, bitmapData->bitmapLength,
bitmapData->compressed, RDP_CODEC_ID_NONE);
if (reused)
bitmap->Free(context, bitmap);
@ -324,10 +321,8 @@ void bitmap_cache_free(rdpBitmapCache* bitmapCache)
{
bitmap = bitmapCache->cells[i].entries[j];
if (bitmap != NULL)
{
if (bitmap)
Bitmap_Free(bitmapCache->context, bitmap);
}
}
free(bitmapCache->cells[i].entries);

View File

@ -751,11 +751,12 @@ int clear_compress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE**
return 1;
}
void clear_context_reset(CLEAR_CONTEXT* clear)
int clear_context_reset(CLEAR_CONTEXT* clear)
{
clear->seqNumber = 0;
clear->VBarStorageCursor = 0;
clear->ShortVBarStorageCursor = 0;
return 1;
}
CLEAR_CONTEXT* clear_context_new(BOOL Compressor)

View File

@ -1299,6 +1299,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
int x, y;
int srcFlip;
int dstFlip;
int nSrcPad;
int nDstPad;
BYTE a, r, g, b;
int beg, end, inc;
int srcBitsPerPixel;
@ -1312,10 +1314,19 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
srcBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(dwSrcFormat) / 8);
srcFlip = FREERDP_PIXEL_FORMAT_FLIP(dwSrcFormat);
if (nSrcStep < 0)
nSrcStep = srcBytesPerPixel * nWidth;
dstBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(dwDstFormat);
dstBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(dwDstFormat) / 8);
dstFlip = FREERDP_PIXEL_FORMAT_FLIP(dwDstFormat);
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
nSrcPad = (nSrcStep - (nWidth * srcBytesPerPixel));
nDstPad = (nDstStep - (nWidth * dstBytesPerPixel));
if (srcFlip != dstFlip)
vFlip = TRUE;
@ -1327,9 +1338,6 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
if (srcBytesPerPixel == 4)
{
if (nSrcStep < 0)
nSrcStep = srcBytesPerPixel * nWidth;
if (srcBitsPerPixel == 24)
{
if (dstBytesPerPixel == 4) /* srcBytesPerPixel == dstBytesPerPixel */
@ -1339,11 +1347,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
UINT32* pSrcPixel;
UINT32* pDstPixel;
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)];
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)];
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
@ -1356,18 +1361,17 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
pDstPixel++;
}
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))];
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))];
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad];
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
return 1;
}
else if (dstBitsPerPixel == 24) /* srcBitsPerPixel == dstBitsPerPixel */
{
UINT32* pSrcPixel;
UINT32* pDstPixel;
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
if (overlap && (nYSrc < nYDst))
{
beg = nHeight - 1;
@ -1385,8 +1389,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
{
for (y = beg; y != end; y += inc)
{
pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * srcBytesPerPixel)];
pDstPixel = (UINT32*) &pDstData[((nYDst + y) * nDstStep) + (nXDst * dstBytesPerPixel)];
pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
pDstPixel = (UINT32*) &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
MoveMemory(pDstPixel, pSrcPixel, nWidth * 4);
}
}
@ -1394,11 +1398,13 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
{
for (y = beg; y != end; y += inc)
{
pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * srcBytesPerPixel)];
pDstPixel = (UINT32*) &pDstData[((nYDst + (nHeight - y - 1)) * nDstStep) + (nXDst * dstBytesPerPixel)];
pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
pDstPixel = (UINT32*) &pDstData[((nYDst + (nHeight - y - 1)) * nDstStep) + (nXDst * 4)];
MoveMemory(pDstPixel, pSrcPixel, nWidth * 4);
}
}
return 1;
}
}
else if (dstBytesPerPixel == 3)
@ -1406,11 +1412,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
UINT32* pSrcPixel;
BYTE* pDstPixel;
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)];
pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)];
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * 3)];
for (y = 0; y < nHeight; y++)
{
@ -1425,9 +1428,11 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
pSrcPixel++;
}
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))];
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))];
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcStep];
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstStep];
}
return 1;
}
else if (dstBytesPerPixel == 2)
{
@ -1436,11 +1441,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
UINT32* pSrcPixel;
UINT16* pDstPixel;
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)];
pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)];
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * 2)];
for (y = 0; y < nHeight; y++)
{
@ -1454,20 +1456,19 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
pDstPixel++;
}
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))];
pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))];
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad];
pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[nDstPad];
}
return 1;
}
else if (dstBitsPerPixel == 15)
{
UINT32* pSrcPixel;
UINT16* pDstPixel;
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)];
pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)];
pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * 2)];
for (y = 0; y < nHeight; y++)
{
@ -1481,15 +1482,182 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs
pDstPixel++;
}
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))];
pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))];
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad];
pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[nDstPad];
}
return 1;
}
}
}
}
else if (srcBytesPerPixel == 3)
{
if (dstBytesPerPixel == 4)
{
if ((dstBitsPerPixel == 32) || (dstBitsPerPixel == 24))
{
BYTE* pSrcPixel;
BYTE* pDstPixel;
if (!vFlip)
{
pSrcPixel = (BYTE*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 3)];
pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
*pDstPixel++ = *pSrcPixel++;
*pDstPixel++ = *pSrcPixel++;
*pDstPixel++ = *pSrcPixel++;
*pDstPixel++ = 0xFF;
}
pSrcPixel = (BYTE*) &((BYTE*) pSrcPixel)[nSrcPad];
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstPad];
}
}
else
{
pSrcPixel = (BYTE*) &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 3)];
pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
*pDstPixel++ = *pSrcPixel++;
*pDstPixel++ = *pSrcPixel++;
*pDstPixel++ = *pSrcPixel++;
*pDstPixel++ = 0xFF;
}
pSrcPixel = (BYTE*) &((BYTE*) pSrcPixel)[-((nSrcStep - nSrcPad) + nSrcStep)];
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstPad];
}
}
return 1;
}
}
}
else if (srcBytesPerPixel == 2)
{
if (srcBitsPerPixel == 16)
{
if (dstBytesPerPixel == 4)
{
if ((dstBitsPerPixel == 32) || (dstBitsPerPixel == 24))
{
UINT16* pSrcPixel;
UINT32* pDstPixel;
if (!vFlip)
{
pSrcPixel = (UINT16*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 2)];
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
GetRGB16(r, g, b, *pSrcPixel);
*pDstPixel = ARGB32(0xFF, r, g, b);
pSrcPixel++;
pDstPixel++;
}
pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[nSrcPad];
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
}
else
{
pSrcPixel = (UINT16*) &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 2)];
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
GetRGB16(r, g, b, *pSrcPixel);
*pDstPixel = ARGB32(0xFF, r, g, b);
pSrcPixel++;
pDstPixel++;
}
pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[-((nSrcStep - nSrcPad) + nSrcStep)];
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
}
return 1;
}
}
}
else if (srcBitsPerPixel == 15)
{
if (dstBytesPerPixel == 4)
{
if ((dstBitsPerPixel == 32) || (dstBitsPerPixel == 24))
{
UINT16* pSrcPixel;
UINT32* pDstPixel;
if (!vFlip)
{
pSrcPixel = (UINT16*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 2)];
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
GetRGB15(r, g, b, *pSrcPixel);
*pDstPixel = ARGB32(0xFF, r, g, b);
pSrcPixel++;
pDstPixel++;
}
pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[nSrcPad];
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
}
else
{
pSrcPixel = (UINT16*) &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 2)];
pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
GetRGB15(r, g, b, *pSrcPixel);
*pDstPixel = ARGB32(0xFF, r, g, b);
pSrcPixel++;
pDstPixel++;
}
pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[-((nSrcStep - nSrcPad) + nSrcStep)];
pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad];
}
}
}
}
}
}
else if (srcBytesPerPixel == 1)
{
return 0;
}
return -1;
}
void* freerdp_image_memset32(UINT32* ptr, UINT32 fill, size_t length)

View File

@ -510,6 +510,11 @@ BOOL h264_context_init(H264_CONTEXT* h264)
return FALSE;
}
int h264_context_reset(H264_CONTEXT* h264)
{
return 1;
}
H264_CONTEXT* h264_context_new(BOOL Compressor)
{
H264_CONTEXT* h264;

View File

@ -238,9 +238,11 @@ static INLINE UINT32 ExtractRunLength(UINT32 code, BYTE* pbOrderHdr, UINT32* adv
int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcData, UINT32 SrcSize, int bpp,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
{
int status;
BOOL vFlip;
int scanline;
BYTE* pDstData;
UINT32 SrcFormat;
UINT32 BufferSize;
int dstBitsPerPixel;
int dstBytesPerPixel;
@ -258,51 +260,81 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa
scanline = nWidth * 3;
BufferSize = scanline * nHeight;
if (BufferSize > interleaved->FlipSize)
SrcFormat = PIXEL_FORMAT_RGB24_VF;
if ((SrcFormat == DstFormat) && !nXDst && !nYDst && (scanline == nDstStep))
{
interleaved->FlipBuffer = _aligned_realloc(interleaved->FlipBuffer, BufferSize, 16);
interleaved->FlipSize = BufferSize;
RleDecompress24to24(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight);
return 1;
}
if (!interleaved->FlipBuffer)
if (BufferSize > interleaved->TempSize)
{
interleaved->TempBuffer = _aligned_realloc(interleaved->TempBuffer, BufferSize, 16);
interleaved->TempSize = BufferSize;
}
if (!interleaved->TempBuffer)
return -1;
RleDecompress24to24(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight);
freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight);
RleDecompress24to24(pSrcData, SrcSize, interleaved->TempBuffer, scanline, nWidth, nHeight);
status = freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst,
nWidth, nHeight, interleaved->TempBuffer, SrcFormat, scanline, 0, 0);
}
else if ((bpp == 16) || (bpp == 15))
{
scanline = nWidth * 2;
BufferSize = scanline * nHeight;
if (BufferSize > interleaved->FlipSize)
SrcFormat = (bpp == 16) ? PIXEL_FORMAT_RGB16_VF : PIXEL_FORMAT_RGB15_VF;
if ((SrcFormat == DstFormat) && !nXDst && !nYDst && (scanline == nDstStep))
{
interleaved->FlipBuffer = _aligned_realloc(interleaved->FlipBuffer, BufferSize, 16);
interleaved->FlipSize = BufferSize;
RleDecompress16to16(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight);
return 1;
}
if (!interleaved->FlipBuffer)
if (BufferSize > interleaved->TempSize)
{
interleaved->TempBuffer = _aligned_realloc(interleaved->TempBuffer, BufferSize, 16);
interleaved->TempSize = BufferSize;
}
if (!interleaved->TempBuffer)
return -1;
RleDecompress16to16(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight);
freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight);
RleDecompress16to16(pSrcData, SrcSize, interleaved->TempBuffer, scanline, nWidth, nHeight);
status = freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst,
nWidth, nHeight, interleaved->TempBuffer, SrcFormat, scanline, 0, 0);
}
else if (bpp == 8)
{
scanline = nWidth;
BufferSize = scanline * nHeight;
if (BufferSize > interleaved->FlipSize)
SrcFormat = PIXEL_FORMAT_RGB8_VF;
if ((SrcFormat == DstFormat) && !nXDst && !nYDst && (scanline == nDstStep))
{
interleaved->FlipBuffer = _aligned_realloc(interleaved->FlipBuffer, BufferSize, 16);
interleaved->FlipSize = BufferSize;
RleDecompress8to8(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight);
return 1;
}
if (!interleaved->FlipBuffer)
if (BufferSize > interleaved->TempSize)
{
interleaved->TempBuffer = _aligned_realloc(interleaved->TempBuffer, BufferSize, 16);
interleaved->TempSize = BufferSize;
}
if (!interleaved->TempBuffer)
return -1;
RleDecompress8to8(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight);
freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight);
RleDecompress8to8(pSrcData, SrcSize, interleaved->TempBuffer, scanline, nWidth, nHeight);
status = freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst,
nWidth, nHeight, interleaved->TempBuffer, SrcFormat, scanline, 0, 0);
}
else
{
@ -312,6 +344,11 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa
return 1;
}
int bitmap_interleaved_context_reset(BITMAP_INTERLEAVED_CONTEXT* interleaved)
{
return 1;
}
BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor)
{
BITMAP_INTERLEAVED_CONTEXT* interleaved;
@ -320,8 +357,8 @@ BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor)
if (interleaved)
{
interleaved->FlipSize = 64 * 64 * 3;
interleaved->FlipBuffer = _aligned_malloc(interleaved->FlipSize, 16);
interleaved->TempSize = 64 * 64 * 3;
interleaved->TempBuffer = _aligned_malloc(interleaved->TempSize, 16);
}
return interleaved;
@ -332,7 +369,7 @@ void bitmap_interleaved_context_free(BITMAP_INTERLEAVED_CONTEXT* interleaved)
if (!interleaved)
return;
_aligned_free(interleaved->FlipBuffer);
_aligned_free(interleaved->TempBuffer);
free(interleaved);
}

View File

@ -252,6 +252,11 @@ static void nsc_profiler_print(NSC_CONTEXT* context)
PROFILER_PRINT_FOOTER;
}
int nsc_context_reset(NSC_CONTEXT* context)
{
return 1;
}
NSC_CONTEXT* nsc_context_new(void)
{
UINT8 i;

View File

@ -1107,6 +1107,11 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data,
return dstData;
}
int freerdp_bitmap_planar_context_reset(BITMAP_PLANAR_CONTEXT* context)
{
return 1;
}
BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, int maxWidth, int maxHeight)
{
BITMAP_PLANAR_CONTEXT* context;

View File

@ -247,6 +247,53 @@ void* progressive_get_surface_data(PROGRESSIVE_CONTEXT* progressive, UINT16 surf
return pData;
}
PROGRESSIVE_SURFACE_CONTEXT* progressive_surface_context_new(UINT16 surfaceId, UINT32 width, UINT32 height)
{
PROGRESSIVE_SURFACE_CONTEXT* surface;
surface = (PROGRESSIVE_SURFACE_CONTEXT*) calloc(1, sizeof(PROGRESSIVE_SURFACE_CONTEXT));
if (!surface)
return NULL;
surface->id = surfaceId;
surface->width = width;
surface->height = height;
surface->gridWidth = (width + (width % 64)) / 64;
surface->gridHeight = (height + (height % 64)) / 64;
surface->gridSize = surface->gridWidth * surface->gridHeight;
surface->tiles = (RFX_PROGRESSIVE_TILE*) calloc(surface->gridSize, sizeof(RFX_PROGRESSIVE_TILE));
if (!surface->tiles)
return NULL;
return surface;
}
void progressive_surface_context_free(PROGRESSIVE_SURFACE_CONTEXT* surface)
{
UINT32 index;
RFX_PROGRESSIVE_TILE* tile;
for (index = 0; index < surface->gridSize; index++)
{
tile = &(surface->tiles[index]);
if (tile->data)
_aligned_free(tile->data);
if (tile->sign)
_aligned_free(tile->sign);
if (tile->current)
_aligned_free(tile->current);
}
free(surface->tiles);
free(surface);
}
int progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, UINT32 width, UINT32 height)
{
PROGRESSIVE_SURFACE_CONTEXT* surface;
@ -255,23 +302,11 @@ int progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16
if (!surface)
{
surface = (PROGRESSIVE_SURFACE_CONTEXT*) malloc(sizeof(PROGRESSIVE_SURFACE_CONTEXT));
surface = progressive_surface_context_new(surfaceId, width, height);
if (!surface)
return -1;
surface->id = surfaceId;
surface->width = width;
surface->height = height;
surface->gridWidth = (width + (width % 64)) / 64;
surface->gridHeight = (height + (height % 64)) / 64;
surface->gridSize = surface->gridWidth * surface->gridHeight;
surface->tiles = (RFX_PROGRESSIVE_TILE*) calloc(surface->gridSize, sizeof(RFX_PROGRESSIVE_TILE));
if (!surface->tiles)
return -1;
progressive_set_surface_data(progressive, surfaceId, (void*) surface);
}
@ -287,9 +322,7 @@ int progressive_delete_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16
if (surface)
{
progressive_set_surface_data(progressive, surfaceId, NULL);
free(surface->tiles);
free(surface);
progressive_surface_context_free(surface);
}
return 1;
@ -1758,9 +1791,9 @@ int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT3
return 1;
}
void progressive_context_reset(PROGRESSIVE_CONTEXT* progressive)
int progressive_context_reset(PROGRESSIVE_CONTEXT* progressive)
{
return 1;
}
PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor)
@ -1814,6 +1847,11 @@ PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor)
void progressive_context_free(PROGRESSIVE_CONTEXT* progressive)
{
int count;
int index;
ULONG_PTR* pKeys = NULL;
PROGRESSIVE_SURFACE_CONTEXT* surface;
if (!progressive)
return;
@ -1824,6 +1862,16 @@ void progressive_context_free(PROGRESSIVE_CONTEXT* progressive)
free(progressive->quantVals);
free(progressive->quantProgVals);
count = HashTable_GetKeys(progressive->SurfaceContexts, &pKeys);
for (index = 0; index < count; index++)
{
surface = (PROGRESSIVE_SURFACE_CONTEXT*) HashTable_GetItemValue(progressive->SurfaceContexts, (void*) pKeys[index]);
progressive_surface_context_free(surface);
}
free(pKeys);
HashTable_Free(progressive->SurfaceContexts);
free(progressive);

View File

@ -416,10 +416,11 @@ void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_f
}
}
void rfx_context_reset(RFX_CONTEXT* context)
int rfx_context_reset(RFX_CONTEXT* context)
{
context->state = RFX_STATE_SEND_HEADERS;
context->frameIdx = 0;
return 1;
}
static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s)

View File

@ -4,6 +4,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/codec/mppc.h>
#include <freerdp/log.h>
static BYTE TEST_RDP5_COMPRESSED_DATA[] =
{
@ -747,18 +748,13 @@ int test_MppcCompressBellsRdp5()
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(1, TRUE);
SrcSize = sizeof(TEST_MPPC_BELLS) - 1;
pSrcData = (BYTE*) TEST_MPPC_BELLS;
expectedSize = sizeof(TEST_MPPC_BELLS_RDP5) - 1;
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("Flags: 0x%04X DstSize: %d\n", Flags, DstSize);
if (DstSize != expectedSize)
@ -770,18 +766,14 @@ int test_MppcCompressBellsRdp5()
if (memcmp(pDstData, TEST_MPPC_BELLS_RDP5, DstSize) != 0)
{
printf("MppcCompressBellsRdp5: output mismatch\n");
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_MPPC_BELLS_RDP5, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_MPPC_BELLS_RDP5, DstSize * 8, 0);
return -1;
}
mppc_context_free(mppc);
return 0;
}
@ -796,18 +788,13 @@ int test_MppcCompressBellsRdp4()
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(0, TRUE);
SrcSize = sizeof(TEST_MPPC_BELLS) - 1;
pSrcData = (BYTE*) TEST_MPPC_BELLS;
expectedSize = sizeof(TEST_MPPC_BELLS_RDP4) - 1;
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("flags: 0x%04X size: %d\n", Flags, DstSize);
if (DstSize != expectedSize)
@ -819,18 +806,14 @@ int test_MppcCompressBellsRdp4()
if (memcmp(pDstData, TEST_MPPC_BELLS_RDP4, DstSize) != 0)
{
printf("MppcCompressBellsRdp4: output mismatch\n");
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_MPPC_BELLS_RDP4, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_MPPC_BELLS_RDP4, DstSize * 8, 0);
return -1;
}
mppc_context_free(mppc);
return 0;
}
@ -844,14 +827,11 @@ int test_MppcDecompressBellsRdp5()
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE* pDstData = NULL;
mppc = mppc_context_new(1, FALSE);
SrcSize = sizeof(TEST_MPPC_BELLS_RDP5) - 1;
pSrcData = (BYTE*) TEST_MPPC_BELLS_RDP5;
Flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 1;
expectedSize = sizeof(TEST_MPPC_BELLS) - 1;
status = mppc_decompress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
printf("flags: 0x%04X size: %d\n", Flags, DstSize);
@ -868,7 +848,6 @@ int test_MppcDecompressBellsRdp5()
}
mppc_context_free(mppc);
return 0;
}
@ -882,14 +861,11 @@ int test_MppcDecompressBellsRdp4()
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE* pDstData = NULL;
mppc = mppc_context_new(0, FALSE);
SrcSize = sizeof(TEST_MPPC_BELLS_RDP4) - 1;
pSrcData = (BYTE*) TEST_MPPC_BELLS_RDP4;
Flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 0;
expectedSize = sizeof(TEST_MPPC_BELLS) - 1;
status = mppc_decompress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
printf("flags: 0x%04X size: %d\n", Flags, DstSize);
@ -906,7 +882,6 @@ int test_MppcDecompressBellsRdp4()
}
mppc_context_free(mppc);
return 0;
}
@ -921,18 +896,13 @@ int test_MppcCompressIslandRdp5()
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(1, TRUE);
SrcSize = sizeof(TEST_ISLAND_DATA) - 1;
pSrcData = (BYTE*) TEST_ISLAND_DATA;
expectedSize = sizeof(TEST_ISLAND_DATA_RDP5) - 1;
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("Flags: 0x%04X DstSize: %d\n", Flags, DstSize);
if (DstSize != expectedSize)
@ -944,18 +914,14 @@ int test_MppcCompressIslandRdp5()
if (memcmp(pDstData, TEST_ISLAND_DATA_RDP5, DstSize) != 0)
{
printf("MppcCompressIslandRdp5: output mismatch\n");
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_ISLAND_DATA_RDP5, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_ISLAND_DATA_RDP5, DstSize * 8, 0);
return -1;
}
mppc_context_free(mppc);
return 0;
}
@ -970,18 +936,13 @@ int test_MppcCompressBufferRdp5()
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(1, TRUE);
SrcSize = sizeof(TEST_RDP5_UNCOMPRESSED_DATA);
pSrcData = (BYTE*) TEST_RDP5_UNCOMPRESSED_DATA;
expectedSize = sizeof(TEST_RDP5_COMPRESSED_DATA);
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("flags: 0x%04X size: %d\n", Flags, DstSize);
if (DstSize != expectedSize)
@ -997,7 +958,6 @@ int test_MppcCompressBufferRdp5()
}
mppc_context_free(mppc);
return 0;
}
@ -1011,14 +971,11 @@ int test_MppcDecompressBufferRdp5()
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE* pDstData = NULL;
mppc = mppc_context_new(1, FALSE);
SrcSize = sizeof(TEST_RDP5_COMPRESSED_DATA);
pSrcData = (BYTE*) TEST_RDP5_COMPRESSED_DATA;
Flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 1;
expectedSize = sizeof(TEST_RDP5_UNCOMPRESSED_DATA);
status = mppc_decompress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
printf("flags: 0x%04X size: %d\n", Flags, DstSize);
@ -1035,7 +992,6 @@ int test_MppcDecompressBufferRdp5()
}
mppc_context_free(mppc);
return 0;
}

View File

@ -21,49 +21,37 @@ int test_NCrushCompressBells()
UINT32 expectedSize;
BYTE OutputBuffer[65536];
NCRUSH_CONTEXT* ncrush;
ncrush = ncrush_context_new(TRUE);
SrcSize = sizeof(TEST_BELLS_DATA) - 1;
pSrcData = (BYTE*) TEST_BELLS_DATA;
expectedSize = sizeof(TEST_BELLS_NCRUSH) - 1;
pDstData = OutputBuffer;
DstSize = sizeof(OutputBuffer);
ZeroMemory(OutputBuffer, sizeof(OutputBuffer));
status = ncrush_compress(ncrush, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("status: %d Flags: 0x%04X DstSize: %d\n", status, Flags, DstSize);
if (DstSize != expectedSize)
{
printf("NCrushCompressBells: output size mismatch: Actual: %d, Expected: %d\n", DstSize, expectedSize);
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_BELLS_NCRUSH, expectedSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_BELLS_NCRUSH, expectedSize * 8, 0);
return -1;
}
if (memcmp(pDstData, TEST_BELLS_NCRUSH, DstSize) != 0)
{
printf("NCrushCompressBells: output mismatch\n");
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_BELLS_NCRUSH, expectedSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_BELLS_NCRUSH, expectedSize * 8, 0);
return -1;
}
ncrush_context_free(ncrush);
return 1;
}
@ -77,14 +65,11 @@ int test_NCrushDecompressBells()
UINT32 expectedSize;
BYTE* pDstData = NULL;
NCRUSH_CONTEXT* ncrush;
ncrush = ncrush_context_new(FALSE);
SrcSize = sizeof(TEST_BELLS_NCRUSH) - 1;
pSrcData = (BYTE*) TEST_BELLS_NCRUSH;
Flags = PACKET_COMPRESSED | 2;
expectedSize = sizeof(TEST_BELLS_DATA) - 1;
status = ncrush_decompress(ncrush, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
printf("Flags: 0x%04X DstSize: %d\n", Flags, DstSize);
@ -101,7 +86,6 @@ int test_NCrushDecompressBells()
}
ncrush_context_free(ncrush);
return 1;
}

View File

@ -2934,7 +2934,7 @@ void dump_color_channel(BYTE* data, int width, int height)
for (j = 0; j < width; j++)
{
printf("%02X%s", *data,
((j + 1) == width)? "\n" : " ");
((j + 1) == width)? "\n" : " ");
data += 4;
}
}
@ -2951,28 +2951,21 @@ int test_individual_planes_encoding_rle()
int availableSize;
DWORD planarFlags;
BITMAP_PLANAR_CONTEXT* planar;
planarFlags = PLANAR_FORMAT_HEADER_NA;
planarFlags |= PLANAR_FORMAT_HEADER_RLE;
width = 64;
height = 64;
planeSize = width * height;
planar = freerdp_bitmap_planar_context_new(planarFlags, width, height);
CopyMemory(planar->planes[1], (BYTE*) TEST_64X64_RED_PLANE, planeSize); /* Red */
CopyMemory(planar->planes[2], (BYTE*) TEST_64X64_GREEN_PLANE, planeSize); /* Green */
CopyMemory(planar->planes[3], (BYTE*) TEST_64X64_BLUE_PLANE, planeSize); /* Blue */
CopyMemory(planar->planes[1], (BYTE*) TEST_64X64_RED_PLANE, planeSize); /* Red */
CopyMemory(planar->planes[2], (BYTE*) TEST_64X64_GREEN_PLANE, planeSize); /* Green */
CopyMemory(planar->planes[3], (BYTE*) TEST_64X64_BLUE_PLANE, planeSize); /* Blue */
freerdp_bitmap_planar_delta_encode_plane(planar->planes[1], width, height, planar->deltaPlanes[1]); /* Red */
freerdp_bitmap_planar_delta_encode_plane(planar->planes[2], width, height, planar->deltaPlanes[2]); /* Green */
freerdp_bitmap_planar_delta_encode_plane(planar->planes[3], width, height, planar->deltaPlanes[3]); /* Blue */
pOutput = planar->rlePlanesBuffer;
availableSize = planeSize * 3;
/* Red */
dstSizes[1] = availableSize;
if (!freerdp_bitmap_planar_compress_plane_rle(planar->deltaPlanes[1], width, height, pOutput, &dstSizes[1]))
@ -2988,7 +2981,7 @@ int test_individual_planes_encoding_rle()
if (dstSizes[1] != sizeof(TEST_64X64_RED_PLANE_RLE))
{
printf("RedPlaneRle unexpected size: actual: %d, expected: %d\n",
dstSizes[1], (int) sizeof(TEST_64X64_RED_PLANE_RLE));
dstSizes[1], (int) sizeof(TEST_64X64_RED_PLANE_RLE));
//return -1;
}
@ -2997,18 +2990,14 @@ int test_individual_planes_encoding_rle()
if (memcmp(planar->rlePlanes[1], (BYTE*) TEST_64X64_RED_PLANE_RLE, compareSize) != 0)
{
printf("RedPlaneRle doesn't match expected output\n");
printf("RedPlaneRle Expected (%d):\n", (int) sizeof(TEST_64X64_RED_PLANE_RLE));
//winpr_HexDump((BYTE*) TEST_64X64_RED_PLANE_RLE, sizeof(TEST_64X64_RED_PLANE_RLE));
//winpr_HexDump("codec.test", WLOG_DEBUG, (BYTE*) TEST_64X64_RED_PLANE_RLE, sizeof(TEST_64X64_RED_PLANE_RLE));
printf("RedPlaneRle Actual (%d):\n", dstSizes[1]);
//winpr_HexDump(planar->rlePlanes[1], dstSizes[1]);
//winpr_HexDump("codec.test", WLOG_DEBUG, planar->rlePlanes[1], dstSizes[1]);
return -1;
}
/* Green */
dstSizes[2] = availableSize;
if (!freerdp_bitmap_planar_compress_plane_rle(planar->deltaPlanes[2], width, height, pOutput, &dstSizes[2]))
@ -3024,7 +3013,7 @@ int test_individual_planes_encoding_rle()
if (dstSizes[2] != sizeof(TEST_64X64_GREEN_PLANE_RLE))
{
printf("GreenPlaneRle unexpected size: actual: %d, expected: %d\n",
dstSizes[1], (int) sizeof(TEST_64X64_GREEN_PLANE_RLE));
dstSizes[1], (int) sizeof(TEST_64X64_GREEN_PLANE_RLE));
return -1;
}
@ -3033,18 +3022,14 @@ int test_individual_planes_encoding_rle()
if (memcmp(planar->rlePlanes[2], (BYTE*) TEST_64X64_GREEN_PLANE_RLE, compareSize) != 0)
{
printf("GreenPlaneRle doesn't match expected output\n");
printf("GreenPlaneRle Expected (%d):\n", (int) sizeof(TEST_64X64_GREEN_PLANE_RLE));
winpr_HexDump((BYTE*) TEST_64X64_GREEN_PLANE_RLE, (int) sizeof(TEST_64X64_GREEN_PLANE_RLE));
winpr_HexDump("codec.test", WLOG_DEBUG, (BYTE*) TEST_64X64_GREEN_PLANE_RLE, (int) sizeof(TEST_64X64_GREEN_PLANE_RLE));
printf("GreenPlaneRle Actual (%d):\n", dstSizes[2]);
winpr_HexDump(planar->rlePlanes[2], dstSizes[2]);
winpr_HexDump("codec.test", WLOG_DEBUG, planar->rlePlanes[2], dstSizes[2]);
return -1;
}
/* Blue */
dstSizes[3] = availableSize;
if (!freerdp_bitmap_planar_compress_plane_rle(planar->deltaPlanes[3], width, height, pOutput, &dstSizes[3]))
@ -3060,7 +3045,7 @@ int test_individual_planes_encoding_rle()
if (dstSizes[3] != sizeof(TEST_64X64_BLUE_PLANE_RLE))
{
printf("BluePlaneRle unexpected size: actual: %d, expected: %d\n",
dstSizes[1], (int) sizeof(TEST_64X64_BLUE_PLANE_RLE));
dstSizes[1], (int) sizeof(TEST_64X64_BLUE_PLANE_RLE));
return -1;
}
@ -3069,18 +3054,14 @@ int test_individual_planes_encoding_rle()
if (memcmp(planar->rlePlanes[3], (BYTE*) TEST_64X64_BLUE_PLANE_RLE, compareSize) != 0)
{
printf("BluePlaneRle doesn't match expected output\n");
printf("BluePlaneRle Expected (%d):\n", (int) sizeof(TEST_64X64_BLUE_PLANE_RLE));
winpr_HexDump((BYTE*) TEST_64X64_BLUE_PLANE_RLE, (int) sizeof(TEST_64X64_BLUE_PLANE_RLE));
winpr_HexDump("codec.test", WLOG_DEBUG, (BYTE*) TEST_64X64_BLUE_PLANE_RLE, (int) sizeof(TEST_64X64_BLUE_PLANE_RLE));
printf("BluePlaneRle Actual (%d):\n", dstSizes[3]);
winpr_HexDump(planar->rlePlanes[3], dstSizes[3]);
winpr_HexDump("codec.test", WLOG_DEBUG, planar->rlePlanes[3], dstSizes[3]);
return -1;
}
freerdp_bitmap_planar_context_free(planar);
return 0;
}
@ -3100,41 +3081,29 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
BYTE* compressedBitmap;
BYTE* decompressedBitmap;
BITMAP_PLANAR_CONTEXT* planar;
planarFlags = PLANAR_FORMAT_HEADER_NA;
planarFlags |= PLANAR_FORMAT_HEADER_RLE;
planar = freerdp_bitmap_planar_context_new(planarFlags, 64, 64);
clrconv = freerdp_clrconv_new(0);
srcBitmap16 = (BYTE*) TEST_RLE_UNCOMPRESSED_BITMAP_16BPP;
srcBitmap32 = freerdp_image_convert(srcBitmap16, NULL, 32, 32, 16, 32, clrconv);
format = PIXEL_FORMAT_ARGB32;
#if 0
freerdp_bitmap_compress_planar(planar, srcBitmap32, format, 32, 32, 32 * 4, NULL, &dstSize);
freerdp_bitmap_planar_compress_plane_rle((BYTE*) TEST_RLE_SCANLINE_UNCOMPRESSED, 12, 1, NULL, &dstSize);
freerdp_bitmap_planar_delta_encode_plane((BYTE*) TEST_RDP6_SCANLINES_ABSOLUTE, 6, 3, NULL);
freerdp_bitmap_planar_compress_plane_rle((BYTE*) TEST_RDP6_SCANLINES_DELTA_2C_ENCODED_UNSIGNED, 6, 3, NULL, &dstSize);
#endif
#if 1
for (i = 4; i < 64; i += 4)
{
width = i;
height = i;
whiteBitmap = (BYTE*) malloc(width * height * 4);
FillMemory(whiteBitmap, width * height * 4, 0xFF);
fill_bitmap_alpha_channel(whiteBitmap, width, height, 0x00);
compressedBitmap = freerdp_bitmap_compress_planar(planar, whiteBitmap, format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
@ -3154,11 +3123,9 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
if (memcmp(decompressedBitmap, whiteBitmap, width * height * 4) != 0)
{
printf("white bitmap\n");
winpr_HexDump(whiteBitmap, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, whiteBitmap, width * height * 4);
printf("decompressed bitmap\n");
winpr_HexDump(decompressedBitmap, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, decompressedBitmap, width * height * 4);
printf("error decompressed white bitmap corrupted: width: %d height: %d\n", width, height);
return -1;
}
@ -3171,13 +3138,10 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
{
width = i;
height = i;
blackBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(blackBitmap, width * height * 4);
fill_bitmap_alpha_channel(blackBitmap, width, height, 0x00);
compressedBitmap = freerdp_bitmap_compress_planar(planar, blackBitmap, format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
@ -3197,11 +3161,9 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
if (memcmp(decompressedBitmap, blackBitmap, width * height * 4) != 0)
{
printf("black bitmap\n");
winpr_HexDump(blackBitmap, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, blackBitmap, width * height * 4);
printf("decompressed bitmap\n");
winpr_HexDump(decompressedBitmap, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, decompressedBitmap, width * height * 4);
printf("error decompressed black bitmap corrupted: width: %d height: %d\n", width, height);
return -1;
}
@ -3213,13 +3175,10 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
return 0;
/* Experimental Case 01 */
width = 64;
height = 64;
compressedBitmap = freerdp_bitmap_compress_planar(planar, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01,
format, width, height, width * 4, NULL, &dstSize);
format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
@ -3243,27 +3202,21 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
{
#if 0
printf("experimental bitmap 01\n");
winpr_HexDump((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01, width * height * 4);
printf("decompressed bitmap\n");
winpr_HexDump(decompressedBitmap, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, decompressedBitmap, width * height * 4);
#endif
printf("error: decompressed experimental bitmap 01 is corrupted\n");
return -1;
}
free(compressedBitmap);
free(decompressedBitmap);
/* Experimental Case 02 */
width = 64;
height = 64;
compressedBitmap = freerdp_bitmap_compress_planar(planar, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_02,
format, width, height, width * 4, NULL, &dstSize);
format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
@ -3287,12 +3240,10 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
{
#if 0
printf("experimental bitmap 02\n");
winpr_HexDump((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_02, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_02, width * height * 4);
printf("decompressed bitmap\n");
winpr_HexDump(decompressedBitmap, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, decompressedBitmap, width * height * 4);
#endif
printf("error: decompressed experimental bitmap 02 is corrupted\n");
return -1;
}
@ -3307,13 +3258,10 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
}
/* Experimental Case 03 */
width = 64;
height = 64;
compressedBitmap = freerdp_bitmap_compress_planar(planar, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_03,
format, width, height, width * 4, NULL, &dstSize);
format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
@ -3337,23 +3285,18 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
{
#if 0
printf("experimental bitmap 03\n");
winpr_HexDump((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_03, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_03, width * height * 4);
printf("decompressed bitmap\n");
winpr_HexDump(decompressedBitmap, width * height * 4);
winpr_HexDump("codec.test", WLOG_DEBUG, decompressedBitmap, width * height * 4);
#endif
printf("error: decompressed experimental bitmap 03 is corrupted\n");
return -1;
}
free(compressedBitmap);
free(decompressedBitmap);
freerdp_clrconv_free(clrconv);
_aligned_free(srcBitmap32);
freerdp_bitmap_planar_context_free(planar);
return 0;
}

View File

@ -2,6 +2,7 @@
#include <winpr/path.h>
#include <winpr/image.h>
#include <winpr/print.h>
#include <winpr/wlog.h>
#include <freerdp/codec/region.h>

View File

@ -54,49 +54,37 @@ int test_XCrushCompressBells()
UINT32 expectedSize;
BYTE OutputBuffer[65536];
XCRUSH_CONTEXT* xcrush;
xcrush = xcrush_context_new(TRUE);
SrcSize = sizeof(TEST_BELLS_DATA) - 1;
pSrcData = (BYTE*) TEST_BELLS_DATA;
expectedSize = sizeof(TEST_BELLS_DATA_XCRUSH) - 1;
pDstData = OutputBuffer;
DstSize = sizeof(OutputBuffer);
ZeroMemory(OutputBuffer, sizeof(OutputBuffer));
status = xcrush_compress(xcrush, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("status: %d Flags: 0x%04X DstSize: %d\n", status, Flags, DstSize);
if (DstSize != expectedSize)
{
printf("XCrushCompressBells: output size mismatch: Actual: %d, Expected: %d\n", DstSize, expectedSize);
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_BELLS_DATA_XCRUSH, expectedSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_BELLS_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
}
if (memcmp(pDstData, TEST_BELLS_DATA_XCRUSH, DstSize) != 0)
{
printf("XCrushCompressBells: output mismatch\n");
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_BELLS_DATA_XCRUSH, expectedSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_BELLS_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
}
xcrush_context_free(xcrush);
return 1;
}
@ -111,49 +99,37 @@ int test_XCrushCompressIsland()
UINT32 expectedSize;
BYTE OutputBuffer[65536];
XCRUSH_CONTEXT* xcrush;
xcrush = xcrush_context_new(TRUE);
SrcSize = sizeof(TEST_ISLAND_DATA) - 1;
pSrcData = (BYTE*) TEST_ISLAND_DATA;
expectedSize = sizeof(TEST_ISLAND_DATA_XCRUSH) - 1;
pDstData = OutputBuffer;
DstSize = sizeof(OutputBuffer);
ZeroMemory(OutputBuffer, sizeof(OutputBuffer));
status = xcrush_compress(xcrush, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("status: %d Flags: 0x%04X DstSize: %d\n", status, Flags, DstSize);
if (DstSize != expectedSize)
{
printf("XCrushCompressIsland: output size mismatch: Actual: %d, Expected: %d\n", DstSize, expectedSize);
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_ISLAND_DATA_XCRUSH, expectedSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_ISLAND_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
}
if (memcmp(pDstData, TEST_ISLAND_DATA_XCRUSH, DstSize) != 0)
{
printf("XCrushCompressIsland: output mismatch\n");
printf("Actual\n");
BitDump(pDstData, DstSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(TEST_ISLAND_DATA_XCRUSH, expectedSize * 8, 0);
BitDump(__FUNCTION__, WLOG_INFO, TEST_ISLAND_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
}
xcrush_context_free(xcrush);
return 1;
}
@ -161,7 +137,6 @@ int TestFreeRDPCodecXCrush(int argc, char* argv[])
{
//if (test_XCrushCompressBells() < 0)
// return -1;
if (test_XCrushCompressIsland() < 0)
return -1;

View File

@ -23,6 +23,8 @@
#include "bulk.h"
#define TAG "com.freerdp.core"
//#define WITH_BULK_DEBUG 1
const char* bulk_get_compression_flags_string(UINT32 flags)
@ -52,19 +54,15 @@ const char* bulk_get_compression_flags_string(UINT32 flags)
UINT32 bulk_compression_level(rdpBulk* bulk)
{
rdpSettings* settings = bulk->context->settings;
bulk->CompressionLevel = (settings->CompressionLevel >= PACKET_COMPR_TYPE_RDP61) ?
PACKET_COMPR_TYPE_RDP61 : settings->CompressionLevel;
PACKET_COMPR_TYPE_RDP61 : settings->CompressionLevel;
return bulk->CompressionLevel;
}
UINT32 bulk_compression_max_size(rdpBulk* bulk)
{
bulk_compression_level(bulk);
bulk->CompressionMaxSize = (bulk->CompressionLevel < PACKET_COMPR_TYPE_64K) ? 8192 : 65536;
return bulk->CompressionMaxSize;
}
@ -76,11 +74,9 @@ int bulk_compress_validate(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE**
UINT32 _SrcSize = 0;
UINT32 _DstSize = 0;
UINT32 _Flags = 0;
_pSrcData = *ppDstData;
_SrcSize = *pDstSize;
_Flags = *pFlags | bulk->CompressionLevel;
status = bulk_decompress(bulk, _pSrcData, _SrcSize, &_pDstData, &_DstSize, _Flags);
if (status < 0)
@ -98,15 +94,12 @@ int bulk_compress_validate(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE**
if (memcmp(_pDstData, pSrcData, SrcSize) != 0)
{
DEBUG_MSG("compression/decompression input/output mismatch! flags: 0x%04X\n", _Flags);
#if 1
DEBUG_MSG("Actual:\n");
winpr_HexDump(_pDstData, SrcSize);
winpr_HexDump(TAG, WLOG_DEBUG, _pDstData, SrcSize);
DEBUG_MSG("Expected:\n");
winpr_HexDump(pSrcData, SrcSize);
winpr_HexDump(TAG, WLOG_DEBUG, pSrcData, SrcSize);
#endif
return -1;
}
@ -121,9 +114,7 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
UINT32 CompressedBytes;
UINT32 UncompressedBytes;
double CompressionRatio;
metrics = bulk->context->metrics;
bulk_compression_max_size(bulk);
type = flags & BULK_COMPRESSION_TYPE_MASK;
@ -165,22 +156,20 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
{
CompressedBytes = SrcSize;
UncompressedBytes = *pDstSize;
CompressionRatio = metrics_write_bytes(metrics, UncompressedBytes, CompressedBytes);
#ifdef WITH_BULK_DEBUG
{
DEBUG_MSG("Decompress Type: %d Flags: %s (0x%04X) Compression Ratio: %f (%d / %d), Total: %f (%u / %u)\n",
type, bulk_get_compression_flags_string(flags), flags,
CompressionRatio, CompressedBytes, UncompressedBytes,
metrics->TotalCompressionRatio, (UINT32) metrics->TotalCompressedBytes,
(UINT32) metrics->TotalUncompressedBytes);
type, bulk_get_compression_flags_string(flags), flags,
CompressionRatio, CompressedBytes, UncompressedBytes,
metrics->TotalCompressionRatio, (UINT32) metrics->TotalCompressedBytes,
(UINT32) metrics->TotalUncompressedBytes);
}
#endif
}
else
{
DEBUG_WARN( "Decompression failure!\n");
DEBUG_WARN("Decompression failure!\n");
}
return status;
@ -193,7 +182,6 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
UINT32 CompressedBytes;
UINT32 UncompressedBytes;
double CompressionRatio;
metrics = bulk->context->metrics;
if ((SrcSize <= 50) || (SrcSize >= 16384))
@ -205,10 +193,9 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
*ppDstData = bulk->OutputBuffer;
*pDstSize = sizeof(bulk->OutputBuffer);
bulk_compression_level(bulk);
bulk_compression_max_size(bulk);
if ((bulk->CompressionLevel == PACKET_COMPR_TYPE_8K) ||
(bulk->CompressionLevel == PACKET_COMPR_TYPE_64K))
{
@ -232,25 +219,24 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
{
CompressedBytes = *pDstSize;
UncompressedBytes = SrcSize;
CompressionRatio = metrics_write_bytes(metrics, UncompressedBytes, CompressedBytes);
#ifdef WITH_BULK_DEBUG
{
DEBUG_MSG("Compress Type: %d Flags: %s (0x%04X) Compression Ratio: %f (%d / %d), Total: %f (%u / %u)\n",
bulk->CompressionLevel, bulk_get_compression_flags_string(*pFlags), *pFlags,
CompressionRatio, CompressedBytes, UncompressedBytes,
metrics->TotalCompressionRatio, (UINT32) metrics->TotalCompressedBytes,
(UINT32) metrics->TotalUncompressedBytes);
bulk->CompressionLevel, bulk_get_compression_flags_string(*pFlags), *pFlags,
CompressionRatio, CompressedBytes, UncompressedBytes,
metrics->TotalCompressionRatio, (UINT32) metrics->TotalCompressedBytes,
(UINT32) metrics->TotalUncompressedBytes);
}
#endif
}
#if 0
if (bulk_compress_validate(bulk, pSrcData, SrcSize, ppDstData, pDstSize, pFlags) < 0)
status = -1;
#endif
#endif
return status;
}
@ -258,10 +244,8 @@ void bulk_reset(rdpBulk* bulk)
{
mppc_context_reset(bulk->mppcSend, FALSE);
mppc_context_reset(bulk->mppcRecv, FALSE);
ncrush_context_reset(bulk->ncrushRecv, FALSE);
ncrush_context_reset(bulk->ncrushSend, FALSE);
xcrush_context_reset(bulk->xcrushRecv, FALSE);
xcrush_context_reset(bulk->xcrushSend, FALSE);
}
@ -269,22 +253,17 @@ void bulk_reset(rdpBulk* bulk)
rdpBulk* bulk_new(rdpContext* context)
{
rdpBulk* bulk;
bulk = (rdpBulk*) calloc(1, sizeof(rdpBulk));
if (bulk)
{
bulk->context = context;
bulk->mppcSend = mppc_context_new(1, TRUE);
bulk->mppcRecv = mppc_context_new(1, FALSE);
bulk->ncrushRecv = ncrush_context_new(FALSE);
bulk->ncrushSend = ncrush_context_new(TRUE);
bulk->xcrushRecv = xcrush_context_new(FALSE);
bulk->xcrushSend = xcrush_context_new(TRUE);
bulk->CompressionLevel = context->settings->CompressionLevel;
}
@ -298,12 +277,9 @@ void bulk_free(rdpBulk* bulk)
mppc_context_free(bulk->mppcSend);
mppc_context_free(bulk->mppcRecv);
ncrush_context_free(bulk->ncrushRecv);
ncrush_context_free(bulk->ncrushSend);
xcrush_context_free(bulk->xcrushRecv);
xcrush_context_free(bulk->xcrushSend);
free(bulk);
}

View File

@ -33,6 +33,8 @@
#include "certificate.h"
#define TAG "com.freerdp.core"
/**
*
* X.509 Certificate Structure
@ -121,7 +123,8 @@
*
*/
static const char *certificate_read_errors[] = {
static const char* certificate_read_errors[] =
{
"Certificate tag",
"TBSCertificate",
"Explicit Contextual Tag [0]",
@ -159,75 +162,91 @@ BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
int modulus_length;
int exponent_length;
int error = 0;
s = Stream_New(cert->data, cert->length);
if (!s)
return FALSE;
info->Modulus = 0;
if (!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */
goto error1;
error++;
if (!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */
goto error1;
error++;
if (!ber_read_contextual_tag(s, 0, &length, TRUE)) /* Explicit Contextual Tag [0] */
goto error1;
error++;
if (!ber_read_integer(s, &version)) /* version (INTEGER) */
goto error1;
error++;
version++;
/* serialNumber */
if (!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */
goto error1;
error++;
/* signature */
if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
goto error1;
error++;
/* issuer */
if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
goto error1;
error++;
/* validity */
if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Validity (SEQUENCE) */
goto error1;
error++;
/* subject */
if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
goto error1;
error++;
/* subjectPublicKeyInfo */
if (!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */
goto error1;
error++;
/* subjectPublicKeyInfo::AlgorithmIdentifier */
if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
goto error1;
error++;
/* subjectPublicKeyInfo::subjectPublicKey */
if (!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */
goto error1;
error++;
/* RSAPublicKey (SEQUENCE) */
if (!ber_read_sequence_tag(s, &length)) /* SEQUENCE */
goto error1;
error++;
if (!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */
goto error1;
error++;
/* skip zero padding, if any */
@ -255,8 +274,10 @@ BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
info->ModulusLength = modulus_length;
info->Modulus = (BYTE*) malloc(info->ModulusLength);
if (!info->Modulus)
goto error1;
Stream_Read(s, info->Modulus, info->ModulusLength);
error++;
@ -271,15 +292,13 @@ BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
Stream_Read(s, &info->exponent[4 - exponent_length], exponent_length);
crypto_reverse(info->Modulus, info->ModulusLength);
crypto_reverse(info->exponent, 4);
Stream_Free(s, FALSE);
return TRUE;
error2:
free(info->Modulus);
info->Modulus = 0;
error1:
DEBUG_WARN( "error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error);
DEBUG_WARN("error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error);
Stream_Free(s, FALSE);
return FALSE;
}
@ -293,18 +312,20 @@ error1:
rdpX509CertChain* certificate_new_x509_certificate_chain(UINT32 count)
{
rdpX509CertChain* x509_cert_chain;
x509_cert_chain = (rdpX509CertChain*)malloc(sizeof(rdpX509CertChain));
x509_cert_chain = (rdpX509CertChain *)malloc(sizeof(rdpX509CertChain));
if (!x509_cert_chain)
return NULL;
x509_cert_chain->count = count;
x509_cert_chain->array = (rdpCertBlob *)calloc(count, sizeof(rdpCertBlob));
x509_cert_chain->array = (rdpCertBlob*)calloc(count, sizeof(rdpCertBlob));
if (!x509_cert_chain->array)
{
free(x509_cert_chain);
return NULL;
}
return x509_cert_chain;
}
@ -340,11 +361,12 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w
if (Stream_GetRemainingLength(s) < 20)
return FALSE;
Stream_Read(s, magic, 4);
if (memcmp(magic, "RSA1", 4) != 0)
{
DEBUG_WARN( "%s: magic error\n", __FUNCTION__);
DEBUG_WARN("%s: magic error\n", __FUNCTION__);
return FALSE;
}
@ -356,14 +378,16 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w
if (Stream_GetRemainingLength(s) < modlen + 8) // count padding
return FALSE;
certificate->cert_info.ModulusLength = modlen;
certificate->cert_info.Modulus = malloc(certificate->cert_info.ModulusLength);
if (!certificate->cert_info.Modulus)
return FALSE;
Stream_Read(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength);
/* 8 bytes of zero padding */
Stream_Seek(s, 8);
return TRUE;
}
@ -375,13 +399,13 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific
BYTE sig[TSSK_KEY_LENGTH];
BYTE encsig[TSSK_KEY_LENGTH + 8];
BYTE md5hash[CRYPTO_MD5_DIGEST_LENGTH];
md5ctx = crypto_md5_init();
if (!md5ctx)
return FALSE;
crypto_md5_update(md5ctx, sigdata, sigdatalen);
crypto_md5_final(md5ctx, md5hash);
Stream_Read(s, encsig, siglen);
/* Last 8 bytes shall be all zero. */
@ -391,19 +415,18 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific
if (sum != 0)
{
DEBUG_WARN( "%s: invalid signature\n", __FUNCTION__);
DEBUG_WARN("%s: invalid signature\n", __FUNCTION__);
//return FALSE;
}
siglen -= 8;
// TODO: check the result of decrypt
crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
/* Verify signature. */
if (memcmp(md5hash, sig, sizeof(md5hash)) != 0)
{
DEBUG_WARN( "%s: invalid signature\n", __FUNCTION__);
DEBUG_WARN("%s: invalid signature\n", __FUNCTION__);
//return FALSE;
}
@ -419,7 +442,7 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific
if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
{
DEBUG_WARN( "%s: invalid signature\n", __FUNCTION__);
DEBUG_WARN("%s: invalid signature\n", __FUNCTION__);
//return FALSE;
}
@ -453,8 +476,8 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate
if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA))
{
DEBUG_WARN( "%s: unsupported signature or key algorithm, dwSigAlgId=%d dwKeyAlgId=%d\n",
__FUNCTION__, dwSigAlgId, dwKeyAlgId);
DEBUG_WARN("%s: unsupported signature or key algorithm, dwSigAlgId=%d dwKeyAlgId=%d\n",
__FUNCTION__, dwSigAlgId, dwKeyAlgId);
return FALSE;
}
@ -462,17 +485,18 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate
if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
{
DEBUG_WARN( "%s: unsupported public key blob type %d\n", __FUNCTION__, wPublicKeyBlobType);
DEBUG_WARN("%s: unsupported public key blob type %d\n", __FUNCTION__, wPublicKeyBlobType);
return FALSE;
}
Stream_Read_UINT16(s, wPublicKeyBlobLen);
if (Stream_GetRemainingLength(s) < wPublicKeyBlobLen)
return FALSE;
if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen))
{
DEBUG_WARN( "%s: error in server public key\n", __FUNCTION__);
DEBUG_WARN("%s: error in server public key\n", __FUNCTION__);
return FALSE;
}
@ -484,26 +508,27 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate
if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
{
DEBUG_WARN( "%s: unsupported blob signature %d\n", __FUNCTION__, wSignatureBlobType);
DEBUG_WARN("%s: unsupported blob signature %d\n", __FUNCTION__, wSignatureBlobType);
return FALSE;
}
Stream_Read_UINT16(s, wSignatureBlobLen);
if (Stream_GetRemainingLength(s) < wSignatureBlobLen)
{
DEBUG_WARN( "%s: not enought bytes for signature(len=%d)\n", __FUNCTION__, wSignatureBlobLen);
DEBUG_WARN("%s: not enought bytes for signature(len=%d)\n", __FUNCTION__, wSignatureBlobLen);
return FALSE;
}
if (wSignatureBlobLen != 72)
{
DEBUG_WARN( "%s: invalid signature length (got %d, expected %d)\n", __FUNCTION__, wSignatureBlobLen, 64);
DEBUG_WARN("%s: invalid signature length (got %d, expected %d)\n", __FUNCTION__, wSignatureBlobLen, 64);
return FALSE;
}
if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s, wSignatureBlobLen))
{
DEBUG_WARN( "%s: unable to parse server public signature\n", __FUNCTION__);
DEBUG_WARN("%s: unable to parse server public signature\n", __FUNCTION__);
return FALSE;
}
@ -522,14 +547,14 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
UINT32 certLength;
UINT32 numCertBlobs;
BOOL ret;
DEBUG_CERTIFICATE("Server X.509 Certificate Chain");
if (Stream_GetRemainingLength(s) < 4)
return FALSE;
Stream_Read_UINT32(s, numCertBlobs); /* numCertBlobs */
Stream_Read_UINT32(s, numCertBlobs); /* numCertBlobs */
certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs);
if (!certificate->x509_cert_chain)
return FALSE;
@ -544,10 +569,11 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
return FALSE;
DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength);
certificate->x509_cert_chain->array[i].data = (BYTE*) malloc(certLength);
if (!certificate->x509_cert_chain->array[i].data)
return FALSE;
Stream_Read(s, certificate->x509_cert_chain->array[i].data, certLength);
certificate->x509_cert_chain->array[i].length = certLength;
@ -557,19 +583,24 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
DEBUG_CERTIFICATE("License Server Certificate");
ret = certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &cert_info);
DEBUG_LICENSE("modulus length:%d", (int) cert_info.ModulusLength);
if (cert_info.Modulus)
free(cert_info.Modulus);
if (!ret) {
DEBUG_WARN( "failed to read License Server, content follows:\n");
winpr_HexDump(certificate->x509_cert_chain->array[i].data, certificate->x509_cert_chain->array[i].length);
if (!ret)
{
DEBUG_WARN("failed to read License Server, content follows:\n");
winpr_HexDump(TAG, WLOG_ERROR, certificate->x509_cert_chain->array[i].data, certificate->x509_cert_chain->array[i].length);
return FALSE;
}
}
else if (numCertBlobs - i == 1)
{
DEBUG_CERTIFICATE("Terminal Server Certificate");
if (!certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &certificate->cert_info))
return FALSE;
DEBUG_CERTIFICATE("modulus length:%d", (int) certificate->cert_info.ModulusLength);
}
}
@ -594,7 +625,6 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv
return TRUE;
s = Stream_New(server_cert, length);
Stream_Read_UINT32(s, dwVersion); /* dwVersion (4 bytes) */
switch (dwVersion & CERT_CHAIN_VERSION_MASK)
@ -608,13 +638,12 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv
break;
default:
DEBUG_WARN( "invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK);
DEBUG_WARN("invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK);
ret = FALSE;
break;
}
Stream_Free(s, FALSE);
return ret;
}
@ -623,22 +652,24 @@ rdpRsaKey* key_new(const char* keyfile)
FILE* fp;
RSA* rsa;
rdpRsaKey* key;
key = (rdpRsaKey*)calloc(1, sizeof(rdpRsaKey));
key = (rdpRsaKey *)calloc(1, sizeof(rdpRsaKey));
if (!key)
return NULL;
fp = fopen(keyfile, "r");
if (fp == NULL)
{
DEBUG_WARN( "%s: unable to open RSA key file %s: %s.", __FUNCTION__, keyfile, strerror(errno));
DEBUG_WARN("%s: unable to open RSA key file %s: %s.", __FUNCTION__, keyfile, strerror(errno));
goto out_free;
}
rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
if (rsa == NULL)
{
DEBUG_WARN( "%s: unable to load RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno));
DEBUG_WARN("%s: unable to load RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno));
ERR_print_errors_fp(stderr);
fclose(fp);
goto out_free;
@ -649,7 +680,7 @@ rdpRsaKey* key_new(const char* keyfile)
switch (RSA_check_key(rsa))
{
case 0:
DEBUG_WARN( "%s: invalid RSA key in %s\n", __FUNCTION__, keyfile);
DEBUG_WARN("%s: invalid RSA key in %s\n", __FUNCTION__, keyfile);
goto out_free_rsa;
case 1:
@ -657,38 +688,38 @@ rdpRsaKey* key_new(const char* keyfile)
break;
default:
DEBUG_WARN( "%s: unexpected error when checking RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno));
DEBUG_WARN("%s: unexpected error when checking RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno));
ERR_print_errors_fp(stderr);
goto out_free_rsa;
}
if (BN_num_bytes(rsa->e) > 4)
{
DEBUG_WARN( "%s: RSA public exponent too large in %s\n", __FUNCTION__, keyfile);
DEBUG_WARN("%s: RSA public exponent too large in %s\n", __FUNCTION__, keyfile);
goto out_free_rsa;
}
key->ModulusLength = BN_num_bytes(rsa->n);
key->Modulus = (BYTE *)malloc(key->ModulusLength);
key->Modulus = (BYTE*)malloc(key->ModulusLength);
if (!key->Modulus)
goto out_free_rsa;
BN_bn2bin(rsa->n, key->Modulus);
crypto_reverse(key->Modulus, key->ModulusLength);
key->PrivateExponentLength = BN_num_bytes(rsa->d);
key->PrivateExponent = (BYTE *)malloc(key->PrivateExponentLength);
key->PrivateExponent = (BYTE*)malloc(key->PrivateExponentLength);
if (!key->PrivateExponent)
goto out_free_modulus;
BN_bn2bin(rsa->d, key->PrivateExponent);
crypto_reverse(key->PrivateExponent, key->PrivateExponentLength);
memset(key->exponent, 0, sizeof(key->exponent));
BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
crypto_reverse(key->exponent, sizeof(key->exponent));
RSA_free(rsa);
return key;
out_free_modulus:
free(key->Modulus);
out_free_rsa:
@ -705,6 +736,7 @@ void key_free(rdpRsaKey* key)
if (key->Modulus)
free(key->Modulus);
free(key->PrivateExponent);
free(key);
}

View File

@ -91,6 +91,72 @@ int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags)
return 1;
}
int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags)
{
if (flags & FREERDP_CODEC_INTERLEAVED)
{
if (codecs->interleaved)
{
bitmap_interleaved_context_reset(codecs->interleaved);
}
}
if (flags & FREERDP_CODEC_PLANAR)
{
if (codecs->planar)
{
freerdp_bitmap_planar_context_reset(codecs->planar);
}
}
if (flags & FREERDP_CODEC_NSCODEC)
{
if (codecs->nsc)
{
nsc_context_reset(codecs->nsc);
}
}
if (flags & FREERDP_CODEC_REMOTEFX)
{
if (codecs->rfx)
{
rfx_context_reset(codecs->rfx);
}
}
if (flags & FREERDP_CODEC_CLEARCODEC)
{
if (codecs->clear)
{
clear_context_reset(codecs->clear);
}
}
if (flags & FREERDP_CODEC_ALPHACODEC)
{
}
if (flags & FREERDP_CODEC_PROGRESSIVE)
{
if (codecs->progressive)
{
progressive_context_reset(codecs->progressive);
}
}
if (flags & FREERDP_CODEC_H264)
{
if (codecs->h264)
{
h264_context_reset(codecs->h264);
}
}
return 1;
}
rdpCodecs* codecs_new(rdpContext* context)
{
rdpCodecs* codecs;

View File

@ -34,9 +34,11 @@
#include "http.h"
#define TAG "gateway"
HttpContext* http_context_new()
{
return (HttpContext *)calloc(1, sizeof(HttpContext));
return (HttpContext*)calloc(1, sizeof(HttpContext));
}
void http_context_set_method(HttpContext* http_context, char* method)
@ -167,13 +169,13 @@ char* http_encode_body_line(char* param, char* value)
{
char* line;
int length;
length = strlen(param) + strlen(value) + 2;
line = (char*) malloc(length + 1);
if (!line)
return NULL;
sprintf_s(line, length + 1, "%s: %s", param, value);
sprintf_s(line, length + 1, "%s: %s", param, value);
return line;
}
@ -182,14 +184,14 @@ char* http_encode_content_length_line(int ContentLength)
char* line;
int length;
char str[32];
_itoa_s(ContentLength, str, sizeof(str), 10);
length = strlen("Content-Length") + strlen(str) + 2;
line = (char *)malloc(length + 1);
line = (char*)malloc(length + 1);
if (!line)
return NULL;
sprintf_s(line, length + 1, "Content-Length: %s", str);
sprintf_s(line, length + 1, "Content-Length: %s", str);
return line;
}
@ -197,13 +199,13 @@ char* http_encode_header_line(char* Method, char* URI)
{
char* line;
int length;
length = strlen("HTTP/1.1") + strlen(Method) + strlen(URI) + 2;
line = (char *)malloc(length + 1);
line = (char*)malloc(length + 1);
if (!line)
return NULL;
sprintf_s(line, length + 1, "%s %s HTTP/1.1", Method, URI);
sprintf_s(line, length + 1, "%s %s HTTP/1.1", Method, URI);
return line;
}
@ -211,25 +213,25 @@ char* http_encode_authorization_line(char* AuthScheme, char* AuthParam)
{
char* line;
int length;
length = strlen("Authorization") + strlen(AuthScheme) + strlen(AuthParam) + 3;
line = (char*) malloc(length + 1);
if (!line)
return NULL;
sprintf_s(line, length + 1, "Authorization: %s %s", AuthScheme, AuthParam);
sprintf_s(line, length + 1, "Authorization: %s %s", AuthScheme, AuthParam);
return line;
}
wStream* http_request_write(HttpContext* http_context, HttpRequest* http_request)
{
int i, count;
char **lines;
char** lines;
wStream* s;
int length = 0;
count = 9;
lines = (char **)calloc(count, sizeof(char *));
lines = (char**)calloc(count, sizeof(char*));
if (!lines)
return NULL;
@ -252,12 +254,14 @@ wStream* http_request_write(HttpContext* http_context, HttpRequest* http_request
if (http_request->Authorization != NULL)
{
lines[8] = http_encode_body_line("Authorization", http_request->Authorization);
if (!lines[8])
goto out_free;
}
else if ((http_request->AuthScheme != NULL) && (http_request->AuthParam != NULL))
{
lines[8] = http_encode_authorization_line(http_request->AuthScheme, http_request->AuthParam);
if (!lines[8])
goto out_free;
}
@ -266,10 +270,11 @@ wStream* http_request_write(HttpContext* http_context, HttpRequest* http_request
{
length += (strlen(lines[i]) + 2); /* add +2 for each '\r\n' character */
}
length += 2; /* empty line "\r\n" at end of header */
length += 1; /* null terminator */
s = Stream_New(NULL, length);
if (!s)
goto out_free;
@ -279,21 +284,21 @@ wStream* http_request_write(HttpContext* http_context, HttpRequest* http_request
Stream_Write(s, "\r\n", 2);
free(lines[i]);
}
Stream_Write(s, "\r\n", 2);
free(lines);
Stream_Write(s, "\0", 1); /* append null terminator */
Stream_Rewind(s, 1); /* don't include null terminator in length */
Stream_Length(s) = Stream_GetPosition(s);
return s;
out_free:
for (i = 0; i < 9; i++)
{
if (lines[i])
free(lines[i]);
}
free(lines);
return NULL;
}
@ -310,10 +315,13 @@ void http_request_free(HttpRequest* http_request)
if (http_request->AuthParam)
free(http_request->AuthParam);
if (http_request->AuthScheme)
free(http_request->AuthScheme);
if (http_request->Authorization)
free(http_request->Authorization);
free(http_request->Content);
free(http_request->Method);
free(http_request->URI);
@ -325,22 +333,25 @@ BOOL http_response_parse_header_status_line(HttpResponse* http_response, char* s
char* separator;
char* status_code;
char* reason_phrase;
separator = strchr(status_line, ' ');
if (!separator)
return FALSE;
status_code = separator + 1;
separator = strchr(status_code, ' ');
if (!separator)
return FALSE;
reason_phrase = separator + 1;
reason_phrase = separator + 1;
*separator = '\0';
http_response->StatusCode = atoi(status_code);
http_response->ReasonPhrase = _strdup(reason_phrase);
if (!http_response->ReasonPhrase)
return FALSE;
*separator = ' ';
return TRUE;
}
@ -354,8 +365,7 @@ BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, c
else if (_stricmp(name, "WWW-Authenticate") == 0)
{
char* separator;
char *authScheme, *authValue;
char* authScheme, *authValue;
separator = strchr(value, ' ');
if (separator != NULL)
@ -367,23 +377,27 @@ BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, c
* opaque="5ccc069c403ebaf9f0171e9517f40e41"
*/
*separator = '\0';
authScheme = _strdup(value);
authValue = _strdup(separator + 1);
if (!authScheme || !authValue)
return FALSE;
*separator = ' ';
}
else
{
authScheme = _strdup(value);
if (!authScheme)
return FALSE;
authValue = NULL;
}
return ListDictionary_Add(http_response->Authenticates, authScheme, authValue);
}
return TRUE;
}
@ -410,7 +424,6 @@ BOOL http_response_parse_header(HttpResponse* http_response)
for (count = 1; count < http_response->count; count++)
{
line = http_response->lines[count];
/**
* name end_of_header
* | |
@ -421,21 +434,24 @@ BOOL http_response_parse_header(HttpResponse* http_response)
* colon_pos value
*/
colon_pos = strchr(line, ':');
if ((colon_pos == NULL) || (colon_pos == line))
return FALSE;
/* retrieve the position just after header name */
for(end_of_header = colon_pos; end_of_header != line; end_of_header--)
for (end_of_header = colon_pos; end_of_header != line; end_of_header--)
{
c = end_of_header[-1];
if (c != ' ' && c != '\t' && c != ':')
break;
}
if (end_of_header == line)
return FALSE;
end_of_header_char = *end_of_header;
*end_of_header = '\0';
name = line;
/* eat space and tabs before header value */
@ -450,6 +466,7 @@ BOOL http_response_parse_header(HttpResponse* http_response)
*end_of_header = end_of_header_char;
}
return TRUE;
}
@ -459,9 +476,10 @@ void http_response_print(HttpResponse* http_response)
for (i = 0; i < http_response->count; i++)
{
DEBUG_WARN( "%s\n", http_response->lines[i]);
DEBUG_WARN("%s\n", http_response->lines[i]);
}
DEBUG_WARN( "\n");
DEBUG_WARN("\n");
}
HttpResponse* http_response_recv(rdpTls* tls)
@ -474,15 +492,16 @@ HttpResponse* http_response_recv(rdpTls* tls)
char* content;
char* header_end;
HttpResponse* http_response;
nbytes = 0;
length = 10000;
content = NULL;
buffer = calloc(length, 1);
if (!buffer)
return NULL;
http_response = http_response_new();
if (!http_response)
goto out_free;
@ -494,7 +513,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
while (nbytes < 5)
{
status = BIO_read(tls->bio, p, length - nbytes);
if (status <= 0)
{
if (!BIO_should_retry(tls->bio))
@ -512,11 +531,11 @@ HttpResponse* http_response_recv(rdpTls* tls)
}
header_end = strstr((char*) buffer, "\r\n\r\n");
if (!header_end)
{
DEBUG_WARN( "%s: invalid response:\n", __FUNCTION__);
winpr_HexDump(buffer, status);
DEBUG_WARN("%s: invalid response:\n", __FUNCTION__);
winpr_HexDump(TAG, WLOG_ERROR, buffer, status);
goto out_error;
}
@ -526,11 +545,9 @@ HttpResponse* http_response_recv(rdpTls* tls)
{
int count;
char* line;
header_end[0] = '\0';
header_end[1] = '\0';
content = header_end + 2;
count = 0;
line = (char*) buffer;
@ -541,9 +558,11 @@ HttpResponse* http_response_recv(rdpTls* tls)
}
http_response->count = count;
if (count)
{
http_response->lines = (char **)calloc(http_response->count, sizeof(char *));
http_response->lines = (char**)calloc(http_response->count, sizeof(char*));
if (!http_response->lines)
goto out_error;
}
@ -554,6 +573,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
while (line != NULL)
{
http_response->lines[count] = _strdup(line);
if (!http_response->lines[count])
goto out_error;
@ -564,10 +584,12 @@ HttpResponse* http_response_recv(rdpTls* tls)
if (!http_response_parse_header(http_response))
goto out_error;
http_response->bodyLen = nbytes - (content - (char *)buffer);
http_response->bodyLen = nbytes - (content - (char*)buffer);
if (http_response->bodyLen > 0)
{
http_response->BodyContent = (BYTE *)malloc(http_response->bodyLen);
http_response->BodyContent = (BYTE*)malloc(http_response->bodyLen);
if (!http_response->BodyContent)
goto out_error;
@ -586,9 +608,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
}
free(buffer);
return http_response;
out_error:
http_response_free(http_response);
out_free:
@ -596,7 +616,7 @@ out_free:
return NULL;
}
static BOOL strings_equals_nocase(void *obj1, void *obj2)
static BOOL strings_equals_nocase(void* obj1, void* obj2)
{
if (!obj1 || !obj2)
return FALSE;
@ -604,16 +624,18 @@ static BOOL strings_equals_nocase(void *obj1, void *obj2)
return _stricmp(obj1, obj2) == 0;
}
static void string_free(void *obj1)
static void string_free(void* obj1)
{
if (!obj1)
return;
free(obj1);
}
HttpResponse* http_response_new()
{
HttpResponse *ret = (HttpResponse *)calloc(1, sizeof(HttpResponse));
HttpResponse* ret = (HttpResponse*)calloc(1, sizeof(HttpResponse));
if (!ret)
return NULL;
@ -636,9 +658,7 @@ void http_response_free(HttpResponse* http_response)
free(http_response->lines[i]);
free(http_response->lines);
free(http_response->ReasonPhrase);
ListDictionary_Free(http_response->Authenticates);
if (http_response->ContentLength > 0)

View File

@ -31,6 +31,7 @@
#include <winpr/tchar.h>
#include <winpr/synch.h>
#include <winpr/dsparse.h>
#include <freerdp/log.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
@ -48,10 +49,11 @@
#include "rpc.h"
#define TAG FREERDP_TAG("core.gateway")
/* Security Verification Trailer Signature */
rpc_sec_verification_trailer RPC_SEC_VERIFICATION_TRAILER =
{ { 0x8a, 0xe3, 0x13, 0x71, 0x02, 0xf4, 0x36, 0x71 } };
{ { 0x8a, 0xe3, 0x13, 0x71, 0x02, 0xf4, 0x36, 0x71 } };
static char* PTYPE_STRINGS[] =
{
@ -92,45 +94,51 @@ const RPC_SECURITY_PROVIDER_INFO RPC_SECURITY_PROVIDER_INFO_TABLE[] =
void rpc_pdu_header_print(rpcconn_hdr_t* header)
{
DEBUG_WARN( "rpc_vers: %d\n", header->common.rpc_vers);
DEBUG_WARN( "rpc_vers_minor: %d\n", header->common.rpc_vers_minor);
DEBUG_WARN("rpc_vers: %d\n", header->common.rpc_vers);
DEBUG_WARN("rpc_vers_minor: %d\n", header->common.rpc_vers_minor);
if (header->common.ptype > PTYPE_RTS)
DEBUG_WARN( "ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype);
DEBUG_WARN("ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype);
else
DEBUG_WARN( "ptype: %s (%d)\n", PTYPE_STRINGS[header->common.ptype], header->common.ptype);
DEBUG_WARN("ptype: %s (%d)\n", PTYPE_STRINGS[header->common.ptype], header->common.ptype);
DEBUG_WARN("pfc_flags (0x%02X) = {", header->common.pfc_flags);
DEBUG_WARN( "pfc_flags (0x%02X) = {", header->common.pfc_flags);
if (header->common.pfc_flags & PFC_FIRST_FRAG)
DEBUG_WARN( " PFC_FIRST_FRAG");
DEBUG_WARN(" PFC_FIRST_FRAG");
if (header->common.pfc_flags & PFC_LAST_FRAG)
DEBUG_WARN( " PFC_LAST_FRAG");
DEBUG_WARN(" PFC_LAST_FRAG");
if (header->common.pfc_flags & PFC_PENDING_CANCEL)
DEBUG_WARN( " PFC_PENDING_CANCEL");
DEBUG_WARN(" PFC_PENDING_CANCEL");
if (header->common.pfc_flags & PFC_RESERVED_1)
DEBUG_WARN( " PFC_RESERVED_1");
DEBUG_WARN(" PFC_RESERVED_1");
if (header->common.pfc_flags & PFC_CONC_MPX)
DEBUG_WARN( " PFC_CONC_MPX");
DEBUG_WARN(" PFC_CONC_MPX");
if (header->common.pfc_flags & PFC_DID_NOT_EXECUTE)
DEBUG_WARN( " PFC_DID_NOT_EXECUTE");
DEBUG_WARN(" PFC_DID_NOT_EXECUTE");
if (header->common.pfc_flags & PFC_OBJECT_UUID)
DEBUG_WARN( " PFC_OBJECT_UUID");
DEBUG_WARN( " }\n");
DEBUG_WARN(" PFC_OBJECT_UUID");
DEBUG_WARN( "packed_drep[4]: %02X %02X %02X %02X\n",
header->common.packed_drep[0], header->common.packed_drep[1],
header->common.packed_drep[2], header->common.packed_drep[3]);
DEBUG_WARN( "frag_length: %d\n", header->common.frag_length);
DEBUG_WARN( "auth_length: %d\n", header->common.auth_length);
DEBUG_WARN( "call_id: %d\n", header->common.call_id);
DEBUG_WARN(" }\n");
DEBUG_WARN("packed_drep[4]: %02X %02X %02X %02X\n",
header->common.packed_drep[0], header->common.packed_drep[1],
header->common.packed_drep[2], header->common.packed_drep[3]);
DEBUG_WARN("frag_length: %d\n", header->common.frag_length);
DEBUG_WARN("auth_length: %d\n", header->common.auth_length);
DEBUG_WARN("call_id: %d\n", header->common.call_id);
if (header->common.ptype == PTYPE_RESPONSE)
{
DEBUG_WARN( "alloc_hint: %d\n", header->response.alloc_hint);
DEBUG_WARN( "p_cont_id: %d\n", header->response.p_cont_id);
DEBUG_WARN( "cancel_count: %d\n", header->response.cancel_count);
DEBUG_WARN( "reserved: %d\n", header->response.reserved);
DEBUG_WARN("alloc_hint: %d\n", header->response.alloc_hint);
DEBUG_WARN("p_cont_id: %d\n", header->response.p_cont_id);
DEBUG_WARN("cancel_count: %d\n", header->response.cancel_count);
DEBUG_WARN("reserved: %d\n", header->response.reserved);
}
}
@ -147,11 +155,9 @@ void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header)
UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment)
{
UINT32 pad;
pad = *offset;
*offset = (*offset + alignment - 1) & ~(alignment - 1);
pad = *offset - pad;
return pad;
}
@ -245,7 +251,6 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l
UINT32 auth_pad_length;
UINT32 sec_trailer_offset;
rpc_sec_trailer* sec_trailer;
*offset = RPC_COMMON_FIELDS_LENGTH;
header = ((rpcconn_hdr_t*) buffer);
@ -265,7 +270,7 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l
*offset += 4;
break;
default:
DEBUG_WARN( "%s: unknown ptype=0x%x\n", __FUNCTION__, header->common.ptype);
DEBUG_WARN("%s: unknown ptype=0x%x\n", __FUNCTION__, header->common.ptype);
return FALSE;
}
@ -275,27 +280,23 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l
if (header->common.ptype == PTYPE_REQUEST)
{
UINT32 sec_trailer_offset;
sec_trailer_offset = header->common.frag_length - header->common.auth_length - 8;
*length = sec_trailer_offset - *offset;
return TRUE;
}
frag_length = header->common.frag_length;
auth_length = header->common.auth_length;
sec_trailer_offset = frag_length - auth_length - 8;
sec_trailer = (rpc_sec_trailer*) &buffer[sec_trailer_offset];
auth_pad_length = sec_trailer->auth_pad_length;
#if 0
DEBUG_WARN( "sec_trailer: type: %d level: %d pad_length: %d reserved: %d context_id: %d\n",
sec_trailer->auth_type,
sec_trailer->auth_level,
sec_trailer->auth_pad_length,
sec_trailer->auth_reserved,
sec_trailer->auth_context_id);
DEBUG_WARN("sec_trailer: type: %d level: %d pad_length: %d reserved: %d context_id: %d\n",
sec_trailer->auth_type,
sec_trailer->auth_level,
sec_trailer->auth_pad_length,
sec_trailer->auth_reserved,
sec_trailer->auth_context_id);
#endif
/**
@ -306,8 +307,8 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l
if ((frag_length - (sec_trailer_offset + 8)) != auth_length)
{
DEBUG_WARN( "invalid auth_length: actual: %d, expected: %d\n", auth_length,
(frag_length - (sec_trailer_offset + 8)));
DEBUG_WARN("invalid auth_length: actual: %d, expected: %d\n", auth_length,
(frag_length - (sec_trailer_offset + 8)));
}
*length = frag_length - auth_length - 24 - 8 - auth_pad_length;
@ -317,10 +318,10 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l
int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
{
int status;
status = BIO_read(rpc->TlsOut->bio, data, length);
if (status > 0) {
if (status > 0)
{
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(data, status);
#endif
@ -336,25 +337,20 @@ int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
int rpc_out_write(rdpRpc* rpc, const BYTE* data, int length)
{
int status;
status = tls_write_all(rpc->TlsOut, data, length);
return status;
}
int rpc_in_write(rdpRpc* rpc, const BYTE* data, int length)
{
int status;
#ifdef WITH_DEBUG_TSG
DEBUG_WARN( "Sending PDU (length: %d)\n", length);
DEBUG_WARN("Sending PDU (length: %d)\n", length);
rpc_pdu_header_print((rpcconn_hdr_t*) data);
winpr_HexDump(data, length);
DEBUG_WARN( "\n");
winpr_HexDump(TAG, WLOG_DEBUG, data, length);
DEBUG_WARN("\n");
#endif
status = tls_write_all(rpc->TlsIn, data, length);
return status;
}
@ -369,27 +365,26 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
RpcClientCall* clientCall;
SECURITY_STATUS encrypt_status;
rpcconn_request_hdr_t* request_pdu;
ntlm = rpc->ntlm;
if (!ntlm || !ntlm->table)
{
DEBUG_WARN( "%s: invalid ntlm context\n", __FUNCTION__);
DEBUG_WARN("%s: invalid ntlm context\n", __FUNCTION__);
return -1;
}
if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK)
{
DEBUG_WARN( "%s: QueryContextAttributes SECPKG_ATTR_SIZES failure\n", __FUNCTION__);
DEBUG_WARN("%s: QueryContextAttributes SECPKG_ATTR_SIZES failure\n", __FUNCTION__);
return -1;
}
request_pdu = (rpcconn_request_hdr_t*) calloc(1, sizeof(rpcconn_request_hdr_t));
if (!request_pdu)
return -1;
rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) request_pdu);
request_pdu->ptype = PTYPE_REQUEST;
request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
request_pdu->auth_length = (UINT16) ntlm->ContextSizes.cbMaxSignature;
@ -397,8 +392,8 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
request_pdu->alloc_hint = length;
request_pdu->p_cont_id = 0x0000;
request_pdu->opnum = opnum;
clientCall = rpc_client_call_new(request_pdu->call_id, request_pdu->opnum);
if (!clientCall)
goto out_free_pdu;
@ -409,11 +404,9 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
rpc->PipeCallId = request_pdu->call_id;
request_pdu->stub_data = data;
offset = 24;
stub_data_pad = 0;
stub_data_pad = rpc_offset_align(&offset, 8);
offset += length;
request_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4);
request_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
@ -421,42 +414,38 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
request_pdu->auth_verifier.auth_reserved = 0x00;
request_pdu->auth_verifier.auth_context_id = 0x00000000;
offset += (8 + request_pdu->auth_length);
request_pdu->frag_length = offset;
buffer = (BYTE*) calloc(1, request_pdu->frag_length);
if (!buffer)
goto out_free_pdu;
CopyMemory(buffer, request_pdu, 24);
CopyMemory(buffer, request_pdu, 24);
offset = 24;
rpc_offset_pad(&offset, stub_data_pad);
CopyMemory(&buffer[offset], request_pdu->stub_data, length);
offset += length;
rpc_offset_pad(&offset, request_pdu->auth_verifier.auth_pad_length);
CopyMemory(&buffer[offset], &request_pdu->auth_verifier.auth_type, 8);
offset += 8;
Buffers[0].BufferType = SECBUFFER_DATA; /* auth_data */
Buffers[1].BufferType = SECBUFFER_TOKEN; /* signature */
Buffers[0].pvBuffer = buffer;
Buffers[0].cbBuffer = offset;
Buffers[1].cbBuffer = ntlm->ContextSizes.cbMaxSignature;
Buffers[1].pvBuffer = calloc(1, Buffers[1].cbBuffer);
if (!Buffers[1].pvBuffer)
return -1;
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->SendSeqNum++);
if (encrypt_status != SEC_E_OK)
{
DEBUG_WARN( "EncryptMessage status: 0x%08X\n", encrypt_status);
DEBUG_WARN("EncryptMessage status: 0x%08X\n", encrypt_status);
free(request_pdu);
return -1;
}
@ -469,9 +458,7 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
length = -1;
free(request_pdu);
return length;
out_free_clientCall:
rpc_client_call_free(clientCall);
out_free_pdu:
@ -486,7 +473,7 @@ BOOL rpc_connect(rdpRpc* rpc)
if (!rts_connect(rpc))
{
DEBUG_WARN( "rts_connect error!\n");
DEBUG_WARN("rts_connect error!\n");
return FALSE;
}
@ -494,7 +481,7 @@ BOOL rpc_connect(rdpRpc* rpc)
if (rpc_secure_bind(rpc) != 0)
{
DEBUG_WARN( "rpc_secure_bind error!\n");
DEBUG_WARN("rpc_secure_bind error!\n");
return FALSE;
}
@ -509,7 +496,6 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne
connection->DefaultInChannel->PingOriginator.ConnectionTimeout = 30;
connection->DefaultInChannel->PingOriginator.KeepAliveInterval = 0;
connection->DefaultInChannel->Mutex = CreateMutex(NULL, FALSE, NULL);
connection->DefaultOutChannel->State = CLIENT_OUT_CHANNEL_STATE_INITIAL;
connection->DefaultOutChannel->BytesReceived = 0;
connection->DefaultOutChannel->ReceiverAvailableWindow = rpc->ReceiveWindow;
@ -527,16 +513,18 @@ RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
return NULL;
connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
connection->DefaultInChannel = (RpcInChannel *)calloc(1, sizeof(RpcInChannel));
connection->DefaultInChannel = (RpcInChannel*)calloc(1, sizeof(RpcInChannel));
if (!connection->DefaultInChannel)
goto out_free;
connection->DefaultOutChannel = (RpcOutChannel*)calloc(1, sizeof(RpcOutChannel));
if (!connection->DefaultOutChannel)
goto out_default_in;
rpc_client_virtual_connection_init(rpc, connection);
return connection;
out_default_in:
free(connection->DefaultInChannel);
out_free:
@ -557,60 +545,56 @@ void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection
rdpRpc* rpc_new(rdpTransport* transport)
{
rdpRpc* rpc = (rdpRpc*) calloc(1, sizeof(rdpRpc));
if (!rpc)
return NULL;
rpc->State = RPC_CLIENT_STATE_INITIAL;
rpc->transport = transport;
rpc->settings = transport->settings;
rpc->SendSeqNum = 0;
rpc->ntlm = ntlm_new();
if (!rpc->ntlm)
goto out_free;
rpc->NtlmHttpIn = ntlm_http_new();
if (!rpc->NtlmHttpIn)
goto out_free_ntlm;
rpc->NtlmHttpOut = ntlm_http_new();
if (!rpc->NtlmHttpOut)
goto out_free_ntlm_http_in;
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN);
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT);
rpc->PipeCallId = 0;
rpc->StubCallId = 0;
rpc->StubFragCount = 0;
rpc->rpc_vers = 5;
rpc->rpc_vers_minor = 0;
/* little-endian data representation */
rpc->packed_drep[0] = 0x10;
rpc->packed_drep[1] = 0x00;
rpc->packed_drep[2] = 0x00;
rpc->packed_drep[3] = 0x00;
rpc->max_xmit_frag = 0x0FF8;
rpc->max_recv_frag = 0x0FF8;
rpc->ReceiveWindow = 0x00010000;
rpc->ChannelLifetime = 0x40000000;
rpc->ChannelLifetimeSet = 0;
rpc->KeepAliveInterval = 300000;
rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval;
rpc->CurrentKeepAliveTime = 0;
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
if (!rpc->VirtualConnection)
goto out_free_ntlm_http_out;
rpc->VirtualConnectionCookieTable = ArrayList_New(TRUE);
if (!rpc->VirtualConnectionCookieTable)
goto out_free_virtual_connection;
@ -621,9 +605,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
rpc->client->SynchronousSend = TRUE;
rpc->client->SynchronousReceive = TRUE;
return rpc;
out_free_virtualConnectionCookieTable:
rpc_client_free(rpc);
ArrayList_Free(rpc->VirtualConnectionCookieTable);
@ -653,10 +635,8 @@ void rpc_free(rdpRpc* rpc)
}
rpc_client_virtual_connection_free(rpc->VirtualConnection);
ArrayList_Clear(rpc->VirtualConnectionCookieTable);
ArrayList_Free(rpc->VirtualConnectionCookieTable);
free(rpc);
}
}

View File

@ -37,6 +37,7 @@
#include "rpc_client.h"
#include "../rdp.h"
#define TAG "gateway"
#define SYNCHRONOUS_TIMEOUT 5000
wStream* rpc_client_fragment_pool_take(rdpRpc* rpc)
@ -67,10 +68,13 @@ RPC_PDU* rpc_client_receive_pool_take(rdpRpc* rpc)
if (!pdu)
{
pdu = (RPC_PDU *)malloc(sizeof(RPC_PDU));
pdu = (RPC_PDU*)malloc(sizeof(RPC_PDU));
if (!pdu)
return NULL;
pdu->s = Stream_New(NULL, rpc->max_recv_frag);
if (!pdu->s)
{
free(pdu);
@ -80,10 +84,8 @@ RPC_PDU* rpc_client_receive_pool_take(rdpRpc* rpc)
pdu->CallId = 0;
pdu->Flags = 0;
Stream_Length(pdu->s) = 0;
Stream_SetPosition(pdu->s, 0);
return pdu;
}
@ -100,14 +102,12 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
wStream* fragment;
rpcconn_hdr_t* header;
freerdp* instance;
instance = (freerdp *)rpc->transport->settings->instance;
instance = (freerdp*)rpc->transport->settings->instance;
if (!rpc->client->pdu)
rpc->client->pdu = rpc_client_receive_pool_take(rpc);
fragment = Queue_Dequeue(rpc->client->FragmentQueue);
buffer = (BYTE*) Stream_Buffer(fragment);
header = (rpcconn_hdr_t*) Stream_Buffer(fragment);
@ -115,33 +115,30 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
{
rpc->client->pdu->Flags = 0;
rpc->client->pdu->CallId = header->common.call_id;
Stream_EnsureCapacity(rpc->client->pdu->s, Stream_Length(fragment));
Stream_Write(rpc->client->pdu->s, buffer, Stream_Length(fragment));
Stream_Length(rpc->client->pdu->s) = Stream_GetPosition(rpc->client->pdu->s);
rpc_client_fragment_pool_return(rpc, fragment);
Queue_Enqueue(rpc->client->ReceiveQueue, rpc->client->pdu);
SetEvent(rpc->transport->ReceiveEvent);
rpc->client->pdu = NULL;
return 0;
}
switch (header->common.ptype)
{
case PTYPE_RTS:
if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED)
{
DEBUG_WARN( "%s: warning: unhandled RTS PDU\n", __FUNCTION__);
DEBUG_WARN("%s: warning: unhandled RTS PDU\n", __FUNCTION__);
return 0;
}
DEBUG_WARN( "%s: Receiving Out-of-Sequence RTS PDU\n", __FUNCTION__);
DEBUG_WARN("%s: Receiving Out-of-Sequence RTS PDU\n", __FUNCTION__);
rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length);
rpc_client_fragment_pool_return(rpc, fragment);
return 0;
case PTYPE_FAULT:
rpc_recv_fault_pdu(header);
Queue_Enqueue(rpc->client->ReceiveQueue, NULL);
@ -149,7 +146,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
case PTYPE_RESPONSE:
break;
default:
DEBUG_WARN( "%s: unexpected RPC PDU type %d\n", __FUNCTION__, header->common.ptype);
DEBUG_WARN("%s: unexpected RPC PDU type %d\n", __FUNCTION__, header->common.ptype);
Queue_Enqueue(rpc->client->ReceiveQueue, NULL);
return -1;
}
@ -159,7 +156,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength))
{
DEBUG_WARN( "%s: expected stub\n", __FUNCTION__);
DEBUG_WARN("%s: expected stub\n", __FUNCTION__);
Queue_Enqueue(rpc->client->ReceiveQueue, NULL);
return -1;
}
@ -173,10 +170,8 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
if ((header->common.call_id == rpc->PipeCallId) && (header->common.pfc_flags & PFC_LAST_FRAG))
{
TerminateEventArgs e;
instance->context->rdp->disconnect = TRUE;
rpc->transport->tsg->state = TSG_STATE_TUNNEL_CLOSE_PENDING;
EventArgsInit(&e, "freerdp");
e.code = 0;
PubSub_OnTerminate(instance->context->pubSub, instance->context, &e);
@ -195,13 +190,12 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
if (rpc->StubCallId != header->common.call_id)
{
DEBUG_WARN( "%s: invalid call_id: actual: %d, expected: %d, frag_count: %d\n", __FUNCTION__,
rpc->StubCallId, header->common.call_id, rpc->StubFragCount);
DEBUG_WARN("%s: invalid call_id: actual: %d, expected: %d, frag_count: %d\n", __FUNCTION__,
rpc->StubCallId, header->common.call_id, rpc->StubFragCount);
}
Stream_Write(rpc->client->pdu->s, &buffer[StubOffset], StubLength);
rpc->StubFragCount++;
rpc_client_fragment_pool_return(rpc, fragment);
if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < (rpc->ReceiveWindow / 2))
@ -220,16 +214,11 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
{
rpc->client->pdu->Flags = RPC_PDU_FLAG_STUB;
rpc->client->pdu->CallId = rpc->StubCallId;
Stream_Length(rpc->client->pdu->s) = Stream_GetPosition(rpc->client->pdu->s);
rpc->StubFragCount = 0;
rpc->StubCallId = 0;
Queue_Enqueue(rpc->client->ReceiveQueue, rpc->client->pdu);
rpc->client->pdu = NULL;
return 0;
}
@ -252,11 +241,11 @@ int rpc_client_on_read_event(rdpRpc* rpc)
while (Stream_GetPosition(rpc->client->RecvFrag) < RPC_COMMON_FIELDS_LENGTH)
{
status = rpc_out_read(rpc, Stream_Pointer(rpc->client->RecvFrag),
RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(rpc->client->RecvFrag));
RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(rpc->client->RecvFrag));
if (status < 0)
{
DEBUG_WARN( "rpc_client_frag_read: error reading header\n");
DEBUG_WARN("rpc_client_frag_read: error reading header\n");
return -1;
}
@ -269,25 +258,24 @@ int rpc_client_on_read_event(rdpRpc* rpc)
if (Stream_GetPosition(rpc->client->RecvFrag) < RPC_COMMON_FIELDS_LENGTH)
return status;
header = (rpcconn_common_hdr_t*) Stream_Buffer(rpc->client->RecvFrag);
if (header->frag_length > rpc->max_recv_frag)
{
DEBUG_WARN( "rpc_client_frag_read: invalid fragment size: %d (max: %d)\n",
header->frag_length, rpc->max_recv_frag);
winpr_HexDump(Stream_Buffer(rpc->client->RecvFrag), Stream_GetPosition(rpc->client->RecvFrag));
DEBUG_WARN("rpc_client_frag_read: invalid fragment size: %d (max: %d)\n",
header->frag_length, rpc->max_recv_frag);
winpr_HexDump(TAG, WLOG_ERROR, Stream_Buffer(rpc->client->RecvFrag), Stream_GetPosition(rpc->client->RecvFrag));
return -1;
}
while (Stream_GetPosition(rpc->client->RecvFrag) < header->frag_length)
{
status = rpc_out_read(rpc, Stream_Pointer(rpc->client->RecvFrag),
header->frag_length - Stream_GetPosition(rpc->client->RecvFrag));
header->frag_length - Stream_GetPosition(rpc->client->RecvFrag));
if (status < 0)
{
DEBUG_WARN( "%s: error reading fragment body\n", __FUNCTION__);
DEBUG_WARN("%s: error reading fragment body\n", __FUNCTION__);
return -1;
}
@ -305,10 +293,8 @@ int rpc_client_on_read_event(rdpRpc* rpc)
if (Stream_GetPosition(rpc->client->RecvFrag) >= header->frag_length)
{
/* complete fragment received */
Stream_Length(rpc->client->RecvFrag) = Stream_GetPosition(rpc->client->RecvFrag);
Stream_SetPosition(rpc->client->RecvFrag, 0);
Queue_Enqueue(rpc->client->FragmentQueue, rpc->client->RecvFrag);
rpc->client->RecvFrag = NULL;
@ -330,9 +316,7 @@ RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId)
int index;
int count;
RpcClientCall* clientCall;
ArrayList_Lock(rpc->client->ClientCallList);
clientCall = NULL;
count = ArrayList_Count(rpc->client->ClientCallList);
@ -345,22 +329,20 @@ RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId)
}
ArrayList_Unlock(rpc->client->ClientCallList);
return clientCall;
}
RpcClientCall* rpc_client_call_new(UINT32 CallId, UINT32 OpNum)
{
RpcClientCall* clientCall;
clientCall = (RpcClientCall*) malloc(sizeof(RpcClientCall));
if (!clientCall)
return NULL;
clientCall->CallId = CallId;
clientCall->OpNum = OpNum;
clientCall->State = RPC_CLIENT_CALL_STATE_SEND_PDUS;
return clientCall;
}
@ -373,12 +355,13 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
{
RPC_PDU* pdu;
int status;
pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU));
if (!pdu)
return -1;
pdu->s = Stream_New(buffer, length);
if (!pdu->s)
goto out_free;
@ -388,9 +371,10 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
if (rpc->client->SynchronousSend)
{
status = WaitForSingleObject(rpc->client->PduSentEvent, SYNCHRONOUS_TIMEOUT);
if (status == WAIT_TIMEOUT)
{
DEBUG_WARN( "%s: timed out waiting for pdu sent event %p\n", __FUNCTION__, rpc->client->PduSentEvent);
DEBUG_WARN("%s: timed out waiting for pdu sent event %p\n", __FUNCTION__, rpc->client->PduSentEvent);
return -1;
}
@ -398,7 +382,6 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
}
return 0;
out_free_stream:
Stream_Free(pdu->s, TRUE);
out_free:
@ -412,21 +395,18 @@ int rpc_send_dequeue_pdu(rdpRpc* rpc)
RPC_PDU* pdu;
RpcClientCall* clientCall;
rpcconn_common_hdr_t* header;
RpcInChannel *inChannel;
RpcInChannel* inChannel;
pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->SendQueue);
if (!pdu)
return 0;
inChannel = rpc->VirtualConnection->DefaultInChannel;
WaitForSingleObject(inChannel->Mutex, INFINITE);
status = rpc_in_write(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s));
header = (rpcconn_common_hdr_t*) Stream_Buffer(pdu->s);
clientCall = rpc_client_call_find_by_id(rpc, header->call_id);
clientCall->State = RPC_CLIENT_CALL_STATE_DISPATCHED;
ReleaseMutex(inChannel->Mutex);
/*
@ -456,34 +436,33 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc)
RPC_PDU* pdu;
DWORD dwMilliseconds;
DWORD result;
dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT * 4 : 0;
result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);
if (result == WAIT_TIMEOUT)
{
DEBUG_WARN( "%s: timed out waiting for receive event\n", __FUNCTION__);
DEBUG_WARN("%s: timed out waiting for receive event\n", __FUNCTION__);
return NULL;
}
if (result != WAIT_OBJECT_0)
return NULL;
pdu = (RPC_PDU *)Queue_Dequeue(rpc->client->ReceiveQueue);
pdu = (RPC_PDU*)Queue_Dequeue(rpc->client->ReceiveQueue);
#ifdef WITH_DEBUG_TSG
if (pdu)
{
DEBUG_WARN( "Receiving PDU (length: %d, CallId: %d)\n", pdu->s->length, pdu->CallId);
winpr_HexDump(Stream_Buffer(pdu->s), Stream_Length(pdu->s));
DEBUG_WARN( "\n");
DEBUG_WARN("Receiving PDU (length: %d, CallId: %d)\n", pdu->s->length, pdu->CallId);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(pdu->s), Stream_Length(pdu->s));
DEBUG_WARN("\n");
}
else
{
DEBUG_WARN( "Receiving a NULL PDU\n");
DEBUG_WARN("Receiving a NULL PDU\n");
}
#endif
#endif
return pdu;
}
@ -491,14 +470,13 @@ RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc)
{
DWORD dwMilliseconds;
DWORD result;
dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0;
result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);
if (result != WAIT_OBJECT_0)
return NULL;
return (RPC_PDU *)Queue_Peek(rpc->client->ReceiveQueue);
return (RPC_PDU*)Queue_Peek(rpc->client->ReceiveQueue);
}
static void* rpc_client_thread(void* arg)
@ -509,12 +487,9 @@ static void* rpc_client_thread(void* arg)
HANDLE events[3];
HANDLE ReadEvent;
int fd;
rpc = (rdpRpc*) arg;
fd = BIO_get_fd(rpc->TlsOut->bio, NULL);
ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, fd);
nCount = 0;
events[nCount++] = rpc->client->StopEvent;
events[nCount++] = Queue_Event(rpc->client->SendQueue);
@ -527,7 +502,7 @@ static void* rpc_client_thread(void* arg)
*/
if (rpc_client_on_read_event(rpc) < 0)
{
DEBUG_WARN( "%s: an error occured when treating first packet\n", __FUNCTION__);
DEBUG_WARN("%s: an error occured when treating first packet\n", __FUNCTION__);
goto out;
}
@ -555,7 +530,6 @@ static void* rpc_client_thread(void* arg)
out:
CloseHandle(ReadEvent);
return NULL;
}
@ -576,55 +550,66 @@ static void rpc_fragment_free(wStream* fragment)
int rpc_client_new(rdpRpc* rpc)
{
RpcClient* client = NULL;
client = (RpcClient *)calloc(1, sizeof(RpcClient));
client = (RpcClient*)calloc(1, sizeof(RpcClient));
rpc->client = client;
if (!client)
return -1;
client->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rpc_client_thread,
rpc, CREATE_SUSPENDED, NULL);
(LPTHREAD_START_ROUTINE) rpc_client_thread,
rpc, CREATE_SUSPENDED, NULL);
if (!client->Thread)
return -1;
client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!client->StopEvent)
return -1;
client->PduSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!client->PduSentEvent)
return -1;
client->SendQueue = Queue_New(TRUE, -1, -1);
if (!client->SendQueue)
return -1;
Queue_Object(client->SendQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
Queue_Object(client->SendQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
client->pdu = NULL;
client->ReceivePool = Queue_New(TRUE, -1, -1);
if (!client->ReceivePool)
return -1;
Queue_Object(client->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
Queue_Object(client->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
client->ReceiveQueue = Queue_New(TRUE, -1, -1);
if (!client->ReceiveQueue)
return -1;
Queue_Object(client->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
Queue_Object(client->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
client->RecvFrag = NULL;
client->FragmentPool = Queue_New(TRUE, -1, -1);
if (!client->FragmentPool)
return -1;
Queue_Object(client->FragmentPool)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
Queue_Object(client->FragmentPool)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
client->FragmentQueue = Queue_New(TRUE, -1, -1);
if (!client->FragmentQueue)
return -1;
Queue_Object(client->FragmentQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
Queue_Object(client->FragmentQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
client->ClientCallList = ArrayList_New(TRUE);
if (!client->ClientCallList)
return -1;
ArrayList_Object(client->ClientCallList)->fnObjectFree = (OBJECT_FREE_FN) rpc_client_call_free;
return 0;
}
@ -632,9 +617,8 @@ int rpc_client_new(rdpRpc* rpc)
int rpc_client_start(rdpRpc* rpc)
{
rpc->client->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rpc_client_thread,
rpc, 0, NULL);
(LPTHREAD_START_ROUTINE) rpc_client_thread,
rpc, 0, NULL);
return 0;
}
@ -653,7 +637,6 @@ int rpc_client_stop(rdpRpc* rpc)
int rpc_client_free(rdpRpc* rpc)
{
RpcClient* client;
client = rpc->client;
if (!client)
@ -667,6 +650,7 @@ int rpc_client_free(rdpRpc* rpc)
if (client->FragmentPool)
Queue_Free(client->FragmentPool);
if (client->FragmentQueue)
Queue_Free(client->FragmentQueue);
@ -675,6 +659,7 @@ int rpc_client_free(rdpRpc* rpc)
if (client->ReceivePool)
Queue_Free(client->ReceivePool);
if (client->ReceiveQueue)
Queue_Free(client->ReceiveQueue);
@ -683,6 +668,7 @@ int rpc_client_free(rdpRpc* rpc)
if (client->StopEvent)
CloseHandle(client->StopEvent);
if (client->PduSentEvent)
CloseHandle(client->PduSentEvent);

File diff suppressed because it is too large Load Diff

View File

@ -33,11 +33,10 @@ rdpBitmap* Bitmap_Alloc(rdpContext* context)
rdpGraphics* graphics;
graphics = context->graphics;
bitmap = (rdpBitmap*) malloc(graphics->Bitmap_Prototype->size);
bitmap = (rdpBitmap*) calloc(1, graphics->Bitmap_Prototype->size);
if (bitmap)
{
ZeroMemory(bitmap, graphics->Bitmap_Prototype->size);
CopyMemory(bitmap, graphics->Bitmap_Prototype, sizeof(rdpBitmap));
bitmap->data = NULL;
}
@ -96,11 +95,10 @@ rdpPointer* Pointer_Alloc(rdpContext* context)
rdpGraphics* graphics;
graphics = context->graphics;
pointer = (rdpPointer*) malloc(graphics->Pointer_Prototype->size);
pointer = (rdpPointer*) calloc(1, graphics->Pointer_Prototype->size);
if (pointer)
{
ZeroMemory(pointer, graphics->Pointer_Prototype->size);
CopyMemory(pointer, graphics->Pointer_Prototype, sizeof(rdpPointer));
}
@ -163,11 +161,10 @@ rdpGlyph* Glyph_Alloc(rdpContext* context)
rdpGraphics* graphics;
graphics = context->graphics;
glyph = (rdpGlyph*) malloc(graphics->Glyph_Prototype->size);
glyph = (rdpGlyph*) calloc(1, graphics->Glyph_Prototype->size);
if (glyph)
{
ZeroMemory(glyph, graphics->Glyph_Prototype->size);
CopyMemory(glyph, graphics->Glyph_Prototype, sizeof(rdpGlyph));
}

View File

@ -23,12 +23,14 @@
#endif
#include <winpr/crt.h>
#include <freerdp/log.h>
#include "redirection.h"
#include "certificate.h"
#include "license.h"
#define TAG FREERDP_TAG("core")
/* #define LICENSE_NULL_CLIENT_RANDOM 1 */
/* #define LICENSE_NULL_PREMASTER_SECRET 1 */
@ -36,20 +38,20 @@
static const char* const LICENSE_MESSAGE_STRINGS[] =
{
"",
"License Request",
"Platform Challenge",
"New License",
"Upgrade License",
"", "", "", "", "", "",
"", "", "", "", "", "",
"",
"License Info",
"New License Request",
"",
"Platform Challenge Response",
"", "", "", "", "", "", "", "", "",
"Error Alert"
"",
"License Request",
"Platform Challenge",
"New License",
"Upgrade License",
"", "", "", "", "", "",
"", "", "", "", "", "",
"",
"License Info",
"New License Request",
"",
"Platform Challenge Response",
"", "", "", "", "", "", "", "", "",
"Error Alert"
};
static const char* const error_codes[] =
@ -82,18 +84,14 @@ void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
{
char* CompanyName = NULL;
char* ProductId = NULL;
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) productInfo->pbCompanyName,
productInfo->cbCompanyName / 2, &CompanyName, 0, NULL, NULL);
productInfo->cbCompanyName / 2, &CompanyName, 0, NULL, NULL);
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) productInfo->pbProductId,
productInfo->cbProductId / 2, &ProductId, 0, NULL, NULL);
DEBUG_WARN( "ProductInfo:\n");
DEBUG_WARN( "\tdwVersion: 0x%08X\n", productInfo->dwVersion);
DEBUG_WARN( "\tCompanyName: %s\n", CompanyName);
DEBUG_WARN( "\tProductId: %s\n", ProductId);
productInfo->cbProductId / 2, &ProductId, 0, NULL, NULL);
DEBUG_WARN("ProductInfo:\n");
DEBUG_WARN("\tdwVersion: 0x%08X\n", productInfo->dwVersion);
DEBUG_WARN("\tCompanyName: %s\n", CompanyName);
DEBUG_WARN("\tProductId: %s\n", ProductId);
free(CompanyName);
free(ProductId);
}
@ -102,13 +100,12 @@ void license_print_scope_list(SCOPE_LIST* scopeList)
{
int index;
LICENSE_BLOB* scope;
DEBUG_WARN( "ScopeList (%d):\n", scopeList->count);
DEBUG_WARN("ScopeList (%d):\n", scopeList->count);
for (index = 0; index < scopeList->count; index++)
{
scope = &scopeList->array[index];
DEBUG_WARN( "\t%s\n", (char*) scope->data);
DEBUG_WARN("\t%s\n", (char*) scope->data);
}
}
@ -133,7 +130,6 @@ BOOL license_read_preamble(wStream* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsg
Stream_Read_UINT8(s, *bMsgType); /* bMsgType (1 byte) */
Stream_Read_UINT8(s, *flags); /* flags (1 byte) */
Stream_Read_UINT16(s, *wMsgSize); /* wMsgSize (2 bytes) */
return TRUE;
}
@ -163,17 +159,15 @@ void license_write_preamble(wStream* s, BYTE bMsgType, BYTE flags, UINT16 wMsgSi
wStream* license_send_stream_init(rdpLicense* license)
{
wStream* s;
license->rdp->sec_flags = SEC_LICENSE_PKT;
if (license->rdp->do_crypt)
license->rdp->sec_flags |= SEC_LICENSE_ENCRYPT_CS;
license->rdp->sec_flags |= SEC_LICENSE_ENCRYPT_CS;
s = transport_send_stream_init(license->rdp->transport, 4096);
rdp_init_stream(license->rdp, s);
license->PacketHeaderLength = Stream_GetPosition(s);
Stream_Seek(s, LICENSE_PREAMBLE_LENGTH);
return s;
}
@ -190,13 +184,10 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type)
BYTE flags;
UINT16 wMsgSize;
rdpRdp* rdp = license->rdp;
DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]);
length = Stream_GetPosition(s);
wMsgSize = length - license->PacketHeaderLength;
Stream_SetPosition(s, license->PacketHeaderLength);
flags = PREAMBLE_VERSION_3_0;
/**
@ -208,17 +199,13 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type)
flags |= EXTENDED_ERROR_MSG_SUPPORTED;
license_write_preamble(s, type, flags, wMsgSize);
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize);
winpr_HexDump(Stream_Pointer(s) - LICENSE_PREAMBLE_LENGTH, wMsgSize);
DEBUG_WARN("Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Pointer(s) - LICENSE_PREAMBLE_LENGTH, wMsgSize);
#endif
Stream_SetPosition(s, length);
rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
rdp->sec_flags = 0;
return TRUE;
}
@ -241,7 +228,7 @@ int license_recv(rdpLicense* license, wStream* s)
if (!rdp_read_header(license->rdp, s, &length, &channelId))
{
DEBUG_WARN( "%s: Incorrect RDP header.\n", __FUNCTION__);
DEBUG_WARN("%s: Incorrect RDP header.\n", __FUNCTION__);
return -1;
}
@ -252,7 +239,7 @@ int license_recv(rdpLicense* license, wStream* s)
{
if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags))
{
DEBUG_WARN( "%s: rdp_decrypt failed\n", __FUNCTION__);
DEBUG_WARN("%s: rdp_decrypt failed\n", __FUNCTION__);
return -1;
}
}
@ -268,7 +255,7 @@ int license_recv(rdpLicense* license, wStream* s)
if (status < 0)
{
DEBUG_WARN( "%s: unexpected license packet.\n", __FUNCTION__);
DEBUG_WARN("%s: unexpected license packet.\n", __FUNCTION__);
return status;
}
@ -283,32 +270,33 @@ int license_recv(rdpLicense* license, wStream* s)
switch (bMsgType)
{
case LICENSE_REQUEST:
if (!license_read_license_request_packet(license, s))
return -1;
license_send_new_license_request_packet(license);
break;
case PLATFORM_CHALLENGE:
if (!license_read_platform_challenge_packet(license, s))
return -1;
license_send_platform_challenge_response_packet(license);
break;
case NEW_LICENSE:
license_read_new_license_packet(license, s);
break;
case UPGRADE_LICENSE:
license_read_upgrade_license_packet(license, s);
break;
case ERROR_ALERT:
if (!license_read_error_alert_packet(license, s))
return -1;
break;
break;
default:
DEBUG_WARN( "%s: invalid bMsgType:%d\n", __FUNCTION__, bMsgType);
DEBUG_WARN("%s: invalid bMsgType:%d\n", __FUNCTION__, bMsgType);
return FALSE;
}
@ -319,11 +307,9 @@ void license_generate_randoms(rdpLicense* license)
{
ZeroMemory(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */
ZeroMemory(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
#ifndef LICENSE_NULL_CLIENT_RANDOM
crypto_nonce(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */
#endif
#ifndef LICENSE_NULL_PREMASTER_SECRET
crypto_nonce(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
#endif
@ -337,45 +323,35 @@ void license_generate_randoms(rdpLicense* license)
void license_generate_keys(rdpLicense* license)
{
security_master_secret(license->PremasterSecret, license->ClientRandom,
license->ServerRandom, license->MasterSecret); /* MasterSecret */
license->ServerRandom, license->MasterSecret); /* MasterSecret */
security_session_key_blob(license->MasterSecret, license->ClientRandom,
license->ServerRandom, license->SessionKeyBlob); /* SessionKeyBlob */
license->ServerRandom, license->SessionKeyBlob); /* SessionKeyBlob */
security_mac_salt_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->MacSaltKey); /* MacSaltKey */
license->ServerRandom, license->MacSaltKey); /* MacSaltKey */
security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "ClientRandom:\n");
winpr_HexDump(license->ClientRandom, CLIENT_RANDOM_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN( "ServerRandom:\n");
winpr_HexDump(license->ServerRandom, SERVER_RANDOM_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN( "PremasterSecret:\n");
winpr_HexDump(license->PremasterSecret, PREMASTER_SECRET_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN( "MasterSecret:\n");
winpr_HexDump(license->MasterSecret, MASTER_SECRET_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN( "SessionKeyBlob:\n");
winpr_HexDump(license->SessionKeyBlob, SESSION_KEY_BLOB_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN( "MacSaltKey:\n");
winpr_HexDump(license->MacSaltKey, MAC_SALT_KEY_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN( "LicensingEncryptionKey:\n");
winpr_HexDump(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN("ClientRandom:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->ClientRandom, CLIENT_RANDOM_LENGTH);
DEBUG_WARN("\n");
DEBUG_WARN("ServerRandom:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->ServerRandom, SERVER_RANDOM_LENGTH);
DEBUG_WARN("\n");
DEBUG_WARN("PremasterSecret:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->PremasterSecret, PREMASTER_SECRET_LENGTH);
DEBUG_WARN("\n");
DEBUG_WARN("MasterSecret:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->MasterSecret, MASTER_SECRET_LENGTH);
DEBUG_WARN("\n");
DEBUG_WARN("SessionKeyBlob:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->SessionKeyBlob, SESSION_KEY_BLOB_LENGTH);
DEBUG_WARN("\n");
DEBUG_WARN("MacSaltKey:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->MacSaltKey, MAC_SALT_KEY_LENGTH);
DEBUG_WARN("\n");
DEBUG_WARN("LicensingEncryptionKey:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
DEBUG_WARN("\n");
#endif
}
@ -388,14 +364,13 @@ void license_generate_hwid(rdpLicense* license)
{
CryptoMd5 md5;
BYTE* mac_address;
ZeroMemory(license->HardwareId, HWID_LENGTH);
mac_address = license->rdp->transport->TcpIn->mac_address;
md5 = crypto_md5_init();
if (!md5)
{
DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__);
DEBUG_WARN("%s: unable to allocate a md5\n", __FUNCTION__);
return;
}
@ -412,16 +387,14 @@ void license_get_server_rsa_public_key(rdpLicense* license)
if (license->ServerCertificate->length < 1)
{
certificate_read_server_certificate(license->certificate,
license->rdp->settings->ServerCertificate,
license->rdp->settings->ServerCertificateLength);
license->rdp->settings->ServerCertificate,
license->rdp->settings->ServerCertificateLength);
}
Exponent = license->certificate->cert_info.exponent;
Modulus = license->certificate->cert_info.Modulus;
ModulusLength = license->certificate->cert_info.ModulusLength;
CopyMemory(license->Exponent, Exponent, 4);
license->ModulusLength = ModulusLength;
license->Modulus = (BYTE*) malloc(ModulusLength);
memcpy(license->Modulus, Modulus, ModulusLength);
@ -430,51 +403,43 @@ void license_get_server_rsa_public_key(rdpLicense* license)
void license_encrypt_premaster_secret(rdpLicense* license)
{
BYTE* EncryptedPremasterSecret;
license_get_server_rsa_public_key(license);
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "Modulus (%d bits):\n", license->ModulusLength * 8);
winpr_HexDump(license->Modulus, license->ModulusLength);
DEBUG_WARN( "\n");
DEBUG_WARN( "Exponent:\n");
winpr_HexDump(license->Exponent, 4);
DEBUG_WARN( "\n");
DEBUG_WARN("Modulus (%d bits):\n", license->ModulusLength * 8);
winpr_HexDump(TAG, WLOG_DEBUG, license->Modulus, license->ModulusLength);
DEBUG_WARN("\n");
DEBUG_WARN("Exponent:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->Exponent, 4);
DEBUG_WARN("\n");
#endif
EncryptedPremasterSecret = (BYTE*) malloc(license->ModulusLength);
ZeroMemory(EncryptedPremasterSecret, license->ModulusLength);
license->EncryptedPremasterSecret->type = BB_RANDOM_BLOB;
license->EncryptedPremasterSecret->length = PREMASTER_SECRET_LENGTH;
#ifndef LICENSE_NULL_PREMASTER_SECRET
license->EncryptedPremasterSecret->length =
crypto_rsa_public_encrypt(license->PremasterSecret, PREMASTER_SECRET_LENGTH,
license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret);
license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret);
#endif
license->EncryptedPremasterSecret->data = EncryptedPremasterSecret;
}
void license_decrypt_platform_challenge(rdpLicense* license)
{
CryptoRc4 rc4;
license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length);
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
if (!rc4)
{
DEBUG_WARN( "%s: unable to allocate a rc4\n", __FUNCTION__);
DEBUG_WARN("%s: unable to allocate a rc4\n", __FUNCTION__);
return;
}
crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
license->EncryptedPlatformChallenge->data,
license->PlatformChallenge->data);
license->EncryptedPlatformChallenge->data,
license->PlatformChallenge->data);
crypto_rc4_free(rc4);
}
@ -491,7 +456,6 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
return FALSE;
Stream_Read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */
Stream_Read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */
if (Stream_GetRemainingLength(s) < productInfo->cbCompanyName + 4)
@ -499,7 +463,6 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
productInfo->pbCompanyName = (BYTE*) malloc(productInfo->cbCompanyName);
Stream_Read(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
Stream_Read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */
if (Stream_GetRemainingLength(s) < productInfo->cbProductId)
@ -511,7 +474,6 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
productInfo->pbProductId = (BYTE*) malloc(productInfo->cbProductId);
Stream_Read(s, productInfo->pbProductId, productInfo->cbProductId);
return TRUE;
}
@ -524,15 +486,12 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
LICENSE_PRODUCT_INFO* license_new_product_info()
{
LICENSE_PRODUCT_INFO* productInfo;
productInfo = (LICENSE_PRODUCT_INFO*) malloc(sizeof(LICENSE_PRODUCT_INFO));
productInfo->dwVersion = 0;
productInfo->cbCompanyName = 0;
productInfo->pbCompanyName = NULL;
productInfo->cbProductId = 0;
productInfo->pbProductId = NULL;
return productInfo;
}
@ -574,20 +533,19 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
return FALSE;
/*
* Server can choose to not send data by setting length to 0.
* If so, it may not bother to set the type, so shortcut the warning
*/
* Server can choose to not send data by setting length to 0.
* If so, it may not bother to set the type, so shortcut the warning
*/
if ((blob->type != BB_ANY_BLOB) && (blob->length == 0))
return TRUE;
if ((blob->type != wBlobType) && (blob->type != BB_ANY_BLOB))
{
DEBUG_WARN( "license binary blob type (%x) does not match expected type (%x).\n", wBlobType, blob->type);
DEBUG_WARN("license binary blob type (%x) does not match expected type (%x).\n", wBlobType, blob->type);
}
blob->type = wBlobType;
blob->data = (BYTE*) malloc(blob->length);
Stream_Read(s, blob->data, blob->length); /* blobData */
return TRUE;
}
@ -602,7 +560,6 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
void license_write_binary_blob(wStream* s, LICENSE_BLOB* blob)
{
Stream_EnsureRemainingCapacity(s, blob->length + 4);
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
Stream_Write_UINT16(s, blob->length); /* wBlobLen (2 bytes) */
@ -613,17 +570,15 @@ void license_write_binary_blob(wStream* s, LICENSE_BLOB* blob)
void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
{
UINT32 length;
length = ModulusLength + 8;
if (blob->length > ModulusLength)
{
DEBUG_WARN( "license_write_encrypted_premaster_secret_blob: invalid blob\n");
DEBUG_WARN("license_write_encrypted_premaster_secret_blob: invalid blob\n");
return;
}
Stream_EnsureRemainingCapacity(s, length + 4);
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
Stream_Write_UINT16(s, length); /* wBlobLen (2 bytes) */
@ -642,12 +597,10 @@ void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo
LICENSE_BLOB* license_new_binary_blob(UINT16 type)
{
LICENSE_BLOB* blob;
blob = (LICENSE_BLOB*) malloc(sizeof(LICENSE_BLOB));
blob->type = type;
blob->length = 0;
blob->data = NULL;
return blob;
}
@ -681,6 +634,7 @@ BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList)
return FALSE;
Stream_Read_UINT32(s, scopeCount); /* ScopeCount (4 bytes) */
if (scopeCount > Stream_GetRemainingLength(s) / 4) /* every blob is at least 4 bytes */
return FALSE;
@ -708,11 +662,9 @@ BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList)
SCOPE_LIST* license_new_scope_list()
{
SCOPE_LIST* scopeList;
scopeList = (SCOPE_LIST*) malloc(sizeof(SCOPE_LIST));
scopeList->count = 0;
scopeList->array = NULL;
return scopeList;
}
@ -781,19 +733,15 @@ BOOL license_read_license_request_packet(rdpLicense* license, wStream* s)
license_generate_keys(license);
license_generate_hwid(license);
license_encrypt_premaster_secret(license);
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "ServerRandom:\n");
winpr_HexDump(license->ServerRandom, 32);
DEBUG_WARN( "\n");
DEBUG_WARN("ServerRandom:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->ServerRandom, 32);
DEBUG_WARN("\n");
license_print_product_info(license->ProductInfo);
DEBUG_WARN( "\n");
DEBUG_WARN("\n");
license_print_scope_list(license->ScopeList);
DEBUG_WARN( "\n");
DEBUG_WARN("\n");
#endif
return TRUE;
}
@ -808,14 +756,12 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
{
BYTE MacData[16];
UINT32 ConnectFlags = 0;
DEBUG_LICENSE("Receiving Platform Challenge Packet");
if (Stream_GetRemainingLength(s) < 4)
return FALSE;
Stream_Read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */
/* EncryptedPlatformChallenge */
license->EncryptedPlatformChallenge->type = BB_ANY_BLOB;
license_read_binary_blob(s, license->EncryptedPlatformChallenge);
@ -825,26 +771,20 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
return FALSE;
Stream_Read(s, MacData, 16); /* MACData (16 bytes) */
license_decrypt_platform_challenge(license);
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "ConnectFlags: 0x%08X\n", ConnectFlags);
DEBUG_WARN( "\n");
DEBUG_WARN( "EncryptedPlatformChallenge:\n");
winpr_HexDump(license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length);
DEBUG_WARN( "\n");
DEBUG_WARN( "PlatformChallenge:\n");
winpr_HexDump(license->PlatformChallenge->data, license->PlatformChallenge->length);
DEBUG_WARN( "\n");
DEBUG_WARN( "MacData:\n");
winpr_HexDump(MacData, 16);
DEBUG_WARN( "\n");
DEBUG_WARN("ConnectFlags: 0x%08X\n", ConnectFlags);
DEBUG_WARN("\n");
DEBUG_WARN("EncryptedPlatformChallenge:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length);
DEBUG_WARN("\n");
DEBUG_WARN("PlatformChallenge:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->PlatformChallenge->data, license->PlatformChallenge->length);
DEBUG_WARN("\n");
DEBUG_WARN("MacData:\n");
winpr_HexDump(TAG, WLOG_DEBUG, MacData, 16);
DEBUG_WARN("\n");
#endif
return TRUE;
}
@ -896,8 +836,8 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s)
return FALSE;
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "dwErrorCode: %s, dwStateTransition: %s\n",
error_codes[dwErrorCode], state_transitions[dwStateTransition]);
DEBUG_WARN("dwErrorCode: %s, dwStateTransition: %s\n",
error_codes[dwErrorCode], state_transitions[dwStateTransition]);
#endif
if (dwErrorCode == STATUS_VALID_CLIENT)
@ -911,18 +851,14 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s)
case ST_TOTAL_ABORT:
license->state = LICENSE_STATE_ABORTED;
break;
case ST_NO_TRANSITION:
license->state = LICENSE_STATE_COMPLETED;
break;
case ST_RESET_PHASE_TO_START:
license->state = LICENSE_STATE_AWAIT;
break;
case ST_RESEND_LAST_MESSAGE:
break;
default:
break;
}
@ -941,33 +877,26 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
{
UINT32 PlatformId;
UINT32 PreferredKeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
PlatformId = CLIENT_OS_ID_WINNT_POST_52 | CLIENT_IMAGE_ID_MICROSOFT;
Stream_Write_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
Stream_Write_UINT32(s, PlatformId); /* PlatformId (4 bytes) */
Stream_Write(s, license->ClientRandom, 32); /* ClientRandom (32 bytes) */
license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength); /* EncryptedPremasterSecret */
license_write_binary_blob(s, license->ClientUserName); /* ClientUserName */
license_write_binary_blob(s, license->ClientMachineName); /* ClientMachineName */
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "PreferredKeyExchangeAlg: 0x%08X\n", PreferredKeyExchangeAlg);
DEBUG_WARN( "\n");
DEBUG_WARN( "ClientRandom:\n");
winpr_HexDump(license->ClientRandom, 32);
DEBUG_WARN( "\n");
DEBUG_WARN( "EncryptedPremasterSecret\n");
winpr_HexDump(license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length);
DEBUG_WARN( "\n");
DEBUG_WARN( "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data);
DEBUG_WARN( "\n");
DEBUG_WARN( "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
DEBUG_WARN( "\n");
DEBUG_WARN("PreferredKeyExchangeAlg: 0x%08X\n", PreferredKeyExchangeAlg);
DEBUG_WARN("\n");
DEBUG_WARN("ClientRandom:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->ClientRandom, 32);
DEBUG_WARN("\n");
DEBUG_WARN("EncryptedPremasterSecret\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length);
DEBUG_WARN("\n");
DEBUG_WARN("ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data);
DEBUG_WARN("\n");
DEBUG_WARN("ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
DEBUG_WARN("\n");
#endif
}
@ -981,9 +910,7 @@ void license_send_new_license_request_packet(rdpLicense* license)
{
wStream* s;
char* username;
DEBUG_LICENSE("Sending New License Packet");
s = license_send_stream_init(license);
if (license->rdp->settings->Username != NULL)
@ -993,17 +920,12 @@ void license_send_new_license_request_packet(rdpLicense* license)
license->ClientUserName->data = (BYTE*) username;
license->ClientUserName->length = strlen(username) + 1;
license->ClientMachineName->data = (BYTE*) license->rdp->settings->ClientHostname;
license->ClientMachineName->length = strlen(license->rdp->settings->ClientHostname) + 1;
license_write_new_license_request_packet(license, s);
license_send(license, s, NEW_LICENSE_REQUEST);
license->ClientUserName->data = NULL;
license->ClientUserName->length = 0;
license->ClientMachineName->data = NULL;
license->ClientMachineName->length = 0;
}
@ -1020,7 +942,6 @@ void license_write_platform_challenge_response_packet(rdpLicense* license, wStre
{
license_write_binary_blob(s, license->EncryptedPlatformChallenge); /* EncryptedPlatformChallengeResponse */
license_write_binary_blob(s, license->EncryptedHardwareId); /* EncryptedHWID */
Stream_EnsureRemainingCapacity(s, 16);
Stream_Write(s, macData, 16); /* MACData */
}
@ -1038,51 +959,42 @@ void license_send_platform_challenge_response_packet(rdpLicense* license)
BYTE* buffer;
CryptoRc4 rc4;
BYTE mac_data[16];
DEBUG_LICENSE("Sending Platform Challenge Response Packet");
s = license_send_stream_init(license);
license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
length = license->PlatformChallenge->length + HWID_LENGTH;
buffer = (BYTE*) malloc(length);
CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
security_mac_data(license->MacSaltKey, buffer, length, mac_data);
free(buffer);
buffer = (BYTE*) malloc(HWID_LENGTH);
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
if (!rc4)
{
DEBUG_WARN( "%s: unable to allocate a rc4\n", __FUNCTION__);
DEBUG_WARN("%s: unable to allocate a rc4\n", __FUNCTION__);
free(buffer);
return;
}
crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
crypto_rc4_free(rc4);
license->EncryptedHardwareId->type = BB_DATA_BLOB;
license->EncryptedHardwareId->data = buffer;
license->EncryptedHardwareId->length = HWID_LENGTH;
#ifdef WITH_DEBUG_LICENSE
DEBUG_WARN( "LicensingEncryptionKey:\n");
winpr_HexDump(license->LicensingEncryptionKey, 16);
DEBUG_WARN( "\n");
DEBUG_WARN( "HardwareId:\n");
winpr_HexDump(license->HardwareId, HWID_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN( "EncryptedHardwareId:\n");
winpr_HexDump(license->EncryptedHardwareId->data, HWID_LENGTH);
DEBUG_WARN( "\n");
DEBUG_WARN("LicensingEncryptionKey:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey, 16);
DEBUG_WARN("\n");
DEBUG_WARN("HardwareId:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->HardwareId, HWID_LENGTH);
DEBUG_WARN("\n");
DEBUG_WARN("EncryptedHardwareId:\n");
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedHardwareId->data, HWID_LENGTH);
DEBUG_WARN("\n");
#endif
license_write_platform_challenge_response_packet(license, s, mac_data);
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
}
@ -1095,16 +1007,11 @@ void license_send_platform_challenge_response_packet(rdpLicense* license)
BOOL license_send_valid_client_error_packet(rdpLicense* license)
{
wStream* s;
s = license_send_stream_init(license);
DEBUG_LICENSE("Sending Error Alert Packet");
Stream_Write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */
Stream_Write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */
license_write_binary_blob(s, license->ErrorInfo);
return license_send(license, s, ERROR_ALERT);
}
@ -1117,13 +1024,11 @@ BOOL license_send_valid_client_error_packet(rdpLicense* license)
rdpLicense* license_new(rdpRdp* rdp)
{
rdpLicense* license;
license = (rdpLicense*) malloc(sizeof(rdpLicense));
if (license != NULL)
{
ZeroMemory(license, sizeof(rdpLicense));
license->rdp = rdp;
license->state = LICENSE_STATE_AWAIT;
license->certificate = certificate_new();

View File

@ -27,6 +27,7 @@
#include <unistd.h>
#endif
#include <freerdp/log.h>
#include <freerdp/crypto/tls.h>
#include <winpr/crt.h>
@ -39,6 +40,8 @@
#include "nla.h"
#define TAG FREERDP_TAG("core")
/**
* TSRequest ::= SEQUENCE {
* version [0] INTEGER,
@ -114,7 +117,6 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
rdpTls* tls = NULL;
freerdp* instance;
rdpSettings* settings;
PromptPassword = FALSE;
settings = credssp->settings;
instance = (freerdp*) settings->instance;
@ -129,6 +131,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
}
#ifndef _WIN32
if (PromptPassword)
{
if (settings->RestrictedAdminModeRequired)
@ -137,6 +140,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
PromptPassword = FALSE;
}
}
#endif
if (PromptPassword)
@ -144,7 +148,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
if (instance->Authenticate)
{
BOOL proceed = instance->Authenticate(instance,
&settings->Username, &settings->Password, &settings->Domain);
&settings->Username, &settings->Password, &settings->Domain);
if (!proceed)
{
@ -152,12 +156,10 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
freerdp_set_last_error(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
return 0;
}
}
}
sspi_SetAuthIdentity(&(credssp->identity), settings->Username, settings->Domain, settings->Password);
#ifndef _WIN32
{
SEC_WINNT_AUTH_IDENTITY* identity = &(credssp->identity);
@ -172,8 +174,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
free(identity->Password);
identity->PasswordLength = ConvertToUnicode(CP_UTF8, 0,
settings->PasswordHash, -1, &identity->Password, 0) - 1;
settings->PasswordHash, -1, &identity->Password, 0) - 1;
/**
* Multiply password hash length by 64 to obtain a length exceeding
* the maximum (256) and use it this for hash identification in WinPR.
@ -184,10 +185,9 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
}
}
#endif
#ifdef WITH_DEBUG_NLA
DEBUG_MSG("User: %s Domain: %s Password: %s\n",
(char*) credssp->identity.User, (char*) credssp->identity.Domain, (char*) credssp->identity.Password);
(char*) credssp->identity.User, (char*) credssp->identity.Domain, (char*) credssp->identity.Password);
#endif
if (credssp->transport->layer == TRANSPORT_LAYER_TLS)
@ -200,27 +200,23 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
}
else
{
DEBUG_WARN( "Unknown NLA transport layer\n");
DEBUG_WARN("Unknown NLA transport layer\n");
return 0;
}
sspi_SecBufferAlloc(&credssp->PublicKey, tls->PublicKeyLength);
CopyMemory(credssp->PublicKey.pvBuffer, tls->PublicKey, tls->PublicKeyLength);
length = sizeof(TERMSRV_SPN_PREFIX) + strlen(settings->ServerHostname);
spn = (SEC_CHAR*) malloc(length + 1);
sprintf(spn, "%s%s", TERMSRV_SPN_PREFIX, settings->ServerHostname);
#ifdef UNICODE
credssp->ServicePrincipalName = (LPTSTR) malloc(length * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, spn, length,
(LPWSTR) credssp->ServicePrincipalName, length);
(LPWSTR) credssp->ServicePrincipalName, length);
free(spn);
#else
credssp->ServicePrincipalName = spn;
#endif
return 1;
}
@ -234,10 +230,8 @@ int credssp_ntlm_server_init(rdpCredssp* credssp)
freerdp* instance;
rdpSettings* settings = credssp->settings;
instance = (freerdp*) settings->instance;
sspi_SecBufferAlloc(&credssp->PublicKey, credssp->transport->TlsIn->PublicKeyLength);
CopyMemory(credssp->PublicKey.pvBuffer, credssp->transport->TlsIn->PublicKey, credssp->transport->TlsIn->PublicKeyLength);
return 1;
}
@ -257,30 +251,27 @@ int credssp_client_authenticate(rdpCredssp* credssp)
BOOL have_context;
BOOL have_input_buffer;
BOOL have_pub_key_auth;
sspi_GlobalInit();
if (credssp_ntlm_client_init(credssp) == 0)
return 0;
credssp->table = InitSecurityInterfaceEx(0);
status = credssp->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &pPackageInfo);
if (status != SEC_E_OK)
{
DEBUG_WARN( "QuerySecurityPackageInfo status: 0x%08X\n", status);
DEBUG_WARN("QuerySecurityPackageInfo status: 0x%08X\n", status);
return 0;
}
cbMaxToken = pPackageInfo->cbMaxToken;
status = credssp->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME,
SECPKG_CRED_OUTBOUND, NULL, &credssp->identity, NULL, NULL, &credentials, &expiration);
SECPKG_CRED_OUTBOUND, NULL, &credssp->identity, NULL, NULL, &credentials, &expiration);
if (status != SEC_E_OK)
{
DEBUG_WARN( "AcquireCredentialsHandle status: 0x%08X\n", status);
DEBUG_WARN("AcquireCredentialsHandle status: 0x%08X\n", status);
return 0;
}
@ -290,7 +281,6 @@ int credssp_client_authenticate(rdpCredssp* credssp)
ZeroMemory(&input_buffer, sizeof(SecBuffer));
ZeroMemory(&output_buffer, sizeof(SecBuffer));
ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes));
/*
* from tspkg.dll: 0x00000132
* ISC_REQ_MUTUAL_AUTH
@ -298,7 +288,6 @@ int credssp_client_authenticate(rdpCredssp* credssp)
* ISC_REQ_USE_SESSION_KEY
* ISC_REQ_ALLOCATE_MEMORY
*/
fContextReq = ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY;
while (TRUE)
@ -309,12 +298,11 @@ int credssp_client_authenticate(rdpCredssp* credssp)
output_buffer.BufferType = SECBUFFER_TOKEN;
output_buffer.cbBuffer = cbMaxToken;
output_buffer.pvBuffer = malloc(output_buffer.cbBuffer);
status = credssp->table->InitializeSecurityContext(&credentials,
(have_context) ? &credssp->context : NULL,
credssp->ServicePrincipalName, fContextReq, 0,
SECURITY_NATIVE_DREP, (have_input_buffer) ? &input_buffer_desc : NULL,
0, &credssp->context, &output_buffer_desc, &pfContextAttr, &expiration);
(have_context) ? &credssp->context : NULL,
credssp->ServicePrincipalName, fContextReq, 0,
SECURITY_NATIVE_DREP, (have_input_buffer) ? &input_buffer_desc : NULL,
0, &credssp->context, &output_buffer_desc, &pfContextAttr, &expiration);
if (have_input_buffer && (input_buffer.pvBuffer))
{
@ -339,7 +327,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK)
{
DEBUG_WARN( "QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
DEBUG_WARN("QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
return 0;
}
@ -352,12 +340,10 @@ int credssp_client_authenticate(rdpCredssp* credssp)
{
credssp->negoToken.pvBuffer = output_buffer.pvBuffer;
credssp->negoToken.cbBuffer = output_buffer.cbBuffer;
#ifdef WITH_DEBUG_CREDSSP
DEBUG_WARN( "Sending Authentication Token\n");
winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer);
DEBUG_WARN("Sending Authentication Token\n");
winpr_HexDump(TAG, WLOG_DEBUG, credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer);
#endif
credssp_send(credssp);
credssp_buffer_free(credssp);
}
@ -366,7 +352,6 @@ int credssp_client_authenticate(rdpCredssp* credssp)
break;
/* receive server response and place in input buffer */
input_buffer_desc.ulVersion = SECBUFFER_VERSION;
input_buffer_desc.cBuffers = 1;
input_buffer_desc.pBuffers = &input_buffer;
@ -376,13 +361,11 @@ int credssp_client_authenticate(rdpCredssp* credssp)
return -1;
#ifdef WITH_DEBUG_CREDSSP
DEBUG_WARN( "Receiving Authentication Token (%d)\n", (int) credssp->negoToken.cbBuffer);
winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer);
DEBUG_WARN("Receiving Authentication Token (%d)\n", (int) credssp->negoToken.cbBuffer);
winpr_HexDump(TAG, WLOG_DEBUG, credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer);
#endif
input_buffer.pvBuffer = credssp->negoToken.pvBuffer;
input_buffer.cbBuffer = credssp->negoToken.cbBuffer;
have_input_buffer = TRUE;
have_context = TRUE;
}
@ -392,34 +375,29 @@ int credssp_client_authenticate(rdpCredssp* credssp)
return -1;
/* Verify Server Public Key Echo */
status = credssp_decrypt_public_key_echo(credssp);
credssp_buffer_free(credssp);
if (status != SEC_E_OK)
{
DEBUG_WARN( "Could not verify public key echo!\n");
DEBUG_WARN("Could not verify public key echo!\n");
return -1;
}
/* Send encrypted credentials */
status = credssp_encrypt_ts_credentials(credssp);
if (status != SEC_E_OK)
{
DEBUG_WARN( "credssp_encrypt_ts_credentials status: 0x%08X\n", status);
DEBUG_WARN("credssp_encrypt_ts_credentials status: 0x%08X\n", status);
return 0;
}
credssp_send(credssp);
credssp_buffer_free(credssp);
/* Free resources */
credssp->table->FreeCredentialsHandle(&credentials);
credssp->table->FreeContextBuffer(pPackageInfo);
return 1;
}
@ -445,7 +423,6 @@ int credssp_server_authenticate(rdpCredssp* credssp)
BOOL have_context;
BOOL have_input_buffer;
BOOL have_pub_key_auth;
sspi_GlobalInit();
if (credssp_ntlm_server_init(credssp) == 0)
@ -455,7 +432,6 @@ int credssp_server_authenticate(rdpCredssp* credssp)
{
HMODULE hSSPI;
INIT_SECURITY_INTERFACE pInitSecurityInterface;
hSSPI = LoadLibrary(credssp->SspiModule);
if (!hSSPI)
@ -469,7 +445,6 @@ int credssp_server_authenticate(rdpCredssp* credssp)
#else
pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA");
#endif
credssp->table = pInitSecurityInterface();
}
else
@ -481,18 +456,17 @@ int credssp_server_authenticate(rdpCredssp* credssp)
if (status != SEC_E_OK)
{
DEBUG_WARN( "QuerySecurityPackageInfo status: 0x%08X\n", status);
DEBUG_WARN("QuerySecurityPackageInfo status: 0x%08X\n", status);
return 0;
}
cbMaxToken = pPackageInfo->cbMaxToken;
status = credssp->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME,
SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &credentials, &expiration);
SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &credentials, &expiration);
if (status != SEC_E_OK)
{
DEBUG_WARN( "AcquireCredentialsHandle status: 0x%08X\n", status);
DEBUG_WARN("AcquireCredentialsHandle status: 0x%08X\n", status);
return 0;
}
@ -504,24 +478,19 @@ int credssp_server_authenticate(rdpCredssp* credssp)
ZeroMemory(&input_buffer_desc, sizeof(SecBufferDesc));
ZeroMemory(&output_buffer_desc, sizeof(SecBufferDesc));
ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes));
/*
* from tspkg.dll: 0x00000112
* ASC_REQ_MUTUAL_AUTH
* ASC_REQ_CONFIDENTIALITY
* ASC_REQ_ALLOCATE_MEMORY
*/
fContextReq = 0;
fContextReq |= ASC_REQ_MUTUAL_AUTH;
fContextReq |= ASC_REQ_CONFIDENTIALITY;
fContextReq |= ASC_REQ_CONNECTION;
fContextReq |= ASC_REQ_USE_SESSION_KEY;
fContextReq |= ASC_REQ_REPLAY_DETECT;
fContextReq |= ASC_REQ_SEQUENCE_DETECT;
fContextReq |= ASC_REQ_EXTENDED_ERROR;
while (TRUE)
@ -530,9 +499,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
input_buffer_desc.cBuffers = 1;
input_buffer_desc.pBuffers = &input_buffer;
input_buffer.BufferType = SECBUFFER_TOKEN;
/* receive authentication token */
input_buffer_desc.ulVersion = SECBUFFER_VERSION;
input_buffer_desc.cBuffers = 1;
input_buffer_desc.pBuffers = &input_buffer;
@ -542,16 +509,15 @@ int credssp_server_authenticate(rdpCredssp* credssp)
return -1;
#ifdef WITH_DEBUG_CREDSSP
DEBUG_WARN( "Receiving Authentication Token\n");
DEBUG_WARN("Receiving Authentication Token\n");
credssp_buffer_print(credssp);
#endif
input_buffer.pvBuffer = credssp->negoToken.pvBuffer;
input_buffer.cbBuffer = credssp->negoToken.cbBuffer;
if (credssp->negoToken.cbBuffer < 1)
{
DEBUG_WARN( "CredSSP: invalid negoToken!\n");
DEBUG_WARN("CredSSP: invalid negoToken!\n");
return -1;
}
@ -561,12 +527,10 @@ int credssp_server_authenticate(rdpCredssp* credssp)
output_buffer.BufferType = SECBUFFER_TOKEN;
output_buffer.cbBuffer = cbMaxToken;
output_buffer.pvBuffer = malloc(output_buffer.cbBuffer);
status = credssp->table->AcceptSecurityContext(&credentials,
have_context? &credssp->context: NULL,
&input_buffer_desc, fContextReq, SECURITY_NATIVE_DREP, &credssp->context,
&output_buffer_desc, &pfContextAttr, &expiration);
have_context? &credssp->context: NULL,
&input_buffer_desc, fContextReq, SECURITY_NATIVE_DREP, &credssp->context,
&output_buffer_desc, &pfContextAttr, &expiration);
credssp->negoToken.pvBuffer = output_buffer.pvBuffer;
credssp->negoToken.cbBuffer = output_buffer.cbBuffer;
@ -587,36 +551,33 @@ int credssp_server_authenticate(rdpCredssp* credssp)
if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK)
{
DEBUG_WARN( "QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
DEBUG_WARN("QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
return 0;
}
if (credssp_decrypt_public_key_echo(credssp) != SEC_E_OK)
{
DEBUG_WARN( "Error: could not verify client's public key echo\n");
DEBUG_WARN("Error: could not verify client's public key echo\n");
return -1;
}
sspi_SecBufferFree(&credssp->negoToken);
credssp->negoToken.pvBuffer = NULL;
credssp->negoToken.cbBuffer = 0;
credssp_encrypt_public_key_echo(credssp);
}
if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED))
{
DEBUG_WARN( "AcceptSecurityContext status: 0x%08X\n", status);
DEBUG_WARN("AcceptSecurityContext status: 0x%08X\n", status);
return -1; /* Access Denied */
}
/* send authentication token */
#ifdef WITH_DEBUG_CREDSSP
DEBUG_WARN( "Sending Authentication Token\n");
DEBUG_WARN("Sending Authentication Token\n");
credssp_buffer_print(credssp);
#endif
credssp_send(credssp);
credssp_buffer_free(credssp);
@ -633,13 +594,13 @@ int credssp_server_authenticate(rdpCredssp* credssp)
if (credssp_decrypt_ts_credentials(credssp) != SEC_E_OK)
{
DEBUG_WARN( "Could not decrypt TSCredentials status: 0x%08X\n", status);
DEBUG_WARN("Could not decrypt TSCredentials status: 0x%08X\n", status);
return 0;
}
if (status != SEC_E_OK)
{
DEBUG_WARN( "AcceptSecurityContext status: 0x%08X\n", status);
DEBUG_WARN("AcceptSecurityContext status: 0x%08X\n", status);
return 0;
}
@ -647,7 +608,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
if (status != SEC_E_OK)
{
DEBUG_WARN( "ImpersonateSecurityContext status: 0x%08X\n", status);
DEBUG_WARN("ImpersonateSecurityContext status: 0x%08X\n", status);
return 0;
}
else
@ -656,13 +617,12 @@ int credssp_server_authenticate(rdpCredssp* credssp)
if (status != SEC_E_OK)
{
DEBUG_WARN( "RevertSecurityContext status: 0x%08X\n", status);
DEBUG_WARN("RevertSecurityContext status: 0x%08X\n", status);
return 0;
}
}
credssp->table->FreeContextBuffer(pPackageInfo);
return 1;
}
@ -724,17 +684,12 @@ SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp)
SecBufferDesc Message;
SECURITY_STATUS status;
int public_key_length;
public_key_length = credssp->PublicKey.cbBuffer;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
sspi_SecBufferAlloc(&credssp->pubKeyAuth, credssp->ContextSizes.cbMaxSignature + public_key_length);
Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature;
Buffers[0].pvBuffer = credssp->pubKeyAuth.pvBuffer;
Buffers[1].cbBuffer = public_key_length;
Buffers[1].pvBuffer = ((BYTE*) credssp->pubKeyAuth.pvBuffer) + credssp->ContextSizes.cbMaxSignature;
CopyMemory(Buffers[1].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[1].cbBuffer);
@ -748,12 +703,11 @@ SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp)
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, credssp->send_seq_num++);
if (status != SEC_E_OK)
{
DEBUG_WARN( "EncryptMessage status: 0x%08X\n", status);
DEBUG_WARN("EncryptMessage status: 0x%08X\n", status);
return status;
}
@ -774,34 +728,28 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp)
if (credssp->PublicKey.cbBuffer + credssp->ContextSizes.cbMaxSignature != credssp->pubKeyAuth.cbBuffer)
{
DEBUG_WARN( "unexpected pubKeyAuth buffer size:%d\n", (int) credssp->pubKeyAuth.cbBuffer);
DEBUG_WARN("unexpected pubKeyAuth buffer size:%d\n", (int) credssp->pubKeyAuth.cbBuffer);
return SEC_E_INVALID_TOKEN;
}
length = credssp->pubKeyAuth.cbBuffer;
buffer = (BYTE*) malloc(length);
CopyMemory(buffer, credssp->pubKeyAuth.pvBuffer, length);
public_key_length = credssp->PublicKey.cbBuffer;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */
Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature;
Buffers[0].pvBuffer = buffer;
Buffers[1].cbBuffer = length - credssp->ContextSizes.cbMaxSignature;
Buffers[1].pvBuffer = buffer + credssp->ContextSizes.cbMaxSignature;
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
status = credssp->table->DecryptMessage(&credssp->context, &Message, credssp->recv_seq_num++, &pfQOP);
if (status != SEC_E_OK)
{
DEBUG_WARN( "DecryptMessage failure: 0x%08X\n", status);
DEBUG_WARN("DecryptMessage failure: 0x%08X\n", status);
return status;
}
@ -816,40 +764,32 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp)
if (memcmp(public_key1, public_key2, public_key_length) != 0)
{
DEBUG_WARN( "Could not verify server's public key echo\n");
DEBUG_WARN( "Expected (length = %d):\n", public_key_length);
winpr_HexDump(public_key1, public_key_length);
DEBUG_WARN( "Actual (length = %d):\n", public_key_length);
winpr_HexDump(public_key2, public_key_length);
DEBUG_WARN("Could not verify server's public key echo\n");
DEBUG_WARN("Expected (length = %d):\n", public_key_length);
winpr_HexDump(TAG, WLOG_ERROR, public_key1, public_key_length);
DEBUG_WARN("Actual (length = %d):\n", public_key_length);
winpr_HexDump(TAG, WLOG_ERROR, public_key2, public_key_length);
return SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */
}
free(buffer);
return SEC_E_OK;
}
int credssp_sizeof_ts_password_creds(rdpCredssp* credssp)
{
int length = 0;
length += ber_sizeof_sequence_octet_string(credssp->identity.DomainLength * 2);
length += ber_sizeof_sequence_octet_string(credssp->identity.UserLength * 2);
length += ber_sizeof_sequence_octet_string(credssp->identity.PasswordLength * 2);
return length;
}
void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s)
{
int length;
/* TSPasswordCreds (SEQUENCE) */
ber_read_sequence_tag(s, &length);
/* [0] domainName (OCTET STRING) */
ber_read_contextual_tag(s, 0, &length, TRUE);
ber_read_octet_string_tag(s, &length);
@ -858,7 +798,6 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s)
CopyMemory(credssp->identity.Domain, Stream_Pointer(s), credssp->identity.DomainLength);
Stream_Seek(s, credssp->identity.DomainLength);
credssp->identity.DomainLength /= 2;
/* [1] userName (OCTET STRING) */
ber_read_contextual_tag(s, 1, &length, TRUE);
ber_read_octet_string_tag(s, &length);
@ -867,7 +806,6 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s)
CopyMemory(credssp->identity.User, Stream_Pointer(s), credssp->identity.UserLength);
Stream_Seek(s, credssp->identity.UserLength);
credssp->identity.UserLength /= 2;
/* [2] password (OCTET STRING) */
ber_read_contextual_tag(s, 2, &length, TRUE);
ber_read_octet_string_tag(s, &length);
@ -876,7 +814,6 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s)
CopyMemory(credssp->identity.Password, Stream_Pointer(s), credssp->identity.PasswordLength);
Stream_Seek(s, credssp->identity.PasswordLength);
credssp->identity.PasswordLength /= 2;
credssp->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
}
@ -884,31 +821,23 @@ int credssp_write_ts_password_creds(rdpCredssp* credssp, wStream* s)
{
int size = 0;
int innerSize = credssp_sizeof_ts_password_creds(credssp);
/* TSPasswordCreds (SEQUENCE) */
size += ber_write_sequence_tag(s, innerSize);
/* [0] domainName (OCTET STRING) */
size += ber_write_sequence_octet_string(s, 0, (BYTE*) credssp->identity.Domain, credssp->identity.DomainLength * 2);
/* [1] userName (OCTET STRING) */
size += ber_write_sequence_octet_string(s, 1, (BYTE*) credssp->identity.User, credssp->identity.UserLength * 2);
/* [2] password (OCTET STRING) */
size += ber_write_sequence_octet_string(s, 2, (BYTE*) credssp->identity.Password, credssp->identity.PasswordLength * 2);
return size;
}
int credssp_sizeof_ts_credentials(rdpCredssp* credssp)
{
int size = 0;
size += ber_sizeof_integer(1);
size += ber_sizeof_contextual_tag(ber_sizeof_integer(1));
size += ber_sizeof_sequence_octet_string(ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp)));
return size;
}
@ -917,22 +846,16 @@ void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials)
wStream* s;
int length;
int ts_password_creds_length;
s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer);
/* TSCredentials (SEQUENCE) */
ber_read_sequence_tag(s, &length);
/* [0] credType (INTEGER) */
ber_read_contextual_tag(s, 0, &length, TRUE);
ber_read_integer(s, NULL);
/* [1] credentials (OCTET STRING) */
ber_read_contextual_tag(s, 1, &length, TRUE);
ber_read_octet_string_tag(s, &ts_password_creds_length);
credssp_read_ts_password_creds(credssp, s);
Stream_Free(s, FALSE);
}
@ -941,22 +864,16 @@ int credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s)
int size = 0;
int innerSize = credssp_sizeof_ts_credentials(credssp);
int passwordSize;
/* TSCredentials (SEQUENCE) */
size += ber_write_sequence_tag(s, innerSize);
/* [0] credType (INTEGER) */
size += ber_write_contextual_tag(s, 0, ber_sizeof_integer(1), TRUE);
size += ber_write_integer(s, 1);
/* [1] credentials (OCTET STRING) */
passwordSize = ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp));
size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), TRUE);
size += ber_write_octet_string_tag(s, passwordSize);
size += credssp_write_ts_password_creds(credssp, s);
return size;
}
@ -972,7 +889,6 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp)
int DomainLength;
int UserLength;
int PasswordLength;
DomainLength = credssp->identity.DomainLength;
UserLength = credssp->identity.UserLength;
PasswordLength = credssp->identity.PasswordLength;
@ -986,7 +902,6 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp)
length = ber_sizeof_sequence(credssp_sizeof_ts_credentials(credssp));
sspi_SecBufferAlloc(&credssp->ts_credentials, length);
s = Stream_New((BYTE*) credssp->ts_credentials.pvBuffer, length);
credssp_write_ts_credentials(credssp, s);
@ -1005,26 +920,19 @@ SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp)
SecBuffer Buffers[2];
SecBufferDesc Message;
SECURITY_STATUS status;
credssp_encode_ts_credentials(credssp);
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
sspi_SecBufferAlloc(&credssp->authInfo, credssp->ContextSizes.cbMaxSignature + credssp->ts_credentials.cbBuffer);
Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature;
Buffers[0].pvBuffer = credssp->authInfo.pvBuffer;
ZeroMemory(Buffers[0].pvBuffer, Buffers[0].cbBuffer);
Buffers[1].cbBuffer = credssp->ts_credentials.cbBuffer;
Buffers[1].pvBuffer = &((BYTE*) credssp->authInfo.pvBuffer)[Buffers[0].cbBuffer];
CopyMemory(Buffers[1].pvBuffer, credssp->ts_credentials.pvBuffer, Buffers[1].cbBuffer);
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, credssp->send_seq_num++);
if (status != SEC_E_OK)
@ -1041,39 +949,32 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp)
SecBuffer Buffers[2];
SecBufferDesc Message;
SECURITY_STATUS status;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
if (credssp->authInfo.cbBuffer < 1)
{
DEBUG_WARN( "credssp_decrypt_ts_credentials missing authInfo buffer\n");
DEBUG_WARN("credssp_decrypt_ts_credentials missing authInfo buffer\n");
return SEC_E_INVALID_TOKEN;
}
length = credssp->authInfo.cbBuffer;
buffer = (BYTE*) malloc(length);
CopyMemory(buffer, credssp->authInfo.pvBuffer, length);
Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature;
Buffers[0].pvBuffer = buffer;
Buffers[1].cbBuffer = length - credssp->ContextSizes.cbMaxSignature;
Buffers[1].pvBuffer = &buffer[credssp->ContextSizes.cbMaxSignature];
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
status = credssp->table->DecryptMessage(&credssp->context, &Message, credssp->recv_seq_num++, &pfQOP);
if (status != SEC_E_OK)
return status;
credssp_read_ts_credentials(credssp, &Buffers[1]);
free(buffer);
return SEC_E_OK;
}
@ -1127,20 +1028,14 @@ void credssp_send(rdpCredssp* credssp)
int nego_tokens_length;
int pub_key_auth_length;
int auth_info_length;
nego_tokens_length = (credssp->negoToken.cbBuffer > 0) ? credssp_sizeof_nego_tokens(credssp->negoToken.cbBuffer) : 0;
pub_key_auth_length = (credssp->pubKeyAuth.cbBuffer > 0) ? credssp_sizeof_pub_key_auth(credssp->pubKeyAuth.cbBuffer) : 0;
auth_info_length = (credssp->authInfo.cbBuffer > 0) ? credssp_sizeof_auth_info(credssp->authInfo.cbBuffer) : 0;
length = nego_tokens_length + pub_key_auth_length + auth_info_length;
ts_request_length = credssp_sizeof_ts_request(length);
s = Stream_New(NULL, ber_sizeof_sequence(ts_request_length));
/* TSRequest */
ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */
/* [0] version */
ber_write_contextual_tag(s, 0, 3, TRUE);
ber_write_integer(s, 2); /* INTEGER */
@ -1149,12 +1044,10 @@ void credssp_send(rdpCredssp* credssp)
if (nego_tokens_length > 0)
{
length = nego_tokens_length;
length -= ber_write_contextual_tag(s, 1, ber_sizeof_sequence(ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer))), TRUE); /* NegoData */
length -= ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer))); /* SEQUENCE OF NegoDataItem */
length -= ber_write_sequence_tag(s, ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer)); /* NegoDataItem */
length -= ber_write_sequence_octet_string(s, 0, (BYTE*) credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); /* OCTET STRING */
length -= ber_write_sequence_octet_string(s, 0, (BYTE*) credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); /* OCTET STRING */
// assert length == 0
}
@ -1163,7 +1056,6 @@ void credssp_send(rdpCredssp* credssp)
{
length = auth_info_length;
length -= ber_write_sequence_octet_string(s, 2, credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer);
// assert length == 0
}
@ -1172,14 +1064,11 @@ void credssp_send(rdpCredssp* credssp)
{
length = pub_key_auth_length;
length -= ber_write_sequence_octet_string(s, 3, credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer);
// assert length == 0
}
Stream_SealLength(s);
transport_write(credssp->transport, s);
Stream_Free(s, TRUE);
}
@ -1195,22 +1084,20 @@ int credssp_recv(rdpCredssp* credssp)
int length;
int status;
UINT32 version;
s = Stream_New(NULL, 4096);
status = transport_read_pdu(credssp->transport, s);
if (status < 0)
{
DEBUG_WARN( "credssp_recv() error: %d\n", status);
DEBUG_WARN("credssp_recv() error: %d\n", status);
Stream_Free(s, TRUE);
return -1;
}
/* TSRequest */
if(!ber_read_sequence_tag(s, &length) ||
!ber_read_contextual_tag(s, 0, &length, TRUE) ||
!ber_read_integer(s, &version))
if (!ber_read_sequence_tag(s, &length) ||
!ber_read_contextual_tag(s, 0, &length, TRUE) ||
!ber_read_integer(s, &version))
{
Stream_Free(s, TRUE);
return -1;
@ -1220,14 +1107,15 @@ int credssp_recv(rdpCredssp* credssp)
if (ber_read_contextual_tag(s, 1, &length, TRUE) != FALSE)
{
if (!ber_read_sequence_tag(s, &length) || /* SEQUENCE OF NegoDataItem */
!ber_read_sequence_tag(s, &length) || /* NegoDataItem */
!ber_read_contextual_tag(s, 0, &length, TRUE) || /* [0] negoToken */
!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
((int) Stream_GetRemainingLength(s)) < length)
!ber_read_sequence_tag(s, &length) || /* NegoDataItem */
!ber_read_contextual_tag(s, 0, &length, TRUE) || /* [0] negoToken */
!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
((int) Stream_GetRemainingLength(s)) < length)
{
Stream_Free(s, TRUE);
return -1;
}
sspi_SecBufferAlloc(&credssp->negoToken, length);
Stream_Read(s, credssp->negoToken.pvBuffer, length);
credssp->negoToken.cbBuffer = length;
@ -1237,11 +1125,12 @@ int credssp_recv(rdpCredssp* credssp)
if (ber_read_contextual_tag(s, 2, &length, TRUE) != FALSE)
{
if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
((int) Stream_GetRemainingLength(s)) < length)
((int) Stream_GetRemainingLength(s)) < length)
{
Stream_Free(s, TRUE);
return -1;
}
sspi_SecBufferAlloc(&credssp->authInfo, length);
Stream_Read(s, credssp->authInfo.pvBuffer, length);
credssp->authInfo.cbBuffer = length;
@ -1251,18 +1140,18 @@ int credssp_recv(rdpCredssp* credssp)
if (ber_read_contextual_tag(s, 3, &length, TRUE) != FALSE)
{
if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
((int) Stream_GetRemainingLength(s)) < length)
((int) Stream_GetRemainingLength(s)) < length)
{
Stream_Free(s, TRUE);
return -1;
}
sspi_SecBufferAlloc(&credssp->pubKeyAuth, length);
Stream_Read(s, credssp->pubKeyAuth.pvBuffer, length);
credssp->pubKeyAuth.cbBuffer = length;
}
Stream_Free(s, TRUE);
return 0;
}
@ -1270,20 +1159,23 @@ void credssp_buffer_print(rdpCredssp* credssp)
{
if (credssp->negoToken.cbBuffer > 0)
{
DEBUG_WARN( "CredSSP.negoToken (length = %d):\n", (int) credssp->negoToken.cbBuffer);
winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer);
DEBUG_WARN("CredSSP.negoToken (length = %d):\n", (int) credssp->negoToken.cbBuffer);
winpr_HexDump(TAG, WLOG_ERROR, credssp->negoToken.pvBuffer,
credssp->negoToken.cbBuffer);
}
if (credssp->pubKeyAuth.cbBuffer > 0)
{
DEBUG_WARN( "CredSSP.pubKeyAuth (length = %d):\n", (int) credssp->pubKeyAuth.cbBuffer);
winpr_HexDump(credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer);
DEBUG_WARN("CredSSP.pubKeyAuth (length = %d):\n", (int) credssp->pubKeyAuth.cbBuffer);
winpr_HexDump(TAG, WLOG_ERROR, credssp->pubKeyAuth.pvBuffer,
credssp->pubKeyAuth.cbBuffer);
}
if (credssp->authInfo.cbBuffer > 0)
{
DEBUG_WARN( "CredSSP.authInfo (length = %d):\n", (int) credssp->authInfo.cbBuffer);
winpr_HexDump(credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer);
DEBUG_WARN("CredSSP.authInfo (length = %d):\n", (int) credssp->authInfo.cbBuffer);
winpr_HexDump(TAG, WLOG_ERROR, credssp->authInfo.pvBuffer,
credssp->authInfo.cbBuffer);
}
}
@ -1301,7 +1193,6 @@ LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname)
LPTSTR hostnameX = NULL;
LPTSTR ServiceClassX = NULL;
LPTSTR ServicePrincipalName = NULL;
#ifdef UNICODE
ConvertToUnicode(CP_UTF8, 0, hostname, -1, &hostnameX, 0);
ConvertToUnicode(CP_UTF8, 0, ServiceClass, -1, &ServiceClassX, 0);
@ -1315,7 +1206,6 @@ LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname)
ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX);
free(ServiceClassX);
free(hostnameX);
return ServicePrincipalName;
}
@ -1330,6 +1220,7 @@ LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname)
}
ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR));
if (!ServicePrincipalName)
return NULL;
@ -1345,7 +1236,6 @@ LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname)
free(ServiceClassX);
free(hostnameX);
return ServicePrincipalName;
}
@ -1358,7 +1248,6 @@ LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname)
rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings)
{
rdpCredssp* credssp;
credssp = (rdpCredssp*) calloc(1, sizeof(rdpCredssp));
if (credssp)
@ -1367,7 +1256,6 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings*
LONG status;
DWORD dwType;
DWORD dwSize;
credssp->instance = instance;
credssp->settings = settings;
credssp->server = settings->ServerMode;
@ -1382,7 +1270,7 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings*
if (credssp->server)
{
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"),
0, KEY_READ | KEY_WOW64_64KEY, &hKey);
0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS)
{
@ -1391,9 +1279,8 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings*
if (status == ERROR_SUCCESS)
{
credssp->SspiModule = (LPTSTR) malloc(dwSize + sizeof(TCHAR));
status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType,
(BYTE*) credssp->SspiModule, &dwSize);
(BYTE*) credssp->SspiModule, &dwSize);
if (status == ERROR_SUCCESS)
{
@ -1422,9 +1309,7 @@ void credssp_free(rdpCredssp* credssp)
sspi_SecBufferFree(&credssp->PublicKey);
sspi_SecBufferFree(&credssp->ts_credentials);
free(credssp->ServicePrincipalName);
free(credssp->identity.User);
free(credssp->identity.Domain);
free(credssp->identity.Password);

View File

@ -1153,7 +1153,10 @@ static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
status = rdp_recv_pdu(rdp, s);
if ((status >= 0) && (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE))
{
rdp_client_transition_to_state(rdp, CONNECTION_STATE_ACTIVE);
return 2;
}
break;
case CONNECTION_STATE_ACTIVE:

View File

@ -22,43 +22,57 @@
#endif
#include <winpr/crt.h>
#include <freerdp/log.h>
#include "connection.h"
#include "redirection.h"
#define TAG FREERDP_TAG("core")
void rdp_print_redirection_flags(UINT32 flags)
{
DEBUG_WARN( "redirectionFlags = {\n");
DEBUG_WARN("redirectionFlags = {\n");
if (flags & LB_TARGET_NET_ADDRESS)
DEBUG_WARN( "\tLB_TARGET_NET_ADDRESS\n");
if (flags & LB_LOAD_BALANCE_INFO)
DEBUG_WARN( "\tLB_LOAD_BALANCE_INFO\n");
if (flags & LB_USERNAME)
DEBUG_WARN( "\tLB_USERNAME\n");
if (flags & LB_DOMAIN)
DEBUG_WARN( "\tLB_DOMAIN\n");
if (flags & LB_PASSWORD)
DEBUG_WARN( "\tLB_PASSWORD\n");
if (flags & LB_DONTSTOREUSERNAME)
DEBUG_WARN( "\tLB_DONTSTOREUSERNAME\n");
if (flags & LB_SMARTCARD_LOGON)
DEBUG_WARN( "\tLB_SMARTCARD_LOGON\n");
if (flags & LB_NOREDIRECT)
DEBUG_WARN( "\tLB_NOREDIRECT\n");
if (flags & LB_TARGET_FQDN)
DEBUG_WARN( "\tLB_TARGET_FQDN\n");
if (flags & LB_TARGET_NETBIOS_NAME)
DEBUG_WARN( "\tLB_TARGET_NETBIOS_NAME\n");
if (flags & LB_TARGET_NET_ADDRESSES)
DEBUG_WARN( "\tLB_TARGET_NET_ADDRESSES\n");
if (flags & LB_CLIENT_TSV_URL)
DEBUG_WARN( "\tLB_CLIENT_TSV_URL\n");
if (flags & LB_SERVER_TSV_CAPABLE)
DEBUG_WARN( "\tLB_SERVER_TSV_CAPABLE\n");
DEBUG_WARN("\tLB_TARGET_NET_ADDRESS\n");
DEBUG_WARN( "}\n");
if (flags & LB_LOAD_BALANCE_INFO)
DEBUG_WARN("\tLB_LOAD_BALANCE_INFO\n");
if (flags & LB_USERNAME)
DEBUG_WARN("\tLB_USERNAME\n");
if (flags & LB_DOMAIN)
DEBUG_WARN("\tLB_DOMAIN\n");
if (flags & LB_PASSWORD)
DEBUG_WARN("\tLB_PASSWORD\n");
if (flags & LB_DONTSTOREUSERNAME)
DEBUG_WARN("\tLB_DONTSTOREUSERNAME\n");
if (flags & LB_SMARTCARD_LOGON)
DEBUG_WARN("\tLB_SMARTCARD_LOGON\n");
if (flags & LB_NOREDIRECT)
DEBUG_WARN("\tLB_NOREDIRECT\n");
if (flags & LB_TARGET_FQDN)
DEBUG_WARN("\tLB_TARGET_FQDN\n");
if (flags & LB_TARGET_NETBIOS_NAME)
DEBUG_WARN("\tLB_TARGET_NETBIOS_NAME\n");
if (flags & LB_TARGET_NET_ADDRESSES)
DEBUG_WARN("\tLB_TARGET_NET_ADDRESSES\n");
if (flags & LB_CLIENT_TSV_URL)
DEBUG_WARN("\tLB_CLIENT_TSV_URL\n");
if (flags & LB_SERVER_TSV_CAPABLE)
DEBUG_WARN("\tLB_SERVER_TSV_CAPABLE\n");
DEBUG_WARN("}\n");
}
BOOL rdp_redirection_read_string(wStream* s, char** str)
@ -67,7 +81,7 @@ BOOL rdp_redirection_read_string(wStream* s, char** str)
if (Stream_GetRemainingLength(s) < 4)
{
DEBUG_WARN( "rdp_redirection_read_string failure: cannot read length\n");
DEBUG_WARN("rdp_redirection_read_string failure: cannot read length\n");
return FALSE;
}
@ -75,13 +89,12 @@ BOOL rdp_redirection_read_string(wStream* s, char** str)
if (Stream_GetRemainingLength(s) < length)
{
DEBUG_WARN( "rdp_redirection_read_string failure: incorrect length %d\n", length);
DEBUG_WARN("rdp_redirection_read_string failure: incorrect length %d\n", length);
return FALSE;
}
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), length / 2, str, 0, NULL, NULL);
Stream_Seek(s, length);
return TRUE;
}
@ -89,7 +102,6 @@ int rdp_redirection_apply_settings(rdpRdp* rdp)
{
rdpSettings* settings = rdp->settings;
rdpRedirection* redirection = rdp->redirection;
settings->RedirectionFlags = redirection->flags;
settings->RedirectedSessionId = redirection->sessionID;
@ -107,7 +119,6 @@ int rdp_redirection_apply_settings(rdpRdp* rdp)
* Free previous LoadBalanceInfo, if any, otherwise it may end up
* being reused for the redirected session, which is not what we want.
*/
free(settings->LoadBalanceInfo);
settings->LoadBalanceInfo = NULL;
settings->LoadBalanceInfoLength = 0;
@ -162,9 +173,7 @@ int rdp_redirection_apply_settings(rdpRdp* rdp)
if (settings->RedirectionFlags & LB_TARGET_NET_ADDRESSES)
{
UINT32 i;
freerdp_target_net_addresses_free(settings);
settings->TargetNetAddressCount = redirection->TargetNetAddressesCount;
settings->TargetNetAddresses = (char**) malloc(sizeof(char*) * settings->TargetNetAddressCount);
@ -190,10 +199,8 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
Stream_Read_UINT16(s, length); /* length (2 bytes) */
Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */
Stream_Read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */
WLog_Print(redirection->log, WLOG_DEBUG, "flags: 0x%04X, redirFlags: 0x%04X length: %d, sessionID: 0x%08X",
flags, redirection->flags, length, redirection->sessionID);
flags, redirection->flags, length, redirection->sessionID);
#ifdef WITH_DEBUG_REDIR
rdp_print_redirection_flags(redirection->flags);
#endif
@ -218,7 +225,7 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
Stream_Read(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
#ifdef WITH_DEBUG_REDIR
DEBUG_REDIR("loadBalanceInfo:");
winpr_HexDump(redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
winpr_HexDump(TAG, WLOG_DEBUG, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
#endif
}
@ -247,10 +254,9 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
Stream_Read_UINT32(s, redirection->PasswordLength);
redirection->Password = (BYTE*) malloc(redirection->PasswordLength);
Stream_Read(s, redirection->Password, redirection->PasswordLength);
#ifdef WITH_DEBUG_REDIR
DEBUG_REDIR("PasswordCookie:");
winpr_HexDump(redirection->Password, redirection->PasswordLength);
winpr_HexDump(TAG, WLOG_DEBUG, redirection->Password, redirection->PasswordLength);
#endif
}
@ -282,10 +288,9 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
redirection->TsvUrl = (BYTE*) malloc(redirection->TsvUrlLength);
Stream_Read(s, redirection->TsvUrl, redirection->TsvUrlLength);
#ifdef WITH_DEBUG_REDIR
DEBUG_REDIR("TsvUrl:");
winpr_HexDump(redirection->TsvUrl, redirection->TsvUrlLength);
winpr_HexDump(TAG, WLOG_DEBUG, redirection->TsvUrl, redirection->TsvUrlLength);
#endif
}
@ -299,13 +304,10 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
return -1;
Stream_Read_UINT32(s, targetNetAddressesLength);
Stream_Read_UINT32(s, redirection->TargetNetAddressesCount);
count = redirection->TargetNetAddressesCount;
redirection->TargetNetAddresses = (char**) malloc(count * sizeof(char*));
ZeroMemory(redirection->TargetNetAddresses, count * sizeof(char*));
WLog_Print(redirection->log, WLOG_DEBUG, "TargetNetAddressesCount: %d", redirection->TargetNetAddressesCount);
for (i = 0; i < (int) count; i++)
@ -354,14 +356,12 @@ int rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s)
rdpRedirection* redirection_new()
{
rdpRedirection* redirection;
redirection = (rdpRedirection*) calloc(1, sizeof(rdpRedirection));
if (redirection)
{
WLog_Init();
redirection->log = WLog_Get("com.freerdp.core.redirection");
#ifdef WITH_DEBUG_REDIR
WLog_SetLogLevel(redirection->log, WLOG_TRACE);
#endif

View File

@ -31,6 +31,7 @@
#include <winpr/print.h>
#include <winpr/stream.h>
#include <freerdp/log.h>
#include <freerdp/error.h>
#include <freerdp/utils/tcp.h>
#include <freerdp/utils/ringbuffer.h>
@ -54,6 +55,7 @@
#include "transport.h"
#include "rdp.h"
#define TAG FREERDP_TAG("core")
#define BUFFER_SIZE 16384
@ -62,12 +64,9 @@ static void* transport_client_thread(void* arg);
wStream* transport_send_stream_init(rdpTransport* transport, int size)
{
wStream* s;
s = StreamPool_Take(transport->ReceivePool, size);
Stream_EnsureCapacity(s, size);
Stream_SetPosition(s, 0);
return s;
}
@ -87,10 +86,8 @@ void transport_stop(rdpTransport* transport)
{
SetEvent(transport->stopEvent);
WaitForSingleObject(transport->thread, INFINITE);
CloseHandle(transport->thread);
CloseHandle(transport->stopEvent);
transport->thread = NULL;
transport->stopEvent = NULL;
}
@ -105,9 +102,7 @@ BOOL transport_disconnect(rdpTransport* transport)
return FALSE;
transport_stop(transport);
BIO_free_all(transport->frontBio);
transport->frontBio = 0;
return status;
}
@ -115,7 +110,6 @@ BOOL transport_disconnect(rdpTransport* transport)
BOOL transport_connect_rdp(rdpTransport* transport)
{
/* RDP encryption */
return TRUE;
}
@ -128,11 +122,8 @@ static int transport_bio_tsg_write(BIO* bio, const char* buf, int num)
{
int status;
rdpTsg* tsg;
tsg = (rdpTsg*) bio->ptr;
BIO_clear_flags(bio, BIO_FLAGS_WRITE);
status = tsg_write(tsg, (BYTE*) buf, num);
if (status < 0)
@ -151,11 +142,8 @@ static int transport_bio_tsg_read(BIO* bio, char* buf, int size)
{
int status;
rdpTsg* tsg;
tsg = (rdpTsg*) bio->ptr;
BIO_clear_flags(bio, BIO_FLAGS_READ);
status = tsg_read(bio->ptr, (BYTE*) buf, size);
if (status < 0)
@ -227,13 +215,12 @@ BIO_METHOD* BIO_s_tsg(void)
BOOL transport_connect_tls(rdpTransport* transport)
{
rdpSettings *settings = transport->settings;
rdpTls *targetTls;
BIO *targetBio;
rdpSettings* settings = transport->settings;
rdpTls* targetTls;
BIO* targetBio;
int tls_status;
freerdp* instance;
rdpContext* context;
instance = (freerdp*) transport->settings->instance;
context = instance->context;
@ -241,7 +228,6 @@ BOOL transport_connect_tls(rdpTransport* transport)
{
transport->TsgTls = tls_new(transport->settings);
transport->layer = TRANSPORT_LAYER_TSG_TLS;
targetTls = transport->TsgTls;
targetBio = transport->frontBio;
}
@ -255,11 +241,9 @@ BOOL transport_connect_tls(rdpTransport* transport)
targetTls = transport->TlsIn;
targetBio = transport->TcpIn->bufferedBio;
transport->layer = TRANSPORT_LAYER_TLS;
}
targetTls->hostname = settings->ServerHostname;
targetTls->port = settings->ServerPort;
@ -267,7 +251,6 @@ BOOL transport_connect_tls(rdpTransport* transport)
targetTls->port = 3389;
targetTls->isGatewayTransport = FALSE;
tls_status = tls_connect(targetTls, targetBio);
if (tls_status < 1)
@ -290,9 +273,10 @@ BOOL transport_connect_tls(rdpTransport* transport)
}
transport->frontBio = targetTls->bio;
if (!transport->frontBio)
{
DEBUG_WARN( "%s: unable to prepend a filtering TLS bio", __FUNCTION__);
DEBUG_WARN("%s: unable to prepend a filtering TLS bio", __FUNCTION__);
return FALSE;
}
@ -303,8 +287,7 @@ BOOL transport_connect_nla(rdpTransport* transport)
{
freerdp* instance;
rdpSettings* settings;
rdpCredssp *credSsp;
rdpCredssp* credSsp;
settings = transport->settings;
instance = (freerdp*) settings->instance;
@ -319,6 +302,7 @@ BOOL transport_connect_nla(rdpTransport* transport)
if (!transport->credssp)
{
transport->credssp = credssp_new(instance, transport, settings);
if (!transport->credssp)
return FALSE;
@ -328,12 +312,14 @@ BOOL transport_connect_nla(rdpTransport* transport)
{
transport->credssp->ServicePrincipalName =
credssp_make_spn(settings->AuthenticationServiceClass, settings->ServerHostname);
if (!transport->credssp->ServicePrincipalName)
return FALSE;
}
}
credSsp = transport->credssp;
if (credssp_authenticate(credSsp) < 0)
{
if (!connectErrorCode)
@ -344,20 +330,17 @@ BOOL transport_connect_nla(rdpTransport* transport)
freerdp_set_last_error(instance->context, FREERDP_ERROR_AUTHENTICATION_FAILED);
}
DEBUG_WARN( "Authentication failure, check credentials.\n"
"If credentials are valid, the NTLMSSP implementation may be to blame.\n");
DEBUG_WARN("Authentication failure, check credentials.\n"
"If credentials are valid, the NTLMSSP implementation may be to blame.\n");
transport_set_nla_mode(transport, FALSE);
credssp_free(credSsp);
transport->credssp = NULL;
return FALSE;
}
transport_set_nla_mode(transport, FALSE);
credssp_free(credSsp);
transport->credssp = NULL;
return TRUE;
}
@ -367,11 +350,9 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
int tls_status;
freerdp* instance;
rdpContext* context;
rdpSettings *settings = transport->settings;
rdpSettings* settings = transport->settings;
instance = (freerdp*) transport->settings->instance;
context = instance->context;
tsg = tsg_new(transport);
if (!tsg)
@ -403,9 +384,7 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
transport->TlsIn->hostname = transport->TlsOut->hostname = settings->GatewayHostname;
transport->TlsIn->port = transport->TlsOut->port = settings->GatewayPort;
transport->TlsIn->isGatewayTransport = TRUE;
tls_status = tls_connect(transport->TlsIn, transport->TcpIn->bufferedBio);
if (tls_status < 1)
@ -425,7 +404,6 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
}
transport->TlsOut->isGatewayTransport = TRUE;
tls_status = tls_connect(transport->TlsOut, transport->TcpOut->bufferedBio);
if (tls_status < 1)
@ -449,7 +427,6 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
transport->frontBio = BIO_new(BIO_s_tsg());
transport->frontBio->ptr = tsg;
return TRUE;
}
@ -457,7 +434,6 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
{
BOOL status = FALSE;
rdpSettings* settings = transport->settings;
transport->async = settings->AsyncTransport;
if (transport->GatewayEnabled)
@ -482,7 +458,6 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
else
{
status = tcp_connect(transport->TcpIn, hostname, port, timeout);
transport->SplitInputOutput = FALSE;
transport->TcpOut = transport->TcpIn;
transport->frontBio = transport->TcpIn->bufferedBio;
@ -493,9 +468,8 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
if (transport->async)
{
transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
transport->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL);
(LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL);
}
}
@ -505,7 +479,6 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
BOOL transport_accept_rdp(rdpTransport* transport)
{
/* RDP encryption */
return TRUE;
}
@ -530,7 +503,6 @@ BOOL transport_accept_nla(rdpTransport* transport)
{
freerdp* instance;
rdpSettings* settings;
settings = transport->settings;
instance = (freerdp*) settings->instance;
@ -544,6 +516,7 @@ BOOL transport_accept_nla(rdpTransport* transport)
if (!tls_accept(transport->TlsIn, transport->TcpIn->bufferedBio, settings->CertificateFile, settings->PrivateKeyFile))
return FALSE;
transport->frontBio = transport->TlsIn->bio;
/* Network Level Authentication */
@ -559,26 +532,22 @@ BOOL transport_accept_nla(rdpTransport* transport)
if (credssp_authenticate(transport->credssp) < 0)
{
DEBUG_WARN( "client authentication failure\n");
DEBUG_WARN("client authentication failure\n");
transport_set_nla_mode(transport, FALSE);
credssp_free(transport->credssp);
transport->credssp = NULL;
tls_set_alert_code(transport->TlsIn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DESCRIPTION_ACCESS_DENIED);
return FALSE;
}
/* don't free credssp module yet, we need to copy the credentials from it first */
transport_set_nla_mode(transport, FALSE);
return TRUE;
}
static int transport_wait_for_read(rdpTransport* transport)
{
rdpTcp *tcpIn = transport->TcpIn;
rdpTcp* tcpIn = transport->TcpIn;
if (tcpIn->readBlocked)
{
@ -595,9 +564,9 @@ static int transport_wait_for_read(rdpTransport* transport)
static int transport_wait_for_write(rdpTransport* transport)
{
rdpTcp *tcpOut;
rdpTcp* tcpOut;
tcpOut = transport->SplitInputOutput ? transport->TcpOut : transport->TcpIn;
if (tcpOut->writeBlocked)
{
return tcp_wait_write(tcpOut, 10);
@ -643,16 +612,16 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
* requested bytes */
if (transport_wait_for_read(transport) < 0)
{
DEBUG_WARN( "%s: error when selecting for read\n", __FUNCTION__);
DEBUG_WARN("%s: error when selecting for read\n", __FUNCTION__);
return -1;
}
continue;
}
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(data + read, bytes - read);
#endif
read += status;
}
@ -678,6 +647,7 @@ static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, unsig
{
int status;
status = transport_read_layer(transport, Stream_Pointer(s), toRead);
if (status <= 0)
return status;
@ -702,8 +672,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
int status;
int position;
int pduLength;
BYTE *header;
BYTE* header;
position = 0;
pduLength = 0;
@ -714,7 +683,6 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
return -1;
position = Stream_GetPosition(s);
/* Make sure there is enough space for the longest header within the stream */
Stream_EnsureCapacity(s, 4);
@ -744,6 +712,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
{
if ((status = transport_read_layer_bytes(transport, s, 1)) != 1)
return status;
pduLength = header[2];
pduLength += 3;
}
@ -751,12 +720,13 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
{
if ((status = transport_read_layer_bytes(transport, s, 2)) != 1)
return status;
pduLength = (header[2] << 8) | header[3];
pduLength += 4;
}
else
{
DEBUG_WARN( "Error reading TSRequest!\n");
DEBUG_WARN("Error reading TSRequest!\n");
return -1;
}
}
@ -780,7 +750,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
/* min and max values according to ITU-T Rec. T.123 (01/2007) section 8 */
if (pduLength < 7 || pduLength > 0xFFFF)
{
DEBUG_WARN( "%s: tpkt - invalid pduLength: %d\n", __FUNCTION__, pduLength);
DEBUG_WARN("%s: tpkt - invalid pduLength: %d\n", __FUNCTION__, pduLength);
return -1;
}
}
@ -791,6 +761,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
{
if ((status = transport_read_layer_bytes(transport, s, 1)) != 1)
return status;
pduLength = ((header[1] & 0x7F) << 8) | header[2];
}
else
@ -803,27 +774,27 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
*/
if (pduLength < 3 || pduLength > 0x8000)
{
DEBUG_WARN( "%s: fast path - invalid pduLength: %d\n", __FUNCTION__, pduLength);
DEBUG_WARN("%s: fast path - invalid pduLength: %d\n", __FUNCTION__, pduLength);
return -1;
}
}
}
Stream_EnsureCapacity(s, Stream_GetPosition(s) + pduLength);
status = transport_read_layer_bytes(transport, s, pduLength - Stream_GetPosition(s));
if (status != 1)
return status;
#ifdef WITH_DEBUG_TRANSPORT
/* dump when whole PDU is read */
if (Stream_GetPosition(s) >= pduLength)
{
DEBUG_WARN( "Local < Remote\n");
winpr_HexDump(Stream_Buffer(s), pduLength);
DEBUG_WARN("Local < Remote\n");
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), pduLength);
}
#endif
if (Stream_GetPosition(s) >= pduLength)
@ -834,24 +805,23 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
return Stream_Length(s);
}
BOOL transport_bio_buffered_drain(BIO *bio);
BOOL transport_bio_buffered_drain(BIO* bio);
int transport_write(rdpTransport* transport, wStream* s)
{
int length;
int status = -1;
EnterCriticalSection(&(transport->WriteLock));
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
#ifdef WITH_DEBUG_TRANSPORT
if (length > 0)
{
DEBUG_WARN( "Local > Remote\n");
winpr_HexDump(Stream_Buffer(s), length);
DEBUG_WARN("Local > Remote\n");
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), length);
}
#endif
if (length > 0)
@ -878,28 +848,29 @@ int transport_write(rdpTransport* transport, wStream* s)
if (transport_wait_for_write(transport) < 0)
{
DEBUG_WARN( "%s: error when selecting for write\n", __FUNCTION__);
DEBUG_WARN("%s: error when selecting for write\n", __FUNCTION__);
return -1;
}
continue;
}
if (transport->blocking || transport->settings->WaitForOutputBufferFlush)
{
/* blocking transport, we must ensure the write buffer is really empty */
rdpTcp *out = transport->TcpOut;
rdpTcp* out = transport->TcpOut;
while (out->writeBlocked)
{
if (transport_wait_for_write(transport) < 0)
{
DEBUG_WARN( "%s: error when selecting for write\n", __FUNCTION__);
DEBUG_WARN("%s: error when selecting for write\n", __FUNCTION__);
return -1;
}
if (!transport_bio_buffered_drain(out->bufferedBio))
{
DEBUG_WARN( "%s: error when draining outputBuffer\n", __FUNCTION__);
DEBUG_WARN("%s: error when draining outputBuffer\n", __FUNCTION__);
return -1;
}
}
@ -919,14 +890,12 @@ int transport_write(rdpTransport* transport, wStream* s)
Stream_Release(s);
LeaveCriticalSection(&(transport->WriteLock));
return status;
}
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
{
void* pfd;
#ifdef _WIN32
rfds[*rcount] = transport->TcpIn->event;
(*rcount)++;
@ -936,6 +905,7 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
rfds[*rcount] = transport->TcpOut->event;
(*rcount)++;
}
#else
rfds[*rcount] = (void*)(long)(transport->TcpIn->sockfd);
(*rcount)++;
@ -945,8 +915,8 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
rfds[*rcount] = (void*)(long)(transport->TcpOut->sockfd);
(*rcount)++;
}
#endif
#endif
pfd = GetEventWaitObject(transport->ReceiveEvent);
if (pfd)
@ -997,8 +967,8 @@ BOOL tranport_is_write_blocked(rdpTransport* transport)
return TRUE;
return transport->SplitInputOutput &&
transport->TcpOut &&
transport->TcpOut->writeBlocked;
transport->TcpOut &&
transport->TcpOut->writeBlocked;
}
int tranport_drain_output_buffer(rdpTransport* transport)
@ -1010,6 +980,7 @@ int tranport_drain_output_buffer(rdpTransport* transport)
{
if (!transport_bio_buffered_drain(transport->TcpIn->bufferedBio))
return -1;
ret |= transport->TcpIn->writeBlocked;
}
@ -1017,6 +988,7 @@ int tranport_drain_output_buffer(rdpTransport* transport)
{
if (!transport_bio_buffered_drain(transport->TcpOut->bufferedBio))
return -1;
ret |= transport->TcpOut->writeBlocked;
}
@ -1055,7 +1027,6 @@ int transport_check_fds(rdpTransport* transport)
* Note that transport->ReceiveBuffer is replaced after each iteration
* of this loop with a fresh stream instance from a pool.
*/
if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0)
{
return status;
@ -1069,15 +1040,15 @@ int transport_check_fds(rdpTransport* transport)
* 0: success
* 1: redirection
*/
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
if (recv_status == 1)
{
return 1; /* session redirection */
}
Stream_Release(received);
/* session redirection or activation */
if (recv_status == 1 || recv_status == 2)
{
return recv_status;
}
if (recv_status < 0)
return -1;
}
@ -1088,7 +1059,6 @@ int transport_check_fds(rdpTransport* transport)
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking)
{
BOOL status;
status = TRUE;
transport->blocking = blocking;
@ -1128,25 +1098,19 @@ static void* transport_client_thread(void* arg)
freerdp* instance;
rdpContext* context;
rdpTransport* transport;
transport = (rdpTransport*) arg;
assert(NULL != transport);
assert(NULL != transport->settings);
instance = (freerdp*) transport->settings->instance;
assert(NULL != instance);
context = instance->context;
assert(NULL != instance->context);
WLog_Print(transport->log, WLOG_DEBUG, "Starting transport thread");
nCount = 0;
handles[nCount++] = transport->stopEvent;
handles[nCount++] = transport->connectedEvent;
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
{
WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");
@ -1160,9 +1124,7 @@ static void* transport_client_thread(void* arg)
{
nCount = 0;
handles[nCount++] = transport->stopEvent;
transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
if (transport->layer == TRANSPORT_LAYER_CLOSED)
@ -1178,13 +1140,11 @@ static void* transport_client_thread(void* arg)
if (!freerdp_check_fds(instance))
{
}
}
}
WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");
ExitThread(0);
return NULL;
}
@ -1192,39 +1152,43 @@ static void* transport_client_thread(void* arg)
rdpTransport* transport_new(rdpSettings* settings)
{
rdpTransport* transport;
transport = (rdpTransport*)calloc(1, sizeof(rdpTransport));
transport = (rdpTransport *)calloc(1, sizeof(rdpTransport));
if (!transport)
return NULL;
WLog_Init();
transport->log = WLog_Get("com.freerdp.core.transport");
if (!transport->log)
goto out_free;
transport->TcpIn = tcp_new(settings);
if (!transport->TcpIn)
goto out_free;
transport->settings = settings;
/* a small 0.1ms delay when transport is blocking. */
transport->SleepInterval = 100;
transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);
if (!transport->ReceivePool)
goto out_free_tcpin;
/* receive buffer for non-blocking read. */
transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
if (!transport->ReceiveBuffer)
goto out_free_receivepool;
transport->ReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!transport->ReceiveEvent || transport->ReceiveEvent == INVALID_HANDLE_VALUE)
goto out_free_receivebuffer;
transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!transport->connectedEvent || transport->connectedEvent == INVALID_HANDLE_VALUE)
goto out_free_receiveEvent;
@ -1234,11 +1198,11 @@ rdpTransport* transport_new(rdpSettings* settings)
if (!InitializeCriticalSectionAndSpinCount(&(transport->ReadLock), 4000))
goto out_free_connectedEvent;
if (!InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000))
goto out_free_readlock;
return transport;
out_free_readlock:
DeleteCriticalSection(&(transport->ReadLock));
out_free_connectedEvent:
@ -1267,7 +1231,6 @@ void transport_free(rdpTransport* transport)
Stream_Release(transport->ReceiveBuffer);
StreamPool_Free(transport->ReceivePool);
CloseHandle(transport->ReceiveEvent);
CloseHandle(transport->connectedEvent);
@ -1288,12 +1251,9 @@ void transport_free(rdpTransport* transport)
transport->TcpIn = NULL;
transport->TcpOut = NULL;
tsg_free(transport->tsg);
transport->tsg = NULL;
DeleteCriticalSection(&(transport->ReadLock));
DeleteCriticalSection(&(transport->WriteLock));
free(transport);
}

View File

@ -36,6 +36,7 @@ set(${MODULE_PREFIX}_SRCS
shape.c
graphics.c
graphics.h
gfx.c
gdi.c
gdi.h)

View File

@ -330,6 +330,36 @@ INLINE UINT32 gdi_rop3_code(BYTE code)
return rop3_code_table[code];
}
UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel, BOOL vFlip)
{
UINT32 format = PIXEL_FORMAT_XRGB32_VF;
switch (bitsPerPixel)
{
case 32:
format = vFlip ? PIXEL_FORMAT_XRGB32_VF : PIXEL_FORMAT_XRGB32;
break;
case 24:
format = vFlip ? PIXEL_FORMAT_RGB24_VF : PIXEL_FORMAT_RGB24;
break;
case 16:
format = vFlip ? PIXEL_FORMAT_RGB16_VF : PIXEL_FORMAT_RGB16;
break;
case 15:
format = vFlip ? PIXEL_FORMAT_RGB15_VF : PIXEL_FORMAT_RGB15;
break;
case 8:
format = vFlip ? PIXEL_FORMAT_RGB8_VF : PIXEL_FORMAT_RGB8;
break;
}
return format;
}
INLINE BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y)
{
BYTE* p;
@ -454,6 +484,103 @@ void gdi_bitmap_free_ex(gdiBitmap* bitmap)
}
}
void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
int status;
int nXDst;
int nYDst;
int nXSrc;
int nYSrc;
int nWidth;
int nHeight;
int nSrcStep;
int nDstStep;
UINT32 index;
BYTE* pSrcData;
BYTE* pDstData;
UINT32 SrcSize;
BOOL compressed;
UINT32 SrcFormat;
UINT32 bitsPerPixel;
UINT32 bytesPerPixel;
BITMAP_DATA* bitmap;
rdpGdi* gdi = context->gdi;
rdpCodecs* codecs = context->codecs;
for (index = 0; index < bitmapUpdate->number; index++)
{
bitmap = &(bitmapUpdate->rectangles[index]);
nXSrc = 0;
nYSrc = 0;
nXDst = bitmap->destLeft;
nYDst = bitmap->destTop;
nWidth = bitmap->width;
nHeight = bitmap->height;
pSrcData = bitmap->bitmapDataStream;
SrcSize = bitmap->bitmapLength;
compressed = bitmap->compressed;
bitsPerPixel = bitmap->bitsPerPixel;
bytesPerPixel = (bitsPerPixel + 7) / 8;
SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);
if (gdi->bitmap_size < (nWidth * nHeight * 4))
{
gdi->bitmap_size = nWidth * nHeight * 4;
gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16);
if (!gdi->bitmap_buffer)
return;
}
if (compressed)
{
pDstData = gdi->bitmap_buffer;
if (bitsPerPixel < 32)
{
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);
status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
&pDstData, SrcFormat, nWidth * bytesPerPixel, 0, 0, nWidth, nHeight);
}
else
{
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);
status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight);
}
if (status < 0)
{
DEBUG_WARN("gdi_bitmap_update: bitmap decompression failure\n");
return;
}
pSrcData = gdi->bitmap_buffer;
}
nSrcStep = nWidth * bytesPerPixel;
pDstData = gdi->primary_buffer;
nDstStep = gdi->width * 4;
nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */
nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */
status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, nDstStep, nXDst, nYDst,
nWidth, nHeight, pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc);
gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, nWidth, nHeight);
}
}
void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
{
rdpGdi* gdi = context->gdi;
@ -791,8 +918,6 @@ void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface
}
}
int tilenum = 0;
void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
{
int i, j;
@ -1014,6 +1139,7 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer)
return -1;
instance->context->gdi = gdi;
gdi->context = instance->context;
cache = instance->context->cache;
gdi->codecs = instance->context->codecs;
@ -1100,6 +1226,8 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer)
gdi_register_graphics(instance->context->graphics);
instance->update->BitmapUpdate = gdi_bitmap_update;
return 0;
}
@ -1113,6 +1241,7 @@ void gdi_free(freerdp* instance)
gdi_bitmap_free_ex(gdi->tile);
gdi_bitmap_free_ex(gdi->image);
gdi_DeleteDC(gdi->hdc);
_aligned_free(gdi->bitmap_buffer);
free(gdi->clrconv->palette);
free(gdi->clrconv);
free(gdi);

817
libfreerdp/gdi/gfx.c Normal file
View File

@ -0,0 +1,817 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* GDI Graphics Pipeline
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <freerdp/gdi/gfx.h>
#include <freerdp/gdi/region.h>
int gdi_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics)
{
rdpGdi* gdi = (rdpGdi*) context->custom;
freerdp_client_codecs_reset(gdi->codecs, FREERDP_CODEC_ALL);
region16_init(&(gdi->invalidRegion));
gdi->graphicsReset = TRUE;
return 1;
}
int gdi_OutputUpdate(rdpGdi* gdi)
{
int nDstStep;
BYTE* pDstData;
int nXDst, nYDst;
int nXSrc, nYSrc;
int nWidth, nHeight;
gdiGfxSurface* surface;
RECTANGLE_16 surfaceRect;
const RECTANGLE_16* extents;
rdpUpdate* update = gdi->context->update;
if (!gdi->graphicsReset)
return 1;
nDstStep = gdi->width * 4;
pDstData = gdi->primary_buffer;
surface = (gdiGfxSurface*) gdi->gfx->GetSurfaceData(gdi->gfx, gdi->outputSurfaceId);
if (!surface)
return -1;
surfaceRect.left = 0;
surfaceRect.top = 0;
surfaceRect.right = gdi->width;
surfaceRect.bottom = gdi->height;
region16_intersect_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &surfaceRect);
if (!region16_is_empty(&(gdi->invalidRegion)))
{
extents = region16_extents(&(gdi->invalidRegion));
nXDst = extents->left;
nYDst = extents->top;
nXSrc = extents->left;
nYSrc = extents->top;
nWidth = extents->right - extents->left;
nHeight = extents->bottom - extents->top;
update->BeginPaint(gdi->context);
freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, nDstStep, nXDst, nYDst, nWidth, nHeight,
surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, nXSrc, nYSrc);
gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, nWidth, nHeight);
update->EndPaint(gdi->context);
}
region16_clear(&(gdi->invalidRegion));
return 1;
}
int gdi_OutputExpose(rdpGdi* gdi, int x, int y, int width, int height)
{
RECTANGLE_16 invalidRect;
invalidRect.left = x;
invalidRect.top = y;
invalidRect.right = x + width;
invalidRect.bottom = y + height;
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_StartFrame(RdpgfxClientContext* context, RDPGFX_START_FRAME_PDU* startFrame)
{
rdpGdi* gdi = (rdpGdi*) context->custom;
gdi->inGfxFrame = TRUE;
return 1;
}
int gdi_EndFrame(RdpgfxClientContext* context, RDPGFX_END_FRAME_PDU* endFrame)
{
rdpGdi* gdi = (rdpGdi*) context->custom;
gdi_OutputUpdate(gdi);
gdi->inGfxFrame = FALSE;
return 1;
}
int gdi_SurfaceCommand_Uncompressed(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
gdiGfxSurface* surface;
RECTANGLE_16 invalidRect;
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top,
cmd->width, cmd->height, cmd->data, PIXEL_FORMAT_XRGB32, cmd->width * 4, 0, 0);
invalidRect.left = cmd->left;
invalidRect.top = cmd->top;
invalidRect.right = cmd->right;
invalidRect.bottom = cmd->bottom;
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int j;
UINT16 i;
RFX_RECT* rect;
RFX_TILE* tile;
int nXDst, nYDst;
int nWidth, nHeight;
int nbUpdateRects;
RFX_MESSAGE* message;
gdiGfxSurface* surface;
REGION16 updateRegion;
RECTANGLE_16 updateRect;
RECTANGLE_16* updateRects;
REGION16 clippingRects;
RECTANGLE_16 clippingRect;
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX);
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
message = rfx_process_message(gdi->codecs->rfx, cmd->data, cmd->length);
if (!message)
return -1;
region16_init(&clippingRects);
for (i = 0; i < message->numRects; i++)
{
rect = &(message->rects[i]);
clippingRect.left = cmd->left + rect->x;
clippingRect.top = cmd->top + rect->y;
clippingRect.right = clippingRect.left + rect->width;
clippingRect.bottom = clippingRect.top + rect->height;
region16_union_rect(&clippingRects, &clippingRects, &clippingRect);
}
for (i = 0; i < message->numTiles; i++)
{
tile = message->tiles[i];
updateRect.left = cmd->left + tile->x;
updateRect.top = cmd->top + tile->y;
updateRect.right = updateRect.left + 64;
updateRect.bottom = updateRect.top + 64;
region16_init(&updateRegion);
region16_intersect_rect(&updateRegion, &clippingRects, &updateRect);
updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects);
for (j = 0; j < nbUpdateRects; j++)
{
nXDst = updateRects[j].left;
nYDst = updateRects[j].top;
nWidth = updateRects[j].right - updateRects[j].left;
nHeight = updateRects[j].bottom - updateRects[j].top;
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
nXDst, nYDst, nWidth, nHeight,
tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0);
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &updateRects[j]);
}
region16_uninit(&updateRegion);
}
rfx_message_free(gdi->codecs->rfx, message);
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int status;
BYTE* DstData = NULL;
gdiGfxSurface* surface;
RECTANGLE_16 invalidRect;
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_CLEARCODEC);
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
DstData = surface->data;
status = clear_decompress(gdi->codecs->clear, cmd->data, cmd->length, &DstData,
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height);
if (status < 0)
{
printf("clear_decompress failure: %d\n", status);
return -1;
}
invalidRect.left = cmd->left;
invalidRect.top = cmd->top;
invalidRect.right = cmd->right;
invalidRect.bottom = cmd->bottom;
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int status;
BYTE* DstData = NULL;
gdiGfxSurface* surface;
RECTANGLE_16 invalidRect;
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR);
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
DstData = surface->data;
status = planar_decompress(gdi->codecs->planar, cmd->data, cmd->length, &DstData,
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height);
invalidRect.left = cmd->left;
invalidRect.top = cmd->top;
invalidRect.right = cmd->right;
invalidRect.bottom = cmd->bottom;
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceCommand_H264(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int status;
UINT32 i;
BYTE* DstData = NULL;
H264_CONTEXT* h264;
gdiGfxSurface* surface;
RDPGFX_H264_METABLOCK* meta;
RDPGFX_H264_BITMAP_STREAM* bs;
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_H264);
h264 = gdi->codecs->h264;
bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra;
if (!bs)
return -1;
meta = &(bs->meta);
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
DstData = surface->data;
status = h264_decompress(gdi->codecs->h264, bs->data, bs->length, &DstData,
PIXEL_FORMAT_XRGB32, surface->scanline , surface->height, meta->regionRects, meta->numRegionRects);
if (status < 0)
{
printf("h264_decompress failure: %d\n",status);
return -1;
}
for (i = 0; i < meta->numRegionRects; i++)
{
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), (RECTANGLE_16*) &(meta->regionRects[i]));
}
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int status = 0;
gdiGfxSurface* surface;
RECTANGLE_16 invalidRect;
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_ALPHACODEC);
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
printf("gdi_SurfaceCommand_Alpha: status: %d\n", status);
/* fill with green for now to distinguish from the rest */
freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
cmd->left, cmd->top, cmd->width, cmd->height, 0x00FF00);
invalidRect.left = cmd->left;
invalidRect.top = cmd->top;
invalidRect.right = cmd->right;
invalidRect.bottom = cmd->bottom;
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int i, j;
int status;
BYTE* DstData;
RFX_RECT* rect;
int nXDst, nYDst;
int nXSrc, nYSrc;
int nWidth, nHeight;
int nbUpdateRects;
gdiGfxSurface* surface;
REGION16 updateRegion;
RECTANGLE_16 updateRect;
RECTANGLE_16* updateRects;
REGION16 clippingRects;
RECTANGLE_16 clippingRect;
RFX_PROGRESSIVE_TILE* tile;
PROGRESSIVE_BLOCK_REGION* region;
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PROGRESSIVE);
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
progressive_create_surface_context(gdi->codecs->progressive, cmd->surfaceId, surface->width, surface->height);
DstData = surface->data;
status = progressive_decompress(gdi->codecs->progressive, cmd->data, cmd->length, &DstData,
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId);
if (status < 0)
{
printf("progressive_decompress failure: %d\n", status);
return -1;
}
region = &(gdi->codecs->progressive->region);
region16_init(&clippingRects);
for (i = 0; i < region->numRects; i++)
{
rect = &(region->rects[i]);
clippingRect.left = cmd->left + rect->x;
clippingRect.top = cmd->top + rect->y;
clippingRect.right = clippingRect.left + rect->width;
clippingRect.bottom = clippingRect.top + rect->height;
region16_union_rect(&clippingRects, &clippingRects, &clippingRect);
}
for (i = 0; i < region->numTiles; i++)
{
tile = region->tiles[i];
updateRect.left = cmd->left + tile->x;
updateRect.top = cmd->top + tile->y;
updateRect.right = updateRect.left + 64;
updateRect.bottom = updateRect.top + 64;
region16_init(&updateRegion);
region16_intersect_rect(&updateRegion, &clippingRects, &updateRect);
updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects);
for (j = 0; j < nbUpdateRects; j++)
{
nXDst = updateRects[j].left;
nYDst = updateRects[j].top;
nWidth = updateRects[j].right - updateRects[j].left;
nHeight = updateRects[j].bottom - updateRects[j].top;
nXSrc = nXDst - (cmd->left + tile->x);
nYSrc = nYDst - (cmd->top + tile->y);
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
surface->scanline, nXDst, nYDst, nWidth, nHeight,
tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc);
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &updateRects[j]);
}
region16_uninit(&updateRegion);
}
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceCommand(RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int status = 1;
rdpGdi* gdi = (rdpGdi*) context->custom;
switch (cmd->codecId)
{
case RDPGFX_CODECID_UNCOMPRESSED:
status = gdi_SurfaceCommand_Uncompressed(gdi, context, cmd);
break;
case RDPGFX_CODECID_CAVIDEO:
status = gdi_SurfaceCommand_RemoteFX(gdi, context, cmd);
break;
case RDPGFX_CODECID_CLEARCODEC:
status = gdi_SurfaceCommand_ClearCodec(gdi, context, cmd);
break;
case RDPGFX_CODECID_PLANAR:
status = gdi_SurfaceCommand_Planar(gdi, context, cmd);
break;
case RDPGFX_CODECID_H264:
status = gdi_SurfaceCommand_H264(gdi, context, cmd);
break;
case RDPGFX_CODECID_ALPHA:
status = gdi_SurfaceCommand_Alpha(gdi, context, cmd);
break;
case RDPGFX_CODECID_CAPROGRESSIVE:
status = gdi_SurfaceCommand_Progressive(gdi, context, cmd);
break;
case RDPGFX_CODECID_CAPROGRESSIVE_V2:
break;
}
return 1;
}
int gdi_DeleteEncodingContext(RdpgfxClientContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext)
{
return 1;
}
int gdi_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface)
{
gdiGfxSurface* surface;
surface = (gdiGfxSurface*) calloc(1, sizeof(gdiGfxSurface));
if (!surface)
return -1;
surface->surfaceId = createSurface->surfaceId;
surface->width = (UINT32) createSurface->width;
surface->height = (UINT32) createSurface->height;
surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE;
surface->scanline = (surface->width + (surface->width % 4)) * 4;
surface->data = (BYTE*) calloc(1, surface->scanline * surface->height);
if (!surface->data)
return -1;
context->SetSurfaceData(context, surface->surfaceId, (void*) surface);
return 1;
}
int gdi_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface)
{
gdiGfxSurface* surface = NULL;
rdpGdi* gdi = (rdpGdi*) context->custom;
surface = (gdiGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId);
if (surface)
{
free(surface->data);
free(surface);
}
context->SetSurfaceData(context, deleteSurface->surfaceId, NULL);
if (gdi->codecs->progressive)
progressive_delete_surface_context(gdi->codecs->progressive, deleteSurface->surfaceId);
return 1;
}
int gdi_SolidFill(RdpgfxClientContext* context, RDPGFX_SOLID_FILL_PDU* solidFill)
{
UINT16 index;
UINT32 color;
BYTE a, r, g, b;
int nWidth, nHeight;
RDPGFX_RECT16* rect;
gdiGfxSurface* surface;
RECTANGLE_16 invalidRect;
rdpGdi* gdi = (rdpGdi*) context->custom;
surface = (gdiGfxSurface*) context->GetSurfaceData(context, solidFill->surfaceId);
if (!surface)
return -1;
b = solidFill->fillPixel.B;
g = solidFill->fillPixel.G;
r = solidFill->fillPixel.R;
a = solidFill->fillPixel.XA;
color = ARGB32(a, r, g, b);
for (index = 0; index < solidFill->fillRectCount; index++)
{
rect = &(solidFill->fillRects[index]);
nWidth = rect->right - rect->left;
nHeight = rect->bottom - rect->top;
invalidRect.left = rect->left;
invalidRect.top = rect->top;
invalidRect.right = rect->right;
invalidRect.bottom = rect->bottom;
freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
rect->left, rect->top, nWidth, nHeight, color);
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
}
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface)
{
UINT16 index;
int nWidth, nHeight;
RDPGFX_RECT16* rectSrc;
RDPGFX_POINT16* destPt;
RECTANGLE_16 invalidRect;
gdiGfxSurface* surfaceSrc;
gdiGfxSurface* surfaceDst;
rdpGdi* gdi = (rdpGdi*) context->custom;
rectSrc = &(surfaceToSurface->rectSrc);
destPt = &surfaceToSurface->destPts[0];
surfaceSrc = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc);
if (surfaceToSurface->surfaceIdSrc != surfaceToSurface->surfaceIdDest)
surfaceDst = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdDest);
else
surfaceDst = surfaceSrc;
if (!surfaceSrc || !surfaceDst)
return -1;
nWidth = rectSrc->right - rectSrc->left;
nHeight = rectSrc->bottom - rectSrc->top;
for (index = 0; index < surfaceToSurface->destPtsCount; index++)
{
destPt = &surfaceToSurface->destPts[index];
freerdp_image_copy(surfaceDst->data, PIXEL_FORMAT_XRGB32, surfaceDst->scanline,
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, PIXEL_FORMAT_XRGB32,
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
invalidRect.left = destPt->x;
invalidRect.top = destPt->y;
invalidRect.right = destPt->x + rectSrc->right;
invalidRect.bottom = destPt->y + rectSrc->bottom;
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
}
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_SurfaceToCache(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache)
{
RDPGFX_RECT16* rect;
gdiGfxSurface* surface;
gdiGfxCacheEntry* cacheEntry;
rect = &(surfaceToCache->rectSrc);
surface = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToCache->surfaceId);
if (!surface)
return -1;
cacheEntry = (gdiGfxCacheEntry*) calloc(1, sizeof(gdiGfxCacheEntry));
if (!cacheEntry)
return -1;
cacheEntry->width = (UINT32) (rect->right - rect->left);
cacheEntry->height = (UINT32) (rect->bottom - rect->top);
cacheEntry->alpha = surface->alpha;
cacheEntry->scanline = (cacheEntry->width + (cacheEntry->width % 4)) * 4;
cacheEntry->data = (BYTE*) calloc(1, cacheEntry->scanline * cacheEntry->height);
if (!cacheEntry->data)
return -1;
freerdp_image_copy(cacheEntry->data, PIXEL_FORMAT_XRGB32, cacheEntry->scanline,
0, 0, cacheEntry->width, cacheEntry->height, surface->data,
PIXEL_FORMAT_XRGB32, surface->scanline, rect->left, rect->top);
context->SetCacheSlotData(context, surfaceToCache->cacheSlot, (void*) cacheEntry);
return 1;
}
int gdi_CacheToSurface(RdpgfxClientContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface)
{
UINT16 index;
RDPGFX_POINT16* destPt;
gdiGfxSurface* surface;
gdiGfxCacheEntry* cacheEntry;
RECTANGLE_16 invalidRect;
rdpGdi* gdi = (rdpGdi*) context->custom;
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cacheToSurface->surfaceId);
cacheEntry = (gdiGfxCacheEntry*) context->GetCacheSlotData(context, cacheToSurface->cacheSlot);
if (!surface || !cacheEntry)
return -1;
for (index = 0; index < cacheToSurface->destPtsCount; index++)
{
destPt = &cacheToSurface->destPts[index];
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
destPt->x, destPt->y, cacheEntry->width, cacheEntry->height,
cacheEntry->data, PIXEL_FORMAT_XRGB32, cacheEntry->scanline, 0, 0);
invalidRect.left = destPt->x;
invalidRect.top = destPt->y;
invalidRect.right = destPt->x + cacheEntry->width - 1;
invalidRect.bottom = destPt->y + cacheEntry->height - 1;
region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect);
}
if (!gdi->inGfxFrame)
gdi_OutputUpdate(gdi);
return 1;
}
int gdi_CacheImportReply(RdpgfxClientContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply)
{
return 1;
}
int gdi_EvictCacheEntry(RdpgfxClientContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry)
{
gdiGfxCacheEntry* cacheEntry;
cacheEntry = (gdiGfxCacheEntry*) context->GetCacheSlotData(context, evictCacheEntry->cacheSlot);
if (cacheEntry)
{
free(cacheEntry->data);
free(cacheEntry);
}
context->SetCacheSlotData(context, evictCacheEntry->cacheSlot, NULL);
return 1;
}
int gdi_MapSurfaceToOutput(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput)
{
rdpGdi* gdi = (rdpGdi*) context->custom;
gdi->outputSurfaceId = surfaceToOutput->surfaceId;
return 1;
}
int gdi_MapSurfaceToWindow(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow)
{
return 1;
}
void gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx)
{
gdi->gfx = gfx;
gfx->custom = (void*) gdi;
gfx->ResetGraphics = gdi_ResetGraphics;
gfx->StartFrame = gdi_StartFrame;
gfx->EndFrame = gdi_EndFrame;
gfx->SurfaceCommand = gdi_SurfaceCommand;
gfx->DeleteEncodingContext = gdi_DeleteEncodingContext;
gfx->CreateSurface = gdi_CreateSurface;
gfx->DeleteSurface = gdi_DeleteSurface;
gfx->SolidFill = gdi_SolidFill;
gfx->SurfaceToSurface = gdi_SurfaceToSurface;
gfx->SurfaceToCache = gdi_SurfaceToCache;
gfx->CacheToSurface = gdi_CacheToSurface;
gfx->CacheImportReply = gdi_CacheImportReply;
gfx->EvictCacheEntry = gdi_EvictCacheEntry;
gfx->MapSurfaceToOutput = gdi_MapSurfaceToOutput;
gfx->MapSurfaceToWindow = gdi_MapSurfaceToWindow;
region16_init(&(gdi->invalidRegion));
}
void gdi_graphics_pipeline_uninit(rdpGdi* gdi, RdpgfxClientContext* gfx)
{
region16_uninit(&(gdi->invalidRegion));
gdi->gfx = NULL;
gfx->custom = NULL;
}

View File

@ -47,7 +47,7 @@ HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, BYTE*
BYTE* bmpData;
HGDI_BITMAP bitmap;
bmpData = freerdp_image_convert(data, NULL, width, height, gdi->srcBpp, bpp, gdi->clrconv);
bmpData = freerdp_image_convert(data, NULL, width, height, 32, 32, gdi->clrconv);
bitmap = gdi_CreateBitmap(width, height, gdi->dstBpp, bmpData);
return bitmap;
@ -100,111 +100,59 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
{
int status;
UINT16 size;
BYTE* src;
BYTE* dst;
int yindex;
int xindex;
rdpGdi* gdi;
RFX_MESSAGE* msg;
BYTE* pSrcData;
BYTE* pDstData;
UINT32 SrcSize;
UINT32 SrcFormat;
UINT32 bytesPerPixel;
rdpGdi* gdi = context->gdi;
gdi = context->gdi;
size = width * height * ((bpp + 7) / 8);
bytesPerPixel = (bpp + 7) / 8;
size = width * height * 4;
if (!bitmap->data)
bitmap->data = (BYTE*) _aligned_malloc(size, 16);
else
bitmap->data = (BYTE*) _aligned_realloc(bitmap->data, size, 16);
switch (codecId)
pSrcData = data;
SrcSize = (UINT32) length;
pDstData = bitmap->data;
if (compressed)
{
case RDP_CODEC_ID_NSCODEC:
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC);
nsc_process_message(gdi->codecs->nsc, bpp, width, height, data, length);
freerdp_image_flip(gdi->codecs->nsc->BitmapData, bitmap->data, width, height, bpp);
break;
if (bpp < 32)
{
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED);
case RDP_CODEC_ID_REMOTEFX:
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX);
rfx_context_set_pixel_format(gdi->codecs->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(gdi->codecs->rfx, data, length);
status = interleaved_decompress(gdi->codecs->interleaved, pSrcData, SrcSize, bpp,
&pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height);
}
else
{
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR);
if (!msg)
{
DEBUG_WARN( "gdi_Bitmap_Decompress: rfx Decompression Failed\n");
}
else
{
for (yindex = 0; yindex < height; yindex++)
{
src = msg->tiles[0]->data + yindex * 64 * 4;
dst = bitmap->data + yindex * width * 3;
status = planar_decompress(gdi->codecs->planar, pSrcData, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
}
for (xindex = 0; xindex < width; xindex++)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
src++;
}
}
rfx_message_free(gdi->codecs->rfx, msg);
}
break;
case RDP_CODEC_ID_JPEG:
#ifdef WITH_JPEG
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
{
DEBUG_WARN( "gdi_Bitmap_Decompress: jpeg Decompression Failed\n");
}
#endif
break;
default:
if (compressed)
{
BYTE* pDstData;
UINT32 SrcSize;
if (status < 0)
{
DEBUG_WARN("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
return;
}
}
else
{
SrcFormat = gdi_get_pixel_format(bpp, TRUE);
SrcSize = (UINT32) length;
pDstData = bitmap->data;
if (bpp < 32)
{
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED);
status = interleaved_decompress(gdi->codecs->interleaved, data, SrcSize, bpp,
&pDstData, PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
if (status < 0)
{
DEBUG_WARN("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
}
else
{
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR);
status = planar_decompress(gdi->codecs->planar, data, SrcSize, &pDstData,
PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height);
if (status < 0)
{
DEBUG_WARN("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
}
break;
status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0,
width, height, pSrcData, SrcFormat, width * bytesPerPixel, 0, 0);
}
bitmap->width = width;
bitmap->height = height;
bitmap->compressed = FALSE;
bitmap->length = size;
bitmap->bpp = bpp;
bitmap->bpp = 32;
}
void gdi_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)

View File

@ -371,15 +371,15 @@ INLINE int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h)
HGDI_RGN invalid;
HGDI_RGN cinvalid;
if (hdc->hwnd == NULL)
if (!hdc->hwnd)
return 0;
if (hdc->hwnd->invalid == NULL)
if (!hdc->hwnd->invalid)
return 0;
cinvalid = hdc->hwnd->cinvalid;
if (hdc->hwnd->ninvalid + 1 > hdc->hwnd->count)
if ((hdc->hwnd->ninvalid + 1) > hdc->hwnd->count)
{
hdc->hwnd->count *= 2;
cinvalid = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * (hdc->hwnd->count));

View File

@ -3,11 +3,14 @@
#include <winpr/print.h>
#include <freerdp/codec/color.h>
#include <winpr/wlog.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define TAG __FILE__
static INT16 TEST_Y_COMPONENT[4096] =
{
-32, +16, +64, +272, -32, -16, +0, -16,

View File

@ -29,8 +29,11 @@
#include "librail.h"
#include <freerdp/log.h>
#include <freerdp/rail/window.h>
#define TAG FREERDP_TAG("rail")
struct _WINDOW_STYLE
{
UINT32 style;
@ -99,8 +102,8 @@ static const WINDOW_STYLE EXTENDED_WINDOW_STYLES[] =
void print_window_styles(UINT32 style)
{
int i;
DEBUG_WARN("Window Styles:\n{\n");
DEBUG_WARN( "Window Styles:\n{\n");
for (i = 0; i < ARRAYSIZE(WINDOW_STYLES); i++)
{
if (style & WINDOW_STYLES[i].style)
@ -108,20 +111,21 @@ void print_window_styles(UINT32 style)
if (WINDOW_STYLES[i].multi)
{
if ((style & WINDOW_STYLES[i].style) != WINDOW_STYLES[i].style)
continue;
continue;
}
DEBUG_WARN( "\t%s\n", WINDOW_STYLES[i].name);
DEBUG_WARN("\t%s\n", WINDOW_STYLES[i].name);
}
}
DEBUG_WARN( "}\n");
DEBUG_WARN("}\n");
}
void print_extended_window_styles(UINT32 style)
{
int i;
DEBUG_WARN("Extended Window Styles:\n{\n");
DEBUG_WARN( "Extended Window Styles:\n{\n");
for (i = 0; i < ARRAYSIZE(EXTENDED_WINDOW_STYLES); i++)
{
if (style & EXTENDED_WINDOW_STYLES[i].style)
@ -129,13 +133,14 @@ void print_extended_window_styles(UINT32 style)
if (EXTENDED_WINDOW_STYLES[i].multi)
{
if ((style & EXTENDED_WINDOW_STYLES[i].style) != EXTENDED_WINDOW_STYLES[i].style)
continue;
continue;
}
DEBUG_WARN( "\t%s\n", EXTENDED_WINDOW_STYLES[i].name);
DEBUG_WARN("\t%s\n", EXTENDED_WINDOW_STYLES[i].name);
}
}
DEBUG_WARN( "}\n");
DEBUG_WARN("}\n");
}
void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state)
@ -149,13 +154,12 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
}
DEBUG_RAIL("windowId=0x%X ownerWindowId=0x%X",
window->windowId, window->ownerWindowId);
window->windowId, window->ownerWindowId);
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
{
window->style = window_state->style;
window->extendedStyle = window_state->extendedStyle;
#ifdef WITH_DEBUG_RAIL
print_window_styles(window->style);
print_extended_window_styles(window->extendedStyle);
@ -173,9 +177,8 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
window->titleInfo.length = window_state->titleInfo.length;
window->titleInfo.string = malloc(window_state->titleInfo.length);
memcpy(window->titleInfo.string, window_state->titleInfo.string, window->titleInfo.length);
#ifdef WITH_DEBUG_RAIL
winpr_HexDump(window->titleInfo.string, window->titleInfo.length);
winpr_HexDump(TAG, WLOG_DEBUG, window->titleInfo.string, window->titleInfo.length);
#endif
}
@ -183,18 +186,16 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
{
window->clientOffsetX = window_state->clientOffsetX;
window->clientOffsetY = window_state->clientOffsetY;
DEBUG_RAIL("Client Area Offset: (%d, %d)",
window->clientOffsetX, window->clientOffsetY);
window->clientOffsetX, window->clientOffsetY);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
{
window->clientAreaWidth = window_state->clientAreaWidth;
window->clientAreaHeight = window_state->clientAreaHeight;
DEBUG_RAIL("Client Area Size: (%d, %d)",
window->clientAreaWidth, window->clientAreaHeight);
window->clientAreaWidth, window->clientAreaHeight);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
@ -211,27 +212,24 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
{
window->windowOffsetX = window_state->windowOffsetX;
window->windowOffsetY = window_state->windowOffsetY;
DEBUG_RAIL("Window Offset: (%d, %d)",
window->windowOffsetX, window->windowOffsetY);
window->windowOffsetX, window->windowOffsetY);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
{
window->windowClientDeltaX = window_state->windowClientDeltaX;
window->windowClientDeltaY = window_state->windowClientDeltaY;
DEBUG_RAIL("Window Client Delta: (%d, %d)",
window->windowClientDeltaX, window->windowClientDeltaY);
window->windowClientDeltaX, window->windowClientDeltaY);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
{
window->windowWidth = window_state->windowWidth;
window->windowHeight = window_state->windowHeight;
DEBUG_RAIL("Window Size: (%d, %d)",
window->windowWidth, window->windowHeight);
window->windowWidth, window->windowHeight);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
@ -247,8 +245,8 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
for (i = 0; i < (int) window_state->numWindowRects; i++)
{
DEBUG_RAIL("Window Rect #%d: left:%d top:%d right:%d bottom:%d", i,
window_state->windowRects[i].left, window_state->windowRects[i].top,
window_state->windowRects[i].right, window_state->windowRects[i].bottom);
window_state->windowRects[i].left, window_state->windowRects[i].top,
window_state->windowRects[i].right, window_state->windowRects[i].bottom);
}
}
@ -256,9 +254,8 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
{
window->visibleOffsetX = window_state->visibleOffsetX;
window->visibleOffsetY = window_state->visibleOffsetY;
DEBUG_RAIL("Window Visible Offset: (%d, %d)",
window->visibleOffsetX, window->visibleOffsetY);
window->visibleOffsetX, window->visibleOffsetY);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
@ -274,8 +271,8 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
for (i = 0; i < (int) window_state->numVisibilityRects; i++)
{
DEBUG_RAIL("Visibility Rect #%d: left:%d top:%d right:%d bottom:%d", i,
window_state->visibilityRects[i].left, window_state->visibilityRects[i].top,
window_state->visibilityRects[i].right, window_state->visibilityRects[i].bottom);
window_state->visibilityRects[i].left, window_state->visibilityRects[i].top,
window_state->visibilityRects[i].right, window_state->visibilityRects[i].bottom);
}
}
}
@ -285,7 +282,7 @@ void rail_CreateWindow(rdpRail* rail, rdpWindow* window)
if (window->titleInfo.length > 0)
{
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) window->titleInfo.string, window->titleInfo.length / 2,
&window->title, 0, NULL, NULL);
&window->title, 0, NULL, NULL);
}
else
{
@ -299,6 +296,7 @@ void rail_CreateWindow(rdpRail* rail, rdpWindow* window)
{
IFCALL(rail->rail_SetWindowRects, rail, window);
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
IFCALL(rail->rail_SetWindowVisibilityRects, rail, window);
@ -309,12 +307,10 @@ void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
{
if (window->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
{
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
{
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
@ -331,29 +327,24 @@ void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
}
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) window->titleInfo.string, window->titleInfo.length / 2,
&window->title, 0, NULL, NULL);
&window->title, 0, NULL, NULL);
IFCALL(rail->rail_SetWindowText, rail, window);
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
{
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
{
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
{
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
{
}
if ((window->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
@ -364,7 +355,6 @@ void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
{
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
@ -374,7 +364,6 @@ void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
if (window->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
{
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)

10
scripts/autoformat.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
CHANGESET=`git status | cut -d ':' -f 2 | grep -vE "#|no" | grep -E "*\.h|*\.c"` # get filenames from git status
for f in $CHANGESET; do
if [ -e $f ]; then
sh $MY_PATH/format_code.sh $f
fi
done

View File

@ -1,23 +1,38 @@
#!/bin/sh
#!/bin/bash
ASTYLE=`which astyle`
ASTYLE=$(which astyle)
if [ ! -x $ASTYLE ];
then
if [ ! -x $ASTYLE ]; then
echo "No astyle found in path, please install."
exit 1
fi
# Need at least astyle 2.03 due to bugs in older versions
# indenting headers with extern "C"
STR_VERSION=$(($ASTYLE --version) 2>&1)
VERSION=$(echo $STR_VERSION | cut -d ' ' -f4)
MAJOR_VERSION=$(echo $VERSION | cut -d'.' -f1)
MINOR_VERSION=$(echo $VERSION | cut -d'.' -f2)
if [ "$MAJOR_VERSION" -lt "2" ]; then
echo "Your version of astyle($VERSION) is too old, need at least 2.03"
exit 1
fi
if [ "$MINOR_VERSION" -lt "3" ]; then
echo "Your version of astyle($VERSION) is too old, need at least 2.03"
exit 1
fi
if [ $# -le 0 ]; then
echo "Usage:"
echo "\t$0 <file1> [<file2> ...]"
# echo "\t$0 -r <directory>"
echo -e "\t$0 <file1> [<file2> ...]"
exit 2
fi
$ASTYLE --lineend=linux --mode=c --indent=force-tab=4 --brackets=linux --pad-header \
--indent-switches --indent-cases --indent-preprocessor \
--indent-col1-comments --delete-empty-lines --break-closing-brackets \
--align-pointer=name --indent-labels --brackets=break \
--unpad-paren --break-blocks $@
exit $?
--indent-switches --indent-cases --indent-preprocessor \
--indent-col1-comments --delete-empty-lines --break-closing-brackets \
--align-pointer=type --indent-labels --brackets=break \
--unpad-paren --break-blocks $@
exit $?

View File

@ -353,12 +353,6 @@ void mf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
CGEventPost(kCGHIDEventTap, kbEvent);
CFRelease(kbEvent);
CFRelease(source);
/*
if (flags & KBD_FLAGS_EXTENDED)
DEBUG_WARN( "extended ");
DEBUG_WARN( "keypress: down = %d, SCAN=%#0X, VK=%#0X\n", keyDown, code, keymap[code]);
*/
}
void mf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
@ -548,7 +542,6 @@ void mf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
void mf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
DEBUG_WARN( "Unhandled mouse event!!!\n");
/*
if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2))
{

View File

@ -24,6 +24,7 @@
#include <winpr/wtypes.h>
#include <winpr/crt.h>
#include <winpr/wlog.h>
struct _wBitStream
{
@ -47,103 +48,103 @@ extern "C" {
#endif
#define BitStream_Prefetch(_bs) do { \
(_bs->prefetch) = 0; \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 4)) \
(_bs->prefetch) |= (*(_bs->pointer + 4) << 24); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 5)) \
(_bs->prefetch) |= (*(_bs->pointer + 5) << 16); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 6)) \
(_bs->prefetch) |= (*(_bs->pointer + 6) << 8); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 7)) \
(_bs->prefetch) |= (*(_bs->pointer + 7) << 0); \
} while(0)
(_bs->prefetch) = 0; \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 4)) \
(_bs->prefetch) |= (*(_bs->pointer + 4) << 24); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 5)) \
(_bs->prefetch) |= (*(_bs->pointer + 5) << 16); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 6)) \
(_bs->prefetch) |= (*(_bs->pointer + 6) << 8); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 7)) \
(_bs->prefetch) |= (*(_bs->pointer + 7) << 0); \
} while(0)
#define BitStream_Fetch(_bs) do { \
(_bs->accumulator) = 0; \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 0)) \
(_bs->accumulator) |= (*(_bs->pointer + 0) << 24); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 1)) \
(_bs->accumulator) |= (*(_bs->pointer + 1) << 16); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 2)) \
(_bs->accumulator) |= (*(_bs->pointer + 2) << 8); \
if (((UINT32) (_bs->pointer - _bs->buffer)) <(_bs->capacity + 3)) \
(_bs->accumulator) |= (*(_bs->pointer + 3) << 0); \
BitStream_Prefetch(_bs); \
} while(0)
(_bs->accumulator) = 0; \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 0)) \
(_bs->accumulator) |= (*(_bs->pointer + 0) << 24); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 1)) \
(_bs->accumulator) |= (*(_bs->pointer + 1) << 16); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 2)) \
(_bs->accumulator) |= (*(_bs->pointer + 2) << 8); \
if (((UINT32) (_bs->pointer - _bs->buffer)) <(_bs->capacity + 3)) \
(_bs->accumulator) |= (*(_bs->pointer + 3) << 0); \
BitStream_Prefetch(_bs); \
} while(0)
#define BitStream_Flush(_bs) do { \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 0)) \
*(_bs->pointer + 0) = (_bs->accumulator >> 24); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 1)) \
*(_bs->pointer + 1) = (_bs->accumulator >> 16); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 2)) \
*(_bs->pointer + 2) = (_bs->accumulator >> 8); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 3)) \
*(_bs->pointer + 3) = (_bs->accumulator >> 0); \
} while(0)
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 0)) \
*(_bs->pointer + 0) = (_bs->accumulator >> 24); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 1)) \
*(_bs->pointer + 1) = (_bs->accumulator >> 16); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 2)) \
*(_bs->pointer + 2) = (_bs->accumulator >> 8); \
if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 3)) \
*(_bs->pointer + 3) = (_bs->accumulator >> 0); \
} while(0)
#define BitStream_Shift(_bs, _nbits) do { \
if (_nbits == 0) { \
} else if ((_nbits > 0) && (_nbits < 32)) { \
_bs->accumulator <<= _nbits; \
if (_nbits == 0) { \
} else if ((_nbits > 0) && (_nbits < 32)) { \
_bs->accumulator <<= _nbits; \
_bs->position += _nbits; \
_bs->offset += _nbits; \
if (_bs->offset < 32) { \
_bs->mask = ((1 << _nbits) - 1); \
_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \
_bs->prefetch <<= _nbits; \
} else { \
_bs->mask = ((1 << _nbits) - 1); \
_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \
_bs->prefetch <<= _nbits; \
_bs->offset -= 32; \
_bs->pointer += 4; \
BitStream_Prefetch(_bs); \
if (_bs->offset) { \
_bs->mask = ((1 << _bs->offset) - 1); \
_bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask); \
_bs->prefetch <<= _bs->offset; \
} \
} \
} else { \
WLog_WARN("com.winpr.bitstream", "warning: BitStream_Shift(%d)", _nbits); \
} \
} while(0)
#define BitStream_Shift32(_bs) do { \
BitStream_Shift(_bs, 16); \
BitStream_Shift(_bs, 16); \
} while(0)
#define BitStream_Write_Bits(_bs, _bits, _nbits) do { \
_bs->position += _nbits; \
_bs->offset += _nbits; \
if (_bs->offset < 32) { \
_bs->mask = ((1 << _nbits) - 1); \
_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \
_bs->prefetch <<= _nbits; \
_bs->accumulator |= (_bits << (32 - _bs->offset)); \
} else { \
_bs->mask = ((1 << _nbits) - 1); \
_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \
_bs->prefetch <<= _nbits; \
_bs->offset -= 32; \
_bs->mask = ((1 << (_nbits - _bs->offset)) - 1); \
_bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask); \
BitStream_Flush(bs); \
_bs->accumulator = 0; \
_bs->pointer += 4; \
BitStream_Prefetch(_bs); \
if (_bs->offset) { \
_bs->mask = ((1 << _bs->offset) - 1); \
_bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask); \
_bs->prefetch <<= _bs->offset; \
_bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset)); \
} \
} \
} else { \
fprintf(stderr, "warning: BitStream_Shift(%d)\n", _nbits); \
} \
} while(0)
#define BitStream_Shift32(_bs) do { \
BitStream_Shift(_bs, 16); \
BitStream_Shift(_bs, 16); \
} while(0)
#define BitStream_Write_Bits(_bs, _bits, _nbits) do { \
_bs->position += _nbits; \
_bs->offset += _nbits; \
if (_bs->offset < 32) { \
_bs->accumulator |= (_bits << (32 - _bs->offset)); \
} else { \
_bs->offset -= 32; \
_bs->mask = ((1 << (_nbits - _bs->offset)) - 1); \
_bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask); \
BitStream_Flush(bs); \
_bs->accumulator = 0; \
_bs->pointer += 4; \
if (_bs->offset) { \
_bs->mask = ((1 << _bs->offset) - 1); \
_bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset)); \
} \
} \
} while(0)
} while(0)
#define BitStream_GetRemainingLength(_bs) \
(_bs->length - _bs->position)
WINPR_API void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags);
WINPR_API UINT32 ReverseBits32(UINT32 bits, UINT32 nbits);
WINPR_API void BitDump(const char* tag, int level, const BYTE* buffer, UINT32 length, UINT32 flags);
WINPR_API UINT32 ReverseBits32(UINT32 bits, UINT32 nbits);
WINPR_API void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity);
WINPR_API void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity);
WINPR_API wBitStream* BitStream_New();
WINPR_API void BitStream_Free(wBitStream* bs);
WINPR_API wBitStream* BitStream_New();
WINPR_API void BitStream_Free(wBitStream* bs);
#ifdef __cplusplus
}

View File

@ -33,14 +33,14 @@
extern "C" {
#endif
WINPR_API void winpr_HexDump(const BYTE* data, int length);
WINPR_API void winpr_CArrayDump(const BYTE* data, int length, int width);
WINPR_API void winpr_HexDump(const char* tag, int lvl, const BYTE* data, int length);
WINPR_API void winpr_CArrayDump(const char* tag, int lvl, const BYTE* data, int length, int width);
WINPR_API char* winpr_BinToHexString(const BYTE* data, int length, BOOL space);
WINPR_API int wprintfx(const char *fmt, ...);
WINPR_API int wvprintfx(const char *fmt, va_list args);
WINPR_API int wvsnprintfx(char *buffer, size_t bufferSize, const char* fmt, va_list args);
WINPR_API int wprintfx(const char* fmt, ...);
WINPR_API int wvprintfx(const char* fmt, va_list args);
WINPR_API int wvsnprintfx(char* buffer, size_t bufferSize, const char* fmt, va_list args);
#ifdef __cplusplus
}

View File

@ -128,6 +128,7 @@ typedef int (*WLOG_APPENDER_WRITE_PACKET_MESSAGE_FN)(wLog* log, wLogAppender* ap
DWORD State; \
wLogLayout* Layout; \
CRITICAL_SECTION lock; \
BOOL recursive; \
void* TextMessageContext; \
void* DataMessageContext; \
void* ImageMessageContext; \
@ -214,68 +215,86 @@ WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...);
WINPR_API int WLog_PrintMessageVA(wLog* log, wLogMessage* message, va_list args);
#define WLog_Print(_log, _log_level, _fmt, ...) \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_TEXT; \
_log_message.Level = _log_level; \
_log_message.FormatString = _fmt; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
}
do { \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_TEXT; \
_log_message.Level = _log_level; \
_log_message.FormatString = _fmt; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
} \
} while (0)
#define WLog_PrintVA(_log, _log_level, _fmt, _args) \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_TEXT; \
_log_message.Level = _log_level; \
_log_message.FormatString = _fmt; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessageVA(_log, &(_log_message), _args); \
}
do { \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_TEXT; \
_log_message.Level = _log_level; \
_log_message.FormatString = _fmt; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessageVA(_log, &(_log_message), _args); \
} \
} while (0)
#define WLog_Data(_log, _log_level, ...) \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_DATA; \
_log_message.Level = _log_level; \
_log_message.FormatString = NULL; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
}
do { \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_DATA; \
_log_message.Level = _log_level; \
_log_message.FormatString = NULL; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
} \
} while (0)
#define WLog_Image(_log, _log_level, ...) \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_IMAGE; \
_log_message.Level = _log_level; \
_log_message.FormatString = NULL; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
}
do { \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_IMAGE; \
_log_message.Level = _log_level; \
_log_message.FormatString = NULL; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
} \
} while (0)
#define WLog_Packet(_log, _log_level, ...) \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_PACKET; \
_log_message.Level = _log_level; \
_log_message.FormatString = NULL; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
}
do { \
if (_log_level >= WLog_GetLogLevel(_log)) { \
wLogMessage _log_message; \
_log_message.Type = WLOG_MESSAGE_PACKET; \
_log_message.Level = _log_level; \
_log_message.FormatString = NULL; \
_log_message.LineNumber = __LINE__; \
_log_message.FileName = __FILE__; \
_log_message.FunctionName = __FUNCTION__; \
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
} \
} while (0)
#define WLog_IsLevelActive(_log, _log_level) \
(_log_level >= WLog_GetLogLevel(_log))
#define WLog_LVL(tag, lvl, fmt, ...) WLog_Print(WLog_Get(tag), lvl, fmt, ## __VA_ARGS__)
#define WLog_VRB(tag, fmt, ...) WLog_Print(WLog_Get(tag), WLOG_TRACE, fmt, ## __VA_ARGS__)
#define WLog_DBG(tag, fmt, ...) WLog_Print(WLog_Get(tag), WLOG_DEBUG, fmt, ## __VA_ARGS__)
#define WLog_INFO(tag, fmt, ...) WLog_Print(WLog_Get(tag), WLOG_INFO, fmt, ## __VA_ARGS__)
#define WLog_WARN(tag, fmt, ...) WLog_Print(WLog_Get(tag), WLOG_WARN, fmt, ## __VA_ARGS__)
#define WLog_ERR(tag, fmt, ...) WLog_Print(WLog_Get(tag), WLOG_ERROR, fmt, ## __VA_ARGS__)
#define WLog_FATAL(tag, fmt, ...) WLog_Print(WLog_Get(tag), WLOG_FATAL, fmt, ## __VA_ARGS__)
WINPR_API DWORD WLog_GetLogLevel(wLog* log);
WINPR_API void WLog_SetLogLevel(wLog* log, DWORD logLevel);

View File

@ -42,6 +42,9 @@
#include <malloc.h>
#endif
#include "../log.h"
#define TAG WINPR_TAG("crt")
struct winpr_aligned_mem
{
UINT32 sig;
@ -90,12 +93,10 @@ void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
return NULL;
memblock = (void*)((((size_t)(((BYTE*) base) + alignment + offset + sizeof(WINPR_ALIGNED_MEM)) & ~(alignment - 1)) - offset));
pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
pMem->sig = WINPR_ALIGNED_MEM_SIGNATURE;
pMem->base_addr = base;
pMem->size = size;
return memblock;
}
@ -125,15 +126,13 @@ void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, siz
if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
{
fprintf(stderr, "_aligned_offset_realloc: memory block was not allocated by _aligned_malloc!\n");
WLog_ERR(TAG, "_aligned_offset_realloc: memory block was not allocated by _aligned_malloc!");
return NULL;
}
copySize = (pNewMem->size < pMem->size) ? pNewMem->size : pMem->size;
CopyMemory(newMemblock, memblock, copySize);
_aligned_free(memblock);
return newMemblock;
}
@ -162,13 +161,12 @@ void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t a
if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
{
fprintf(stderr, "_aligned_offset_recalloc: memory block was not allocated by _aligned_malloc!\n");
WLog_ERR(TAG, "_aligned_offset_recalloc: memory block was not allocated by _aligned_malloc!");
return NULL;
}
ZeroMemory(newMemblock, pNewMem->size);
_aligned_free(memblock);
return newMemblock;
}
@ -183,7 +181,7 @@ size_t _aligned_msize(void* memblock, size_t alignment, size_t offset)
if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
{
fprintf(stderr, "_aligned_msize: memory block was not allocated by _aligned_malloc!\n");
WLog_ERR(TAG, "_aligned_msize: memory block was not allocated by _aligned_malloc!");
return 0;
}
@ -201,7 +199,7 @@ void _aligned_free(void* memblock)
if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
{
fprintf(stderr, "_aligned_free: memory block was not allocated by _aligned_malloc!\n");
WLog_ERR(TAG, "_aligned_free: memory block was not allocated by _aligned_malloc!");
return;
}

View File

@ -32,6 +32,9 @@
#include "casing.c"
#include "../log.h"
#define TAG WINPR_TAG("crt")
char* _strdup(const char* strSource)
{
char* strDestination;
@ -42,7 +45,7 @@ char* _strdup(const char* strSource)
strDestination = strdup(strSource);
if (strDestination == NULL)
perror("strdup");
WLog_ERR(TAG,"strdup");
return strDestination;
}
@ -61,12 +64,13 @@ WCHAR* _wcsdup(const WCHAR* strSource)
if (strDestination != NULL)
wcscpy((wchar_t*)strDestination, (const wchar_t*)strSource);
#else
strDestination = (WCHAR*) wcsdup((wchar_t*) strSource);
#endif
if (strDestination == NULL)
perror("wcsdup");
WLog_ERR(TAG,"wcsdup");
return strDestination;
}
@ -148,7 +152,6 @@ WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context)
*strToken++ = 0;
*context = strToken;
return nextToken;
}
@ -165,6 +168,7 @@ LPSTR CharUpperA(LPSTR lpsz)
return NULL;
length = strlen(lpsz);
if (length < 1)
return (LPSTR) NULL;
@ -176,7 +180,6 @@ LPSTR CharUpperA(LPSTR lpsz)
c = c - 32;
*lpsz = c;
return lpsz;
}
@ -191,8 +194,7 @@ LPSTR CharUpperA(LPSTR lpsz)
LPWSTR CharUpperW(LPWSTR lpsz)
{
fprintf(stderr, "CharUpperW unimplemented!\n");
WLog_ERR(TAG, "CharUpperW unimplemented!");
return (LPWSTR) NULL;
}
@ -245,7 +247,6 @@ LPSTR CharLowerA(LPSTR lpsz)
c = c + 32;
*lpsz = c;
return lpsz;
}
@ -260,8 +261,7 @@ LPSTR CharLowerA(LPSTR lpsz)
LPWSTR CharLowerW(LPWSTR lpsz)
{
fprintf(stderr, "CharLowerW unimplemented!\n");
WLog_ERR(TAG, "CharLowerW unimplemented!");
return (LPWSTR) NULL;
}
@ -303,7 +303,7 @@ BOOL IsCharAlphaA(CHAR ch)
BOOL IsCharAlphaW(WCHAR ch)
{
fprintf(stderr, "IsCharAlphaW unimplemented!\n");
WLog_ERR(TAG, "IsCharAlphaW unimplemented!");
return 0;
}
@ -318,7 +318,7 @@ BOOL IsCharAlphaNumericA(CHAR ch)
BOOL IsCharAlphaNumericW(WCHAR ch)
{
fprintf(stderr, "IsCharAlphaNumericW unimplemented!\n");
WLog_ERR(TAG, "IsCharAlphaNumericW unimplemented!");
return 0;
}
@ -332,7 +332,7 @@ BOOL IsCharUpperA(CHAR ch)
BOOL IsCharUpperW(WCHAR ch)
{
fprintf(stderr, "IsCharUpperW unimplemented!\n");
WLog_ERR(TAG, "IsCharUpperW unimplemented!");
return 0;
}
@ -346,7 +346,7 @@ BOOL IsCharLowerA(CHAR ch)
BOOL IsCharLowerW(WCHAR ch)
{
fprintf(stderr, "IsCharLowerW unimplemented!\n");
WLog_ERR(TAG, "IsCharLowerW unimplemented!");
return 0;
}

View File

@ -1,8 +1,8 @@
/*
* Copyright 2001-2004 Unicode, Inc.
*
*
* Disclaimer
*
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
@ -10,9 +10,9 @@
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
*
* Limitations on Rights to Redistribute This Code
*
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
@ -52,108 +52,156 @@ static const DWORD halfMask = 0x3FFUL;
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF16 (
const DWORD** sourceStart, const DWORD* sourceEnd,
WCHAR** targetStart, WCHAR* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const DWORD* source = *sourceStart;
WCHAR* target = *targetStart;
while (source < sourceEnd) {
DWORD ch;
if (target >= targetEnd) {
result = targetExhausted; break;
}
ch = *source++;
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = (WCHAR)ch; /* normal case */
}
} else if (ch > UNI_MAX_LEGAL_UTF32) {
if (flags == strictConversion) {
result = sourceIllegal;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
--source; /* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (WCHAR)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (WCHAR)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
ConversionResult ConvertUTF32toUTF16(
const DWORD** sourceStart, const DWORD* sourceEnd,
WCHAR** targetStart, WCHAR* targetEnd, ConversionFlags flags)
{
ConversionResult result = conversionOK;
const DWORD* source = *sourceStart;
WCHAR* target = *targetStart;
while (source < sourceEnd)
{
DWORD ch;
if (target >= targetEnd)
{
result = targetExhausted;
break;
}
ch = *source++;
if (ch <= UNI_MAX_BMP) /* Target is a character <= 0xFFFF */
{
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
{
if (flags == strictConversion)
{
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
else
{
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else
{
*target++ = (WCHAR)ch; /* normal case */
}
}
else if (ch > UNI_MAX_LEGAL_UTF32)
{
if (flags == strictConversion)
{
result = sourceIllegal;
}
else
{
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else
{
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd)
{
--source; /* Back up source pointer! */
result = targetExhausted;
break;
}
ch -= halfBase;
*target++ = (WCHAR)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (WCHAR)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF32 (
const WCHAR** sourceStart, const WCHAR* sourceEnd,
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const WCHAR* source = *sourceStart;
DWORD* target = *targetStart;
DWORD ch, ch2;
while (source < sourceEnd) {
const WCHAR* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
} else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
} else if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
if (target >= targetEnd) {
source = oldSource; /* Back up source pointer! */
result = targetExhausted; break;
}
*target++ = ch;
}
*sourceStart = source;
*targetStart = target;
ConversionResult ConvertUTF16toUTF32(
const WCHAR** sourceStart, const WCHAR* sourceEnd,
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags)
{
ConversionResult result = conversionOK;
const WCHAR* source = *sourceStart;
DWORD* target = *targetStart;
DWORD ch, ch2;
while (source < sourceEnd)
{
const WCHAR* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END)
{
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd)
{
ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END)
{
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
}
else if (flags == strictConversion) /* it's an unpaired high surrogate */
{
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
else /* We don't have the 16 bits following the high surrogate. */
{
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
}
else if (flags == strictConversion)
{
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END)
{
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
if (target >= targetEnd)
{
source = oldSource; /* Back up source pointer! */
result = targetExhausted;
break;
}
*target++ = ch;
}
*sourceStart = source;
*targetStart = target;
#ifdef CVTUTF_DEBUG
if (result == sourceIllegal) {
fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
fflush(stderr);
}
if (result == sourceIllegal)
{
WLOG_WARN(TAG, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
}
#endif
return result;
return result;
}
/* --------------------------------------------------------------------- */
@ -165,15 +213,16 @@ if (result == sourceIllegal) {
* left as-is for anyone who may want to do such conversion, which was
* allowed in earlier algorithms.
*/
static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
static const char trailingBytesForUTF8[256] =
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
/*
@ -181,8 +230,9 @@ static const char trailingBytesForUTF8[256] = {
* This table contains as many values as there might be trailing bytes
* in a UTF-8 sequence.
*/
static const DWORD offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
static const DWORD offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL
};
/*
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
@ -213,9 +263,7 @@ ConversionResult ConvertUTF16toUTF8(
const WCHAR* source;
BOOL computeLength;
ConversionResult result;
computeLength = (!targetEnd) ? TRUE : FALSE;
source = *sourceStart;
target = *targetStart;
result = conversionOK;
@ -227,22 +275,21 @@ ConversionResult ConvertUTF16toUTF8(
const DWORD byteMask = 0xBF;
const DWORD byteMark = 0x80;
const WCHAR* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END)
{
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd)
{
DWORD ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END)
{
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
}
else if (flags == strictConversion)
@ -309,17 +356,19 @@ ConversionResult ConvertUTF16toUTF8(
{
switch (bytesToWrite)
{
/* note: everything falls through. */
/* note: everything falls through. */
case 4:
*--target = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 3:
*--target = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 2:
*--target = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 1:
*--target = (BYTE)(ch | firstByteMark[bytesToWrite]);
}
@ -328,8 +377,7 @@ ConversionResult ConvertUTF16toUTF8(
{
switch (bytesToWrite)
{
/* note: everything falls through. */
/* note: everything falls through. */
case 4:
--target;
ch >>= 6;
@ -352,7 +400,6 @@ ConversionResult ConvertUTF16toUTF8(
*sourceStart = source;
*targetStart = target;
return result;
}
@ -369,32 +416,55 @@ ConversionResult ConvertUTF16toUTF8(
* definition of UTF-8 goes up to 4-byte sequences.
*/
static BOOL isLegalUTF8(const BYTE *source, int length)
static BOOL isLegalUTF8(const BYTE* source, int length)
{
BYTE a;
const BYTE *srcptr = source + length;
const BYTE* srcptr = source + length;
switch (length)
{
default:
return FALSE;
/* Everything else falls through when "TRUE"... */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return FALSE;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return FALSE;
case 2: if ((a = (*--srcptr)) > 0xBF) return FALSE;
/* Everything else falls through when "TRUE"... */
case 4:
if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return FALSE;
case 3:
if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return FALSE;
case 2:
if ((a = (*--srcptr)) > 0xBF) return FALSE;
switch (*source)
{
/* no fall-through in this inner switch */
case 0xE0: if (a < 0xA0) return FALSE; break;
case 0xED: if (a > 0x9F) return FALSE; break;
case 0xF0: if (a < 0x90) return FALSE; break;
case 0xF4: if (a > 0x8F) return FALSE; break;
default: if (a < 0x80) return FALSE;
/* no fall-through in this inner switch */
case 0xE0:
if (a < 0xA0) return FALSE;
break;
case 0xED:
if (a > 0x9F) return FALSE;
break;
case 0xF0:
if (a < 0x90) return FALSE;
break;
case 0xF4:
if (a > 0x8F) return FALSE;
break;
default:
if (a < 0x80) return FALSE;
}
case 1: if (*source >= 0x80 && *source < 0xC2) return FALSE;
case 1:
if (*source >= 0x80 && *source < 0xC2) return FALSE;
}
if (*source > 0xF4)
@ -409,7 +479,7 @@ static BOOL isLegalUTF8(const BYTE *source, int length)
* Exported function to return whether a UTF-8 sequence is legal or not.
* This is not used here; it's just exported.
*/
BOOL isLegalUTF8Sequence(const BYTE *source, const BYTE *sourceEnd)
BOOL isLegalUTF8Sequence(const BYTE* source, const BYTE* sourceEnd)
{
int length = trailingBytesForUTF8[*source] + 1;
@ -429,9 +499,7 @@ ConversionResult ConvertUTF8toUTF16(
const BYTE* source;
BOOL computeLength;
ConversionResult result;
computeLength = (!targetEnd) ? TRUE : FALSE;
result = conversionOK;
source = *sourceStart;
target = *targetStart;
@ -459,12 +527,28 @@ ConversionResult ConvertUTF8toUTF16(
*/
switch (extraBytesToRead)
{
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
case 5:
ch += *source++;
ch <<= 6; /* remember, illegal UTF-8 */
case 4:
ch += *source++;
ch <<= 6; /* remember, illegal UTF-8 */
case 3:
ch += *source++;
ch <<= 6;
case 2:
ch += *source++;
ch <<= 6;
case 1:
ch += *source++;
ch <<= 6;
case 0:
ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
@ -480,7 +564,6 @@ ConversionResult ConvertUTF8toUTF16(
{
/* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
{
if (flags == strictConversion)
@ -524,7 +607,6 @@ ConversionResult ConvertUTF8toUTF16(
else
{
/* target is a character in range 0xFFFF - 0x10FFFF. */
if ((target + 1 >= targetEnd) && (!computeLength))
{
source -= (extraBytesToRead + 1); /* Back up source pointer! */
@ -549,123 +631,201 @@ ConversionResult ConvertUTF8toUTF16(
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF8 (
const DWORD** sourceStart, const DWORD* sourceEnd,
BYTE** targetStart, BYTE* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const DWORD* source = *sourceStart;
BYTE* target = *targetStart;
while (source < sourceEnd) {
DWORD ch;
unsigned short bytesToWrite = 0;
const DWORD byteMask = 0xBF;
const DWORD byteMark = 0x80;
ch = *source++;
if (flags == strictConversion ) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/*
* Figure out how many bytes the result will require. Turn any
* illegally large UTF32 things (> Plane 17) into replacement chars.
*/
if (ch < (DWORD)0x80) { bytesToWrite = 1;
} else if (ch < (DWORD)0x800) { bytesToWrite = 2;
} else if (ch < (DWORD)0x10000) { bytesToWrite = 3;
} else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
} else { bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
result = sourceIllegal;
}
ConversionResult ConvertUTF32toUTF8(
const DWORD** sourceStart, const DWORD* sourceEnd,
BYTE** targetStart, BYTE* targetEnd, ConversionFlags flags)
{
ConversionResult result = conversionOK;
const DWORD* source = *sourceStart;
BYTE* target = *targetStart;
target += bytesToWrite;
if (target > targetEnd) {
--source; /* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /* note: everything falls through. */
case 4: *--target = (BYTE)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (BYTE)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (BYTE)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (BYTE) (ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
while (source < sourceEnd)
{
DWORD ch;
unsigned short bytesToWrite = 0;
const DWORD byteMask = 0xBF;
const DWORD byteMark = 0x80;
ch = *source++;
if (flags == strictConversion)
{
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
{
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/*
* Figure out how many bytes the result will require. Turn any
* illegally large UTF32 things (> Plane 17) into replacement chars.
*/
if (ch < (DWORD)0x80)
{
bytesToWrite = 1;
}
else if (ch < (DWORD)0x800)
{
bytesToWrite = 2;
}
else if (ch < (DWORD)0x10000)
{
bytesToWrite = 3;
}
else if (ch <= UNI_MAX_LEGAL_UTF32)
{
bytesToWrite = 4;
}
else
{
bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
result = sourceIllegal;
}
target += bytesToWrite;
if (target > targetEnd)
{
--source; /* Back up source pointer! */
target -= bytesToWrite;
result = targetExhausted;
break;
}
switch (bytesToWrite) /* note: everything falls through. */
{
case 4:
*--target = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 3:
*--target = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 2:
*--target = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 1:
*--target = (BYTE)(ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF32 (
const BYTE** sourceStart, const BYTE* sourceEnd,
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const BYTE* source = *sourceStart;
DWORD* target = *targetStart;
while (source < sourceEnd) {
DWORD ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
if (! isLegalUTF8(source, extraBytesToRead+1)) {
result = sourceIllegal;
break;
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6;
case 4: ch += *source++; ch <<= 6;
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
ConversionResult ConvertUTF8toUTF32(
const BYTE** sourceStart, const BYTE* sourceEnd,
DWORD** targetStart, DWORD* targetEnd, ConversionFlags flags)
{
ConversionResult result = conversionOK;
const BYTE* source = *sourceStart;
DWORD* target = *targetStart;
if (target >= targetEnd) {
source -= (extraBytesToRead+1); /* Back up the source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_LEGAL_UTF32) {
/*
* UTF-16 surrogate values are illegal in UTF-32, and anything
* over Plane 17 (> 0x10FFFF) is illegal.
*/
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead+1); /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = ch;
}
} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
result = sourceIllegal;
*target++ = UNI_REPLACEMENT_CHAR;
}
}
*sourceStart = source;
*targetStart = target;
return result;
while (source < sourceEnd)
{
DWORD ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd)
{
result = sourceExhausted;
break;
}
/* Do this check whether lenient or strict */
if (! isLegalUTF8(source, extraBytesToRead+1))
{
result = sourceIllegal;
break;
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead)
{
case 5:
ch += *source++;
ch <<= 6;
case 4:
ch += *source++;
ch <<= 6;
case 3:
ch += *source++;
ch <<= 6;
case 2:
ch += *source++;
ch <<= 6;
case 1:
ch += *source++;
ch <<= 6;
case 0:
ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd)
{
source -= (extraBytesToRead+1); /* Back up the source pointer! */
result = targetExhausted;
break;
}
if (ch <= UNI_MAX_LEGAL_UTF32)
{
/*
* UTF-16 surrogate values are illegal in UTF-32, and anything
* over Plane 17 (> 0x10FFFF) is illegal.
*/
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
{
if (flags == strictConversion)
{
source -= (extraBytesToRead+1); /* return to the illegal value itself */
result = sourceIllegal;
break;
}
else
{
*target++ = UNI_REPLACEMENT_CHAR;
}
}
else
{
*target++ = ch;
}
}
else /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
{
result = sourceIllegal;
*target++ = UNI_REPLACEMENT_CHAR;
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* ---------------------------------------------------------------------

View File

@ -2,6 +2,7 @@
#include <winpr/crt.h>
#include <winpr/print.h>
#include <winpr/crypto.h>
#include <winpr/wlog.h>
static const char* SECRET_PASSWORD_TEST = "MySecretPassword123!";
@ -11,13 +12,10 @@ int TestCryptoProtectMemory(int argc, char* argv[])
int cbCipherText;
char* pPlainText;
BYTE* pCipherText;
pPlainText = (char*) SECRET_PASSWORD_TEST;
cbPlainText = strlen(pPlainText) + 1;
cbCipherText = cbPlainText + (CRYPTPROTECTMEMORY_BLOCK_SIZE - (cbPlainText % CRYPTPROTECTMEMORY_BLOCK_SIZE));
printf("cbPlainText: %d cbCipherText: %d\n", cbPlainText, cbCipherText);
pCipherText = (BYTE*) malloc(cbCipherText);
CopyMemory(pCipherText, pPlainText, cbPlainText);
ZeroMemory(&pCipherText[cbPlainText], (cbCipherText - cbPlainText));
@ -29,8 +27,7 @@ int TestCryptoProtectMemory(int argc, char* argv[])
}
printf("PlainText: %s (cbPlainText = %d, cbCipherText = %d)\n", pPlainText, cbPlainText, cbCipherText);
winpr_HexDump(pCipherText, cbCipherText);
winpr_HexDump("crypto.test", WLOG_DEBUG, pCipherText, cbCipherText);
if (!CryptUnprotectMemory(pCipherText, cbCipherText, CRYPTPROTECTMEMORY_SAME_PROCESS))
{
@ -39,9 +36,7 @@ int TestCryptoProtectMemory(int argc, char* argv[])
}
printf("Decrypted CipherText: %s\n", pCipherText);
SecureZeroMemory(pCipherText, cbCipherText);
free(pCipherText);
return 0;
}

View File

@ -40,6 +40,9 @@
#include <fcntl.h>
#endif
#include "../log.h"
#define TAG WINPR_TAG("file")
/**
* api-ms-win-core-file-l1-2-0.dll:
*
@ -194,20 +197,16 @@
*/
/* _HandleCreators is a NULL-terminated array with a maximun of HANDLE_CREATOR_MAX HANDLE_CREATOR */
#define HANDLE_CREATOR_MAX 128
static HANDLE_CREATOR **_HandleCreators = NULL;
static HANDLE_CREATOR** _HandleCreators = NULL;
static CRITICAL_SECTION _HandleCreatorsLock;
static pthread_once_t _HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
static void _HandleCreatorsInit()
{
/* NB: error management to be done outside of this function */
assert(_HandleCreators == NULL);
_HandleCreators = (HANDLE_CREATOR**)calloc(HANDLE_CREATOR_MAX+1, sizeof(HANDLE_CREATOR*));
InitializeCriticalSection(&_HandleCreatorsLock);
assert(_HandleCreators != NULL);
}
@ -234,7 +233,6 @@ BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator)
return FALSE;
}
EnterCriticalSection(&_HandleCreatorsLock);
for (i=0; i<HANDLE_CREATOR_MAX; i++)
@ -242,15 +240,12 @@ BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator)
if (_HandleCreators[i] == NULL)
{
_HandleCreators[i] = pHandleCreator;
LeaveCriticalSection(&_HandleCreatorsLock);
return TRUE;
}
}
SetLastError(ERROR_INSUFFICIENT_BUFFER);
LeaveCriticalSection(&_HandleCreatorsLock);
return FALSE;
}
@ -262,7 +257,7 @@ static BOOL g_AioSignalHandlerInstalled = FALSE;
void AioSignalHandler(int signum, siginfo_t* siginfo, void* arg)
{
printf("AioSignalHandler\n");
WLog_INFO("%d", signum);
}
int InstallAioSignalHandler()
@ -270,15 +265,11 @@ int InstallAioSignalHandler()
if (!g_AioSignalHandlerInstalled)
{
struct sigaction action;
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGIO);
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = (void*) &AioSignalHandler;
sigaction(SIGIO, &action, NULL);
g_AioSignalHandlerInstalled = TRUE;
}
@ -288,7 +279,7 @@ int InstallAioSignalHandler()
#endif /* HAVE_AIO_H */
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
int i;
char* name;
@ -316,12 +307,12 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
for (i=0; _HandleCreators[i] != NULL; i++)
{
HANDLE_CREATOR *creator = (HANDLE_CREATOR*)_HandleCreators[i];
HANDLE_CREATOR* creator = (HANDLE_CREATOR*)_HandleCreators[i];
if (creator && creator->IsHandled(lpFileName))
{
HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
LeaveCriticalSection(&_HandleCreatorsLock);
return newHandle;
}
@ -340,12 +331,9 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
return INVALID_HANDLE_VALUE;
free(name);
pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE));
hNamedPipe = (HANDLE) pNamedPipe;
WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE);
pNamedPipe->name = _strdup(lpFileName);
pNamedPipe->dwOpenMode = 0;
pNamedPipe->dwPipeMode = 0;
@ -354,18 +342,14 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
pNamedPipe->nInBufferSize = 0;
pNamedPipe->nDefaultTimeOut = 0;
pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes;
pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName);
pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName);
pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0);
pNamedPipe->serverfd = -1;
pNamedPipe->ServerMode = FALSE;
ZeroMemory(&s, sizeof(struct sockaddr_un));
s.sun_family = AF_UNIX;
strcpy(s.sun_path, pNamedPipe->lpFilePath);
status = connect(pNamedPipe->clientfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un));
if (status != 0)
@ -385,6 +369,7 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
if (flags != -1)
fcntl(pNamedPipe->clientfd, F_SETFL, flags | O_NONBLOCK);
#endif
}
@ -392,7 +377,7 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
}
HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
return NULL;
}
@ -400,9 +385,7 @@ HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
BOOL DeleteFileA(LPCSTR lpFileName)
{
int status;
status = unlink(lpFileName);
return (status != -1) ? TRUE : FALSE;
}
@ -412,13 +395,14 @@ BOOL DeleteFileW(LPCWSTR lpFileName)
}
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
{
ULONG Type;
PVOID Object;
BOOL status = TRUE;
if (hFile == INVALID_HANDLE_VALUE) {
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
@ -437,7 +421,6 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
{
int io_status;
WINPR_PIPE* pipe;
pipe = (WINPR_PIPE*) Object;
do
@ -467,7 +450,6 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
{
int io_status;
WINPR_NAMED_PIPE* pipe;
pipe = (WINPR_NAMED_PIPE*) Object;
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
@ -495,6 +477,7 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
case EWOULDBLOCK:
SetLastError(ERROR_NO_DATA);
break;
default:
SetLastError(ERROR_BROKEN_PIPE);
break;
@ -506,7 +489,6 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
else
{
/* Overlapped I/O */
if (!lpOverlapped)
return FALSE;
@ -514,27 +496,21 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
return FALSE;
pipe->lpOverlapped = lpOverlapped;
#ifdef HAVE_AIO_H
{
int aio_status;
struct aiocb cb;
ZeroMemory(&cb, sizeof(struct aiocb));
cb.aio_fildes = pipe->clientfd;
cb.aio_buf = lpBuffer;
cb.aio_nbytes = nNumberOfBytesToRead;
cb.aio_offset = lpOverlapped->Offset;
cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
cb.aio_sigevent.sigev_signo = SIGIO;
cb.aio_sigevent.sigev_value.sival_ptr = (void*) lpOverlapped;
InstallAioSignalHandler();
aio_status = aio_read(&cb);
printf("aio_read status: %d\n", aio_status);
WLog_DBG(TAG, "aio_read status: %d", aio_status);
if (aio_status < 0)
status = FALSE;
@ -542,15 +518,11 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
return status;
}
#else
/* synchronous behavior */
lpOverlapped->Internal = 0;
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToRead;
lpOverlapped->Pointer = (PVOID) lpBuffer;
SetEvent(lpOverlapped->hEvent);
#endif
}
@ -561,25 +533,26 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
}
BOOL ReadFileEx(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
return TRUE;
}
BOOL ReadFileScatter(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
{
return TRUE;
}
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
{
ULONG Type;
PVOID Object;
BOOL status = TRUE;
if (hFile == INVALID_HANDLE_VALUE) {
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
@ -590,7 +563,6 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
{
int io_status;
WINPR_PIPE* pipe;
pipe = (WINPR_PIPE*) Object;
do
@ -603,14 +575,12 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
io_status = 0;
*lpNumberOfBytesWritten = io_status;
return TRUE;
}
else if (Type == HANDLE_TYPE_NAMED_PIPE)
{
int io_status;
WINPR_NAMED_PIPE* pipe;
pipe = (WINPR_NAMED_PIPE*) Object;
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
@ -630,12 +600,13 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
{
*lpNumberOfBytesWritten = 0;
switch(errno)
switch (errno)
{
case EWOULDBLOCK:
io_status = 0;
status = TRUE;
break;
default:
status = FALSE;
}
@ -647,7 +618,6 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
else
{
/* Overlapped I/O */
if (!lpOverlapped)
return FALSE;
@ -655,26 +625,20 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
return FALSE;
pipe->lpOverlapped = lpOverlapped;
#ifdef HAVE_AIO_H
{
struct aiocb cb;
ZeroMemory(&cb, sizeof(struct aiocb));
cb.aio_fildes = pipe->clientfd;
cb.aio_buf = (void*) lpBuffer;
cb.aio_nbytes = nNumberOfBytesToWrite;
cb.aio_offset = lpOverlapped->Offset;
cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
cb.aio_sigevent.sigev_signo = SIGIO;
cb.aio_sigevent.sigev_value.sival_ptr = (void*) lpOverlapped;
InstallAioSignalHandler();
io_status = aio_write(&cb);
printf("aio_write status: %d\n", io_status);
WLog_DBG("aio_write status: %d", io_status);
if (io_status < 0)
status = FALSE;
@ -682,15 +646,11 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
return status;
}
#else
/* synchronous behavior */
lpOverlapped->Internal = 1;
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToWrite;
lpOverlapped->Pointer = (PVOID) lpBuffer;
SetEvent(lpOverlapped->hEvent);
#endif
}
@ -701,13 +661,13 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
}
BOOL WriteFileEx(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
return TRUE;
}
BOOL WriteFileGather(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
{
return TRUE;
}
@ -723,37 +683,37 @@ BOOL SetEndOfFile(HANDLE hFile)
}
DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
{
return TRUE;
}
BOOL SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
{
return TRUE;
}
BOOL LockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh)
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh)
{
return TRUE;
}
BOOL LockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
{
return TRUE;
}
BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
{
return TRUE;
}
BOOL UnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)
DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)
{
return TRUE;
}
@ -774,14 +734,10 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
int length;
struct stat fileStat;
WIN32_FILE_SEARCH* pFileSearch;
ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
pFileSearch = (WIN32_FILE_SEARCH*) malloc(sizeof(WIN32_FILE_SEARCH));
ZeroMemory(pFileSearch, sizeof(WIN32_FILE_SEARCH));
/* Separate lpFileName into path and pattern components */
p = strrchr(lpFileName, '/');
if (!p)
@ -792,7 +748,6 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
pFileSearch->lpPath = (LPSTR) malloc(length + 1);
CopyMemory(pFileSearch->lpPath, lpFileName, length);
pFileSearch->lpPath[length] = '\0';
length = strlen(lpFileName) - index;
pFileSearch->lpPattern = (LPSTR) malloc(length + 1);
CopyMemory(pFileSearch->lpPattern, &lpFileName[index + 1], length);
@ -813,7 +768,6 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
}
/* Open directory for reading */
pFileSearch->pDir = opendir(pFileSearch->lpPath);
if (!pFileSearch->pDir)
@ -847,13 +801,13 @@ HANDLE FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
}
HANDLE FindFirstFileExA(LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
{
return NULL;
}
HANDLE FindFirstFileExW(LPCWSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
{
return NULL;
}
@ -890,19 +844,20 @@ BOOL FindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
BOOL FindClose(HANDLE hFindFile)
{
WIN32_FILE_SEARCH* pFileSearch;
pFileSearch = (WIN32_FILE_SEARCH*) hFindFile;
if (pFileSearch)
{
if (pFileSearch->lpPath)
free(pFileSearch->lpPath);
if (pFileSearch->lpPattern)
free(pFileSearch->lpPattern);
if (pFileSearch->pDir)
closedir(pFileSearch->pDir);
free(pFileSearch);
free(pFileSearch);
return TRUE;
}
@ -947,7 +902,6 @@ char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName)
return NULL;
lpFileName = _strdup(&lpName[strlen(NAMED_PIPE_PREFIX_PATH)]);
return lpFileName;
}
@ -955,12 +909,9 @@ char* GetNamedPipeUnixDomainSocketBaseFilePathA()
{
char* lpTempPath;
char* lpPipePath;
lpTempPath = GetKnownPath(KNOWN_PATH_TEMP);
lpPipePath = GetCombinedPath(lpTempPath, ".pipe");
free(lpTempPath);
return lpPipePath;
}
@ -969,15 +920,11 @@ char* GetNamedPipeUnixDomainSocketFilePathA(LPCSTR lpName)
char* lpPipePath;
char* lpFileName;
char* lpFilePath;
lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA();
lpFileName = GetNamedPipeNameWithoutPrefixA(lpName);
lpFilePath = GetCombinedPath(lpPipePath, (char*) lpFileName);
free(lpPipePath);
free(lpFileName);
return lpFilePath;
}
@ -986,14 +933,12 @@ int GetNamePipeFileDescriptor(HANDLE hNamedPipe)
#ifndef _WIN32
int fd;
WINPR_NAMED_PIPE* pNamedPipe;
pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe;
if (!pNamedPipe || pNamedPipe->Type != HANDLE_TYPE_NAMED_PIPE)
return -1;
fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd;
return fd;
#else
return -1;
@ -1004,7 +949,6 @@ int UnixChangeFileMode(const char* filename, int flags)
{
#ifndef _WIN32
mode_t fl = 0;
fl |= (flags & 0x4000) ? S_ISUID : 0;
fl |= (flags & 0x2000) ? S_ISGID : 0;
fl |= (flags & 0x1000) ? S_ISVTX : 0;
@ -1017,7 +961,6 @@ int UnixChangeFileMode(const char* filename, int flags)
fl |= (flags & 0x0004) ? S_IROTH : 0;
fl |= (flags & 0x0002) ? S_IWOTH : 0;
fl |= (flags & 0x0001) ? S_IXOTH : 0;
return chmod(filename, fl);
#else
return 0;

View File

@ -34,6 +34,9 @@
#include <fcntl.h>
#endif
#include "../log.h"
#define TAG WINPR_TAG("file")
/**
* File System Behavior in the Microsoft Windows Environment:
* http://download.microsoft.com/download/4/3/8/43889780-8d45-4b2e-9d3a-c696a890309f/File%20System%20Behavior%20Overview.pdf
@ -42,7 +45,6 @@
LPSTR FilePatternFindNextWildcardA(LPCSTR lpPattern, DWORD* pFlags)
{
LPSTR lpWildcard;
*pFlags = 0;
lpWildcard = strpbrk(lpPattern, "*?~");
@ -82,7 +84,7 @@ LPSTR FilePatternFindNextWildcardA(LPCSTR lpPattern, DWORD* pFlags)
}
BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName, size_t cchFileName,
LPCSTR lpX, size_t cchX, LPCSTR lpY, size_t cchY, LPCSTR lpWildcard, LPSTR* ppMatchEnd)
LPCSTR lpX, size_t cchX, LPCSTR lpY, size_t cchY, LPCSTR lpWildcard, LPSTR* ppMatchEnd)
{
LPSTR lpMatch;
@ -101,7 +103,6 @@ BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName, size_t cchFileName,
/*
* State 0: match 'X'
*/
if (_strnicmp(lpFileName, lpX, cchX) != 0)
return FALSE;
@ -134,9 +135,7 @@ BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName, size_t cchFileName,
/**
* State 3: final state
*/
*ppMatchEnd = (LPSTR) &lpMatch[cchY];
return TRUE;
}
else if (*lpWildcard == '?')
@ -149,7 +148,6 @@ BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName, size_t cchFileName,
/*
* State 0: match 'X'
*/
if (cchFileName < cchX)
return FALSE;
@ -174,7 +172,7 @@ BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName, size_t cchFileName,
if (_strnicmp(lpMatch, lpY, cchY) != 0)
return FALSE;
}
}
else
{
if ((cchX + 1) > cchFileName)
@ -186,15 +184,12 @@ BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName, size_t cchFileName,
/**
* State 3: final state
*/
*ppMatchEnd = (LPSTR) &lpMatch[cchY];
return TRUE;
}
else if (*lpWildcard == '~')
{
fprintf(stderr, "warning: unimplemented '~' pattern match\n");
WLog_ERR(TAG, "warning: unimplemented '~' pattern match");
return TRUE;
}
@ -264,7 +259,6 @@ BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
if (!FilePatternFindNextWildcardA(lpTail, &dwFlags))
{
/* tail contains no wildcards */
if (cchFileName < cchTail)
return FALSE;
@ -308,7 +302,6 @@ BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
* ^EOF of .^
*
*/
lpWildcard = FilePatternFindNextWildcardA(lpPattern, &dwFlags);
if (lpWildcard)
@ -324,13 +317,10 @@ BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
size_t cchSubFileName;
size_t cchWildcard;
size_t cchNextWildcard;
cchSubPattern = cchPattern;
lpSubPattern = (LPSTR) lpPattern;
cchSubFileName = cchFileName;
lpSubFileName = (LPSTR) lpFileName;
cchWildcard = ((dwFlags & WILDCARD_DOS) ? 2 : 1);
lpNextWildcard = FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
@ -338,13 +328,10 @@ BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
{
lpX = (LPSTR) lpSubPattern;
cchX = (lpWildcard - lpSubPattern);
lpY = (LPSTR) &lpSubPattern[cchX + cchWildcard];
cchY = (cchSubPattern - (lpY - lpSubPattern));
match = FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName,
lpX, cchX, lpY, cchY, lpWildcard, &lpMatchEnd);
lpX, cchX, lpY, cchY, lpWildcard, &lpMatchEnd);
return match;
}
else
@ -353,25 +340,20 @@ BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
{
cchSubFileName = cchFileName - (lpSubFileName - lpFileName);
cchNextWildcard = ((dwNextFlags & WILDCARD_DOS) ? 2 : 1);
lpX = (LPSTR) lpSubPattern;
cchX = (lpWildcard - lpSubPattern);
lpY = (LPSTR) &lpSubPattern[cchX + cchWildcard];
cchY = (lpNextWildcard - lpWildcard) - cchWildcard;
match = FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName,
lpX, cchX, lpY, cchY, lpWildcard, &lpMatchEnd);
lpX, cchX, lpY, cchY, lpWildcard, &lpMatchEnd);
if (!match)
return FALSE;
lpSubFileName = lpMatchEnd;
cchWildcard = cchNextWildcard;
lpWildcard = lpNextWildcard;
dwFlags = dwNextFlags;
lpNextWildcard = FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
}
@ -381,7 +363,6 @@ BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
else
{
/* no wildcard characters */
if (_stricmp(lpFileName, lpPattern) == 0)
return TRUE;
}

View File

@ -44,27 +44,23 @@
/* _HandleCreators is a NULL-terminated array with a maximun of HANDLE_CREATOR_MAX HANDLE_CREATOR */
#define HANDLE_CLOSE_CB_MAX 128
static HANDLE_CLOSE_CB **_HandleCloseCbs = NULL;
static HANDLE_CLOSE_CB** _HandleCloseCbs = NULL;
static CRITICAL_SECTION _HandleCloseCbsLock;
static pthread_once_t _HandleCloseCbsInitialized = PTHREAD_ONCE_INIT;
static void _HandleCloseCbsInit()
{
/* NB: error management to be done outside of this function */
assert(_HandleCloseCbs == NULL);
_HandleCloseCbs = (HANDLE_CLOSE_CB**)calloc(HANDLE_CLOSE_CB_MAX+1, sizeof(HANDLE_CLOSE_CB*));
InitializeCriticalSection(&_HandleCloseCbsLock);
assert(_HandleCloseCbs != NULL);
}
/**
* Returns TRUE on success, FALSE otherwise.
*/
BOOL RegisterHandleCloseCb(HANDLE_CLOSE_CB *pHandleCloseCb)
BOOL RegisterHandleCloseCb(HANDLE_CLOSE_CB* pHandleCloseCb)
{
int i;
@ -85,7 +81,6 @@ BOOL RegisterHandleCloseCb(HANDLE_CLOSE_CB *pHandleCloseCb)
if (_HandleCloseCbs[i] == NULL)
{
_HandleCloseCbs[i] = pHandleCloseCb;
LeaveCriticalSection(&_HandleCloseCbsLock);
return TRUE;
}
@ -116,16 +111,15 @@ BOOL CloseHandle(HANDLE hObject)
return FALSE;
}
EnterCriticalSection(&_HandleCloseCbsLock);
for (i=0; _HandleCloseCbs[i] != NULL; i++)
{
HANDLE_CLOSE_CB *close_cb = (HANDLE_CLOSE_CB*)_HandleCloseCbs[i];
HANDLE_CLOSE_CB* close_cb = (HANDLE_CLOSE_CB*)_HandleCloseCbs[i];
if (close_cb && close_cb->IsHandled(hObject))
{
BOOL result = close_cb->CloseHandle(hObject);
LeaveCriticalSection(&_HandleCloseCbsLock);
return result;
}
@ -133,44 +127,37 @@ BOOL CloseHandle(HANDLE hObject)
LeaveCriticalSection(&_HandleCloseCbsLock);
if (Type == HANDLE_TYPE_THREAD)
{
WINPR_THREAD* thread;
thread = (WINPR_THREAD*) Object;
if (thread->started) {
if (thread->started)
{
pthread_detach(thread->thread);
}
free(thread);
free(thread);
return TRUE;
}
else if (Type == HANDLE_TYPE_PROCESS)
{
WINPR_PROCESS* process;
process = (WINPR_PROCESS*) Object;
free(process);
return TRUE;
}
else if (Type == HANDLE_TYPE_MUTEX)
{
WINPR_MUTEX* mutex;
mutex = (WINPR_MUTEX*) Object;
pthread_mutex_destroy(&mutex->mutex);
free(Object);
return TRUE;
}
else if (Type == HANDLE_TYPE_EVENT)
{
WINPR_EVENT* event;
event = (WINPR_EVENT*) Object;
if (!event->bAttached)
@ -180,6 +167,7 @@ BOOL CloseHandle(HANDLE hObject)
close(event->pipe_fd[0]);
event->pipe_fd[0] = -1;
}
if (event->pipe_fd[1] != -1)
{
close(event->pipe_fd[1]);
@ -188,15 +176,12 @@ BOOL CloseHandle(HANDLE hObject)
}
free(Object);
return TRUE;
}
else if (Type == HANDLE_TYPE_SEMAPHORE)
{
WINPR_SEMAPHORE* semaphore;
semaphore = (WINPR_SEMAPHORE*) Object;
#ifdef WINPR_PIPE_SEMAPHORE
if (semaphore->pipe_fd[0] != -1)
@ -212,37 +197,31 @@ BOOL CloseHandle(HANDLE hObject)
}
#else
#if defined __APPLE__
semaphore_destroy(mach_task_self(), *((winpr_sem_t*) semaphore->sem));
#else
sem_destroy((winpr_sem_t*) semaphore->sem);
#endif
#endif
free(Object);
return TRUE;
}
else if (Type == HANDLE_TYPE_TIMER)
{
WINPR_TIMER* timer;
timer = (WINPR_TIMER*) Object;
#ifdef __linux__
if (timer->fd != -1)
close(timer->fd);
#endif
free(Object);
return TRUE;
}
else if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
{
WINPR_PIPE* pipe;
pipe = (WINPR_PIPE*) Object;
if (pipe->fd != -1)
@ -251,19 +230,21 @@ BOOL CloseHandle(HANDLE hObject)
}
free(Object);
return TRUE;
}
else if (Type == HANDLE_TYPE_NAMED_PIPE)
{
WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*) Object;
if (pNamedPipe->clientfd != -1) {
//fprintf(stderr, "%s: closing clientfd %d\n", __FUNCTION__, pNamedPipe->clientfd);
if (pNamedPipe->clientfd != -1)
{
//WLOG_DBG(TAG, "%s: closing clientfd %d\n", __FUNCTION__, pNamedPipe->clientfd);
close(pNamedPipe->clientfd);
}
if (pNamedPipe->serverfd != -1) {
//fprintf(stderr, "%s: closing serverfd %d\n", __FUNCTION__, pNamedPipe->serverfd);
if (pNamedPipe->serverfd != -1)
{
//WLOG_DBG(TAG, "%s: closing serverfd %d\n", __FUNCTION__, pNamedPipe->serverfd);
close(pNamedPipe->serverfd);
}
@ -274,13 +255,11 @@ BOOL CloseHandle(HANDLE hObject)
free((void*)pNamedPipe->lpFilePath);
free((void*)pNamedPipe->name);
free(pNamedPipe);
return TRUE;
}
else if (Type == HANDLE_TYPE_ACCESS_TOKEN)
{
WINPR_ACCESS_TOKEN* token;
token = (WINPR_ACCESS_TOKEN*) Object;
if (token->Username)
@ -290,7 +269,6 @@ BOOL CloseHandle(HANDLE hObject)
free(token->Domain);
free(token);
return TRUE;
}
@ -298,7 +276,7 @@ BOOL CloseHandle(HANDLE hObject)
}
BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle,
LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
{
return TRUE;
}

View File

@ -26,6 +26,9 @@
#include <winpr/library.h>
#include "../log.h"
#define TAG WINPR_TAG("library")
/**
* api-ms-win-core-libraryloader-l1-1-1.dll:
*
@ -92,12 +95,11 @@ BOOL SetDefaultDllDirectories(DWORD DirectoryFlags)
HMODULE LoadLibraryA(LPCSTR lpLibFileName)
{
HMODULE library;
library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
if (!library)
{
fprintf(stderr, "LoadLibraryA: %s\n", dlerror());
WLog_ERR(TAG, "LoadLibraryA: %s", dlerror());
return NULL;
}
@ -112,12 +114,11 @@ HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
HMODULE library;
library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
if (!library)
{
fprintf(stderr, "LoadLibraryExA: failed to open %s: %s\n", lpLibFileName, dlerror());
WLog_ERR(TAG, "LoadLibraryExA: failed to open %s: %s", lpLibFileName, dlerror());
return NULL;
}
@ -132,12 +133,11 @@ HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
FARPROC proc;
proc = dlsym(hModule, lpProcName);
if (proc == NULL)
{
fprintf(stderr, "GetProcAddress: could not find procedure %s: %s\n", lpProcName, dlerror());
WLog_ERR(TAG, "GetProcAddress: could not find procedure %s: %s", lpProcName, dlerror());
return (FARPROC) NULL;
}
@ -147,7 +147,6 @@ FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
BOOL FreeLibrary(HMODULE hLibModule)
{
int status;
status = dlclose(hLibModule);
if (status != 0)
@ -180,7 +179,7 @@ DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)
}
DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
{
{
#if defined(__linux__)
int status;
int length;
@ -189,16 +188,13 @@ DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
if (!hModule)
{
char buffer[4096];
sprintf(path, "/proc/%d/exe", getpid());
status = readlink(path, buffer, sizeof(buffer));
if (status < 0)
return 0;
buffer[status] = '\0';
length = strlen(buffer);
if (length < nSize)
@ -214,33 +210,31 @@ DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
return 0;
}
#elif defined(__MACOSX__)
int status;
int length;
if (!hModule)
{
char path[4096];
char buffer[4096];
uint32_t size = sizeof(path);
status = _NSGetExecutablePath(path, &size);
if (status != 0)
{
/* path too small */
return 0;
}
/*
* _NSGetExecutablePath may not return the canonical path,
* so use realpath to find the absolute, canonical path.
*/
realpath(path, buffer);
length = strlen(buffer);
if (length < nSize)
{
CopyMemory(lpFilename, buffer, length);
@ -251,11 +245,11 @@ DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
CopyMemory(lpFilename, buffer, nSize - 1);
lpFilename[nSize - 1] = '\0';
}
return 0;
}
#endif
#endif
return 0;
}

View File

@ -1,8 +1,8 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Windows RAIL
* Winpr log defines
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.com>
* Copyright 2014 Armin Novak <armin.novak@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,11 +17,11 @@
* limitations under the License.
*/
#ifndef __WF_WINDOW_H
#define __WF_WINDOW_H
#ifndef WINPR_LOG_PRIV_H
#define WINPR_LOG_PRIV_H
#include <freerdp/freerdp.h>
#include <winpr/wlog.h>
#include "wf_interface.h"
#define WINPR_TAG(tag) "com.winpr." tag
#endif
#endif /* FREERDP_UTILS_DEBUG_H */

View File

@ -45,6 +45,9 @@
#include "pipe.h"
#include "../log.h"
#define TAG WINPR_TAG("pipe")
/*
* Since the WinPR implementation of named pipes makes use of UNIX domain
* sockets, it is not possible to bind the same name more than once (i.e.,
@ -85,13 +88,12 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
int pipe_fd[2];
WINPR_PIPE* pReadPipe;
WINPR_PIPE* pWritePipe;
pipe_fd[0] = -1;
pipe_fd[1] = -1;
if (pipe(pipe_fd) < 0)
{
printf("CreatePipe: failed to create pipe\n");
WLog_ERR(TAG, "failed to create pipe");
return FALSE;
}
@ -111,13 +113,10 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
pReadPipe->fd = pipe_fd[0];
pWritePipe->fd = pipe_fd[1];
WINPR_HANDLE_SET_TYPE(pReadPipe, HANDLE_TYPE_ANONYMOUS_PIPE);
*((ULONG_PTR*) hReadPipe) = (ULONG_PTR) pReadPipe;
WINPR_HANDLE_SET_TYPE(pWritePipe, HANDLE_TYPE_ANONYMOUS_PIPE);
*((ULONG_PTR*) hWritePipe) = (ULONG_PTR) pWritePipe;
return TRUE;
}
@ -128,43 +127,46 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
static void winpr_unref_named_pipe(WINPR_NAMED_PIPE* pNamedPipe)
{
int index;
NamedPipeServerSocketEntry *baseSocket;
NamedPipeServerSocketEntry* baseSocket;
if (!pNamedPipe)
return;
assert(pNamedPipe->name);
assert(g_NamedPipeServerSockets);
//fprintf(stderr, "%s: %p (%s)\n", __FUNCTION__, pNamedPipe, pNamedPipe->name);
//WLog_VRB(TAG, "%s: %p (%s)", __FUNCTION__, pNamedPipe, pNamedPipe->name);
ArrayList_Lock(g_NamedPipeServerSockets);
for (index = 0; index < ArrayList_Count(g_NamedPipeServerSockets); index++)
{
baseSocket = (NamedPipeServerSocketEntry*) ArrayList_GetItem(
g_NamedPipeServerSockets, index);
g_NamedPipeServerSockets, index);
assert(baseSocket->name);
if (!strcmp(baseSocket->name, pNamedPipe->name))
{
assert(baseSocket->references > 0);
assert(baseSocket->serverfd != -1);
if (--baseSocket->references == 0)
{
//fprintf(stderr, "%s: removing shared server socked resource\n", __FUNCTION__);
//fprintf(stderr, "%s: closing shared serverfd %d\n", __FUNCTION__, baseSocket->serverfd);
//WLog_DBG(TAG, "%s: removing shared server socked resource", __FUNCTION__);
//WLog_DBG(TAG, "%s: closing shared serverfd %d", __FUNCTION__, baseSocket->serverfd);
ArrayList_Remove(g_NamedPipeServerSockets, baseSocket);
close(baseSocket->serverfd);
free(baseSocket->name);
free(baseSocket);
}
break;
}
}
ArrayList_Unlock(g_NamedPipeServerSockets);
}
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances,
DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
int index;
HANDLE hNamedPipe = INVALID_HANDLE_VALUE;
@ -172,23 +174,24 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
struct sockaddr_un s;
WINPR_NAMED_PIPE* pNamedPipe = NULL;
int serverfd = -1;
NamedPipeServerSocketEntry *baseSocket = NULL;
NamedPipeServerSocketEntry* baseSocket = NULL;
if (!lpName)
return INVALID_HANDLE_VALUE;
InitWinPRPipeModule();
pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE));
WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE);
if (!(pNamedPipe->name = _strdup(lpName)))
goto out;
if (!(pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName)))
goto out;
if (!(pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName)))
goto out;
pNamedPipe->dwOpenMode = dwOpenMode;
pNamedPipe->dwPipeMode = dwPipeMode;
pNamedPipe->nMaxInstances = nMaxInstances;
@ -196,20 +199,19 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
pNamedPipe->nInBufferSize = nInBufferSize;
pNamedPipe->nDefaultTimeOut = nDefaultTimeOut;
pNamedPipe->dwFlagsAndAttributes = dwOpenMode;
pNamedPipe->clientfd = -1;
pNamedPipe->ServerMode = TRUE;
ArrayList_Lock(g_NamedPipeServerSockets);
for (index = 0; index < ArrayList_Count(g_NamedPipeServerSockets); index++)
{
baseSocket = (NamedPipeServerSocketEntry*) ArrayList_GetItem(
g_NamedPipeServerSockets, index);
g_NamedPipeServerSockets, index);
if (!strcmp(baseSocket->name, lpName))
{
serverfd = baseSocket->serverfd;
//fprintf(stderr, "using shared socked resource for pipe %p (%s)\n", pNamedPipe, lpName);
//WLog_DBG(TAG, "using shared socked resource for pipe %p (%s)", pNamedPipe, lpName);
break;
}
}
@ -236,7 +238,7 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
if ((serverfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "CreateNamedPipeA: socket error, %s\n", strerror(errno));
WLog_ERR(TAG, "CreateNamedPipeA: socket error, %s", strerror(errno));
goto out;
}
@ -246,34 +248,35 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
if (bind(serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)) == -1)
{
fprintf(stderr, "CreateNamedPipeA: bind error, %s\n", strerror(errno));
WLog_ERR(TAG, "CreateNamedPipeA: bind error, %s", strerror(errno));
goto out;
}
if (listen(serverfd, 2) == -1)
{
fprintf(stderr, "CreateNamedPipeA: listen error, %s\n", strerror(errno));
WLog_ERR(TAG, "CreateNamedPipeA: listen error, %s", strerror(errno));
goto out;
}
UnixChangeFileMode(pNamedPipe->lpFilePath, 0xFFFF);
if (!(baseSocket = (NamedPipeServerSocketEntry *) malloc(sizeof(NamedPipeServerSocketEntry))))
if (!(baseSocket = (NamedPipeServerSocketEntry*) malloc(sizeof(NamedPipeServerSocketEntry))))
goto out;
if (!(baseSocket->name = _strdup(lpName)))
{
free(baseSocket);
goto out;
}
baseSocket->serverfd = serverfd;
baseSocket->references = 0;
ArrayList_Add(g_NamedPipeServerSockets, baseSocket);
//fprintf(stderr, "created shared socked resource for pipe %p (%s). base serverfd = %d\n", pNamedPipe, lpName, serverfd);
//WLog_DBG(TAG, "created shared socked resource for pipe %p (%s). base serverfd = %d", pNamedPipe, lpName, serverfd);
}
pNamedPipe->serverfd = dup(baseSocket->serverfd);
//fprintf(stderr, "using serverfd %d (duplicated from %d)\n", pNamedPipe->serverfd, baseSocket->serverfd);
//WLog_DBG(TAG, "using serverfd %d (duplicated from %d)", pNamedPipe->serverfd, baseSocket->serverfd);
pNamedPipe->pfnUnrefNamedPipe = winpr_unref_named_pipe;
baseSocket->references++;
@ -284,12 +287,13 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD
if (flags != -1)
fcntl(pNamedPipe->serverfd, F_SETFL, flags | O_NONBLOCK);
#endif
}
hNamedPipe = (HANDLE) pNamedPipe;
out:
if (hNamedPipe == INVALID_HANDLE_VALUE)
{
if (pNamedPipe)
@ -299,15 +303,17 @@ out:
free((void*)pNamedPipe->lpFilePath);
free(pNamedPipe);
}
if (serverfd != -1)
close(serverfd);
}
ArrayList_Unlock(g_NamedPipeServerSockets);
return hNamedPipe;
}
HANDLE CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances,
DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
return NULL;
}
@ -328,12 +334,11 @@ BOOL ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped)
{
length = sizeof(struct sockaddr_un);
ZeroMemory(&s, sizeof(struct sockaddr_un));
status = accept(pNamedPipe->serverfd, (struct sockaddr*) &s, &length);
if (status < 0)
{
fprintf(stderr, "ConnectNamedPipe: accept error\n");
WLog_ERR(TAG, "ConnectNamedPipe: accept error");
return FALSE;
}
@ -349,13 +354,10 @@ BOOL ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped)
return FALSE;
pNamedPipe->lpOverlapped = lpOverlapped;
/* synchronous behavior */
lpOverlapped->Internal = 2;
lpOverlapped->InternalHigh = (ULONG_PTR) 0;
lpOverlapped->Pointer = (PVOID) NULL;
SetEvent(lpOverlapped->hEvent);
}
@ -365,7 +367,6 @@ BOOL ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped)
BOOL DisconnectNamedPipe(HANDLE hNamedPipe)
{
WINPR_NAMED_PIPE* pNamedPipe;
pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe;
if (pNamedPipe->clientfd != -1)
@ -378,14 +379,16 @@ BOOL DisconnectNamedPipe(HANDLE hNamedPipe)
}
BOOL PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize,
LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
{
WLog_ERR(TAG, "Not implemented");
return TRUE;
}
BOOL TransactNamedPipe(HANDLE hNamedPipe, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
DWORD nOutBufferSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
{
WLog_ERR(TAG, "Not implemented");
return TRUE;
}
@ -419,12 +422,14 @@ BOOL WaitNamedPipeA(LPCSTR lpNamedPipeName, DWORD nTimeOut)
break;
}
}
free(lpFilePath);
return status;
}
BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
{
WLog_ERR(TAG, "Not implemented");
return TRUE;
}
@ -433,13 +438,11 @@ BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCol
int fd;
int flags;
WINPR_NAMED_PIPE* pNamedPipe;
pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe;
if (lpMode)
{
pNamedPipe->dwPipeMode = *lpMode;
fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd;
if (fd == -1)
@ -457,12 +460,10 @@ BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCol
if (lpMaxCollectionCount)
{
}
if (lpCollectDataTimeout)
{
}
return TRUE;
@ -470,16 +471,19 @@ BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCol
BOOL ImpersonateNamedPipeClient(HANDLE hNamedPipe)
{
WLog_ERR(TAG, "Not implemented");
return FALSE;
}
BOOL GetNamedPipeClientComputerNameA(HANDLE Pipe, LPCSTR ClientComputerName, ULONG ClientComputerNameLength)
{
WLog_ERR(TAG, "Not implemented");
return FALSE;
}
BOOL GetNamedPipeClientComputerNameW(HANDLE Pipe, LPCWSTR ClientComputerName, ULONG ClientComputerNameLength)
{
WLog_ERR(TAG, "Not implemented");
return FALSE;
}

Some files were not shown because too many files have changed in this diff Show More